Reputation: 12064
Look at this code segment:
if(ip_header->protocol == IPPROTO_TCP)
{
tcp_header = (struct tcphdr*)(packet + sizeof(struct ethhdr) + ip_header->ihl*4);
/* Print the Dest and Src ports */
printf("Source Port: %d\n", ntohs(tcp_header->source));
printf("Dest Port: %d\n", ntohs(tcp_header->dest));
}
What i am confused is, in case of determining the size of other headers we normally do, sizeof(struct tcphdr)
or sizeof(struct ethhdr)
but for IP header size, we don't do sizeof instead we do ip_header->ihl*4
. Why is it so? Also what is this 4 for?
Here is how the struct declaration of IP heder:
00116 struct iphdr {
00117 #if defined(__LITTLE_ENDIAN_BITFIELD)
00118 __u8 ihl:4,
00119 version:4;
00120 #elif defined (__BIG_ENDIAN_BITFIELD)
00121 __u8 version:4,
00122 ihl:4;
00123 #else
00124 #error "Please fix <asm/byteorder.h>"
00125 #endif
00126 __u8 tos;
00127 __u16 tot_len;
00128 __u16 id;
00129 __u16 frag_off;
00130 __u8 ttl;
00131 __u8 protocol;
00132 __u16 check;
00133 __u32 saddr;
00134 __u32 daddr;
00135 /*The options start here. */
00136 };
Upvotes: 7
Views: 6992
Reputation: 182619
It's a problem of different units of measurement. The IHL field in the IP header is defined like this:
Internet Header Length is the length of the internet header in 32 bit words.
And this size isn't fixed (because of valid but discouraged IP options). So one packet could have IHL=5, the next could have IHL=6 and so on.
Upvotes: 8