summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWhang Choi <wch0x01@gmail.com>2018-11-30 19:31:54 -0500
committerTobias Klauser <tklauser@distanz.ch>2018-12-02 17:26:52 +0100
commit04b3fe157db3e3aa22caf632928d5f06aa3f88bd (patch)
treefcd32379141cf3248614c53af565aa3ff9a90975
parente313a5415241cd2b0a81ae4ac55a53b36ab153ff (diff)
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 <wch0x01@gmail.com> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
-rw-r--r--netsniff-ng.86
-rw-r--r--netsniff-ng.c35
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 <N>, --overwrite <N>
+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 <name>, --prefix <name>
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 <name> Prefix for pcaps stored in directory\n"
+ " -O|--overwrite <N> Limit the number of pcaps to N (file names use numbers 0 to N-1)\n"
" -T|--magic <pcap-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':