support raw ip captures (no link layer) by faking it

This commit is contained in:
pi-rho 2013-02-05 12:59:44 -06:00
parent ddfda783bd
commit 249e959fcc
3 changed files with 108 additions and 62 deletions

View File

@ -3,8 +3,8 @@
* *
*/ */
#include <err.h>
#include <stdio.h> #include <stdio.h>
#include <sysexits.h>
#include <string.h> #include <string.h>
#include "pcap.h" #include "pcap.h"
#include "netre.h" #include "netre.h"
@ -21,6 +21,8 @@ int pcap_open_in(struct pcap_file *ctx, FILE *f) {
ctx->swap = 1; ctx->swap = 1;
DDUMP("swapped order"); DDUMP("swapped order");
} else { } else {
DDUMP("bad magic");
warnx("unsupported packet capture");
return -1; return -1;
} }
if ((h.version_major != 2) || (h.version_minor != 4)) return -1; if ((h.version_major != 2) || (h.version_minor != 4)) return -1;
@ -29,7 +31,18 @@ int pcap_open_in(struct pcap_file *ctx, FILE *f) {
if (ctx->swap != 0) h.snaplen = bswap32(h.snaplen); if (ctx->swap != 0) h.snaplen = bswap32(h.snaplen);
DDUMP_d(h.snaplen); DDUMP_d(h.snaplen);
if (h.snaplen > MAXFRAME) return -1; if (h.snaplen > MAXFRAME) {
DDUMP("bad snaplen");
warnx("PCAP snaplength too large (%d > %d)", h.snaplen, MAXFRAME);
return -1;
}
DDUMP_x(h.linktype);
if (h.linktype == 101) {
ctx->raw = 1;
} else {
ctx->raw = 0;
}
ctx->f = f; ctx->f = f;
return 0; return 0;
@ -38,7 +51,10 @@ int pcap_open_in(struct pcap_file *ctx, FILE *f) {
int pcap_open_out(struct pcap_file *ctx, FILE *f) { 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->f = f;
ctx->swap = 0; ctx->swap = 0;
@ -56,7 +72,11 @@ int pcap_read_pkthdr(struct pcap_file *ctx, struct pcap_pkthdr *hdr) {
hdr->len = bswap32(hdr->len); 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;
} }
@ -71,9 +91,15 @@ int pcap_write_pkthdr(struct pcap_file *ctx, struct pcap_pkthdr *hdr) {
hdr->caplen = bswap32(hdr->caplen); hdr->caplen = bswap32(hdr->caplen);
hdr->len = bswap32(hdr->len); hdr->len = bswap32(hdr->len);
if (fwrite(&ohdr, sizeof(ohdr), 1, ctx->f) != 1) return -1; if (fwrite(&ohdr, sizeof(ohdr), 1, ctx->f) != 1) {
warn("failed to write packet header");
return -1;
}
} else { } else {
if (fwrite(hdr, sizeof(*hdr), 1, ctx->f) != 1) return -1; if (fwrite(hdr, sizeof(*hdr), 1, ctx->f) != 1) {
warn("failed to write packet header");
return -1;
}
} }
return 0; return 0;

View File

@ -10,6 +10,7 @@
struct pcap_file { struct pcap_file {
FILE *f; FILE *f;
int swap; int swap;
int raw;
}; };
struct pcap_file_header { struct pcap_file_header {
@ -43,6 +44,7 @@ struct pcap_pkthdr {
((i & 0x00ff0000) >> 010) | \ ((i & 0x00ff0000) >> 010) | \
((i & 0x0000ff00) << 010) | \ ((i & 0x0000ff00) << 010) | \
((i & 0x000000ff) << 030)) ((i & 0x000000ff) << 030))
#define bswap16(i) (((i & 0xff00) >> 010) | \ #define bswap16(i) (((i & 0xff00) >> 010) | \
((i & 0x00ff) << 010)) ((i & 0x00ff) << 010))

View File

@ -24,6 +24,12 @@ struct input_file {
struct pcap_pkthdr next; struct pcap_pkthdr next;
}; };
struct linklayer {
uint16_t src[3];
uint16_t dest[3];
uint16_t ethertype;
};
int version(bool error) { int version(bool error) {
fprintf(WHICHOUT(error), "pmerge v.%s - %s\n\n", PACKAGE_VERSION, fprintf(WHICHOUT(error), "pmerge v.%s - %s\n\n", PACKAGE_VERSION,
"Merges pcap files, outputting time-ordered pcap stream"); "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) { int read_next(struct input_file *file) {
if (! file->active) return -1; 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); pcap_close(&file->p);
file->active = 0; file->active = 0;
file->next.ts.tv_sec = 0xffffffff; file->next.ts.tv_sec = 0xffffffff;
@ -56,6 +62,7 @@ int pmerge(FILE *output, struct input_file files[], int nfiles) {
int nopen; int nopen;
int i; int i;
struct pcap_file out; struct pcap_file out;
struct linklayer fake = {{0,0,0}, {1,1,1}, 0x0008};
if (pcap_open_out(&out, output) == -1) { if (pcap_open_out(&out, output) == -1) {
perror("writing pcap header"); perror("writing pcap header");
@ -95,10 +102,20 @@ int pmerge(FILE *output, struct input_file files[], int nfiles) {
/* Write header + frame */ /* Write header + frame */
if (len) { 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) { if (fwrite(&cur->next, sizeof(cur->next), 1, output) != 1) {
perror("error"); perror("error");
return EX_IOERR; 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)) { if (len != fwrite(frame, 1, len, output)) {
perror("error"); perror("error");
return EX_IOERR; return EX_IOERR;
@ -150,6 +167,7 @@ int main(int argc, char *argv[]) {
return EX_NOINPUT; return EX_NOINPUT;
} }
/* prime the input files */
if (pcap_open_in(&cur->p, f) == -1) { if (pcap_open_in(&cur->p, f) == -1) {
fprintf(stderr, "%s: unable to process\n", fn); fprintf(stderr, "%s: unable to process\n", fn);
return EX_IOERR; return EX_IOERR;