代码之家  ›  专栏  ›  技术社区  ›  Jarmund

使用Linux::TunTap读取数据包

  •  6
  • Jarmund  · 技术社区  · 11 年前

    我已经编写了一个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

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

    1 回复  |  直到 11 年前
        1
  •  5
  •   Community Mohan Dere    9 年前

    根据 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";
    }
    

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

    推荐文章