Iterpreting the ip identification field in firewall

July 21, 2007
By Computer security

The IP identification (ID) field is a two-byte field contained within the packet. Its sole purpose in life is allow IP packets to be fragmented: all fragments should contain the same ID as the original packet so that they can be pasted back together again. Most systems use the concept of a monotonically increasing ID: for each packet sent, the field is increased by one.

There is a little twist to this scenario. A little-endian machine (like Intel processors) stores numbers in reverse byte-order than how numbers are represented on the wire. This means that a monotonically increasing integer from a Wintel box will increment the high-order byte first, whereas a Sun SPARC box will increment the low-order byte first. Therefore, lets say that you are being pinged steadily from both a Sun SPARC and a Wintel, you will see the following sort of progression in the IP ID field:

SPARC Wintel
0×01FD 0xFD01
0×01FE 0xFE01
0×01FF 0xFF01
0×0200 0×0002
0×0201 0×0102

The above numbers are shown in hexadecimal, which shows the byte-order problem. However, many firewall logs (stupidly) show these numbers in decimal. If a firewall system assumes the number is big-endian but the incoming packets are little endian, then the progression of the numbers is hidden. For example:

IP ID Big-endian Little-endian
01 FD 509 64769
01 FE 510 65025
01 FF 511 65281
02 00 512 2
02 01 513 258

This entire issue is complicated by the fact that a firewall running on a platform doesn’t have to base its decimal calculation of the IP ID field on the underlying CPU. What I mean by this is that the C code that interprets the IP ID could be written in two ways;

        /* ID field is a 2-byte number at offset 4 within the IP header */

        int ipid_cpu = *(unsigned short*)(iphdr+4);

        int ipid_be = iphdr[4] * 256 + iphdr[5];

The first example is CPU dependent: x86 CPUs will pull it out as a little-endian number, but SPARC CPUs will pull it out as a big-endian number. The second form is CPU independent: it tells all CPUs to interpret the field as a big-endian number. Note: ntohs(*(unsigned short*)(iphdr+4)) will crash a SPARC CPU and is not a good solution

Therefore, if you are running a Linux-based x86 firewall that interprets the IP ID field as a little-endian number, then a string of packets from a Wintel box will demonstrate a monotonically increasing number. However, a stream from a SPARC box will show skipping numbers. Conversely, if the Linux-based firewall uses the (correct) field parsing method, you’ll see the reverse.

Tags:

Leave a Reply

follow twitter

 

March 2010
M T W T F S S
« Feb    
1234567
891011121314
15161718192021
22232425262728
293031