在 Perl 中使用 Sys:Addrr

Utilizing Sys:Addrr in Perl

最终的目标是使用模块创建一个 ARP 侦听器和发送器。

我正在尝试替代:

my $IP = "xx.x.x.xx"; #this is an actual local ip address
my $MacAddress = "ff:ff:ff:ff:ff:ff"; # this is an actual macadd
my $LAN = "xx.x.x.xx/24"; #this has the ip and subnetmask

带有模块Sys::Addrr,每次程序运行时自动获取IP和LAN,这包括在不同的机器上。

我已经使用 cpan- https://metacpan.org/pod/Sys::HostAddr

将代码缩减到这么多
my $sysaddr = Sys::HostAddr->new();
my $href = $sysaddr->ip();
 foreach my $interface ( keys %{$href} ){
     foreach my $aref ( @{$href->{$interface}} ){
          print " $aref->{address}\n"; 
          print " $aref->{netmask}\n";
     }
 }

但我对这段代码或结构的语法理解不够,无法仅提取第一个数组引用以供使用。使用 Data::Dumper 我能够看到分解,注意到它正在将我想要的地址分配给 1 位置,但我似乎仍然无法提取它以供程序使用。

我还注意到无法通过 Sys::Addr 获得 MacAddress - 我假设将需要另一个模块。

编辑: 运行宁时拉取的信息为:

$VAR1 = {
          'lo' => [
                    {
                      'address' => 'x.x.x.x',
                      'netmask' => 'x.x.x.x'
                    }
                  ],
          'eth0' => [
                      {
                        'netmask' => 'x.x.x.x',
                        'address' => 'x.x.x.x'
                      }
                    ]
        };

我正在尝试提取两个变量中的 "eth0" 内容以供程序使用。

没有这个新增的完整代码如下,供参考使用:

use strict;
use warnings;

use Net::Pcap::Easy;
use Net::Netmask;
use Net::ARP;
use Sys::HostAddr

my $IP = "x.x.x.x"; #IP Address omitted for example
my $MacAddress = "ff:ff:ff:ff:ff:ff"; #Mac Address omitted for example
my $LAN = "x.x.x.x/24"; # address omitted for example


my $parentpid = $$;
my $childpid = fork() // die "Fork Failed $!\n";

if ($childpid){
    print "perl lab6.pl $IP\n";
    print "Scanning $LAN\n";
    print "Starting parent $$ with child $childpid\n";
    print "Starting child pid $childpid\n";
    &send_loop;
    sleep 1;
    print "Killing child $childpid\n";
    kill 'KILL', $childpid;
    waitpid ($childpid, 0);
    print "Exiting parent $$\n";
    exit;
}
else {
    &cap_packs;
}

sub cap_packs{
    my $listener = Net::Pcap::Easy->new(
        dev             => "eth0",
        filter          => "arp",
        packets_per_loop    => 1,
        arp_callback        => sub {
                        my($npe,$ether,$arp,$header)=@_;
                        print "Hello";
                        if($arp->{opcode}==2){
                            my $iphex = $arp->{spa};
                            my @ip =($iphex=~/(..)(..)(..)(..)/);
                            my $ipstr = hex($ip[0]).".". hex($ip[1]).".". 
                            hex($ip[2]).".".hex($ip[3]);
                            print "Host $ipstr is alive.";
                            }
                        }
            );
    $listener->loop while 1;
}


sub send_loop{
    my $netobj = new Net::Netmask($LAN);
    for my $Remote_IP ($netobj->enumerate) {
        Net::ARP::send_packet(
            "eth0",
            $IP,
            $Remote_IP,
            $MacAddress,
            "ff:ff:ff:ff:ff:ff",
            "request");
        }
}

对于 Sys::Addr 我想出了如何让它正常工作。

my $sysaddr = Sys::HostAddr->new();

my $IP;
my $LAN;

my $href = $sysaddr->ip();
ints:foreach my $interface ( keys %{$href} ){
    foreach my $aref ( @{$href->{$interface}} ){
    $IP = "$aref->{address}\n";
        $LAN = "$aref->{address}:$aref->{netmask}\n";
    if ($interface eq "eth0"){last ints}
    }
}

这让我可以将 'eth0' 用作全局变量。