AMPR-Rip44

 view release on metacpan or  search on metacpan

bin/rip44d  view on Meta::CPAN

		if ($current_routes{$rkey}->{'t'} < $exp_t) {
			# expire route
			warn "route $rkey has expired, deleting\n" if ($verbose);
			route_delete($rkey);
			delete $current_routes{$rkey};
		} elsif ($current_routes{$rkey}->{'t'} > $now) {
			# clock has jumped backwards, the time is in
			# the future - set 't' to $now so that the route
			# will be expired eventually
			$current_routes{$rkey}->{'t'} = $now;
		}
	}
}

# Consider adding a route in the routing table

sub consider_route($$$$)
{
	my($net, $mask, $nexthop, $rtag) = @_;
	
	my $rkey = "$net/$mask";
	if (defined $current_routes{$rkey}
		&& $current_routes{$rkey}->{'nh'} eq $nexthop
		&& $current_routes{$rkey}->{'rtag'} eq $rtag) {
		# ok, current route is fine
		warn "route $rkey is installed and current\n" if ($verbose > 1);
		$current_routes{$rkey}->{'t'} = time();
		return;
	}
	
	warn "route $rkey updated: via $nexthop rtag $rtag\n" if ($verbose > 1);
	
	$current_routes{$rkey} = {
		'nh' => $nexthop,
		'rtag' => $rtag,
		't' => time()
	};
	
	# now go and update the routing table
	route_delete($rkey);
	my($out, $cmd);
	$cmd = "LANG=C $routebin route add $rkey via $nexthop dev $tunnel_if window $tcp_window onlink";
	$out = `$cmd 2>&1\n`;
	if ($?) {
		warn "route add failed: '$cmd': $out\n";
	}
}

# process a RIPv2 password authentication entry

sub process_rip_auth_entry($)
{
	my($entry) = @_;
	
	my $e_af = unpack('n', substr($entry, 0, 2));
	if ($e_af != 0xFFFF) {
		warn "RIPv2 first message does not contain auth password: ignoring\n" if ($verbose);
		return 0;
	}
	
	my $e_type = unpack('n', substr($entry, 2, 2));
	if ($e_type != RIP_AUTH_PASSWD) {
		warn "ignoring unsupported rip auth type $e_type\n" if ($verbose);
		return 0;
	}
	
	my $e_passwd = substr($entry, 4, 16);
	$e_passwd =~ s/\0*$//; # it's null-padded in the end
	
	if (!defined $rip_passwd) {
		warn "RIPv2 packet contains password $e_passwd but we require none\n" if ($verbose);
		return 0;
	}
	
	if ($e_passwd ne $rip_passwd) {
		warn "RIPv2 invalid password $e_passwd\n" if ($verbose);
		return 0;
	}
	
	return 1;
}

# validate a route entry, make sure we can rather safely
# insert it in the routing table

sub validate_route($$$$$)
{
	my($e_net_i, $e_net_s, $e_netmask, $e_netmask_s, $e_nexthop_s) = @_;
	
	# netmask is correct and not too wide
	my $prefix_len = mask2prefix($e_netmask);
	if ($prefix_len < 0) {
		warn "invalid netmask: $e_netmask_s\n" if ($verbose);
		return (0, 'invalid netmask');
	}
	
	if ($prefix_len < $minimum_prefix_len) {
		warn "$e_net_s/$e_netmask_s => $e_nexthop_s blocked, prefix too short\n";
		return (0, 'prefix length too short');
	}
	
	# 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);



( run in 1.273 second using v1.01-cache-2.11-cpan-df04353d9ac )