我在尝试自己解决这个问题时遇到了这个问题,最后写了一些新的 perl 代码来解决这个问题,所以我想我会分享
它还没有优化或优雅(还),但它可以工作,并且应该非常清楚它在做什么。
list_of_matches('10.48.140.82' , '0.0.0.1')
返回:
10.48.140.82 10.48.140.83
和
list_of_matches('10.48.140.82' , '0.1.0.1')
返回:
10.48.140.82 10.48.140.83 10.49.140.82 10.49.140.83
和
list_of_matches('10.48.140.82' , '0.1.5.1')
返回:
10.48.136.82 10.48.136.83 10.48.137.82 10.48.137.83 10.48.140.82 10.48.140.83 10.48.141.82 10.48.141.83 10.49.136.82 10.49.136.83 10.49.137.82 10.49.137.83 10.49.140.82 10.49.140.83 10.49.141.82 10.49.141.83
代码:
sub list_of_matches_acl {
#Pass in the variables of ACL network and wildcard mask
#eg 10.200.128.0 0.0.0.255
my ( $acl_address, $acl_mask ) = @_;
#The array of possible matches
my @potential_matches;
#Split the incoming parameters into 4 octets
my @acl_address_octets = split /\./, $acl_address;
my @acl_mask_octets = split /\./, $acl_mask;
#Test the 1st octet
my $matches_octet_1_ref
= test_octet( $acl_address_octets[0], $acl_mask_octets[0] );
#Copy the referenced array into a new one
my @one = @{$matches_octet_1_ref};
#Test the 2nd octet
my $matches_octet_2_ref
= test_octet( $acl_address_octets[1], $acl_mask_octets[1] );
#Copy the referenced array into a new one
my @two = @{$matches_octet_2_ref};
#Test the 3rd octet
my $matches_octet_3_ref
= test_octet( $acl_address_octets[2], $acl_mask_octets[2] );
#Copy the referenced array into a new one
my @three = @{$matches_octet_3_ref};
#Test the 4th octet
my $matches_octet_4_ref
= test_octet( $acl_address_octets[3], $acl_mask_octets[3] );
#Copy the referenced array into a new one
my @four = @{$matches_octet_4_ref};
#Assemble the list of possible matches
#Iterating over all options for each octet
foreach my $octet1 (@one) {
foreach my $octet2 (@two) {
foreach my $octet3 (@three) {
foreach my $octet4 (@four) {
#Save this potential match to the array of matches
#say "$octet1.$octet2.$octet3.$octet4"
push( @potential_matches,
"$octet1.$octet2.$octet3.$octet4" );
}
}
}
}
return \@potential_matches;
}
sub test_octet {
#Test all possible numbers in an octet (0..255) against octet of acl and mask
my ( $acl_octet, $acl_wildcard_octet ) = @_;
my @matches;
#Short circuit here for a mask value of 0 since it matches only the $acl_octet
if ( $acl_wildcard_octet eq 0 ) {
push @matches, $acl_octet;
}
else {
for my $test_octet ( 0 .. 255 ) {
if (wildcard_mask_test(
$test_octet, $acl_octet, $acl_wildcard_octet
)
)
{
#If this value is a match, save it
push @matches, $test_octet;
}
}
}
#Return which values from 0..255 match
return \@matches;
}
sub wildcard_mask_test {
#Test one number against acl address and mask
my ( $test_octet, $acl_octet, $acl_wildcard_octet ) = @_;
#Bitwise OR of test_octet and acl_octet against the octet of the wildcard mask
my $test_result = $test_octet | $acl_wildcard_octet;
my $acl_result = $acl_octet | $acl_wildcard_octet;
#Return value is whether they match
return ( $acl_result eq $test_result );
}