AMPR-Rip44

 view release on metacpan or  search on metacpan

META.json  view on Meta::CPAN

   },
   "name" : "AMPR-Rip44",
   "no_index" : {
      "directory" : [
         "t",
         "inc"
      ]
   },
   "prereqs" : {
      "build" : {
         "requires" : {
            "ExtUtils::MakeMaker" : 0
         }
      },
      "configure" : {
         "requires" : {
            "ExtUtils::MakeMaker" : 0
         }
      },
      "runtime" : {
         "requires" : {
            "IO::Socket::Multicast" : 0,
            "Test::More" : 0
         }
      }
   },
   "release_status" : "stable",
   "version" : "0.03"
}

META.yml  view on Meta::CPAN

---
abstract: 'A naive custom RIPv2 daemon'
author:
  - 'Heikki Hannikainen, OH7LZB <hessu@hes.iki.fi>'
build_requires:
  ExtUtils::MakeMaker: 0
configure_requires:
  ExtUtils::MakeMaker: 0
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.112621'
license: unknown
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html
  version: 1.4
name: AMPR-Rip44
no_index:
  directory:
    - t
    - inc
requires:
  IO::Socket::Multicast: 0
  Test::More: 0
version: 0.03

bin/rip44d  view on Meta::CPAN

	RIP_CMD_RESPONSE => 2,
	RIP_AUTH_PASSWD => 2,
	AF_INET => 2,
};

my $rip_passwd;
my $tunnel_if = 'tunl0';
my $routebin = '/sbin/ip';
my $ifconfig = '/sbin/ifconfig';
my $verbose = 0;
# Local gateway addresses (whose routes are skipped)
my %my_addresses;
# Allowed route destination networks
my $net_44_regexp = '^44\.';
# We do not accept routes less specific than /15
my $minimum_prefix_len = 15;
# tcp window to set
my $tcp_window = 840;
# time (in seconds) to use routes which are no longer advertised
# - this is set to a large value, so that if the rip advertisements
# from mirrorshades stop, the network won't go down right away.
my $route_ttl = 7*24*60*60;

bin/rip44d  view on Meta::CPAN

	
	print $fh "Usage:\n"
		. "  $me [-v] [-d] [-i <tunnelif>] [-a <localaddrs>] [-p <password>]\n"
		. "Options:\n"
		. "  -v   increase verbosity slightly to print error messages on stderr\n"
		. "  -d   increase verbosity greatly (debug mode)\n"
		. "  -i <tunnelinterface>\n"
		. "       use the specified tunnel interface, defaults to tunl0\n"
		. "  -a <comma-separated-ip-list>\n"
		. "       ignore routes pointing to these (local) gateways\n"
		. "       (list contains system's local IP addresses by default)\n"
		. "  -p <password>\n"
		. "       use RIPv2 password 'authentication', defaults to none\n"
		;
}

sub VERSION_MESSAGE()
{
	my($fh) = @_;
	
	print $fh "$me version $VERSION\n";
}

# Figure out local interface IP addresses so that routes to them can be ignored

sub fill_local_ifs()
{
	my $s = `$ifconfig -a`;
	
	while ($s =~ s/inet addr:(\d+\.\d+\.\d+\.\d+)//) {
		warn "found local address: $1\n" if ($verbose);
		$my_addresses{$1} = 1;
	}
}

# Convert a netmask (in integer form) to the corresponding prefix length,
# and validate it too. This is a bit ugly, optimizations are welcome.

sub mask2prefix($)
{
	my($mask) = @_; # integer
	
	# convert to a string of 1's and 0's, like this (/25):
	# 11111111111111111111111110000000
	my($bits) = unpack("B32", pack('N', $mask));
	

bin/rip44d  view on Meta::CPAN

	
	# the network-netmask pair makes sense: network & netmask == network
	if (($e_net_i & $e_netmask) != $e_net_i) {
		#print "e_net '$e_net_i' e_netmask '$e_netmask' ANDs to " . ($e_net_i & $e_netmask) . "\n";
		warn "$e_net_s/$e_netmask_s => $e_nexthop_s blocked, subnet-netmask pair does not make sense\n" if ($verbose);
		return (0, 'invalid subnet-netmask pair');
	}
	
	# network is in 44/8
	if ($e_net_s !~ /$net_44_regexp/) {
		warn "$e_net_s/$e_netmask_s => $e_nexthop_s blocked, non-amprnet address\n" if ($verbose);
		return (0, 'net not in 44/8');
	}
	
	# nexthop address is not in 44/8
	if ($e_nexthop_s =~ /$net_44_regexp/) {
		warn "$e_net_s/$e_netmask_s => $e_nexthop_s blocked, nexthop is within amprnet\n" if ($verbose);
		return (0, 'nexthop is in 44/8');
	}
	
	# nexthop address does not point to self
	if (defined $my_addresses{$e_nexthop_s}) {
		warn "$e_net_s/$e_netmask_s => $e_nexthop_s blocked, local gw\n" if ($verbose);
		return (0, 'local gw');
	}
	
	return (1, 'ok');
}

# process a RIPv2 route entry

sub process_rip_route_entry($)

bin/rip44d  view on Meta::CPAN

	my $e_net_i = unpack('N', $e_net);
	my $e_netmask = substr($entry, 8, 4);
	my $e_netmask_i = unpack('N', $e_netmask);
	my $e_nexthop = substr($entry, 12, 4);
	my $e_metric = unpack('N', substr($entry, 16, 4));
	my $e_net_s = inet_ntoa($e_net);
	my $e_netmask_s = inet_ntoa($e_netmask);
	my $e_nexthop_s = inet_ntoa($e_nexthop);
	
	# Validate the route
	my($result, $reason) = validate_route($e_net_i, $e_net_s, $e_netmask_i, $e_netmask_s, $e_nexthop_s);
	if (!$result) {
		warn "entry ignored ($reason): af $e_af rtag $e_rtag $e_net_s/$e_netmask_s via $e_nexthop_s metric $e_metric\n" if ($verbose);
		return 0;
	}
	
	warn "entry: af $e_af rtag $e_rtag $e_net_s/$e_netmask_s via $e_nexthop_s metric $e_metric\n" if ($verbose > 1);
	
	# Ok, we have a valid route, consider adding it in the kernel's routing table
	consider_route($e_net_s, $e_netmask_s, $e_nexthop_s, $e_rtag);
	
	return 1;

bin/rip44d  view on Meta::CPAN

		warn "$me: ignored invalid length packet from $addr_s: " . length($msg) . "\n";
		return -1;
	}
	
	# validate RIP packet header
	my $hdr = substr($msg, 0, 4);
	my $entries = substr($msg, 4);
	
	my($rip_command, $rip_version, $zero1, $zero2) = unpack('C*', $hdr);
	if ($rip_command != RIP_CMD_RESPONSE) {
		warn "$me: ignored non-response RIP packet from $addr_s\n";
		return -1;
	}
	if ($rip_version != 2) {
		warn "$me: ignored RIP version $rip_version packet from $addr_s (only accept v2)\n";
		return -1;
	}
	if ($zero1 != 0 || $zero2 != 0) {
		warn "$me: ignored RIP packet from $addr_s: zero bytes are not zero in header\n";
		return -1;
	}

bin/rip44d  view on Meta::CPAN

	$rip_passwd = $opts{'p'};
}
if ($opts{'v'} && !$verbose) {
	$verbose = 1;
}
if ($opts{'d'}) {
	$verbose = 2;		
}
if ($opts{'a'}) {
	foreach my $a (split(',', $opts{'a'})) {
		$my_addresses{$a} = 1;
	}
}

fill_local_ifs();

# Enable multicast on the tunnel interface, the flag is
# not set by default
system($ifconfig, $tunnel_if, 'multicast') == 0 or die "ifconfig $tunnel_if multicast failed: $?\n";

# Create the UDP multicast socket to receive RIP broadcasts

bin/rip44d  view on Meta::CPAN

	LocalPort => 520,
	ReuseAddr => 1,
) or die $!;

$socket->mcast_add('224.0.0.9', $tunnel_if) or die $!;

my $expire_interval = 60*60;
my $next_expire = time() + $expire_interval;

# Main loop: receive broadcasts, check that they're from the correct
# address and port, and pass them on to processing
warn "entering main loop, waiting for RIPv2 datagrams\n" if ($verbose);
while (1) {
	my $msg;
	my $remote_address = recv($socket, $msg, 1500, 0);
	
	if (!defined $remote_address) {
		next;
	}
	
	my ($peer_port, $peer_addr) = unpack_sockaddr_in($remote_address);
	my $addr_s = inet_ntoa($peer_addr);
	
	if ($addr_s ne '44.0.0.1' || $peer_port ne 520) {
		warn "$me: ignored packet from $addr_s: $peer_port: " . length($msg) . "\n";
		next;
	}
	
	warn "received from $addr_s: $peer_port: " . length($msg) . " bytes\n" if ($verbose);
	
	my $routes = process_msg($addr_s, $peer_port, $msg);

lib/AMPR/Rip44.pm  view on Meta::CPAN

=head1 SYNOPSIS

A naive custom RIPv2 daemon to receive RIP updates from the
44/8 ampr.org routing service, and insert them in the
Linux routing table.

=head1 SUBROUTINES/METHODS

=head2 fill_local_ifs

Figure out local interface IP addresses so that routes to them can be ignored

=cut

sub fill_local_ifs() {

}

=head2 mask2prefix

Convert a netmask (in integer form) to the corresponding prefix length,
and validate it too. This is a bit ugly, optimizations are welcome.

=cut

sub mask2prefix ($) {
	my($mask) = @_; # integer

}



=head1 AUTHOR

Heikki Hannikainen, OH7LZB, C<< <hessu at hes.iki.fi> >>

=head1 BUGS

Please report any bugs or feature requests to C<bug-ampr-rip44 at rt.cpan.org>, or through
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=AMPR-Rip44>.  I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.




=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc AMPR::Rip44

t/perlcriticrc  view on Meta::CPAN

[-ValuesAndExpressions::ProhibitConstantPragma]
[-Subroutines::RequireArgUnpacking]
[-Subroutines::ProhibitSubroutinePrototypes]



( run in 0.652 second using v1.01-cache-2.11-cpan-49f99fa48dc )