linux - 使用 Linux::TunTap 读取数据包

标签 linux perl tcp 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);
}

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

很明显,原始 IP 数据包的原始格式不是人类可读的。这是通过 tuntap 接口(interface)发送 ping 后的输出:

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

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

最佳答案

基于 SteffenUlrich 的评论,我看了看NetPacket::IP ,它通过它的 decode() 方法帮了我的忙。在将其烘焙到我的代码中后,它几乎开箱即用,唯一需要注意的是前四个字节必须来自原始数据(请参阅下面的惰性正则表达式),因为这些字节形成了 TunTap 添加的附加 header 层。

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

#!/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、协议(protocol)号和数据包长度。

关于linux - 使用 Linux::TunTap 读取数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32803409/

相关文章:

linux - sh 中的子字符串返回 "Bad substitution"

linux - LWP 用户代理中的状态读取失败

linux - 生产者消费者——在子进程中使用信号量

linux - TCP_FASTOPEN cookie 是根据什么保存的?

c - 通过 TCP 填充数据

服务器端的 C++ TCP 套接字多次写入()在客户端被视为单次读取

javascript - HTML5 : play on speakers stream from microphone on Ubuntu

perl - 为什么 Perl 认为 -1 是真的?

perl - 如何在 Perl 中通过 ssh 从 cat 获取输入

perl - 停用和删除 Perl Local::Lib