5

I have to do a sniffer as an assignment for the security course. I am using C and the pcap library. I got everything working well (since I got a code from the internet and changed it). But I have some questions about the code.

u_int ip_len = (ih->ver_ihl & 0xf) * 4;   

ih is of type ip_header, and its currently pointing the to IP header in the packet.
ver_ihl gives the version of the IP.
I can't figure out what is: & 0xf) * 4;

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
scatman
  • 14,109
  • 22
  • 70
  • 93

3 Answers3

3

& is the bitwise and operator, in this case you're anding ver_ihl with 0xf which has the effect of clearing all the bits other than the least signifcant 4

0xff & 0x0f = 0x0f

ver_ihl is defined as first 4 bits = version + second 4 = Internet header length. The and operation removes the version data leaving the length data by itself. The length is recorded as count of 32 bit words so the *4 turns ip_len into the count of bytes in the header

In response to your comment:

bitwise and ands the corresponding bits in the operands. When you and anything with 0 it becomes 0 and anything with 1 stays the same.

0xf = 0x0f = binary 0000 1111

So when you and 0x0f with anything the first 4 bits are set to 0 (as you are anding them against 0) and the last 4 bits remain as in the other operand (as you are anding them against 1). This is a common technique called bit masking.

http://en.wikipedia.org/wiki/Bitwise_operation#AND

Patrick
  • 8,175
  • 7
  • 56
  • 72
  • i got the idea (ver_ihl contains the Version (4 bits) + Internet header length (4 bits)) but i still didn't get how this operation is removing the version data. when you are anding with 0xf does this mean that your anding only the fist 4 bits? – scatman Mar 16 '10 at 07:22
1

Reading from RFC 791 that defines IPv4:

A summary of the contents of the internet header follows:

 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         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

The first 8 bits of the IP header are a combination of the version, and the IHL field.

IHL: 4 bits

Internet Header Length is the length of the internet header in 32 bit words, and thus points to the beginning of the data. Note that the minimum value for a correct header is 5.

What the code you have is doing, is taking the first 8 bits there, and chopping out the IHL portion, then converting it to the number of bytes. The bitwise AND by 0xF will isolate the IHL field, and the multiply by 4 is there because there are 4 bytes in a 32-bit word.

Kevin Panko
  • 8,356
  • 19
  • 50
  • 61
0

The ver_ihl field contains two 4-bit integers, packed as the low and high nybble. The length is specified as a number of 32-bit words. So, if you have a Version 4 IP frame, with 20 bytes of header, you'd have a ver_ihl field value of 69. Then you'd have this:

  01000101
& 00001111
  --------
  00000101

So, yes, the "&0xf" masks out the low 4 bits.

Vatine
  • 20,782
  • 4
  • 54
  • 70