使用perl IP库在一系列IP上循环

时间:2016-10-13 14:32:10

标签: perl ipv4

我正在尝试创建一个IP表列表,我可以看到哪些IP正在使用,哪些不在。

我使用Net::IP库。代码段:

my @IPsinrange = &getAllIPs($range) ; #range is x.x.x.x/subnet format
sub getAllIPs {
    my $ip = new Net::IP ($range) || die;
    my @IPs ;
    # Loop
    do {
        push @IPs, $ip->ip() ;
    } while (++$ip);

    return @IPs ;   
}  

这适用于x.x.x.0 / 24网络,这适用于1.2.3.4/32但是当我使用1.2.3.4/29时,循环就会死掉。我认为这可能是因为没有正在使用的IP地址,但是该范围内有4个IP存活。

2 个答案:

答案 0 :(得分:3)

这不起作用的原因是该模块要求您发送适当的网络地址作为给定IP前缀的起点。

由于您要使用/29前缀,因此有效范围为:

1.2.3.0/29
1.2.3.8/29
1.2.3.16/29
...etc

如评论中所述,文档指出正确使用构造函数来获得正确的诊断输出:

$ip = Net::IP->new('1.2.3.0/29') or die (Net::IP::Error());

答案 1 :(得分:1)

我建议您使用Net::CIDR函数库。函数Net::CIDR::cidr2octets完全符合您的需要,并且不会坚持范围的基地址是网络地址

以下是将测试数据1.2.3.4/29用于范围

的示例
use strict;
use warnings 'all';
use feature 'say';

use Net::CIDR;

my @range = Net::CIDR::cidr2octets('1.2.3.4/29');

say for @range;

输出

1.2.3.0
1.2.3.1
1.2.3.2
1.2.3.3
1.2.3.4
1.2.3.5
1.2.3.6
1.2.3.7

如果你想"正常化"一个可能不使用网络地址作为前缀的CIDR块,您可以使用Net::CIDR::cidr2range后跟Net::CIDR::range2cidr。给定'1.2.3.4/29',第一个返回1.2.3.0-1.2.3.7,当结果传递到Net::CIDR::range2cidr时,我们得到一个标准化结果

喜欢这样

Net::CIDR::range2cidr(Net::CIDR::cidr2range('1.2.3.4/29'));

输出

1.2.3.0/29