mirror of https://github.com/dirtbags/fluffy.git
support raw ip captures (no link layer) by faking it
This commit is contained in:
parent
ddfda783bd
commit
249e959fcc
118
src/pcap.c
118
src/pcap.c
|
@ -3,80 +3,106 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#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"
|
||||||
|
|
||||||
int pcap_open_in(struct pcap_file *ctx, FILE *f) {
|
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) {
|
if (MAGIC == h.magic) {
|
||||||
ctx->swap = 0;
|
ctx->swap = 0;
|
||||||
DDUMP("normal order");
|
DDUMP("normal order");
|
||||||
} else if (bswap32(MAGIC) == h.magic) {
|
} else if (bswap32(MAGIC) == h.magic) {
|
||||||
ctx->swap = 1;
|
ctx->swap = 1;
|
||||||
DDUMP("swapped order");
|
DDUMP("swapped order");
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
DDUMP("bad magic");
|
||||||
}
|
warnx("unsupported packet capture");
|
||||||
if ((h.version_major != 2) || (h.version_minor != 4)) return -1;
|
return -1;
|
||||||
DDUMP_d(h.version_major);
|
}
|
||||||
DDUMP_d(h.version_minor);
|
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);
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
ctx->f = f;
|
DDUMP_x(h.linktype);
|
||||||
return 0;
|
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) {
|
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;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcap_read_pkthdr(struct pcap_file *ctx, struct pcap_pkthdr *hdr) {
|
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) {
|
if (ctx->swap) {
|
||||||
hdr->ts.tv_sec = bswap32(hdr->ts.tv_sec);
|
hdr->ts.tv_sec = bswap32(hdr->ts.tv_sec);
|
||||||
hdr->ts.tv_usec = bswap32(hdr->ts.tv_usec);
|
hdr->ts.tv_usec = bswap32(hdr->ts.tv_usec);
|
||||||
hdr->caplen = bswap32(hdr->caplen);
|
hdr->caplen = bswap32(hdr->caplen);
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pcap_write_pkthdr(struct pcap_file *ctx, struct pcap_pkthdr *hdr) {
|
int pcap_write_pkthdr(struct pcap_file *ctx, struct pcap_pkthdr *hdr) {
|
||||||
if (ctx->swap) {
|
if (ctx->swap) {
|
||||||
struct pcap_pkthdr ohdr;
|
struct pcap_pkthdr ohdr;
|
||||||
|
|
||||||
memcpy(&ohdr, hdr, sizeof(ohdr));
|
memcpy(&ohdr, hdr, sizeof(ohdr));
|
||||||
hdr->ts.tv_sec = bswap32(hdr->ts.tv_sec);
|
hdr->ts.tv_sec = bswap32(hdr->ts.tv_sec);
|
||||||
hdr->ts.tv_usec = bswap32(hdr->ts.tv_usec);
|
hdr->ts.tv_usec = bswap32(hdr->ts.tv_usec);
|
||||||
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) {
|
||||||
} else {
|
warn("failed to write packet header");
|
||||||
if (fwrite(hdr, sizeof(*hdr), 1, ctx->f) != 1) return -1;
|
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); }
|
void pcap_close(struct pcap_file *ctx) { fclose(ctx->f); }
|
||||||
|
|
32
src/pcap.h
32
src/pcap.h
|
@ -8,27 +8,28 @@
|
||||||
#define MAXFRAME 65535
|
#define MAXFRAME 65535
|
||||||
|
|
||||||
struct pcap_file {
|
struct pcap_file {
|
||||||
FILE *f;
|
FILE *f;
|
||||||
int swap;
|
int swap;
|
||||||
|
int raw;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pcap_file_header {
|
struct pcap_file_header {
|
||||||
uint32_t magic;
|
uint32_t magic;
|
||||||
uint16_t version_major;
|
uint16_t version_major;
|
||||||
uint16_t version_minor;
|
uint16_t version_minor;
|
||||||
int32_t thiszone; /* gmt to local correction */
|
int32_t thiszone; /* gmt to local correction */
|
||||||
uint32_t sigfigs; /* accuracy of timestamps */
|
uint32_t sigfigs; /* accuracy of timestamps */
|
||||||
int32_t snaplen; /* max length saved portion of each pkt */
|
int32_t snaplen; /* max length saved portion of each pkt */
|
||||||
int32_t linktype; /* data link type (LINKTYPE_*) */
|
int32_t linktype; /* data link type (LINKTYPE_*) */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pcap_pkthdr {
|
struct pcap_pkthdr {
|
||||||
struct pcap_timeval {
|
struct pcap_timeval {
|
||||||
uint32_t tv_sec;
|
uint32_t tv_sec;
|
||||||
uint32_t tv_usec;
|
uint32_t tv_usec;
|
||||||
} ts; /* time stamp */
|
} ts; /* time stamp */
|
||||||
uint32_t caplen; /* length of portion present */
|
uint32_t caplen; /* length of portion present */
|
||||||
uint32_t len; /* length this packet (off wire) */
|
uint32_t len; /* length this packet (off wire) */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef max
|
#ifndef max
|
||||||
|
@ -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))
|
||||||
|
|
||||||
|
|
20
src/pmerge.c
20
src/pmerge.c
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue