Monday, December 19, 2005

Disk Ring Buffer in Tcpdump 3.9.4

I finally got a chance to try Tcpdump 3.9.4 and Libpcap 0.9.4 on FreeBSD using the net/tcpdump and net/libpcap ports. I was unable to install them using packages, so I used the ports tree. I initally got the following error:

===> Extracting for tcpdump-3.9.4
=> MD5 Checksum OK for tcpdump-3.9.4.tar.gz.
=> SHA256 Checksum OK for tcpdump-3.9.4.tar.gz.
===> Patching for tcpdump-3.9.4
===> tcpdump-3.9.4 depends on shared library: pcap.2 - not found
===> Verifying install for pcap.2 in /usr/ports/net/libpcap
===> WARNING: Vulnerability database out of date, checking anyway
=> libpcap-0.9.4.tar.gz doesn't seem to exist in /usr/ports/distfiles/.
=> Attempting to fetch from http://www.tcpdump.org/release/.
libpcap-0.9.4.tar.gz 100% of 415 kB 73 kBps
===> Extracting for libpcap-0.9.4
=> MD5 Checksum OK for libpcap-0.9.4.tar.gz.
=> SHA256 Checksum OK for libpcap-0.9.4.tar.gz.
===> Patching for libpcap-0.9.4
...edited...
===> Installing for libpcap-0.9.4
===> Generating temporary packing list
===> Checking if net/libpcap already installed
[ -d /usr/local/lib ] || (mkdir -p /usr/local/lib; chmod 755
/usr/local/lib)
install -o root -g wheel -m 444 libpcap.a /usr/local/lib/libpcap.a
ranlib /usr/local/lib/libpcap.a
[ -d /usr/local/include ] || (mkdir -p /usr/local/include; chmod 755
/usr/local/include)
install -o root -g wheel -m 444 ./pcap.h /usr/local/include/pcap.h
install -o root -g wheel -m 444 ./pcap-bpf.h /usr/local/include/pcap-bpf.h
install -o root -g wheel -m 444 ./pcap-namedb.h
/usr/local/include/pcap-namedb.h
[ -d /usr/local/man/man3 ] || (mkdir -p /usr/local/man/man3; chmod 755
/usr/local/man/man3)
install -o root -g wheel -m 444 ./pcap.3 /usr/local/man/man3/pcap.3
===> Compressing manual pages for libpcap-0.9.4
===> Registering installation for libpcap-0.9.4
===> Returning to build of tcpdump-3.9.4
Error: shared library "pcap.2" does not exist
*** Error code 1

Stop in /usr/ports/net/tcpdump.

I took at look at the Makefile for net/tcpdump and saw this:

# TODO: Add strict sanity check that we're compiling against a
# version of libpcap with which this tcpdump release is compatible.
#
.if defined(TCPDUMP_OVERWRITE_BASE) || !defined(WITH_LIBPCAP_BASE)
LIB_DEPENDS= pcap.2:${PORTSDIR}/net/libpcap
.endif

I noticed this created when building libpcap-0.9.4:

/usr/ports/net/libpcap/work/libpcap-0.9.4/pcap.3

I also saw this on the system:

/usr/src/contrib/libpcap/pcap.3

So I changed tcpdump's Makefile like so:

LIB_DEPENDS= pcap.3:${PORTSDIR}/net/libpcap

I was then able to finish the installation. (I emailed the port maintainer asking if my fix made sense.) I ran Tcpdump:

orr:/usr/ports/net/tcpdump# /usr/local/sbin/tcpdump -V
tcpdump version 3.9.4
libpcap version 0.9.4
Usage: tcpdump [-aAdDeflLnNOpqRStuUvxX] [-c count] [ -C file_size ]
[ -E algo:secret ] [ -F file ] [ -i interface ] [ -M secret ]
[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ]
[ -W filecount ] [ -y datalinktype ] [ -Z user ]
[ expression ]

Note this is not the version installed on the base system:

orr:/usr/ports/net/tcpdump# tcpdump -V
tcpdump version 3.8.3
libpcap version 0.8.3
Usage: tcpdump [-aAdDeflLnNOpqRStuUvxX] [-c count] [ -C file_size ]
[ -E algo:secret ] [ -F file ] [ -i interface ] [ -r file ]
[ -s snaplen ] [ -T type ] [ -w file ] [ -y datalinktype ]
[ expression ]

To look at the new man page for 3.9.4, I had to tell 'man' where to find the new man pages:

man -M /usr/local/man tcpdump

In the man page I saw the following two options:

-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).
...edited...
-W Used in conjunction with the -C option, this will limit the num-
ber of files created to the specified number, and begin over-
writing 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.

Awesome. Let's try it. Here I tell Tcpdump to save five 10 million byte files using the -W 5 and -C 10 switches.

orr:/home/richard$ sudo /usr/local/sbin/tcpdump -n -i fxp0 -s 1515 -C 10 -W 5 -w /nsm/test1.lpc
tcpdump: listening on fxp0, link-type EN10MB (Ethernet), capture size 1515 bytes

If I watch the /nsm directory, I see these files being created. Here the first four files have already appeared:

-rw-r--r-- 1 root sguil 10000114 Dec 19 16:29 test1.lpc0
-rw-r--r-- 1 root sguil 10000018 Dec 19 16:29 test1.lpc1
-rw-r--r-- 1 root sguil 10000110 Dec 19 16:29 test1.lpc2
-rw-r--r-- 1 root sguil 10001244 Dec 19 16:30 test1.lpc3
-rw-r--r-- 1 root sguil 7913472 Dec 19 16:30 test1.lpc4

Soon the first three files are already overwritten, and the fourth file is being overwritten as I check on the /nsm directory again:

-rw-r--r-- 1 root sguil 10000264 Dec 19 16:30 test1.lpc0
-rw-r--r-- 1 root sguil 10001286 Dec 19 16:30 test1.lpc1
-rw-r--r-- 1 root sguil 10000858 Dec 19 16:30 test1.lpc2
-rw-r--r-- 1 root sguil 1245184 Dec 19 16:30 test1.lpc3
-rw-r--r-- 1 root sguil 10000214 Dec 19 16:30 test1.lpc4

So, this system works as advertised. Unfortunately, the file naming convention simply adds 0,1,2,3, or 4 to the end of the specified file name of test1.lpc. This is not how Tethereal handles file naming. I am not sure yet if Tcpdump's system will be suitable for my needs. I imagine that when capturing GB-sized files is involved, the file timestamps may be enough to differentiate them?

By the way, people always ask "Why don't you use Tcpdump's -s 0 option to automatically specify a snaplen?" Here's why:

orr:/home/richard$ sudo /usr/local/sbin/tcpdump -n -i fxp0 -s 0 -C 10 -W 5 -w /nsm/test1.lpc
tcpdump: listening on fxp0, link-type EN10MB (Ethernet), capture size 65535 bytes

65535 bytes? That's IP's theoretical maximum. What's so good about that? It seems hamfisted.

4 comments:

John said...

Hamfisted? That's a new one!

tqbf said...

"-s 0" is shorthand for "maximum snap for this particular interface". It's obviously not really capturing 64k from each packet. On fxp0, 64k really means ~1500 bytes.

Richard Bejtlich said...

Tom, that's good to hear. I guess the Tcpdump developers had to put something in the capture size output?

Brian Kee said...

I have always used "-s 1500" on ethernet segments. What would be the difference here with "-s 0"? Any ideas?