longest prefix match

F

friend.05

I have table of ip adress with prefix.

Now I need to match IP address with corresponding IP with longest
prefix.

I am not sure how can I do that.
 
J

Jürgen Exner

I have table of ip adress with prefix.

'table' is not a standard Perl data structure. How is that 'table'
implemented?
Now I need to match IP address with corresponding IP with longest
prefix.

No idea what an IP prefix is, either, but assuming you are talking about
a list of strings then a pragmatic approach would be:

grep() all list elements, where the IP part is eq to the wanted IP, then
sort() the result by length() and pick the last element.

However If the list is large and performance an issue, then you can
write a simple loop to find the wanted item in one single pass. Just
loop through the list and keep a "best candidate", which is updated
every time you find a better candidate.

for (@IPswithPrefix) {
if (IPsMatch() and length($_) > length($candidate)) {
$candidate = $_;
}
}
print $candidate;

jue
 
F

friend.05

'table' is not a standard Perl data structure. How is that 'table'
implemented?


No idea what an IP prefix is, either, but assuming you are talking about
a list of strings then a pragmatic approach would be:

grep() all list elements, where the IP part is eq to the wanted IP, then
sort() the result by length() and pick the last element.

However If the list is large and performance an issue, then you can
write a simple loop to find the wanted item in one single pass. Just
loop through the list and keep a "best candidate", which is updated
every time you find a better candidate.

for (@IPswithPrefix) {
        if (IPsMatch() and length($_) > length($candidate)) {
                $candidate = $_;
        }}

print $candidate;

jue

Suppose I have C_IP address : 12.120.29.25


and I have list of following IP addresses :

212.120.128.0|19;
12.120.0.0|15;
12.120.16.0|20;
12.120.72.0|22;
12.120.96.0|20;
12.120.40.0|21;
12.120.0.0|21;
12.120.192.0|19;
12.120.16.0|22;
12.120.36.0|22;
12.120.80.0|20;
194.212.120.0|21;
212.120.32.0|19;
212.120.64.0|18;
212.120.192.0|19;
213.3.12.120|29;
116.212.120.0|24;
12.120.24.0|21;


Now I need to map C_IP to list with longest prefix match. (As u can
there are many IP address with 12.120. but I need to map to one with
longest prefix match)
 
T

Ted Zlatanov

f> Suppose I have C_IP address : 12.120.29.25

f> and I have list of following IP addresses :
f> 212.120.128.0|19;
f> 12.120.0.0|15;
f> 12.120.16.0|20;
f> 12.120.72.0|22;
f> 12.120.96.0|20;
f> 12.120.40.0|21;
f> 12.120.0.0|21;
f> 12.120.192.0|19;
f> 12.120.16.0|22;
f> 12.120.36.0|22;
f> 12.120.80.0|20;
f> 194.212.120.0|21;
f> 212.120.32.0|19;
f> 212.120.64.0|18;
f> 212.120.192.0|19;
f> 213.3.12.120|29;
f> 116.212.120.0|24;
f> 12.120.24.0|21;

f> Now I need to map C_IP to list with longest prefix match. (As u can
f> there are many IP address with 12.120. but I need to map to one with
f> longest prefix match)

Look at Net::Netmask and the match() method in particular; just iterate
through the list above in order from largest prefix to smallest and
return when there's a match.

Ted
 
F

friend.05

f> Suppose I have C_IP address : 12.120.29.25

f> and I have list of following IP addresses :
f>  212.120.128.0|19;
f>  12.120.0.0|15;
f>  12.120.16.0|20;
f>  12.120.72.0|22;
f>  12.120.96.0|20;
f>  12.120.40.0|21;
f>  12.120.0.0|21;
f>  12.120.192.0|19;
f>  12.120.16.0|22;
f>  12.120.36.0|22;
f>  12.120.80.0|20;
f>  194.212.120.0|21;
f>  212.120.32.0|19;
f>  212.120.64.0|18;
f>  212.120.192.0|19;
f>  213.3.12.120|29;
f>  116.212.120.0|24;
f>  12.120.24.0|21;

f> Now I need to map C_IP to list with longest prefix match. (As u can
f> there are many IP address with 12.120. but I need to map to one with
f> longest prefix match)

Look at Net::Netmask and the match() method in particular; just iterate
through the list above in order from largest prefix to smallest and
return when there's a match.

Ted

I am little confuse with largest prefix to smallest.

Example:

12.120.16.0|20;
12.120.96.0|20;
12.120.40.0|21;
12.120.72.0|22;
12.120.16.0|22;

In above list what will be order of largest prefix to smallest.


And is there any tutorial with exmple where can I see steps to use
Net::Netmask
 
T

Ted Zlatanov

f> and I have list of following IP addresses :
f>  212.120.128.0|19;
f>  12.120.0.0|15;
f>  12.120.16.0|20;
f>  12.120.72.0|22;
f>  12.120.96.0|20;
f>  12.120.40.0|21;
f>  12.120.0.0|21;
f>  12.120.192.0|19;
f>  12.120.16.0|22;
f>  12.120.36.0|22;
f>  12.120.80.0|20;
f>  194.212.120.0|21;
f>  212.120.32.0|19;
f>  212.120.64.0|18;
f>  212.120.192.0|19;
f>  213.3.12.120|29;
f>  116.212.120.0|24;
f>  12.120.24.0|21;f> Now I need to map C_IP to list with longest prefix match. (As u can
f> there are many IP address with 12.120. but I need to map to one with
f> longest prefix match)
f> I am little confuse with largest prefix to smallest.

f> Example:

f> 12.120.16.0|20;
f> 12.120.96.0|20;
f> 12.120.40.0|21;
f> 12.120.72.0|22;
f> 12.120.16.0|22;

f> In above list what will be order of largest prefix to smallest.

f> And is there any tutorial with exmple where can I see steps to use
f> Net::Netmask

First of all, let's be clear about the problem as I see it, because I
think you haven't understood it clearly. If I'm wrong, sorry, but I'm
trying to help you.

I think you're trying to find the best (smallest) net block match for an
IP. The numbers you quote are net blocks, and you should know what that
means in IPv4 terms. Look it up if you don't.

The "longest" match you want really means the most specific net block,
meaning the net block with the most bits unmasked (thus, the fewest
addresses in it). If there's a tie by number of unmasked bits, the
first one found can win. In the example you give, either of the 22's
for example, if they match.

OK, so the code below walks through the net blocks, adds them to $table,
then finds the smallest net block in $table that matches the IPs. Do
"print Dumper $table" to see what the storage looks like, if you're
curious. I wrote it so you can give it multiple IPs from the command
line, and it doesn't catch the cases where the IP is not found or
invalid.

#!/usr/bin/perl

use warnings;
use strict;
use Data::Dumper;
use Net::Netmask;

my $table = {};

while (<DATA>)
{
chomp;
my $net = new Net::Netmask ($_);
$net->storeNetblock($table);
}

print findNetblock($_, $table) . "\n" foreach @ARGV;

__DATA__
12.120.16.0/20
12.120.96.0/20
12.120.40.0/21
12.120.72.0/22
12.120.16.0/22
 

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,769
Messages
2,569,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top