perl按位AND和按位移位

perl按位AND和按位移位,第1张

概述我正在阅读模块 Net::Pcap::Easy的一些示例代码片段,我遇到了这段代码 my $l3protlen = ord substr $raw_bytes, 14, 1;my $l3prot = $l3protlen & 0xf0 >> 2; # the protocol partreturn unless $l3prot == 4; # return unless IPv4 我正在阅读模块 Net::Pcap::Easy的一些示例代码片段,我遇到了这段代码

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

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

解决方法 为了解析帧,我查了 this page.

现在进入Perl ……

my $l3protlen =  ord substr $raw_bytes,1;

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

在IPv4帧中,前14个字节是MAC头(目标和源MAC地址各6个字节,后面是2字节的Ethertype,可能是0x8000 – 您可以检查这个).在此之后,第15个字节是以太网数据有效载荷的开始:它的第一个字节包含Version(高4字节)和DWORD中的header Length(低4字节).

现在它看起来像这个示例代码的下一行中有一个错误,但它通常可以通过侥幸工作!

my $l3prot    = $l3protlen & 0xf0 >> 2; # the protocol part

在Perl中,>>优先级高于&,所以这相当于

my $l3prot    = $l3protlen & (0xf0 >> 2);

或者如果你愿意的话

my $l3prot    = $l3protlen & 0x3c;

因此,这从$l3prot值中提取位2-5:掩码值0x3c是二进制的0011 1100.因此,例如,值0x86(二进制,1000 0110)将变为0x04(二进制0000 0100).
实际上,“正常”IPv4值是0x45,即协议类型4,报头长度为5个双字.掩盖与0x3c,你得到… 4!但只有侥幸:你已经测试了长度的前2位,而不是协议类型!

这条线肯定是

my $l3prot = ($l3protlen & 0xf0) >> 4;

(注意优先级的括号和4位的移位,而不是2位). (我在CPAN documentation中发现了同样的错误,所以我猜它可能已经广泛传播了.)

return unless $l3prot == 4; # return unless IPv4

对于IPv4,我们希望这个值为4 – 如果不是,立即跳出函数. (因此上面的错误代码给出了结果,这可以将其解释为IPv4数据包,但仅限运气.)

my $l4prot = ord substr $packet,1;

现在提取第24个字节并以相同的方式转换为序数值.这是来自IP标头的协议字节:

return unless $l4prot == '7';

我们希望这是7 – 如果它没有马上跳出功能. (根据IANA,7是“基于核心的树”……但我猜你知道你感兴趣的协议!)

总结

以上是内存溢出为你收集整理的perl按位AND和按位移位全部内容,希望文章能够帮你解决perl按位AND和按位移位所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1257999.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-07
下一篇 2022-06-07

发表评论

登录后才能评论

评论列表(0条)

保存