/*
** wtap2dmp.c for  in 
** 
** Made by 
** Login   <vianney@epita.fr>
** 
** Started on  Thu Oct 28 20:12:16 1999 
** Last update Thu Oct 28 20:12:17 1999 
*/
#include <stdio.h>
#include <assert.h>
#include <wtap.h>
#include <pcap.h>

wtap			*wt;
FILE			*ostream = NULL;
int			records = 0;

/* the following is taken from libpcap as sf_write_header was static */
#define TCPDUMP_MAGIC 0xa1b2c3d4

int			my_sf_write_header(fp,linktype,thiszone,snaplen)
FILE			*fp;
int			linktype;
int			thiszone;
int			snaplen;
{
  struct pcap_file_header hdr;

  hdr.magic = TCPDUMP_MAGIC;
  hdr.version_major = PCAP_VERSION_MAJOR;
  hdr.version_minor = PCAP_VERSION_MINOR;
  hdr.thiszone = thiszone;
  hdr.snaplen = snaplen;
  hdr.sigfigs = 0;
  hdr.linktype = linktype;
  if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
    return (-1);
  return (0);
}

int			wtap_encap_to_pcap_linktype(wtapencap)
int			wtapencap;
{
  switch (wtapencap)
    {
    case WTAP_ENCAP_NONE:
      return (-1);
    case WTAP_ENCAP_ETHERNET:
      return (DLT_EN10MB);
    case WTAP_ENCAP_TR:
      return (DLT_IEEE802);
    case WTAP_ENCAP_SLIP:
      return (DLT_SLIP);
    case WTAP_ENCAP_PPP:
      return (DLT_PPP);
    case WTAP_ENCAP_FDDI:
      return (DLT_FDDI);
    case WTAP_ENCAP_RAW_IP:
      return (-1);
    case WTAP_ENCAP_ARCNET:
      return (DLT_ARCNET);
    case WTAP_ENCAP_ATM_RFC1483:
      return (DLT_ATM_RFC1483);
    }
  return (-1);
}

void			dispatch(ofile,wp,offset,buf)
char			*ofile;
struct wtap_pkthdr	*wp;
int			offset;
u_char			*buf;
{
  struct pcap_pkthdr	pp;
  static int		linktype = -1;
  static int		wtapencap = -1;

  if (ostream == NULL)
    {
      if (!strcmp(ofile,"-"))
	ostream = stdout;
      else
	{
	  if ((ostream = fopen(ofile,"w+")) == NULL)
	    {
	      perror("fopen");
	      exit(1);
	    }
	}
      if ((linktype = wtap_encap_to_pcap_linktype(wp->pkt_encap)) < 0)
	{
	  fprintf(stderr,"unknown wtap encapsulation %d\n",wp->pkt_encap);
	  exit(1);
	}
      wtapencap = wp->pkt_encap;
      my_sf_write_header(ostream,
			 linktype,
			 0, /* what should I put here? */
			 wtap_snapshot_length(wt));
    }
  if (wp->pkt_encap != wtapencap)
    {
      fprintf(stderr,
	      "stoping here because can't manage various linktypes in pcap\n");
      exit(1);
    }
  pp.ts.tv_sec = wp->ts.tv_sec;
  pp.ts.tv_usec = wp->ts.tv_usec;
  pp.caplen = wp->caplen;
  pp.len = wp->len;
  pcap_dump((u_char *)ostream,&pp,buf);
  records++;
}

char			*filetypestrs[] = 
{
  "unknown",
  "wtap",
  "pcap",
  "lanalyzer",
  "?",
  "ngsniffer",
  "snoop",
  "iptrace",
  "netmon",
  "netxray",
  NULL
};

#define MAXFILETYPESTRS 9 

int			main(argc,argv)
int			argc;
char			**argv;
{
  char			*ifile;
  char			*ofile;
  int			filetype;

  if (argc != 3)
    {
      char		**ptr;

      fprintf(stderr,"usage: wtap2dmp ifile ofile|-\n");
      fprintf(stderr,"Recognized formats for ifile: ");
      ptr = filetypestrs;
      while (*ptr)
	{
	  fprintf(stderr,"%s ",*ptr);
	  ptr++;
	}
      fprintf(stderr,"\n");
      exit(1);
    }
  ifile = argv[1];
  ofile = argv[2];
  if ((wt = wtap_open_offline(ifile)) == NULL)
    {
      fprintf(stderr,"wtap_open_offline: problem\n");
      exit(1);
    }
  filetype = wtap_file_type(wt);
  if (filetype > MAXFILETYPESTRS)
    {
      fprintf(stderr,"bad wtap file type %d\n",filetype);
      /* fallthrough */
    }
  fprintf(stderr,"reading a %s file...\n",filetypestrs[filetype]);
  wtap_loop(wt,
	    0,
	    (wtap_handler)dispatch,
	    (u_char *)ofile);
  fclose(ostream);
  fprintf(stderr,"%d records out\n",records);
  exit(0);
}
