使用Linux :: TunTap读取数据包

Jar*_*und 6 linux perl tcp-ip tun

我已经整理了一个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);
}
Run Code Online (Sandbox Code Playgroud)

现在的问题是:如何将表示从tntap设备读取的原始IP数据包的字符串转换为适当的数据结构进行处理?特别是我在源,目的地和序列号之后.

显然,原始IP数据包的原始格式不是很易读.这是通过tuntap接口发送ping后的输出:

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

如何从此处继续以编程方式处理此数据?

Jar*_*und 5

根据SteffenUlrich的评论,我查看了NetPacket::IP,它通过它的decode()方法为我解决了问题。在将它烘焙到我的代码中后,它几乎开箱即用,唯一的警告是前四个字节必须来自原始数据(请参阅下面的惰性正则表达式),因为这些字节形成了由 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";
}
Run Code Online (Sandbox Code Playgroud)

上面的代码打印了序列、源IP、目的IP、协议号和数据包长度。