From 04b3fe157db3e3aa22caf632928d5f06aa3f88bd Mon Sep 17 00:00:00 2001 From: Whang Choi Date: Fri, 30 Nov 2018 19:31:54 -0500 Subject: netsniff-ng: implement rotating capture files Add a new option -O, --overwrite which allows to rotate capture files. The timestamp in the file name is replaced with a number that wraps around after reaching the specified number of files. Example usage: netsniff-ng -s -F 1KiB -O 10 -i eth0 -o /output/folder Fixes #147 Signed-off-by: Whang Choi Signed-off-by: Tobias Klauser --- netsniff-ng.8 | 6 ++++++ netsniff-ng.c | 35 ++++++++++++++++++++++++++++------- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/netsniff-ng.8 b/netsniff-ng.8 index c937978..e4cc14b 100644 --- a/netsniff-ng.8 +++ b/netsniff-ng.8 @@ -175,6 +175,12 @@ Process a number of packets and then exit. If the number of packets is 0, then this is equivalent to infinite packets resp. processing until interrupted. Otherwise, a number given as an unsigned integer will limit processing. .TP +.B -O , --overwrite +A number from 0 to N-1 will be used in the file name instead of a Unix +timestamp. The previous file will be overwritten when number wraps around. The +maximum value is 2^32 - 1. Intended for rotating capture files when used +with options \fB\-F\fP and \fB\-P\fP. +.TP .B -P , --prefix When dumping pcap files into a folder, a file name prefix can be defined with this option. If not otherwise specified, the default prefix is \[lq]dump\-\[rq] diff --git a/netsniff-ng.c b/netsniff-ng.c index 48e1221..1a74d91 100644 --- a/netsniff-ng.c +++ b/netsniff-ng.c @@ -68,6 +68,7 @@ struct ctx { uint32_t fanout_group, fanout_type; uint64_t pkts_seen, pkts_recvd, pkts_drops; uint64_t pkts_recvd_last, pkts_drops_last, pkts_skipd_last; + unsigned long overwrite_interval, file_number; }; static volatile sig_atomic_t sigint = 0, sighup = 0; @@ -75,7 +76,7 @@ static volatile bool next_dump = false; static volatile sig_atomic_t sighup_time = 0; static const char *short_options = - "d:i:o:rf:MNJt:S:k:n:b:HQmcsqXlvhF:RGAP:Vu:g:T:DBUC:K:L:w"; + "d:i:o:rf:MNJt:S:k:n:b:HQmcsqXlvhF:RGAO:P:Vu:g:T:DBUC:K:L:w"; static const struct option long_options[] = { {"dev", required_argument, NULL, 'd'}, {"in", required_argument, NULL, 'i'}, @@ -87,6 +88,7 @@ static const struct option long_options[] = { {"ring-size", required_argument, NULL, 'S'}, {"kernel-pull", required_argument, NULL, 'k'}, {"bind-cpu", required_argument, NULL, 'b'}, + {"overwrite", required_argument, NULL, 'O'}, {"prefix", required_argument, NULL, 'P'}, {"user", required_argument, NULL, 'u'}, {"group", required_argument, NULL, 'g'}, @@ -778,6 +780,22 @@ out: } } +static void generate_multi_pcap_filename(struct ctx *ctx, char *fname, size_t size, time_t ftime) +{ + if (ctx->overwrite_interval > 0) { + slprintf(fname, size, "%s/%s%010lu.pcap", ctx->device_out, + ctx->prefix ? : "dump-", ctx->file_number); + + ctx->file_number++; + + if (ctx->file_number >= ctx->overwrite_interval) + ctx->file_number = 0; + } else { + slprintf(fname, size, "%s/%s%lu.pcap", ctx->device_out, + ctx->prefix ? : "dump-", ftime); + } +} + static void finish_multi_pcap_file(struct ctx *ctx, int fd) { __pcap_io->fsync_pcap(fd); @@ -794,7 +812,7 @@ static void finish_multi_pcap_file(struct ctx *ctx, int fd) static int next_multi_pcap_file(struct ctx *ctx, int fd) { int ret; - char fname[PATH_MAX]; + char fname[PATH_MAX] = {0}; time_t ftime; __pcap_io->fsync_pcap(fd); @@ -810,8 +828,7 @@ static int next_multi_pcap_file(struct ctx *ctx, int fd) } else ftime = time(NULL); - slprintf(fname, sizeof(fname), "%s/%s%lu.pcap", ctx->device_out, - ctx->prefix ? : "dump-", ftime); + generate_multi_pcap_filename(ctx, fname, sizeof(fname), ftime); fd = open_or_die_m(fname, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, DEFFILEMODE); @@ -844,15 +861,14 @@ static void reset_interval(struct ctx *ctx) static int begin_multi_pcap_file(struct ctx *ctx) { int fd, ret; - char fname[PATH_MAX]; + char fname[PATH_MAX] = {0}; bug_on(!__pcap_io); if (ctx->device_out[strlen(ctx->device_out) - 1] == '/') ctx->device_out[strlen(ctx->device_out) - 1] = 0; - slprintf(fname, sizeof(fname), "%s/%s%lu.pcap", ctx->device_out, - ctx->prefix ? : "dump-", time(NULL)); + generate_multi_pcap_filename(ctx, fname, sizeof(fname), time(NULL)); fd = open_or_die_m(fname, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, DEFFILEMODE); @@ -1239,6 +1255,7 @@ static void __noreturn help(void) " -R|--rfraw Capture or inject raw 802.11 frames\n" " -n|--num <0|uint> Number of packets until exit (def: 0)\n" " -P|--prefix Prefix for pcaps stored in directory\n" + " -O|--overwrite Limit the number of pcaps to N (file names use numbers 0 to N-1)\n" " -T|--magic Pcap magic number/pcap format to store, see -D\n" " -w|--cooked Use Linux \"cooked\" header instead of link header\n" " -D|--dump-pcap-types Dump pcap types and magic numbers and quit\n" @@ -1317,6 +1334,9 @@ int main(int argc, char **argv) case 'P': ctx.prefix = xstrdup(optarg); break; + case 'O': + ctx.overwrite_interval = strtoul(optarg, NULL, 0); + break; case 'R': ctx.rfraw = 1; break; @@ -1526,6 +1546,7 @@ int main(int argc, char **argv) case 'f': case 't': case 'P': + case 'O': case 'F': case 'n': case 'S': -- cgit v1.2.3-54-g00ecf