add pcap2snoopy converter Reference: /n/atom/patch/applied2013/pcap2snoopy Date: Wed Jun 19 01:43:22 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/pcap2snoopy.c Thu Jan 1 00:00:00 1970 +++ /sys/src/cmd/pcap2snoopy.c Wed Jun 19 01:43:06 2013 @@ -0,0 +1,192 @@ +#include +#include +#include + +#define vprint(...) if(verbose)fprint(2, __VA_ARGS); else {} + +enum { + Pcapversmaj = 2, + Pcapversmin = 4, +}; + +uvlong (*get64)(char *); +ulong (*get32)(char *); +ushort (*get16)(char *); + +int verbose; +uchar magicbe[] = {0xa1, 0xb2, 0xc3, 0xd4}; +uchar magicle[] = {0xd4, 0xc3, 0xb2, 0xa1}; + +ushort +leget16(char *sp) +{ + uchar *p = (uchar*)sp; + return (ushort)p[0] | (ushort)p[1]<<8; +} + +ulong +leget32(char *sp) +{ + return leget16(sp) | leget16(sp+2)<<16; +} + +uvlong +leget64(char *sp) +{ + return (uvlong)leget32(sp) | (uvlong)leget32(sp+4)<<32; +} + +ushort +beget16(char *sp) +{ + uchar *p = (uchar*)sp; + return (ushort)p[0]<<8 | (ushort)p[1]; +} + +ulong +beget32(char *sp) +{ + return beget16(sp)<<16 | beget16(sp+2); +} + +uvlong +beget64(char *sp) +{ + return (uvlong)beget32(sp)<<32 | (uvlong)beget32(sp+4); +} + +void +beput16(char *sp, ushort v) +{ + uchar *p = (uchar *)sp; + p[0] = v>>8; + p[1] = v; +} + +void +beput32(char *sp, ulong v) +{ + beput16(sp, v>>16); + beput16(sp+2, v); +} + +void +beput64(char *sp, uvlong v) +{ + beput32(sp, v>>32); + beput32(sp+4, v); +} + +char buf[64*1024]; + +void +usage(void) +{ + fprint(2, "usage: pcap2snoopy [-v]\n"); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + char *p, hdr[24], inpkthdr[16], outpkthdr[10]; + long n, need, maxlen, linktype; + ulong len, caplen, v; + uvlong timestamp; + Biobuf b; + + ARGBEGIN{ + case 'v': + verbose = 1; + break; + default: + usage(); + }ARGEND + if(argc > 0) + usage(); + + if(Binit(&b, 0, OREAD) < 0) + sysfatal("Binit: %r"); + + if(Bread(&b, hdr, sizeof hdr) != sizeof hdr) + sysfatal("reading header: %r"); + + p = hdr; + if(memcmp(p, magicbe, 4) == 0){ + if(verbose) + fprint(2, "big endian\n"); + get64 = beget64; + get32 = beget32; + get16 = beget16; + }else if(memcmp(p, magicle, 4) == 0){ + if(verbose) + fprint(2, "little endian\n"); + get64 = leget64; + get32 = leget32; + get16 = leget16; + }else + sysfatal("invalid magic (0x%ux%ux%ux%ux)", p[0], p[1], p[2], p[3]); + p += 4; + + if((v = get16(p)) != Pcapversmaj) + sysfatal("wrong pcap major version (%ld, need %d)", v, Pcapversmaj); + p += 2; + if((v = get16(p)) != Pcapversmin) + fprint(2, "wrong minor version number (%ld, want %d)\n", v, Pcapversmin); + p += 2; + + + p += 4; /* 4 bytes long, gmt to local correction */ + p += 4; /* 4 bytes ulong, accuracy of timestamps */ + maxlen = get32(p); + p += 4; + linktype = get32(p); + p += 4; + assert(p == hdr+sizeof hdr); + + if(verbose) + fprint(2, "maxpacketlen=%lud linktype=0x%lux\n", maxlen, linktype); + + for(;;){ + n = Bread(&b, inpkthdr, sizeof inpkthdr); + if(n == 0) + break; + if(n < 0) + sysfatal("reading packet header: %r"); + p = inpkthdr; + timestamp = get32(p) * 1e9; + timestamp += get32(p+4) * 1000; + p += 8; + caplen = get32(p); + p += 4; + len = get32(p); + p += 4; + USED(p); + if(caplen != len) + fprint(2, "packet not entirely captured (have %uld of %uld bytes)\n", caplen, len); + + p = outpkthdr; + beput16(p, caplen); + p += 2; + beput64(p, timestamp); + p += 8; + USED(p); + if(write(1, outpkthdr, sizeof outpkthdr) != sizeof outpkthdr) + sysfatal("writing header: %r"); + + need = caplen; + while(need > 0){ + n = need; + if(n > sizeof buf) + n = need; + if(Bread(&b, buf, n) != n) + sysfatal("reading packet: %r\n"); + if(write(1, buf, n) != n) + sysfatal("writing packet: %r"); + need -= n; + } + + if(verbose) + fprint(2, "have packet of %lud bytes\n", caplen); + } +}