So I’ve decided to finally getting around to revising (and then taking) my SANS 503 exam (or GCIA). It’s been a while since I’ve spent anytime looking at packets up close and personal so rather than me suffering alone I thought I would blog as I go (plus it’s a good way to remember stuff).

This is the first in a new series called “Packet Addict” (that’s me by the way).

Today we are going to have a look at IPv4 packets, what makes up a IP packet and how you can read these things in their “naked” version (or Hex if you want to be precise). I’m going to be honest you can find all of this on Google, so go ahead or just carry on reading.

DISCLAIMER: If I get something wrong, please tell me as I’m revising for an exam and you wouldn’t want to feel guilty if I fail because you didn’t tell me something was wrong.. now would YOU.

So lets just cover some key terms before we start.

Bit – Smallest unit of a packet, has the value of 0 or 1 (so either on or off).
Nibble – Made up of 4 bits and has is one hexadecimal value.
Byte – This is 8 bits, or 2 nibbles and is 2 hexadecimal values.

So to put some context (we all love context), a TCP flag (covered later but used here for reference) is made up of 1 bit which means it’s either on or off (set or unset).

An example of a nibble (4 bits) would be the IP version number (currently you either get 4 or 6 but you know).

A byte is something like the IP Time to Live (amount of hops before the packet dies a slow and painful death in the darkness that is the internet), working on the basis that it’s 2 hexadecimal values then the maximum it can be (or should be) is 255 (0xFF).

To convert hex to decimal in python you can use this snippet of code:

`>>> print int("5", 16)`

Hexadecimal is a base 16 numbering system, so the python code takes your value (5 in this case) and prints the int value based on it being base 16.

All make sense?? Awesome lets carry on.

So an IPv4 packet is a minimum of 20 bytes with a maximum of 60 bytes, most IPv4 packets are 20 bytes and I’ve not come across one that is larger than that but I’ve led a settled life.

So in order to work out from hex (that’s hexadecimal in big word speak) what a IPv4 header is really saying (without using Wireshark) you need one of these things below (not mine, found it on the internet).. This is a graphical representation of an IPv4 header and it’s associated bits (and bytes), so now with the magic of a calculator and Google for when I get stuck, lets make some packet magic.

OK so here is the hex dump of a IPv4 header (taken from a random pcap file).

4500 003c 2d70 4000 4006 d7f6 0a14 9096 0a14 9097

So lets work through the first few bits together. Every IPv4 packet starts (typically) with 4500 which makes it a bit easier to spot when looking at lots of raw packets. So remembering that each hex character is a nibble (2 bits) and using the IPv4 Header image from above we can begin to break out the individual parts of the packet.

Version -> 4 bits (1 hex) = 4
IHL -> 4 bits (1 hex) = 5

Now this is the bit that confuses me, how does a 5 in hex equal 20 bytes?? (the standard length of an IPv4 header)… Google to the rescue..

Brain Meltdown:
The IHL (Internet Header Length) field is 4 bits long and specifies the header length in 32-bit word (4 bytes).

So there are two ways to do this, my way and the right way but mine is quicker. 4 bits for IHL, multiple that by your IHL value (5) and you get 20 bytes.

The correct way is to do it like this:

5 * 32 / 8 = 20 (bytes)

5 is the IHL value, multiple by 32 (32 bit word), divide by 8 (number of bits in a byte).

So confused yet?? I know I am (trying writing a blog about this stuff), but lets continue. Next we will break down each chunk of the packet and then we can convert it back to decimal (i.e. readable format) later. Using the table above and the raw packet I will map each value into the diagram below with the hex values. So I’ve tried to match the colouring coding across the original IPv4 Header picture a bit further up. Lets work through each value, convert it to decimal and then we should be able to see it make a bit more sense.

IP Version = 4 – Makes sense it’s an IPv4 packet after all
IHL = 5 – So we know that we need to multiple this by 4 to get the number of bytes = 20 bytes
Type of Service = 00 – So this is a result of zero, not uncommon to see in IP headers
Total Length = 003c – If we convert this to decimal we get 60, which is the size of the packet in bytes
IP Identification Number = 2d70 – This converts to 11632, this value is usually used for identifing the group of fragments of a single IP datagram
Flags = 4 – These flags are used for determining if a packet is fragmented or not and each of the 3 flags is a bit value (either 1 or a 0). The flags are:
bit 0: Reserved, must be zero
bit 1: Don’t Fragment (DF)
bit 2: More Fragments (MF)
So if we look at this from a binary point of view (as we are dealing with bits), we would get 0 1 0 0 which is hexadecimal for 4 (Don’t Fragment). If it was a fragmented packet it would be binary of 0 0 1 0 which is hexadecimal of 2.
Fragment Offset = 000 – A value of zero means it’s either the first fragment, but in this case because the Don’t Fragment bit isn’t set then there is no need for an offset.
Time to Live = 40 – This converts back to 64 decimal which is a “standard” TTL for a packet
Protocol = 06 – This converts to 6 decimal which is the protocol number for a TCP packet (the next layer)
Header Checksum = d7f6 – These are used for error checking, this value converts to 55286
Source IP = 0a149096 – So we know that the maximum value for an IPv4 Address is 255, so each octet of the IP address will be 2 hex values seperated by a “.”, so
if we break each down in 2 hex value pairs we get 0a 14 90 96, which converts to 10.20.144.150.
Destination IP = 0a149097 – Same principal as before, we turn this value into 0a 14 90 97 which in turns converts to 10.20.144.151

So there you go, a fully decoded IPv4 packet.. trust me it was as painful to write as it was for you to read.. 🙂

1. Smoke says: