我必须做一个嗅探器作为安全课程的作业。我正在使用 C 和 pcap 库。我让一切运行良好(因为我从互联网上获得了代码并进行了更改)。但我对代码有一些疑问。
u_int ip_len = (ih->ver_ihl & 0xf) * 4;
ih
类型为ip_header
,并且它当前指向数据包中的 IP 标头。
ver_ihl
给出 IP 的版本。
我不知道是什么:& 0xf) * 4;
我必须做一个嗅探器作为安全课程的作业。我正在使用 C 和 pcap 库。我让一切运行良好(因为我从互联网上获得了代码并进行了更改)。但我对代码有一些疑问。
u_int ip_len = (ih->ver_ihl & 0xf) * 4;
ih
类型为ip_header
,并且它当前指向数据包中的 IP 标头。
ver_ihl
给出 IP 的版本。
我不知道是什么:& 0xf) * 4;
& 是按位与运算符,在这种情况下,您将 ver_ihl 与 0xf 进行与运算,其效果是清除除最低有效位 4 之外的所有位
0xff & 0x0f = 0x0f
ver_ihl 定义为前 4 位 = 版本 + 后 4 = Internet 标头长度。and 操作删除版本数据,保留长度数据。长度记录为 32 位字的计数,因此 *4 将 ip_len 转换为标头中的字节数
回应您的评论:
按位与操作数中的相应位相加。当你和任何有 0 的东西变成 0 和任何有 1 的东西保持不变。
0xf = 0x0f = 二进制 0000 1111
因此,当您和 0x0f 使用任何东西时,前 4 位设置为 0(因为您将它们与 0 相加)并且最后 4 位保持在另一个操作数中(因为您将它们与 1 相加)。这是一种称为位掩码的常用技术。
从定义 IPv4的RFC 791中读取:
互联网标头内容摘要如下:
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 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
IP 报头的前 8 位是版本和 IHL 字段的组合。
国际人道法:4 位
Internet Header Length 是 32 位字中 Internet 标头的长度,因此指向数据的开头。请注意,正确标头的最小值是 5。
你所拥有的代码正在做的是在那里获取前 8 位,并去掉 IHL 部分,然后将其转换为字节数。按位与0xF
将隔离 IHL 字段,而乘以 4 是因为 32 位字中有 4 个字节。
ver_ihl 字段包含两个 4 位整数,打包为低 nybble 和高 nybble。长度指定为 32 位字的数量。因此,如果您有一个带有 20 字节标头的第 4 版 IP 帧,您的 ver_ihl 字段值为 69。那么您将拥有:
01000101
& 00001111
--------
00000101
所以,是的,“&0xf”屏蔽了低 4 位。