请看这段代码:
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));
}
我感到困惑的是,如果确定我们通常执行的其他标头的大小,sizeof(struct tcphdr)
或sizeof(struct ethhdr)
,但对于IP标头大小,我们不会执行sizeof而是ip_header->ihl*4
1}}。为什么会这样?这个4还有什么用?
以下是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 };
答案 0 :(得分:6)
这是不同测量单位的问题。 IP头中的IHL字段定义如下:
Internet标头长度是32位互联网标题的长度 字强>
此大小不固定(因为有效但不鼓励的IP选项)。因此,一个数据包可能有IHL = 5,下一个数据包可能有IHL = 6,依此类推。