Sniffing TCP Packets With Python

Inspired by this StackOverflow question, [“How do I sniff on a port for log messages using python?”][so_question], I decided to figure out how to capture and process packets in Python. It turns out to be quite easy once you work out the kinks. Except the kinks were a pain to determine.

[so_question]: http://stackoverflow.com/q/28870666/47078

Sample output:

$ sudo python capture.py
10:27:44.016601    hello ('127.0.0.1', 61129)
10:27:44.016614    hello ('127.0.0.1', 61129)
10:27:54.019731    hello ('127.0.0.1', 61137)
10:27:54.019741    hello ('127.0.0.1', 61137)

Note
: _It may appear that the same packets are printed twice here, but what you’re really seeing is the same packet going out and then coming back in. The timestamps give it away. Also, if you have an OSX version of tcpdump, the -k ID option will print something like this: (lo0, out) ._

Basic, high-level usage:


And then the actual generator:


Depending on the interface you capture from, you may receive Ethernet, Loopback, or IP packets. This means that a little deduction must be done to determine how to decode them. We figure this out once, and save the decoding function for all future packets. Although, if you never need to enter promiscuous mode[^1], you use the “iptap” interface and you will only ever receive IP packets.

[^1]: Ethernet interfaces normally filter out any network traffic not destined for the current machine. Setting the interface to be promiscuous, tells it to pass through all packets it receives.


All of the decode functions return either data or None if a parsing error occurs. Here’s the one for Ethernet packets:


As a bonus, here’s a couple of methods that print out binary data similar to the hexdump -C command, but without the trailing ASCII.


With debugging turned on, the output is much more verbose:

Capturing on interface(s): iptap
00000000: 4500 004e 0f7a 4000 4006 0000 7f00 0001
00000010: 7f00 0001 2704 f1ab 5a99 b667 c79a 4159
00000020: 8018 31d7 fe42 0000 0101 080a 4969 b251
00000030: 4969 b251 6865 6c6c 6f20 2827 3132 372e
00000040: 302e 302e 3127 2c20 3631 3836 3729

Packet type: ip
10:45:44.428427    hello ('127.0.0.1', 61867)
00000000: 4500 004e 0f7a 4000 4006 2d2e 7f00 0001
00000010: 7f00 0001 2704 f1ab 5a99 b667 c79a 4159
00000020: 8018 31d7 fe42 0000 0101 080a 4969 b251
00000030: 4969 b251 6865 6c6c 6f20 2827 3132 372e
00000040: 302e 302e 3127 2c20 3631 3836 3729

10:45:44.428447    hello ('127.0.0.1', 61867)

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *