使用 Linux::TunTap 读取数据包
Reading packets with 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);
}
现在的问题是:如何将从 tuntap 设备读取的表示原始 IP 数据包的字符串转换为适当的数据结构以进行处理?特别是我在源、目标和序列号之后。
显然,原始 IP 数据包的原始格式不是很容易阅读。这是通过 tuntap 接口发送 ping 后的输出:
{{{�}/��8V�| !"#$%&'()*+,-./0123456ET��@@4
我如何才能以编程方式处理这些数据?
根据 SteffenUlrich, I had a look at NetPacket::IP 的评论,它通过其 decode()
方法为我解决了问题。在将其烘焙到我的代码中后,它几乎开箱即用,唯一需要注意的是前四个字节必须来自原始数据(请参阅下面的惰性正则表达式),因为这些字节形成一个额外的 header由 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、协议号和数据包长度。
我编写了一个 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);
}
现在的问题是:如何将从 tuntap 设备读取的表示原始 IP 数据包的字符串转换为适当的数据结构以进行处理?特别是我在源、目标和序列号之后。
显然,原始 IP 数据包的原始格式不是很容易阅读。这是通过 tuntap 接口发送 ping 后的输出:
{{{�}/��8V�| !"#$%&'()*+,-./0123456ET��@@4
我如何才能以编程方式处理这些数据?
根据 SteffenUlrich, I had a look at NetPacket::IP 的评论,它通过其 decode()
方法为我解决了问题。在将其烘焙到我的代码中后,它几乎开箱即用,唯一需要注意的是前四个字节必须来自原始数据(请参阅下面的惰性正则表达式),因为这些字节形成一个额外的 header由 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、协议号和数据包长度。