catnip
catnip is a tiny non-libpcap based network packet capturing tool (currently only for Linux) which when compiled and stripped the binary is smaller than 20kiB. This makes it very suitable for embedded environments where a libpcap based tool, typically 100kiB for just libpcap and 500kiB for tcpdump, would be simply too large. catnip is generally parameter compatible with tcpdump and what makes catnip stand out from other small packet capturing tools is that also supports BPF filtering.
Whilst putting together a buildroot based Linux environment for my Linksys WAG54G I was disappointed to find that a compiled libpcap/tcpdump was just too large for the 4MiB flash I was limited to. Digging around I could not find any other filtering supporting micro-sized libpcap-less capturing tools so set out to write my own, and this is the result of my efforts.
The source code for catnip is downloadable:
- moved to GPLv3
- added support to drop privileges from root when able to
- added '-V' and '-h' support to show version number and usage help information
- fixed pcap packet header which was incorrect for cooked sockets (ie. ppp links)
- noticed tcpdump had a '-ddd' output mode, so used that instead of '-dd'
- fixed filtering on 'any' by gleaning wisdom from libpcap
catnip-20100502.c - initial release
It has been tested under:
- mips (little endian) - uclibc (32bit)
- amd64 (little endian) - glibc (64bit)
- sparc64 (big endian) - glibc (64bit)
Compiled trivially with:
$ gcc -Wall -Os -o catnip catnip.c $ strip catnip
Features
- generally parameter compatible to tcpdump
output format is pcap, so wireshark can open the savefiles
Linux Socket Filter (a la BPF) support
- no library dependencies
- privilege dropping
Known Bugs
- sniffing promiscuously on an 802.11 interface gives some interesting output
- [other] it's a feature I tell you!
TODO
- support mmap'd ring buffer capturing under Linux
- simple verbosity, Layer 2 (Ethernet), Layer 3 (IPv4 and IPv6) and Layer 4 (TCP and UDP) decoder
- Mac OS X/*BSD support
- trigger rules to stop capturing, 'x' packets and/or 'y' seconds
- add minimum boundary for snaplen to be (L2 header)
Usage
catnip must be told which interface to listen on (use 'any' to sniff on all valid interfaces) otherwise it will not run, this is done by using the 'i' parameter like so:
# catnip -i eth0
This is not without it's problems as by default packets will be recorded in pcap format to STDOUT; filling your screen with garbage. Rather neatly 1 you can pipe the output into netcat to get the recording onto another host. This might not be wanted though and you could redirect the output to a file with one of two methods:
# catnip -i eth0 > /tmp/dump.pcap or # catnip -i eth0 -w /tmp/dump.pcap
You might want to record packets (or flush STDOUT) on a per-packet basis which can be done through use of the 'U' flag:
# catnip -i eth0 -U
To sniff non-promiscuously (by default we sniff in promiscuous mode), use the 'p' parameter:
# catnip -i eth0 -p
By default 96 bytes of data is captured, however this can be increased to a maximum of 65535 bytes with 's':
# # 1500 byte limit # catnip -i eth0 -s 1500 # # both the following set to 65535 # catnip -i eth0 -s 65535 # catnip -i eth0 -s 0
Now, the most interesting part is the filtering support. A packet capturing tool on an embedded device with no filtering support would be pretty useless, however the filtering rule building framework has a large footprint. To solve this problem you need to have a copy of tcpdump somewhere, and you create the bytecode there for the filter like so (it must be generated against the loopback device):
berk:~# tcpdump -i lo -ddd host 10.0.0.1 | tee filter.bpf 14 40 0 0 12 21 0 4 2048 32 0 0 26 21 8 0 167772161 32 0 0 30 21 6 7 167772161 21 1 0 2054 21 0 5 32821 32 0 0 28 21 2 0 167772161 32 0 0 38 21 0 1 167772161 6 0 0 65535 6 0 0 0
The output from this is what you pass to catnip via the 'F' parameter, either via a file or from STDIN:
# cat /tmp/filter.bpf | catnip -i eth0 -F - or # catnip -i eth0 -F /tmp/filter.bpf
carefully though, so not to cause a positive feedback loop, for example outputting to the network interface you are sniffing on without a suitable filter in place (1)