用Linux :: TunTap读取数据包

我把一个perl脚本放在一起,通过Linux :: TunTap将数据包读入用户空间,这一切似乎都正常工作:

#!/usr/bin/perl use warnings; use strict; use Linux::TunTap; $tun = new Linux::TunTap(NAME => 'localtun') or die "Couldn't connect to IF\n"; while (my $packet = $tun->get_raw()) { print Dumper($packet); } 

现在的问题是:如何将表示原始IP数据包的string从tuntap设备读取到适当的数据结构中进行处理? 特别是我在源,目的地和序列号之后。

显然,原始IP数据包在原始格式上不是人类可读的。 这是在通过tuntap接口发送ping之后的输出:

{{{ }/ 8V | !"#$%&'()*+,-./0123456ET @@4

如何从这里开始以编程方式处理这些数据?

基于SteffenUlrich的评论,我看了一下NetPacket :: IP ,它通过它的decode()方法为我做了窍门。 在将其烧写到我的代码中之后,它开箱即用,唯一需要注意的是前四个字节必须从原始数据中删除(请参见下面的lazy regex),因为这些字节形成了由TunTap添加的额外头文件层。

我的代码现在看起来像这样,并按预期工作:

 #!/usr/bin/perl use warnings; use strict; use Linux::TunTap; use NetPacket::IP; $tun = new Linux::TunTap(NAME => 'localtun') or die "Couldn't connect to IF\n"; while (my $rawdata = $tun->get_raw()) { $rawdata =~ s/^....//; # Using regex to strip 4 bytes, because I'm lazy my $packet = NetPacket::IP->decode($rawdata); print "$packet->{id} $packet->{src_ip} -> $packet->{dest_ip} $packet->{proto} $packet->{len}\n"; } 

以上代码打印序列,源IP,目标IP,协议号和数据包长度。