From d5aaabde4b0fb13f1d1806433c7c5a4eb411d2bf Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 22 Jan 2012 22:48:59 +0100 Subject: [PATCH] New: pcap-tail --- Makefile | 1 + pcap-tail.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 pcap-tail.c diff --git a/Makefile b/Makefile index 5c3729f..f7d486d 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ parrot: parrot.c xclipcat: xclipcat.c xclipsend: xclipsend.c prefork: prefork.c +pcap-tail: pcap-tail.c fft: fft.c fft: LDFLAGS+=-lm diff --git a/pcap-tail.c b/pcap-tail.c new file mode 100644 index 0000000..f4108a5 --- /dev/null +++ b/pcap-tail.c @@ -0,0 +1,86 @@ +/* + * A tail-like command working on pcap files + * + * (c) 2012 Martin Mares + */ + +#define _LARGEFILE_SOURCE + +#include +#include +#include + +struct pcap_header { + uint32_t magic; + uint16_t major, minor; + uint32_t tz_offset; + uint32_t time_accuracy; + uint32_t snaplen; + uint32_t ll_type; +}; + +struct pcap_packet { + uint32_t time_sec; + uint32_t time_us; + uint32_t captured_len; + uint32_t orig_len; +}; + +int main(int argc, char **argv) +{ + if (argc != 3) { + fprintf(stderr, "Usage: pcap-tail \n"); + return 1; + } + + uint64_t num = atoi(argv[1]); + uint64_t *ring = malloc(num * sizeof(uint64_t)); + if (!ring) { + fprintf(stderr, "Out of memory\n"); + return 1; + } + + FILE *in = fopen(argv[2], "r"); + if (!in) { + fprintf(stderr, "Cannot open %s: %m\n", argv[2]); + return 1; + } + + struct pcap_header hdr; + if (fread(&hdr, sizeof(hdr), 1, in) < 1) { + fprintf(stderr, "Cannot read header\n"); + return 1; + } + if (hdr.magic != 0xa1b2c3d4) { + fprintf(stderr, "Bad (black?) magic\n"); + return 1; + } + + struct pcap_packet pkt; + int ring_pos = 0; + uint64_t count = 0; + for (;;) { + uint64_t pos = ftell(in); + if (fread(&pkt, sizeof(pkt), 1, in) < 1) + break; + // printf("@%d len=%d\n", (int)pos, pkt.captured_len); + ring[ring_pos] = pos; + ring_pos = (ring_pos + 1) % num; + fseek(in, pkt.captured_len, SEEK_CUR); + count++; + } + + fwrite(&hdr, sizeof(hdr), 1, stdout); + if (count > num) { + fseek(in, ring[ring_pos], SEEK_SET); + } else { + fseek(in, ring[0], SEEK_SET); + } + + char buf[4096]; + int n; + while ((n = fread(buf, 1, sizeof(buf), in)) > 0) + fwrite(buf, 1, n, stdout); + + return 0; +} -- 2.39.2