11

I'm looking to be able to capture a rotating tcpdump output which captures 30 minutes worth of data, into 48 files, cyclically.

The man page implies this should be possible, but my testing doesn't seem to produce the result I'm looking for:

-W

      Used in conjunction with the -C option, this will limit the number of files created to the specified number, and begin overwriting files from the beginning, thus creating a 'rotating' buffer.  In addition, it will name the files with enough leading 0s to support the maximum number of files, allowing them to sort correctly.

      Used in conjunction with the -G option, this will limit the number of rotated dump files that get created, exiting with status 0 when reaching the limit.  If used with -C as well, the behavior will result in cyclical files per timeslice.

I'm running this on OS X 10.9.5/10.10.3 clients. Here's the test command; it just exits after the 3rd file:

tcpdump -i en0 -w /var/tmp/trace-%Y-%M-%d_%H.%M.%S.pcap -W 3 -G 3 -C -K -n
12

That's because you wrote -W 3 instead of -W 48. There are, however, other errors in your command.

The option -G means:

-G rotate_seconds

      If specified, rotates the dump file specified with the -w option every rotate_seconds seconds.  Savefiles will have the name specified by -w which should include a time format as defined by strftime(3).  If no time format is specified, each new file will overwrite the previous.

      If used in conjunction with the -C option, filenames will take the form of 'file<count>'.

Since you wrote -G 3, you will be rotating this every 3 seconds, while you stated

...which captures 30 minutes worth of data

Also, the naming scheme is wrong: from the above,

If used in conjunction with the -C option, filenames will take the form of 'file<count>'.

Thus there is no point in specifying the time format for the name.

Further, the -C option has no argument, while, according to the man page, it should:

tcpdump [ -AdDefIKlLnNOpqRStuUvxX ] [ -B buffer_size ] [ -c count ]
-C file_size ] [ -G rotate_seconds ] [ -F file ] [ -I interface ] [ -m module ] [ -M secret ] [ -r file ] [ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ] [ -E spi@ipaddr algo:secret,... ] [ -y datalinktype ] [ -z postrotate-command ] [ -Z user ] [ expression ]

The man page states:

-C

      Before writing a raw packet to a savefile, check whether the file is currently larger than file_size and, if so, close the current savefile and open a new one.  Savefiles after the first savefile will have the name specified with the -w flag, with a number after it, starting at 1 and continuing upward.  The units of file_size are millions of bytes (1,000,000 bytes, not 1,048,576 bytes).

So you should specify -C 100 in order to produce 100 MB files.

In the end, your command should be:

tcpdump -i en0 -w /var/tmp/trace -W 48 -G 1800 -C 100 -K -n

This will rotate files (of names trace1, trace2, ...) cyclically, with period 48, either every 1800 seconds (=30 minutes) or every 100 MB, whichever comes first.

  • The in the end answer is missing the condition If no time format is specified, each new file will overwrite the previous. (I have updated the answer.) – okwap Jan 18 '16 at 2:19
  • 2
    @okwap, when you edited the answer (to add -%Y-%m-%d_%H:%M:%S), you broke the cyclical part of using -G, -C, and -W together. The original answer using just /var/tmp/trace for the -w filename was correct and generated the intended cyclic outputs as described ( trace1,trace2,...). When using -G, -C, and -W together, you can't use the strftime format in the filename and still get the cyclic outputs. With your edit, tcpdump will just continue writing out files non-cyclically because the filenames never repeat. – Bill Menees Nov 8 '16 at 19:49
  • @BillMenees Thanks for bringing this to my attention, I have undone okwap's edit. – MariusMatutiae May 25 '17 at 10:31
  • Just like Swinster in the comment below, I note that this answer does not produce the expected behavior. Using -w -W -C and -G in conjunction causes the same file to be overwritten again and again. It does not cause a number of files to be created equal to -W <n> as one would expect. – Niels2000 Oct 23 '17 at 9:59
6

Expanding upon flabdablet’s answer (changing -G 1800 to -G 300 – rotation every five minutes – just for testing purposes),

tcpdump -i en0 -w /var/tmp/trace-%m-%d-%H-%M-%S-%s -W 3 -G 300

will give you %m=month, %d=day of month, %H=hour of day, %M=minute of day, %S=second of day, %s=millisecond of day, resulting in

/var/temp/trace-03-02-08-30-56-1520002568
/var/temp/trace-03-02-08-35-56-1520002568
/var/temp/trace-03-02-08-40-56-1520002568

Very useful for organizing traces for those pesky intermittent problems.  Also, if you're not root, you may want to sudo and of course make it a nohup:

sudo bash -c "nohup tcpdump -i en0 -w /var/tmp/trace-%m-%d-%H-%M-%S-%s -W 3 -G 300 &"
3

Seems to me that all you need is

tcpdump -i en0 -G 1800 -w /var/tmp/trace-%H-%M.pcap

The strftime format specifier that -G expects in the -w filename doesn't have to represent a complete date and time. With just %H and %M in there, and a rotate time of exactly half an hour, any given invocation of tcpdump will only ever generate two different %M values half an hour apart, and yesterday's trace files will get overwritten when the same hour and minute numbers roll around again.

1

After some experimentation, I couldn't get @MariusMatutiae answer to work as expected. If the time became the limiting factor and without the addition of the time format to the file name, then the current pcap file is simply overwritten.

For example, try:

tcpdump -i en0 -w /var/tmp/trace -W 10 -G 5 -C 1

All you end up with is trace.pcap0 being written over and over.

As it suggested in the comment, if you add the time formatting to the file name, then you simply end up with and every growing list of files.

Therefore, I had to stick with simple size limited files:

tcpdump -i en0 -w /var/tmp/trace -W 48 -C 100
0

Yeah, it doesn't seem to work as MariusMatutiae's answer says.

tcpdump ...{other options}... -w httpdebug.pcap -W 48 -G 1800 -C 100
$ ls -l
-rw-r--r--. 1 tcpdump tcpdump  100007441 Mar 17 17:57 httpdebug.pcap00
-rw-r--r--. 1 tcpdump tcpdump   46895104 Mar 17 18:02 httpdebug.pcap01
-rw-r--r--. 1 tcpdump tcpdump   93091143 Mar 17 17:47 httpdebug.pcap02
-rw-r--r--. 1 tcpdump tcpdump    5372072 Mar 17 16:17 httpdebug.pcap03

It looks to me like it might be capturing as many -C 100MB files as possible in a 30 minute period because httpdebug.pcap03 has the earliest timestamp and it's a lot smaller than 100MB, so it seems like it was cut at a 30 minute mark. Once it hits 30 mins, it seems to jump back to httpdebug.pcap00 and increment the number as it hits 100MB. This means that if you have a lot of requests in a 30 minute period, you get to very high httpdebug.pcapXX numbers. If you never reach that many requests in a period anymore, those high httpdebug.pcapXX numbers won't ever get overwritten.

So I'm thinking cyclical files per timeslice means that the timeslice is -G 1800 and it will cycle every -G 1800 and increment every -C 100.

I'm not sure if -W 48 affects it, but perhaps if you get to httpdebug.pcap47 (count starts at 0`, it will stop capturing packets.


Somewhat recently, there was a GitHub issue opened about the confusing wording. They did not change the implementation, but they tried to make the documentation a little bit clearer.

The proposed changes were merged in on Jan 28, 2019.

As of today, March 17, 2019, here is the current documentation:

-C:

.BI \-C " file_size"
Before writing a raw packet to a savefile, check whether the file is
currently larger than \fIfile_size\fP and, if so, close the current
savefile and open a new one.  Savefiles after the first savefile will
have the name specified with the
.B \-w
flag, with a number after it, starting at 1 and continuing upward.
The units of \fIfile_size\fP are millions of bytes (1,000,000 bytes,
not 1,048,576 bytes).

-G:

.BI \-G " rotate_seconds"
If specified, rotates the dump file specified with the
.B \-w
option every \fIrotate_seconds\fP seconds.
Savefiles will have the name specified by
.B \-w
which should include a time format as defined by
.BR strftime (3).
If no time format is specified, each new file will overwrite the previous.
Whenever a generated filename is not unique, tcpdump will overwrite the
preexisting data; providing a time specification that is coarser than the
capture period is therefore not advised.
.IP
If used in conjunction with the
.B \-C
option, filenames will take the form of `\fIfile\fP<count>'.

-W:

.B \-W
Used in conjunction with the
.B \-C
option, this will limit the number
of files created to the specified number, and begin overwriting files
from the beginning, thus creating a 'rotating' buffer.
In addition, it will name
the files with enough leading 0s to support the maximum number of
files, allowing them to sort correctly.
.IP
Used in conjunction with the
.B \-G
option, this will limit the number of rotated dump files that get
created, exiting with status 0 when reaching the limit.
.IP
If used in conjunction with both
.B \-C
and
.B \-G,
the
.B \-W
option will currently be ignored, and will only affect the file name.

I still think it's a little confusing, but I guess the difference from my conclusion above, is that it says -W when used with -C -G does not affect anything but the file name.

In general, -W is used for limiting the number of files. So don't use it if you want to capture indefinitely.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.