使用 perl IP 库循环遍历一系列 IP

Loop over a range of IPs with perl IP library

我正在尝试创建一个 IP table 列表,我可以在其中查看哪些 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 地址处于活动状态。

这不起作用的原因是模块要求您发送正确的网络地址作为给定 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());

我建议您改用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

如果你想"normalize"一个不能使用网络地址作为前缀的CIDR块,你可以使用Net::CIDR::cidr2range后跟[=​​18=]。给定 '1.2.3.4/29',第一个 returns 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