pcapstreamer – A packet dumper

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 ( and 33rd to 36th byte indicates destination ip address ( 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.


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.