Checking IP addresses against lists of IPs, partial IPs, and netmasks.

A

Adam Funk

I'm trying to write some Perl code to check an IP addresses against a list
of strings containing IP address, partial IP addresses ending in ".",
net/mask pairs and net/masklength pairs.

In other words, I'd like ip_found("192.168.2.3") to return true if the test
list contains any of the following:
192.168.2.3
192.168.
192.168.2.0/255.255.255.0
192.168.2.0/24

I'm sure someone else has done this already -- any good code to recycle?

Thanks,
Adam
 
A

Anno Siegel

Adam Funk said:
I'm trying to write some Perl code to check an IP addresses against a list
of strings containing IP address, partial IP addresses ending in ".",
net/mask pairs and net/masklength pairs.

In other words, I'd like ip_found("192.168.2.3") to return true if the test
list contains any of the following:
192.168.2.3
192.168.
192.168.2.0/255.255.255.0
192.168.2.0/24

I'm sure someone else has done this already -- any good code to recycle?

So what have you tried? Which modules have you considered?

Just throwing specifications at the newsgroup is unlikely to give
useful replies.

Anno
 
A

Adam Funk

Anno said:
So what have you tried? Which modules have you considered?

I had started from scratch using regexps and some other string manipulation,
but fortunately found Net::Netmask, which does a lot of the job for me.

I can read the input file and for each netmask string, create a Net::Netmask
and test with the Net::Netmask->match($ip) method, until it returns true or
I run out of input.

But I'm wondering if there is a more efficient way to do it.
 
A

axel

Adam Funk said:
I'm trying to write some Perl code to check an IP addresses against a list
of strings containing IP address, partial IP addresses ending in ".",
net/mask pairs and net/masklength pairs.
In other words, I'd like ip_found("192.168.2.3") to return true if the test
list contains any of the following:
192.168.2.3
192.168.
192.168.2.0/255.255.255.0
192.168.2.0/24

Unless I am being very stupid here, what you want to do is simply
match '^192.168.' against the list. So a basic check could be:

my @list = qw(192.168.2.3
192.168.
192.168.2.0/255.255.255.0
192.168.2.0/24);
my $instr = '192.168.';
if (grep /^$instr/, @list) { print "OK"}

However I suspect you are wanting to do more than that and check
if the IP address is within a certain range... but then you would
need to supply more information about the address to be checked
(i.e. what class of address).

Axel
 
A

Anno Siegel

Adam Funk said:
I had started from scratch using regexps and some other string manipulation,
but fortunately found Net::Netmask, which does a lot of the job for me.

I can read the input file and for each netmask string, create a Net::Netmask
and test with the Net::Netmask->match($ip) method, until it returns true or
I run out of input.

But I'm wondering if there is a more efficient way to do it.

Don't worry about efficiency at this point. Enjoy having found a
method that *works* and move on. When the program as a whole is too
slow, and if it turns out that the IP search is the culprit, then it's
time to think about a speed-up.

In any case, we have too little information about the way that search
is performed to come up with improvements. If you run many IPs against
a rarely changing set of network blocks the situation is different from
the other way 'round.

Anno
 
T

Tintin

Adam Funk said:
I'm trying to write some Perl code to check an IP addresses against a list
of strings containing IP address, partial IP addresses ending in ".",
net/mask pairs and net/masklength pairs.

In other words, I'd like ip_found("192.168.2.3") to return true if the
test
list contains any of the following:
192.168.2.3
192.168.
192.168.2.0/255.255.255.0
192.168.2.0/24

I'm sure someone else has done this already -- any good code to recycle?


Have a look at:

http://search.cpan.org/~marcel/Net-IP-Match-0.01/Match.pm
http://search.cpan.org/~luismunoz/NetAddr-IP-3.24/IP.pm
 
J

Joe Smith

However I suspect you are wanting to do more than that and check
if the IP address is within a certain range... but then you would
need to supply more information about the address to be checked
(i.e. what class of address).

I've seen that syntax before. The class of address _is_ being provided.

192.168. = 192.168.*.* = 192.168.0.0:255.255.0.0 = 192.168/16
192.168.2 = 192.168.2.* = 192.168.2.0:255.255.255.0 = 192.168.2/24
192.168.2.0/24 = 192.168.2/24
192.168.2.3 = 192.168.2.3:255.255.255.255 = 192.168.2.3/32

-Joe
 
A

axel

I've seen that syntax before. The class of address _is_ being provided.
192.168. = 192.168.*.* = 192.168.0.0:255.255.0.0 = 192.168/16
192.168.2 = 192.168.2.* = 192.168.2.0:255.255.255.0 = 192.168.2/24
192.168.2.0/24 = 192.168.2/24
192.168.2.3 = 192.168.2.3:255.255.255.255 = 192.168.2.3/32

No it was not provided. Only an IP number was provided to be matched.
The class of which is unknown... except in the era of pre-classless
addresses.

We know what a 192.168 number is by simply looking at it... a
private number... but if the number had been 194... it would be a
different story.

Axel
 
A

Adam Funk

Anno said:
Don't worry about efficiency at this point. Enjoy having found a
method that *works* and move on. When the program as a whole is too
slow, and if it turns out that the IP search is the culprit, then it's
time to think about a speed-up.

In any case, we have too little information about the way that search
is performed to come up with improvements. If you run many IPs against
a rarely changing set of network blocks the situation is different from
the other way 'round.

The program would normally check one IP address against a list of IPs
and IP ranges parsed in from a file, so the main part would be
something like this:

$matched = 0 ;
foreach $ip_range (@ip_ranges) {
$block = new Net::Netmask($ip_range);
if ($block->match($ip_to_check)) {
$matched = 1;
last;
}
}

if that looks OK to you!
 
A

Adam Funk

Unless I am being very stupid here,

My examples were not very good.
what you want to do is simply
match '^192.168.' against the list. So a basic check could be:

That would work for the first two examples, but if the list of IP
ranges to check against includes "218.0.0.0/7" then "219.84.130.159"
should match.

However I suspect you are wanting to do more than that and check
if the IP address is within a certain range... but then you would
need to supply more information about the address to be checked
(i.e. what class of address).

I found the Net::Netmask module on CPAN.
 
A

Adam Funk

Anno said:
Don't worry about efficiency at this point. Enjoy having found a
method that *works* and move on. When the program as a whole is too
slow, and if it turns out that the IP search is the culprit, then it's
time to think about a speed-up.

Fair enough! I think what bothered me is that this superficially resembles
testing something for membership of an array by iterating through the array
-- which I know is a no-no (you're supposed to use a hash instead).
 
A

Anno Siegel

Adam Funk said:
Fair enough! I think what bothered me is that this superficially resembles
testing something for membership of an array by iterating through the array
-- which I know is a no-no (you're supposed to use a hash instead).

To get that kind of performance in your situation you'd have to expand
all address blocks explicitly to a hash. That could mean throwing
a *lot* of memory at the problem. Also, it would only gain much if
you have many IPs to check against the same set of address blocks.
Otherwise, rebuilding the hash frequently would eat up the gain.

Anno
 
A

Adam Funk

Anno said:
To get that kind of performance in your situation you'd have to expand
all address blocks explicitly to a hash. That could mean throwing
a *lot* of memory at the problem. Also, it would only gain much if
you have many IPs to check against the same set of address blocks.
Otherwise, rebuilding the hash frequently would eat up the gain.

I agree. Thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top