use strict; use NetAddr::IP; # Sample data my @sources = qw(192.168.0.19/32 192.168.0.20/32 192.168.0.21/32 192.168.0.22/32 192.168.1.72/30 192.168.1.76/30 192.168.1.80/30 192.168.1.84/30); my @dests = qw(192.168.1.73 192.168.1.77 192.168.1.81 192.168.1.85 int1 int2 int3 int4); my @types = qw(static static static static direct direct direct direct); sub lookup { my ($ip_obj, @RIB) = @_; for(my $i = 0; $i < @RIB; $i++) { next if $ip_obj == $RIB[$i]->{dest}; # don't check self if ($ip_obj->within($RIB[$i]->{source})) { return $RIB[$i]->{dest} if $RIB[$i]->{type} eq 'direct' return lookup($RIB[$i]->{dest}, @RIB); } } } my @RIB; # routing table. AoH my %FIB; # forwarding table. H # Produce 'useful' data struct from data for (my $i = 0; $i < @sources; $i++) { $RIB[$i]->{source} = new NetAddr::IP($sources[$i]); # Only create NetAddr::IP obj if not a 'direct' route $RIB[$i]->{dest} = $types[$i] eq 'direct' ? $dests[$i] : new NetAddr::IP($dests[$i]); $RIB[$i]->{type} = $types[$i]; } for (my $i = 0; $i < @RIB; $i++) { next if $RIB[$i]->{type} ne 'static'; # only interested in # static routes $FIB{$RIB[$i]->{source}->addr()} = lookup($RIB[$i]->{dest}, @RIB); } print map{ "$_ -> $FIB{$_}\n" } sort keys %FIB;