Sign in to follow this  
Monder

TCP and IP header

Recommended Posts

I'm writing a small program that decodes TCP and IP headers from a file that is a dump of the raw packets, and there's a couple of aspects about them that puzzle me. The layout for the IP and TCP headers are given in their RFCs as this: IP:
    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |Version|  IHL  |Type of Service|          Total Length         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |         Identification        |Flags|      Fragment Offset    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Time to Live |    Protocol   |         Header Checksum       |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                       Source Address                          |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Destination Address                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TCP:
    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |           |U|A|P|R|S|F|                               |
   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
   |       |           |G|K|H|T|N|N|                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Now the bits I'm having trouble with are the version and IHL fields in the IP header and the Data Offset field in the TCP header in that they don't seem to be located where these diagrams indicate they are. In the IP header I read the diagram as saying the first 4 bits of the IP header are the version and the next 4 bits are the IHL. However if I look at the first byte of an example IP raw packet dump it's 0x45, so the first nibble (first 4 bits) is 0x5 which is the IHL and the next nibble (next 4 bits) is 0x4 which is the version, this seems to be the opposite way round to what the diagram indicates. Similarly for the Data Offset field if I look at the first byte of the 3rd 32-bit word of the raw TCP packet dump, it's 0xA0, so the first nibble is 0 which is part of the reserved field and the next nibble is A which is the data offset, again they are the opposite way round to what I would expect from the diagram. I'm obviously looking at this in wrong way somewhere, so where am I going wrong?

Share this post


Link to post
Share on other sites
Well for the first byte of the IP header the two nibbles are swapped compared to what I'd expect them to be. I'm well aware of the endianess issue and as hplus0603 pointed out that's to do with byte order not bit order. Now if the first byte was transmitted most significant bit first then I'd either have a complete mirror image of the expected value for the first byte (I'd expect 0x54, so if you mirror its binary representation you get 0x2A) of I'd just have the first byte as expected, in either case the two nibbles would not be simply swapped round.

Also when reading 16-bit fields such as total length in the IP field, internally the bytes are as you would expect you just need to handle the endianess issue using ntohs. So why would the first byte be rearranged compared to what I'd expect but the others not?

Share this post


Link to post
Share on other sites
I've now realised where I'm going wrong, as hplus0603 said most significant bit is transmitted first and this is bit 0 on the diagram and I was thinking the most significant bit of the first byte would be bit 7 on the diagram which is what confused me [embarrass]. It makes sense now. Thanks for the help.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this