gpt4 book ai didi

perl 按位与和按位移位

转载 作者:行者123 更新时间:2023-12-04 18:06:20 26 4
gpt4 key购买 nike

我正在阅读模块 Net::Pcap::Easy 的一些示例代码片段,我遇到了这段代码

my $l3protlen = ord substr $raw_bytes, 14, 1;
my $l3prot = $l3protlen & 0xf0 >> 2; # the protocol part
return unless $l3prot == 4; # return unless IPv4
my $l4prot = ord substr $packet, 23, 1;
return unless $l4prot == '7';

在对原始数据包 $raw_bytes 进行完全十六进制转储后,我可以看到这是一个以太网帧,而不是 TCP/UDP 数据包。有人可以解释一下上面的代码是做什么的吗?

最佳答案

为了解析框架,我查找了 this page .

现在到 Perl...

my $l3protlen =  ord substr $raw_bytes, 14, 1;

$raw_bytes 中提取第 15 个字节(字符) , 并转换为其序数值(例如,假设字符集为 ASCII,字符 'A' 将转换为整数 65 (0x41))。这就是 Perl 处理二进制数据的方式,就好像它是一个字符串一样(例如,将它传递给 substr),然后让您将二进制值取回并将它们作为数字处理。 (但请记住 TMTOWTDI。)

在 IPv4 帧中,前 14 个字节是 MAC header (目标和源 MAC 地址各 6 个字节,后跟 2 个字节的 Ethertype,可能是 0x8000 - 你可以检查一下)。在这之后,第 15 个字节是以太网数据负载的开始:第一个字节包含版本(高 4 个字节)和以 DWORD 为单位的 header 长度(低 4 个字节)。

现在在我看来,这个示例代码的下一行有一个错误,但它很可能通常是侥幸完成的!
my $l3prot    = $l3protlen & 0xf0 >> 2; # the protocol part

在 Perl 中, >>优先级高于 & , 所以这将等价于
my $l3prot    = $l3protlen & (0xf0 >> 2);

或者如果你喜欢
my $l3prot    = $l3protlen & 0x3c;

所以这会从 $l3prot 中提取位 2 - 5 value:掩码值 0x3c 是二进制的 0011 1100。例如,值 0x86(二进制 1000 0110)将变为 0x04(二进制 0000 0100)。
事实上,“正常”的 IPv4 值是 0x45,即协议(protocol)类型 4, header 长度 5 个双字。用 0x3c 屏蔽它,你会得到...... 4!但只是侥幸:您测试了长度的前 2 位,而不是协议(protocol)类型!

这条线肯定应该是
my $l3prot = ($l3protlen & 0xf0) >> 4;

(注意括号中的优先级和 4 位的移位,而不是 2 位)。 (我在 CPAN documentation 中发现了同样的错误,所以我猜它可能传播得相当广泛。)
return unless $l3prot == 4; # return unless IPv4

对于 IPv4,我们希望该值为 4 - 如果不是,请立即跳出函数。 (所以上面的错误代码给出了一个结果,它可以被解释为一个 IPv4 数据包,但只能靠运气。)
my $l4prot = ord substr $packet, 23, 1;

现在提取第 24 个字节并以相同的方式转换为序数值。这是来自 IP header 的协议(protocol)字节:
return unless $l4prot == '7';

我们预计这是 7 - 如果它没有立即跳出函数。 (根据 IANA ,7 是“基于核心的树”......但我想你知道你对哪些协议(protocol)感兴趣!)

关于perl 按位与和按位移位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26378753/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com