📄 capconv.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 + -