pcapstreamer - A packet dumper

Updated: May 07, 2024

Hi guys,

Happy Holidays!!

This year is about to finish, thinking about this year, lot of things happened, love, break-up, home, health, mother, father, work and more importently passion. Well, all is well and life is moving ahead. Still I’m travelling alone, in my own path. (What the hell am I, this is suppose to be technical post, shit!! crap philosophy!!)

I got some free time and spent that time learning libpcap. For those who don’t know, it is used in most of the network monitoring/capturing tools in *nix world. Very powerful.

The tcpdump(1) command is one such tool which uses libpcap (actually they are the one who created libpcap from tcpdump) to dump information about packets. It has a robest filtering mechanism to narrow down packet capturing to specific packets.

While trying to understand filter expressions in tcpdump, I got an Idea, I thought why not just convert the bytes in packets to strings and print them in stdout, this way, we can see the exact bytes, so further processing can be done my other unix tools (like awk, perl etc.,).

So, I just wrote a tool called pcapstreamer to capture packets from linux’s any psudo-interface. Its very simple tool, you need to run this tool as root user. It just dump packets, thats all. Here is an example, this shows one packet dumped into stdout.

$ sudo ./pcapstreamer
[cl:76 l:76 t:20111226085033.641612] 00000000 00000000 00000011 00000100 00000000 00000110 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00001000 00000000 01000101 00000000 00000000 00111100 01000111 10001100 01000000 00000000 01000000 00000110 11110101 00101101 01111111 00000000 00000000 00000001 01111111 00000000 00000000 00000001 11100101 01100011 00010101 10110011 01111000 00011101 00100110 01010100 00000000 00000000 00000000 00000000 10100000 00000010 10000000 00011000 11111110 00110000 00000000 00000000 00000010 00000100 01000000 00001100 00000100 00000010 00001000 00001010 00000000 10100010 01100001 11011000 00000000 00000000 00000000 00000000 00000001 00000011 00000011 00000101

Here cl:76 and l:76 indicates captured length, t:20111226085033.641612 indicates timestamp in localtime. Other strings are just pure raw packet.

Linux Cooked Header

To understand first 16 bytes, we need to understand Linux Cooked Header. First 2 bytes 00000000 00000000 or 0x00 represents that this is an incoming packet. To understand the next 2 bytes, we need to refer linux’s ARPHRD_. 3rd and 4th bytes 00000011 00000100 or decimal 772 indicates that this packet is coming into loopback interface. 5th and 6th bytes 00000000 00000110 or 0x0006 indicates the length of link-level address, the next 8 bytes (7th byte to 14th byte) represents the link-level address, however we should take only the next 6 bytes as link-level address, two more bytes (13th and 14th) are padded with zero. 15th and 16th bytes 00000000 00001000 or 0x0008 represents ethertype as ip, this tells us that this is an ip packet. This ends the link-level header (data-link layer in OSI). We are now moving to ip header (network layer in OSI)

IP Header

To understand details from 17th byte to 36th byte, we need to refer IP Header. Higher order 4 bits in 17th byte 0100 or 0x4 indicates that this ip packet is an ipv4 packet. Lower order 4 bits in 17th byte 0101 or 0x5 indicates IHL (Internet Header Length) usually this defaults to 5. 18th bytes represents differentiated services usually 0. 19th and 20th bytes 00000000 00111100 or 0x003c or Decimal 60 represents remaining bytes count (CaptureLength minus Linux-Cooked-Header length). 21st and 22nd bytes 01000111 10001100 indicates identification. Higher order 3 bits in 23rd and 24th bytes 010 indicates that this packet is not fragmented, remaining 13 bits indicates fragment offset. 25th byte 01000000 or 0x40 or Decimal 64 indicates TTL value. 26th byte 00000110 or 0x06 indicates that this is a tcp packet. 27th and 28th packets indicates Header Checksum. 29th to 32nd bytes indicates source ip address (127.0.0.1) and 33rd to 36th byte indicates destination ip address (127.0.0.1). This ends the ip header, we are now moving to tcp header (Transport layer in OSI).

TCP Header

To understand details from 37th byte to 76th byte, we need to refer TCP Header. 37th and 38th bytes 11100101 01100011 or decimal 58723 indicates the source port number. 39th and 40th bytes 00010101 10110011 or decimal 5555 indicates destination port number (means incoming packet is trying to connect port 5555). 41st to 44th byte indicates sequence number and 45th to 48th byte indicates sequence acknowledgement number. Higher order 4 bits in 49th and 50th byte 1010 or Decimal 10 indicates Data offset, means there are 10*4=40 bytes in TCP header. Next 3 higher order bits are reserved in 49th byte 50th byte. Next 3 bits indicates ECN. Next 6 bits 000010 or 0x02 indicates that SYN flag was set in Control bits. 51st and 52 bytes indicates window size, means the sender is willing to accept 10000000 00011000 or decimal 32792 bytes in the response packet. 53rd and 54th bytes indicates checksum. 55th and 56th bytes indicates Urgent pointer, usually 0.

Options

Inside TCP header, bytes 57 to 76 contains value based on 50th byte(Data Offset). In this particular packet, 50th byte has (0xa), which means, TCP header in this packet contains totally 40bytes. Mandatory TCP fields (from 37th byte to 56th byte) are already discussed, but we have 20 more bytes to decode, these bytes are represented as Options in TCP header. They may occur or they may not occur in a TCP packet. Mostly they occur in SYN packet.

Here, 57th byte (0x02) represents option-kind, 58th byte represents option-length (0x04). Both 57th and 58th bytes represents that 59th and 60th bytes 01000000 00001100 or 0x400c or Decimal 16396 indicates Maximum Segment Size. 61st byte (0x04) represents option-kind, 62nd byte (0x02) represents option-length, both bytes represents SACK permitted. 63rd byte (0x08) represents option-kind, 64th byte (0x0a) represents option-length, both bytes indicates that from 65th byte to 68th byte contains TSVal and from 69th byte to 72nd byte contains TSecr. 73rd byte 0x01 indicates option-kind as No-Operation, 74th byte (0x03) indicates option-kind, 75 byte indicates (0x03) option-length, both bytes indicates that 76th byte (0x05) contains WSOpt (Window Scale Option), which means, the host which sent this packet can accept upto 32792 * (2^5) or (windowsize[byte51&52] * (2^wsopt[byte76])) before sending ACK.

pcapstreamer with awk

To display only ICMP packets, we can use the following commandline

$ sudo ./pcapstreamer 2>/dev/null | awk '{if($26 ~ "00000001"){print $0;}}'

To display only SYN packets, we can use the following commandline

$ sudo ./pcapstreamer 2>/dev/null | awk '{ctrlbytes=$49$50; if(ctrlbytes ~ "^.......000010...$"){print $0;}}'

I hope this utility may be useful for newbies like me to learn networking. Have a great new year.