/*  -*- Mode: C;  -*- */

/******************************************************************************
*                                                                             *
*   Copyright 2005 University of Cambridge Computer Laboratory.               *
*                                                                             *
*   This file is part of Nprobe.                                              *
*                                                                             *
*   Nprobe is free software; you can redistribute it and/or modify            *
*   it under the terms of the GNU General Public License as published by      *
*   the Free Software Foundation; either version 2 of the License, or         *
*   (at your option) any later version.                                       *
*                                                                             *
*   Nprobe is distributed in the hope that it will be useful,                 *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*   GNU General Public License for more details.                              *
*                                                                             *
*   You should have received a copy of the GNU General Public License         *
*   along with Nprobe; if not, write to the Free Software                     *
*   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA *
*                                                                             *
******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/mman.h>
#include <asm/page.h>
#ifdef __alpha__
#include <sys/mbuf.h>
#endif
#include <net/route.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <arpa/inet.h>

#ifdef __linux__
#define __USE_BSD
#endif
#include <netinet/ip.h>


#include <netinet/tcp.h>
#ifdef __alpha__
#include <net/if_llc.h>
#endif
#include <netinet/if_fddi.h>
#include <netinet/if_ether.h>

#include <unistd.h>
#include <assert.h>
#include <linux/limits.h>

#include "list.h"
#include "pkt.h"
#include "interface.h"
#include "tcpdump_patch.h"
#include "flows.h"
#include "service.h"
#include "http.h"
#include "tcp.h"
#include "udp.h"
#include "udp_ns.h"
#include "print_util.h"
#include "report.h"
#include "output.h"
#include "if_nprobe.h"
#include "tcpdump_patch.h"
#include "writer.h"
#include "probe_config.h"


/*
 * Dump  packet to dump file 
 */

void 
dump_pkt(prec_t *pp, int why, char *data, unsigned int atmdata)
{ 
  struct packet_header h; /* tcpdump packet hdr */
  char *write_start = dumpp;
  nprobe_hdr_t nh;		/* nprobe `header' */

  unsigned char *start = buf_start(pp);
  int len = pp->wirelen;
  
#ifdef PROBE_FED
  
#ifdef ATM_LANE
  start += 8;
  len -= 8;
#endif

#endif

  /* room in output buffer? */
 // printf("dump used %d written %d\n", dumpblk_used, dumpblk_written);
  if (len > 2000)
    printf("Bugger - infeasable dump len %d !\n", len);
  assert(len < 2000);
  if (dumpblk_used - dumpblk_written > N_DUMPBLKS -1)
    error("dump_pkt", "output buffers exhausted");
  
  nh.u.nh.code = -why;
  nh.u.nh.atmdata = htonl(atmdata);
  
  if (data)
    memcpy(nh.u.nh.data, data, NP_HDR_DATA_SZ);
  
  /* 
   * last two bytes set to mimic ether hdr type field 
   * - don't screw packet filter 
   */
  
  nh.u.nh.etype = ntohs(ETHERTYPE_IP);

#ifndef PROBE_FED
  if (pp->link_type != LINK_RAW_HIGH)
    {
      /* clear old nprobe header */
      start += sizeof(nprobe_hdr_t);
      len -= sizeof(nprobe_hdr_t);
    }
#endif
  
  assert (len >= 0);
  
  h.ts = pp->tstamp;  // struct assignment  

  h.len = h.cap_len = len + sizeof(nprobe_hdr_t);

  DUMP_STRUCT(dumpp, &h, struct packet_header);	/* write tcpdump hdr */
  DUMP_STRUCT(dumpp, &nh, nprobe_hdr_t); /* write pseudo mac header */
  DUMP_MEM(dumpp, start, len);	/* write packet */

  counters.dump_bytes_written += (dumpp - write_start);

  dumpbuf_manage(counters.dump_bytes_written >= dump_file_sz ? CYCLE : NO_CYCLE, 
		 NOT_CYCLE_SYNC, NOT_FINISHING);

  return;
}


/*
 * Args 4-6 not used (there for dump_pkt calling compatability only)
 */

void
dump_ethpkt(prec_t *pp, int why, char *data, unsigned int atmdata)
{
   
  struct packet_header h; /* tcpdump packet hdr */
  char *write_start = dumpp;		/* nprobe `header' */

  unsigned char *start = buf_start(pp);
  int len = pp->wirelen;

#ifdef PROBE_FED

  /*
   * Start points to IP hdr if online probe - otherwise to MAC hdr
   */
start -= sizeof(nprobe_hdr_t);
len += sizeof(nprobe_hdr_t);

#endif /* ifdef PROBE_FED */


  /* room in output buffer? */
 // printf("dump used %d written %d\n", dumpblk_used, dumpblk_written);
  if (len > 2000)
    printf("Bugger - infeasable dump len %d !\n", len);
  assert(len < 2000);
  if (dumpblk_used - dumpblk_written > N_DUMPBLKS -1)
    error("dump_pkt", "output buffers exhausted");
  
  assert (len >= 0);
  
  h.ts = pp->tstamp;  // struct assignment  

  h.len = h.cap_len = len;
  

  DUMP_STRUCT(dumpp, &h, struct packet_header);	/* write tcpdump hdr */
  DUMP_MEM(dumpp, start, len);	/* write packet */

  counters.dump_bytes_written += (dumpp - write_start);

  dumpbuf_manage(counters.dump_bytes_written >= dump_file_sz ? CYCLE : NO_CYCLE, 
		 NOT_CYCLE_SYNC, NOT_FINISHING);

  return;
}

/*****************************************************************************/








