1

我有一个 perl 脚本,它从 TunTap 接口读取和处理 IPv4 数据包。稍微精简一下,看起来是这样的:

#!/usr/bin/perl
use warnings;
use strict;
use Common;
use Linux::TunTap;
use NetPacket::IP;
use IO::Socket;
$|++;

###### Predecs #####
my $tun;
my %config = Loadconfig();

$tun = Linux::TunTap->new(NAME => $config{'localtun_name'})
or die "Couldn't connect to Interface $config{localtun_name}\n";
print "Interface up: " . $tun->{interface} . "\n";

while (my $rawdata = $tun->get_raw()) {
        $rawdata =~ s/^....//; # Strip the TunTap header
        my $packet = NetPacket::IP->decode($rawdata);
        print "$packet->{id} $packet->{src_ip} -> $packet->{dest_ip} $packet->{proto} $packet->{len}\n";
        # Do some processing here
}

出于路由的原因,我需要知道数据的源端口。我还没有找到一种方法来做到这一点NetPacket::IP,那么有没有不同的方法来确定呢?我目前只是NetPacket::IP出于调试原因使用,所以我并没有真正设置该模块,特别是如果一个不同的模块允许我提取除了序列号、大小、源 IP 和目标 IP 之外的源端口。

4

1 回答 1

2

NetPacket::IP只处理没有端口概念的IP数据包。端口仅在 TCP/UDP(或任何您在 IP 之上分层的)层上发挥作用,因此您需要例如NetPacket::TCP获取此信息。您可能需要查看 $packet->{proto} 来决定要使用哪个模块(TCP 或 UDP)进行 layer4 解析。

如果您确定不需要更高级别NetPacket模块有意义的附加标头字段,则可以利用源端口位于 TCP 和 UDP 标头的前 16 位这一事实,因此您可以说

# Untested, so I'm not sure about the case returned in
# $packet->{proto}
if($packet->{proto} eq 'tcp' or $packet->{proto} eq 'udp') {
    $port = unpack('n', $packet->{data});
    ...
}

编辑:顺便说一句,如果这是一个问题,使用 substr() 而不是正则表达式替换应该更快。

于 2015-10-10T11:34:30.257 回答