Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: Determine which route to take

by rjt (Deacon)
on Aug 03, 2013 at 02:15 UTC ( #1047672=note: print w/ replies, xml ) Need Help??


in reply to Determine which route to take

I'd use a module, too, but if you want/need to know how the math works, it's actually pretty simple:

Update: Add this summary of the math:

Convert IP address (or route subnet) to integer:

my $ip = ($A << 24) + ($B << 16) + ($C << 8) + $D; # Do the same for each route address ($net)

Convert /24 CIDR notation to 0xffffff00 netmask:

    my $mask = 0xffffffff ^ (1 << 32 - $cidr) - 1;

Check if a destination IP matches a route:

    ($ip & $mask) == $net;

Full example:

#!/usr/bin/env perl use 5.012; use warnings FATAL => 'all'; # Use an array instead if order is important my %routes = ( '192.168.0.1' => [ '192.168.0.0' => 24 ], '10.10.10.1' => [ '10.10.10.0' => 24 ], 'default' => [ '12.162.8.11' => 28 ], ); printf "%15s -> %s\n", $_, route($_) for qw< 10.10.10.12 128.127.126.125 192.168.0.51 192.168.1.1 10.10.10.5 >; sub ip { $_[0] =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/ or die "Invalid IP"; die "Octet out of range" if ($1 & $2 & $3 & $4) > 255; ($1 << 24) + ($2 << 16) + ($3 << 8) + $4 } sub route { my $ip = ip($_[0]); while (my ($dest, $route) = each %routes) { my ($net, $cidr) = @$route; my $mask = 0xffffffff ^ (1 << 32 - $cidr) - 1; return $dest if ($ip & $mask) == ip($net); } return 'default'; }

Output:

10.10.10.12 -> 10.10.10.1 128.127.126.125 -> default 192.168.0.51 -> 192.168.0.1 192.168.1.1 -> default 10.10.10.5 -> 10.10.10.1


Comment on Re: Determine which route to take
Select or Download Code
Replies are listed 'Best First'.
Re^2: Determine which route to take
by mhearse (Hermit) on Aug 07, 2013 at 16:12 UTC
    Excellent! Thanks so much. I could learn a lot by reading your code. Do you have a github page? Or webpage? With code? Also... where did you learn about bitshifting and netmasking? Can you recommend a book?

      Thanks for the kind words, mhearse. I don't have a public GitHub or web presence, aside from my sundry answers on PerlMonks.

      Also... where did you learn about bitshifting and netmasking?

      I'd better not answer that one directly. :-)

      Have a look at Bitwise_operation, maybe Truth_table for some background. Once you have a decent handle on that, IP subnetting (which I've only just skimmed), looks like a decent intro to IPv4 math.

      Can you recommend a book?

      Unfortunately, my brain's bibliography is in serious need of trie optimization. Any relatively current text on IP networking will probably be a good start, though.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1047672]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2015-07-28 05:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (252 votes), past polls