⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 capconv.c

📁 This directory contains source code for tcpdump, a tool for network monitoring and data acquisition
💻 C
字号:
/*
 * convert a tcpdump capture file to a netmon .cap file.
 * 
 * Andrew Tridgell, October 1997
 * 
 * This only works for 32 bit boxes at the moment. Change the typedefs
 * to work on other sytems
 */

#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <string.h>
#include <sys/time.h>
#include <stdio.h>
#include <fcntl.h>

/* change the following 3 lines to make things work on
 * systems with different word sizes
 */
typedef int            int32;
typedef unsigned int   uint32;
typedef unsigned short uint16;

#define DEBUG 0

#define TCPDUMP_MAGIC 0xa1b2c3d4

/* tcpdump file format
 */
struct tcpdump_file_header {
       uint32  magic;
       uint16  major;
       uint16  minor;
       int32   zone;
       uint32  sigfigs;
       uint32  snap_len;
       uint32  linktype;
     };

struct tcpdump_packet {
       struct timeval ts;
       uint32         caplen;
       uint32         len;
     };

/* .cap file format
 */
struct cap_header {
       char    rtss[4];
       char    minor;
       char    major;
       uint16  captype;
       char    starttime[16];
       uint32  frameoffset;
       uint32  framelength;
       uint32  unknown[24];
     };

struct cap_packet {
       uint32  cap_time; /* milliseconds */
       uint16  len;
       uint16  caplen;
     };


/* file format is:
 * header
 * frames
 * frameoffsets
 */

static void swap_uint32 (void *x)
{
  char c, *p = (char*) x;

  c    = p[0];
  p[0] = p[3];
  p[3] = c;
  c    = p[1];
  p[1] = p[2];
  p[2] = c;
}

static void swap_int32 (void *x)
{
  char c, *p = (char*) x;

  c    = p[0];
  p[0] = p[3];
  p[3] = c;
  c    = p[1];
  p[1] = p[2];
  p[2] = c;
}

static void swap_uint16 (void *x)
{
  char c, *p = (char*) x;

  c    = p[0];
  p[0] = p[1];
  p[1] = c;
}


static void swap_netmon_header (struct cap_header *h)
{
  swap_uint16 (&h->captype);
  swap_uint32 (&h->frameoffset);
  swap_uint32 (&h->framelength);
}

static void swap_netmon_packet (struct cap_packet *p)
{
  swap_uint32 (&p->cap_time);
  swap_uint16 (&p->len);
  swap_uint16 (&p->caplen);
}

static void swap_tcpdump_header (struct tcpdump_file_header *h)
{
  swap_uint32 (&h->magic);
  swap_uint16 (&h->major);
  swap_uint16 (&h->minor);
  swap_int32  (&h->zone);
  swap_uint32 (&h->sigfigs);
  swap_uint32 (&h->snap_len);
  swap_uint32 (&h->linktype);
}

static void swap_tcpdump_packet (struct tcpdump_packet *p)
{
  swap_uint32 (&p->ts.tv_sec);
  swap_uint32 (&p->ts.tv_usec);
  swap_uint32 (&p->len);
  swap_uint32 (&p->caplen);
}


int convert_tcpdump_to_cap (char *infile, char *outfile)
{
  struct tcpdump_file_header tcpdump_header;
  struct tcpdump_packet      tcpdump_pkt;
  struct cap_header          cap_header;
  struct cap_packet          cap_pkt;
  struct timeval             tval1;
  uint32 *framestart = NULL;
  int     maxframes = 1000;
  int     i, fd1, fd2;
  int     snaplen;
  char   *data;
  char    pad[4];
  int     swap_tcpdump = 0;
  int     swap_netmon  = 0;

  fd1 = open (infile, O_RDONLY|O_BINARY);
  if (fd1 == -1)
  {
    perror (infile);
    exit (1);
  }

  fd2 = open (outfile, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0644);
  if (fd2 == -1)
  {
    perror (outfile);
    exit (1);
  }

  if (read(fd1, &tcpdump_header, sizeof(tcpdump_header)) != sizeof(tcpdump_header))
  {
    printf ("can't read tcpdump header\n");
    return (0);
  }

  /* tcpdump files can be in either byte order.
   */
  if (tcpdump_header.magic != TCPDUMP_MAGIC)
  {
    swap_tcpdump = 1;
    swap_tcpdump_header (&tcpdump_header);
  }

  if (tcpdump_header.magic != TCPDUMP_MAGIC)
  {
    printf ("bad magic number %x\n", tcpdump_header.magic);
    return (0);
  }

  /* check if we are little endian. If not, we need to
   * convert the network monitor output
   */
  i = 1;
  if (((char*)&i)[0] != 1)
     swap_netmon = 1;

  /* setup the basic netmon header
   */
  memset (&cap_header, 0, sizeof(cap_header));
  strcpy (cap_header.rtss, "RTSS");
  cap_header.minor   = 1;
  cap_header.major   = 1;
  cap_header.captype = tcpdump_header.linktype;

  /* write it out. we will have to write it again once
   * we've worked out the rest of the parameters
   */
  write (fd2, &cap_header, sizeof(cap_header));

  snaplen = tcpdump_header.snap_len;

  printf ("tcpdump-%d.%d snaplen=%d linktype=%d\n",
          tcpdump_header.major, tcpdump_header.minor,
          snaplen, tcpdump_header.linktype);

  data       = malloc (snaplen);
  framestart = malloc (maxframes * sizeof(framestart[0]));

  if (!framestart)
  {
    perror ("malloc");
    exit (1);
  }

  memset (pad, 0, sizeof(pad));

  for (i = 0; 1; i++)
  {
    if (i == maxframes)
    {
      framestart = realloc (framestart, maxframes * 2 * sizeof(framestart[0]));
      maxframes *= 2;
      if (!framestart)
      {
        perror ("malloc");
        exit (1);
      }
    }

    if (read (fd1, &tcpdump_pkt, sizeof(tcpdump_pkt)) != sizeof(tcpdump_pkt))
       break;

    if (swap_tcpdump)
       swap_tcpdump_packet (&tcpdump_pkt);

    if (i == 0)
       tval1 = tcpdump_pkt.ts;

    if (read (fd1, data, tcpdump_pkt.caplen) != tcpdump_pkt.caplen)
       break;

#if DEBUG
    printf ("frame %d of length=%d:%d\n",
            i+1, tcpdump_pkt.caplen, tcpdump_pkt.len);
#endif

    if (tcpdump_pkt.caplen > tcpdump_pkt.len)
       tcpdump_pkt.caplen = tcpdump_pkt.len;

    framestart[i] = lseek (fd2, 0, SEEK_CUR);

    cap_pkt.cap_time = (tcpdump_pkt.ts.tv_sec - tval1.tv_sec) * 1000 +
                       (tcpdump_pkt.ts.tv_usec - tval1.tv_usec) / 1000;
    cap_pkt.caplen   = tcpdump_pkt.caplen;
    cap_pkt.len      = tcpdump_pkt.len;

    if (swap_netmon)
       swap_netmon_packet (&cap_pkt);

    write (fd2, &cap_pkt, sizeof(cap_pkt));
    write (fd2, data, tcpdump_pkt.caplen);

    if (tcpdump_pkt.caplen % 4 != 0)
      write (fd2, pad, 4 - (tcpdump_pkt.caplen % 4));

#if DEBUG
    printf ("frame %d of length=%d:%d\n",
            i+1, tcpdump_pkt.caplen, tcpdump_pkt.len);
#endif
  }

  cap_header.frameoffset = lseek (fd2, 0, SEEK_CUR);
  cap_header.framelength = i * 4;

  if (swap_netmon)
  {
    int j;

    for (j = 0; j < i; j++)
       swap_uint32 (&framestart[j]);
    swap_netmon_header (&cap_header);
  }

  write (fd2, framestart, i * 4);
  lseek (fd2, 0, SEEK_SET);

  write (fd2, &cap_header, sizeof(cap_header));
  close (fd1);
  close (fd2);

  printf ("converted %d frames\n", i);
  return (i);
}

int main (int argc, char **argv)
{
  if (argc < 3)
  {
    printf ("Convert a tcpdump capture file to a netmon .cap file\n");
    printf ("\tUsage: capconvert <infile> <outfile>\n");
    return (1);
  }
  convert_tcpdump_to_cap (argv[1], argv[2]);
  return (0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -