diff --git a/src/pcap.c b/src/pcap.c index 0328fbe..34a168a 100644 --- a/src/pcap.c +++ b/src/pcap.c @@ -3,80 +3,106 @@ * */ +#include #include -#include #include #include "pcap.h" #include "netre.h" int pcap_open_in(struct pcap_file *ctx, FILE *f) { - struct pcap_file_header h; + struct pcap_file_header h; - if (fread(&h, sizeof(h), 1, f) != 1) h.magic = 0; + if (fread(&h, sizeof(h), 1, f) != 1) h.magic = 0; - if (MAGIC == h.magic) { - ctx->swap = 0; - DDUMP("normal order"); - } else if (bswap32(MAGIC) == h.magic) { - ctx->swap = 1; - DDUMP("swapped order"); - } else { - return -1; - } - if ((h.version_major != 2) || (h.version_minor != 4)) return -1; - DDUMP_d(h.version_major); - DDUMP_d(h.version_minor); + if (MAGIC == h.magic) { + ctx->swap = 0; + DDUMP("normal order"); + } else if (bswap32(MAGIC) == h.magic) { + ctx->swap = 1; + DDUMP("swapped order"); + } else { + DDUMP("bad magic"); + warnx("unsupported packet capture"); + return -1; + } + if ((h.version_major != 2) || (h.version_minor != 4)) return -1; + DDUMP_d(h.version_major); + DDUMP_d(h.version_minor); - if (ctx->swap != 0) h.snaplen = bswap32(h.snaplen); - DDUMP_d(h.snaplen); - if (h.snaplen > MAXFRAME) return -1; + if (ctx->swap != 0) h.snaplen = bswap32(h.snaplen); + DDUMP_d(h.snaplen); + if (h.snaplen > MAXFRAME) { + DDUMP("bad snaplen"); + warnx("PCAP snaplength too large (%d > %d)", h.snaplen, MAXFRAME); + return -1; + } - ctx->f = f; - return 0; + DDUMP_x(h.linktype); + if (h.linktype == 101) { + ctx->raw = 1; + } else { + ctx->raw = 0; + } + + ctx->f = f; + return 0; } int pcap_open_out(struct pcap_file *ctx, FILE *f) { - struct pcap_file_header h = { MAGIC, 2, 4, 0, 0, MAXFRAME, 1 }; + struct pcap_file_header h = { MAGIC, 2, 4, 0, 0, MAXFRAME, 1 }; - if (fwrite(&h, sizeof(h), 1, f) != 1) return -1; + if (fwrite(&h, sizeof(h), 1, f) != 1) { + warn("unable to open file"); + return -1; + } - ctx->f = f; - ctx->swap = 0; + ctx->f = f; + ctx->swap = 0; - return 0; + return 0; } int pcap_read_pkthdr(struct pcap_file *ctx, struct pcap_pkthdr *hdr) { - if (fread(hdr, sizeof(*hdr), 1, ctx->f) != 1) return -1; + if (fread(hdr, sizeof(*hdr), 1, ctx->f) != 1) return -1; - if (ctx->swap) { - hdr->ts.tv_sec = bswap32(hdr->ts.tv_sec); - hdr->ts.tv_usec = bswap32(hdr->ts.tv_usec); - hdr->caplen = bswap32(hdr->caplen); - hdr->len = bswap32(hdr->len); - } + if (ctx->swap) { + hdr->ts.tv_sec = bswap32(hdr->ts.tv_sec); + hdr->ts.tv_usec = bswap32(hdr->ts.tv_usec); + hdr->caplen = bswap32(hdr->caplen); + hdr->len = bswap32(hdr->len); + } - if (hdr->caplen > MAXFRAME) return -1; + if (hdr->caplen > MAXFRAME) { + DDUMP("bad snaplen"); + warnx("packet header capture length too large (%d > %d)", hdr->caplen, MAXFRAME); + return -1; + } - return 0; + return 0; } int pcap_write_pkthdr(struct pcap_file *ctx, struct pcap_pkthdr *hdr) { - if (ctx->swap) { - struct pcap_pkthdr ohdr; + if (ctx->swap) { + struct pcap_pkthdr ohdr; - memcpy(&ohdr, hdr, sizeof(ohdr)); - hdr->ts.tv_sec = bswap32(hdr->ts.tv_sec); - hdr->ts.tv_usec = bswap32(hdr->ts.tv_usec); - hdr->caplen = bswap32(hdr->caplen); - hdr->len = bswap32(hdr->len); + memcpy(&ohdr, hdr, sizeof(ohdr)); + hdr->ts.tv_sec = bswap32(hdr->ts.tv_sec); + hdr->ts.tv_usec = bswap32(hdr->ts.tv_usec); + hdr->caplen = bswap32(hdr->caplen); + hdr->len = bswap32(hdr->len); - if (fwrite(&ohdr, sizeof(ohdr), 1, ctx->f) != 1) return -1; - } else { - if (fwrite(hdr, sizeof(*hdr), 1, ctx->f) != 1) return -1; - } + if (fwrite(&ohdr, sizeof(ohdr), 1, ctx->f) != 1) { + warn("failed to write packet header"); + return -1; + } + } else { + if (fwrite(hdr, sizeof(*hdr), 1, ctx->f) != 1) { + warn("failed to write packet header"); + return -1; + } + } - return 0; + return 0; } void pcap_close(struct pcap_file *ctx) { fclose(ctx->f); } diff --git a/src/pcap.h b/src/pcap.h index 709b732..d5f0fed 100644 --- a/src/pcap.h +++ b/src/pcap.h @@ -8,27 +8,28 @@ #define MAXFRAME 65535 struct pcap_file { - FILE *f; - int swap; + FILE *f; + int swap; + int raw; }; struct pcap_file_header { - uint32_t magic; - uint16_t version_major; - uint16_t version_minor; - int32_t thiszone; /* gmt to local correction */ - uint32_t sigfigs; /* accuracy of timestamps */ - int32_t snaplen; /* max length saved portion of each pkt */ - int32_t linktype; /* data link type (LINKTYPE_*) */ + uint32_t magic; + uint16_t version_major; + uint16_t version_minor; + int32_t thiszone; /* gmt to local correction */ + uint32_t sigfigs; /* accuracy of timestamps */ + int32_t snaplen; /* max length saved portion of each pkt */ + int32_t linktype; /* data link type (LINKTYPE_*) */ }; struct pcap_pkthdr { - struct pcap_timeval { - uint32_t tv_sec; - uint32_t tv_usec; - } ts; /* time stamp */ - uint32_t caplen; /* length of portion present */ - uint32_t len; /* length this packet (off wire) */ + struct pcap_timeval { + uint32_t tv_sec; + uint32_t tv_usec; + } ts; /* time stamp */ + uint32_t caplen; /* length of portion present */ + uint32_t len; /* length this packet (off wire) */ }; #ifndef max @@ -43,6 +44,7 @@ struct pcap_pkthdr { ((i & 0x00ff0000) >> 010) | \ ((i & 0x0000ff00) << 010) | \ ((i & 0x000000ff) << 030)) + #define bswap16(i) (((i & 0xff00) >> 010) | \ ((i & 0x00ff) << 010)) diff --git a/src/pmerge.c b/src/pmerge.c index 36c315a..1249a8d 100644 --- a/src/pmerge.c +++ b/src/pmerge.c @@ -24,6 +24,12 @@ struct input_file { struct pcap_pkthdr next; }; +struct linklayer { + uint16_t src[3]; + uint16_t dest[3]; + uint16_t ethertype; +}; + int version(bool error) { fprintf(WHICHOUT(error), "pmerge v.%s - %s\n\n", PACKAGE_VERSION, "Merges pcap files, outputting time-ordered pcap stream"); @@ -41,7 +47,7 @@ int usage(bool error, char *prog) { int read_next(struct input_file *file) { if (! file->active) return -1; - if (-1 == pcap_read_pkthdr(&file->p, &file->next)) { + if (pcap_read_pkthdr(&file->p, &file->next) == -1) { pcap_close(&file->p); file->active = 0; file->next.ts.tv_sec = 0xffffffff; @@ -56,6 +62,7 @@ int pmerge(FILE *output, struct input_file files[], int nfiles) { int nopen; int i; struct pcap_file out; + struct linklayer fake = {{0,0,0}, {1,1,1}, 0x0008}; if (pcap_open_out(&out, output) == -1) { perror("writing pcap header"); @@ -95,10 +102,20 @@ int pmerge(FILE *output, struct input_file files[], int nfiles) { /* Write header + frame */ if (len) { + if (cur->p.raw) { + cur->next.caplen += sizeof(fake); + cur->next.len += sizeof(fake); + } if (fwrite(&cur->next, sizeof(cur->next), 1, output) != 1) { perror("error"); return EX_IOERR; } + if (cur->p.raw) { + if (fwrite(&fake, sizeof(fake), 1, output) != 1) { + perror("error"); + return EX_IOERR; + } + } if (len != fwrite(frame, 1, len, output)) { perror("error"); return EX_IOERR; @@ -150,6 +167,7 @@ int main(int argc, char *argv[]) { return EX_NOINPUT; } + /* prime the input files */ if (pcap_open_in(&cur->p, f) == -1) { fprintf(stderr, "%s: unable to process\n", fn); return EX_IOERR;