在 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' 用作全局变量。
最终的目标是使用模块创建一个 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' 用作全局变量。