From dc2b5ee2e6e3a50719f3f719295dd3c8538eb827 Mon Sep 17 00:00:00 2001 From: pd1acf Date: Mon, 2 Jan 2012 23:59:27 +0100 Subject: [PATCH 1/6] Update rip44d --- rip44d | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/rip44d b/rip44d index bb003a0..4cdc186 100755 --- a/rip44d +++ b/rip44d @@ -22,9 +22,11 @@ # v1.1 - 2011-09-14 Heikki Hannikainen, OH7LZB # * Enable multicast on the tunnel interface automatically # +# v1.2 - 2012-01-01 Ronald Jochems, PD1ACF +# * Added syslog functionality, using module : http://perldoc.perl.org/Sys/Syslog.html + # Things to do in the future: # -# - proper logging to syslog # - support for better authentication, if one would be supported # - support for multiple RIP masters, to fix the single point of failure # @@ -34,6 +36,7 @@ use warnings; use IO::Socket::Multicast; use Getopt::Std; +use Sys::Syslog; use constant { RIP_HDR_LEN => 4, @@ -49,6 +52,9 @@ my $tunnel_if = 'tunl0'; my $routebin = '/sbin/ip'; my $ifconfig = '/sbin/ifconfig'; my $verbose = 0; +my $syslog = 0; +my $log; +my $UDP_port=520; # Local gateway addresses (whose routes are skipped) my %my_addresses; # Allowed route destination networks @@ -64,18 +70,28 @@ my $route_ttl = 7*24*60*60; my %current_routes; -my $me = 'rip44d'; -my $VERSION = '1.1'; +my $me = $0; +my $VERSION = '1.2'; + +openlog($me, 'cons,pid', 'user'); # help and version texts $Getopt::Std::STANDARD_HELP_VERSION = 1; +sub do_syslog($) +{ + my($logtxt) = @_; + + syslog("info", "%s", "$logtxt") if ($syslog); + +} + sub HELP_MESSAGE() { my($fh) = @_; print $fh "Usage:\n" - . " $me [-v] [-d] [-i ] [-a ] [-p ]\n" + . " $me [-v] [-d] [-l] [-i ] [-a ] [-p ]\n" . "Options:\n" . " -v increase verbosity slightly to print error messages on stderr\n" . " -d increase verbosity greatly (debug mode)\n" @@ -86,6 +102,7 @@ sub HELP_MESSAGE() . " (list contains system's local IP addresses by default)\n" . " -p \n" . " use RIPv2 password 'authentication', defaults to none\n" + . " -l enable syslog functionality\n" ; } @@ -104,6 +121,7 @@ sub fill_local_ifs() while ($s =~ s/inet addr:(\d+\.\d+\.\d+\.\d+)//) { warn "found local address: $1\n" if ($verbose); + $log = do_syslog("found local address: $1"); $my_addresses{$1} = 1; } } @@ -143,6 +161,7 @@ sub route_delete($) if ($?) { if ($verbose > 1 || $out !~ /No such process/) { warn "route del failed: '$cmd': $out\n"; + $log = do_syslog("route del failed: '$cmd': $out") if ($syslog); } } } @@ -152,6 +171,7 @@ sub route_delete($) sub expire_routes() { warn "expiring old routes\n" if ($verbose); + $log = do_syslog("expiring old routes") if ($syslog); my $exp_t = time() - $route_ttl; my $now = time(); @@ -160,6 +180,7 @@ sub expire_routes() if ($current_routes{$rkey}->{'t'} < $exp_t) { # expire route warn "route $rkey has expired, deleting\n" if ($verbose); + $log = do_syslog("route $rkey has expired, deleting") if ($syslog); route_delete($rkey); delete $current_routes{$rkey}; } elsif ($current_routes{$rkey}->{'t'} > $now) { @@ -183,11 +204,13 @@ sub consider_route($$$$) && $current_routes{$rkey}->{'rtag'} eq $rtag) { # ok, current route is fine warn "route $rkey is installed and current\n" if ($verbose > 1); + $log = do_syslog("route $rkey is installed and current") if ($syslog); $current_routes{$rkey}->{'t'} = time(); return; } warn "route $rkey updated: via $nexthop rtag $rtag\n" if ($verbose > 1); + $log = do_syslog("route $rkey updated: via $nexthop rtag $rtag") if ($syslog); $current_routes{$rkey} = { 'nh' => $nexthop, @@ -202,6 +225,7 @@ sub consider_route($$$$) $out = `$cmd 2>&1\n`; if ($?) { warn "route add failed: '$cmd': $out\n"; + $log = do_syslog("route add failed: '$cmd': $out") if ($syslog); } } @@ -214,12 +238,14 @@ sub process_rip_auth_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); + $log = do_syslog("RIPv2 first message does not contain auth password: ignoring") if ($syslog); 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); + $log = do_syslog("ignoring unsupported rip auth type $e_type") if ($syslog); return 0; } @@ -228,11 +254,13 @@ sub process_rip_auth_entry($) if (!defined $rip_passwd) { warn "RIPv2 packet contains password $e_passwd but we require none\n" if ($verbose); + $log = do_syslog("RIPv2 packet contains password $e_passwd but we require none") if ($syslog); return 0; } if ($e_passwd ne $rip_passwd) { warn "RIPv2 invalid password $e_passwd\n" if ($verbose); + $log = do_syslog("RIPv2 invalid password $e_passwd") if ($syslog); return 0; } @@ -250,11 +278,13 @@ sub validate_route($$$$$) my $prefix_len = mask2prefix($e_netmask); if ($prefix_len < 0) { warn "invalid netmask: $e_netmask_s\n" if ($verbose); + $log = do_syslog("invalid netmask: $e_netmask_s") if ($syslog); 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"; + $log = do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, prefix too short") if ($syslog); return (0, 'prefix length too short'); } @@ -262,24 +292,28 @@ sub validate_route($$$$$) 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); + $log = do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, subnet-netmask pair does not make sense") if ($syslog); 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); + $log = do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, non-amprnet address") if ($syslog); 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); + $log = do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, nexthop is within amprnet") if ($syslog); 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); + $log = do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, local gw") if ($syslog); return (0, 'local gw'); } @@ -397,7 +431,7 @@ sub process_msg($$$) # command line parsing my %opts; -getopts('i:p:a:vd', \%opts); +getopts('i:p:a:vdl', \%opts); if (defined $opts{'i'}) { $tunnel_if = $opts{'i'}; @@ -416,6 +450,9 @@ if ($opts{'a'}) { $my_addresses{$a} = 1; } } +if ($opts{'l'}) { + $syslog = 1; +} fill_local_ifs(); @@ -424,9 +461,10 @@ fill_local_ifs(); system($ifconfig, $tunnel_if, 'multicast') == 0 or die "ifconfig $tunnel_if multicast failed: $?\n"; # Create the UDP multicast socket to receive RIP broadcasts -warn "opening UDP socket...\n" if ($verbose); +warn "opening UDP socket $UDP_port...\n" if ($verbose); +$log = do_syslog("opening UDP socket $UDP_port...") if ($syslog); my $socket = IO::Socket::Multicast->new( - LocalPort => 520, + LocalPort => $UDP_port, ReuseAddr => 1, ) or die $!; @@ -438,6 +476,7 @@ 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); +$log = do_syslog("entering main loop, waiting for RIPv2 datagrams") if ($syslog); while (1) { my $msg; my $remote_address = recv($socket, $msg, 1500, 0); @@ -451,13 +490,16 @@ while (1) { if ($addr_s ne '44.0.0.1' || $peer_port ne 520) { warn "$me: ignored packet from $addr_s: $peer_port: " . length($msg) . "\n"; + $log = do_syslog("ignored packet from $addr_s: $peer_port: " . length($msg) ) if ($syslog); next; } warn "received from $addr_s: $peer_port: " . length($msg) . " bytes\n" if ($verbose); + $log = do_syslog("received from $addr_s: $peer_port: " . length($msg) . " bytes") if ($syslog); my $routes = process_msg($addr_s, $peer_port, $msg); warn "processed $routes route entries\n" if ($verbose && $routes >= 0); + $log = do_syslog("processed $routes route entries") if ($syslog); # Consider expiring old routes. This is actually never run if we do not receive # any RIP broadcasts at all (the recv() is blocking) @@ -469,3 +511,4 @@ while (1) { } } +closelog(); From 356642d31ad4a397413250621725d3a56d7d3a92 Mon Sep 17 00:00:00 2001 From: pd1acf Date: Tue, 3 Jan 2012 14:36:39 +0100 Subject: [PATCH 2/6] shortend the lines that call the syslog susbroutine --- rip44d | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/rip44d b/rip44d index 4cdc186..660b356 100755 --- a/rip44d +++ b/rip44d @@ -53,7 +53,6 @@ my $routebin = '/sbin/ip'; my $ifconfig = '/sbin/ifconfig'; my $verbose = 0; my $syslog = 0; -my $log; my $UDP_port=520; # Local gateway addresses (whose routes are skipped) my %my_addresses; @@ -70,7 +69,7 @@ my $route_ttl = 7*24*60*60; my %current_routes; -my $me = $0; +my $me = 'rip44d'; my $VERSION = '1.2'; openlog($me, 'cons,pid', 'user'); @@ -121,7 +120,7 @@ sub fill_local_ifs() while ($s =~ s/inet addr:(\d+\.\d+\.\d+\.\d+)//) { warn "found local address: $1\n" if ($verbose); - $log = do_syslog("found local address: $1"); + do_syslog("found local address: $1"); $my_addresses{$1} = 1; } } @@ -161,7 +160,7 @@ sub route_delete($) if ($?) { if ($verbose > 1 || $out !~ /No such process/) { warn "route del failed: '$cmd': $out\n"; - $log = do_syslog("route del failed: '$cmd': $out") if ($syslog); + do_syslog("route del failed: '$cmd': $out") if ($syslog); } } } @@ -171,7 +170,7 @@ sub route_delete($) sub expire_routes() { warn "expiring old routes\n" if ($verbose); - $log = do_syslog("expiring old routes") if ($syslog); + do_syslog("expiring old routes") if ($syslog); my $exp_t = time() - $route_ttl; my $now = time(); @@ -180,7 +179,7 @@ sub expire_routes() if ($current_routes{$rkey}->{'t'} < $exp_t) { # expire route warn "route $rkey has expired, deleting\n" if ($verbose); - $log = do_syslog("route $rkey has expired, deleting") if ($syslog); + do_syslog("route $rkey has expired, deleting") if ($syslog); route_delete($rkey); delete $current_routes{$rkey}; } elsif ($current_routes{$rkey}->{'t'} > $now) { @@ -204,13 +203,13 @@ sub consider_route($$$$) && $current_routes{$rkey}->{'rtag'} eq $rtag) { # ok, current route is fine warn "route $rkey is installed and current\n" if ($verbose > 1); - $log = do_syslog("route $rkey is installed and current") if ($syslog); + do_syslog("route $rkey is installed and current") if ($syslog); $current_routes{$rkey}->{'t'} = time(); return; } warn "route $rkey updated: via $nexthop rtag $rtag\n" if ($verbose > 1); - $log = do_syslog("route $rkey updated: via $nexthop rtag $rtag") if ($syslog); + do_syslog("route $rkey updated: via $nexthop rtag $rtag") if ($syslog); $current_routes{$rkey} = { 'nh' => $nexthop, @@ -225,7 +224,7 @@ sub consider_route($$$$) $out = `$cmd 2>&1\n`; if ($?) { warn "route add failed: '$cmd': $out\n"; - $log = do_syslog("route add failed: '$cmd': $out") if ($syslog); + do_syslog("route add failed: '$cmd': $out") if ($syslog); } } @@ -238,14 +237,14 @@ sub process_rip_auth_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); - $log = do_syslog("RIPv2 first message does not contain auth password: ignoring") if ($syslog); + do_syslog("RIPv2 first message does not contain auth password: ignoring") if ($syslog); 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); - $log = do_syslog("ignoring unsupported rip auth type $e_type") if ($syslog); + do_syslog("ignoring unsupported rip auth type $e_type") if ($syslog); return 0; } @@ -254,13 +253,13 @@ sub process_rip_auth_entry($) if (!defined $rip_passwd) { warn "RIPv2 packet contains password $e_passwd but we require none\n" if ($verbose); - $log = do_syslog("RIPv2 packet contains password $e_passwd but we require none") if ($syslog); + do_syslog("RIPv2 packet contains password $e_passwd but we require none") if ($syslog); return 0; } if ($e_passwd ne $rip_passwd) { warn "RIPv2 invalid password $e_passwd\n" if ($verbose); - $log = do_syslog("RIPv2 invalid password $e_passwd") if ($syslog); + do_syslog("RIPv2 invalid password $e_passwd") if ($syslog); return 0; } @@ -278,13 +277,13 @@ sub validate_route($$$$$) my $prefix_len = mask2prefix($e_netmask); if ($prefix_len < 0) { warn "invalid netmask: $e_netmask_s\n" if ($verbose); - $log = do_syslog("invalid netmask: $e_netmask_s") if ($syslog); + do_syslog("invalid netmask: $e_netmask_s") if ($syslog); 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"; - $log = do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, prefix too short") if ($syslog); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, prefix too short") if ($syslog); return (0, 'prefix length too short'); } @@ -292,28 +291,28 @@ sub validate_route($$$$$) 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); - $log = do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, subnet-netmask pair does not make sense") if ($syslog); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, subnet-netmask pair does not make sense") if ($syslog); 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); - $log = do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, non-amprnet address") if ($syslog); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, non-amprnet address") if ($syslog); 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); - $log = do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, nexthop is within amprnet") if ($syslog); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, nexthop is within amprnet") if ($syslog); 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); - $log = do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, local gw") if ($syslog); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, local gw") if ($syslog); return (0, 'local gw'); } @@ -462,7 +461,7 @@ system($ifconfig, $tunnel_if, 'multicast') == 0 or die "ifconfig $tunnel_if mult # Create the UDP multicast socket to receive RIP broadcasts warn "opening UDP socket $UDP_port...\n" if ($verbose); -$log = do_syslog("opening UDP socket $UDP_port...") if ($syslog); +do_syslog("opening UDP socket $UDP_port...") if ($syslog); my $socket = IO::Socket::Multicast->new( LocalPort => $UDP_port, ReuseAddr => 1, @@ -476,7 +475,7 @@ 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); -$log = do_syslog("entering main loop, waiting for RIPv2 datagrams") if ($syslog); +do_syslog("entering main loop, waiting for RIPv2 datagrams") if ($syslog); while (1) { my $msg; my $remote_address = recv($socket, $msg, 1500, 0); @@ -490,16 +489,16 @@ while (1) { if ($addr_s ne '44.0.0.1' || $peer_port ne 520) { warn "$me: ignored packet from $addr_s: $peer_port: " . length($msg) . "\n"; - $log = do_syslog("ignored packet from $addr_s: $peer_port: " . length($msg) ) if ($syslog); + do_syslog("ignored packet from $addr_s: $peer_port: " . length($msg) ) if ($syslog); next; } warn "received from $addr_s: $peer_port: " . length($msg) . " bytes\n" if ($verbose); - $log = do_syslog("received from $addr_s: $peer_port: " . length($msg) . " bytes") if ($syslog); + do_syslog("received from $addr_s: $peer_port: " . length($msg) . " bytes") if ($syslog); my $routes = process_msg($addr_s, $peer_port, $msg); warn "processed $routes route entries\n" if ($verbose && $routes >= 0); - $log = do_syslog("processed $routes route entries") if ($syslog); + do_syslog("processed $routes route entries") if ($syslog); # Consider expiring old routes. This is actually never run if we do not receive # any RIP broadcasts at all (the recv() is blocking) From 45d26c921c0fa680e7adc8cc4574222559f1174f Mon Sep 17 00:00:00 2001 From: pd1acf Date: Tue, 3 Jan 2012 22:02:08 +0100 Subject: [PATCH 3/6] rewritten warn into do_syslog --- rip44d | 106 +++++++++++++++++++++++---------------------------------- 1 file changed, 42 insertions(+), 64 deletions(-) diff --git a/rip44d b/rip44d index 660b356..626c03c 100755 --- a/rip44d +++ b/rip44d @@ -29,6 +29,7 @@ # # - support for better authentication, if one would be supported # - support for multiple RIP masters, to fix the single point of failure +# - support for sigh-up message, to remove the routing entries again without manual intervention # use strict; @@ -52,7 +53,6 @@ my $tunnel_if = 'tunl0'; my $routebin = '/sbin/ip'; my $ifconfig = '/sbin/ifconfig'; my $verbose = 0; -my $syslog = 0; my $UDP_port=520; # Local gateway addresses (whose routes are skipped) my %my_addresses; @@ -77,12 +77,13 @@ openlog($me, 'cons,pid', 'user'); # help and version texts $Getopt::Std::STANDARD_HELP_VERSION = 1; +# This subroutine takes care of placing messages on std output, and into syslog facility + sub do_syslog($) { my($logtxt) = @_; - - syslog("info", "%s", "$logtxt") if ($syslog); - + warn "$logtxt\n"; + syslog("info", "%s", "$logtxt"); } sub HELP_MESSAGE() @@ -90,7 +91,7 @@ sub HELP_MESSAGE() my($fh) = @_; print $fh "Usage:\n" - . " $me [-v] [-d] [-l] [-i ] [-a ] [-p ]\n" + . " $me [-v] [-d] [-i ] [-a ] [-p ]\n" . "Options:\n" . " -v increase verbosity slightly to print error messages on stderr\n" . " -d increase verbosity greatly (debug mode)\n" @@ -101,7 +102,6 @@ sub HELP_MESSAGE() . " (list contains system's local IP addresses by default)\n" . " -p \n" . " use RIPv2 password 'authentication', defaults to none\n" - . " -l enable syslog functionality\n" ; } @@ -119,8 +119,7 @@ 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); - do_syslog("found local address: $1"); + do_syslog("found local address: $1") if ( $verbose >= 1 ); $my_addresses{$1} = 1; } } @@ -142,6 +141,7 @@ sub mask2prefix($) return -1 if ($bits !~ /^(1*)(0*)$/); # The amount of 1's in the beginning is the prefix length. + do_syslog("subroutine mask2prefix " . length($1)) if ($verbose > 1); return length($1); } @@ -159,9 +159,8 @@ sub route_delete($) $out = `$cmd 2>&1`; if ($?) { if ($verbose > 1 || $out !~ /No such process/) { - warn "route del failed: '$cmd': $out\n"; - do_syslog("route del failed: '$cmd': $out") if ($syslog); - } + do_syslog("route del failed: '$cmd': $out"); + } } } @@ -169,8 +168,7 @@ sub route_delete($) sub expire_routes() { - warn "expiring old routes\n" if ($verbose); - do_syslog("expiring old routes") if ($syslog); + do_syslog("expiring old routes") if ($verbose); my $exp_t = time() - $route_ttl; my $now = time(); @@ -178,8 +176,7 @@ sub expire_routes() foreach my $rkey (keys %current_routes) { if ($current_routes{$rkey}->{'t'} < $exp_t) { # expire route - warn "route $rkey has expired, deleting\n" if ($verbose); - do_syslog("route $rkey has expired, deleting") if ($syslog); + do_syslog("route $rkey has expired, deleting") if ($verbose); route_delete($rkey); delete $current_routes{$rkey}; } elsif ($current_routes{$rkey}->{'t'} > $now) { @@ -202,14 +199,12 @@ sub consider_route($$$$) && $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); - do_syslog("route $rkey is installed and current") if ($syslog); + do_syslog("route $rkey is installed and current") if ($verbose > 1); $current_routes{$rkey}->{'t'} = time(); return; } - warn "route $rkey updated: via $nexthop rtag $rtag\n" if ($verbose > 1); - do_syslog("route $rkey updated: via $nexthop rtag $rtag") if ($syslog); + do_syslog("route $rkey updated: via $nexthop rtag $rtag") if ($verbose > 1); $current_routes{$rkey} = { 'nh' => $nexthop, @@ -223,8 +218,7 @@ sub consider_route($$$$) $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"; - do_syslog("route add failed: '$cmd': $out") if ($syslog); + do_syslog("route add failed: '$cmd': $out"); } } @@ -236,15 +230,13 @@ sub process_rip_auth_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); - do_syslog("RIPv2 first message does not contain auth password: ignoring") if ($syslog); + do_syslog("RIPv2 first message does not contain auth password: ignoring") 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); - do_syslog("ignoring unsupported rip auth type $e_type") if ($syslog); + do_syslog("ignoring unsupported rip auth type $e_type") if ($verbose); return 0; } @@ -252,14 +244,12 @@ sub process_rip_auth_entry($) $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); - do_syslog("RIPv2 packet contains password $e_passwd but we require none") if ($syslog); + do_syslog("RIPv2 packet contains password $e_passwd but we require none") if ($verbose); return 0; } if ($e_passwd ne $rip_passwd) { - warn "RIPv2 invalid password $e_passwd\n" if ($verbose); - do_syslog("RIPv2 invalid password $e_passwd") if ($syslog); + do_syslog("RIPv2 invalid password $e_passwd") if ($verbose); return 0; } @@ -276,43 +266,37 @@ sub validate_route($$$$$) # 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); - do_syslog("invalid netmask: $e_netmask_s") if ($syslog); + do_syslog("invalid netmask: $e_netmask_s") 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"; - do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, prefix too short") if ($syslog); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, prefix too short") if ($verbose); 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); - do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, subnet-netmask pair does not make sense") if ($syslog); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, subnet-netmask pair does not make sense") 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); - do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, non-amprnet address") if ($syslog); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, non-amprnet address") 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); - do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, nexthop is within amprnet") if ($syslog); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, nexthop is within amprnet") 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); - do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, local gw") if ($syslog); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, local gw") if ($verbose); return (0, 'local gw'); } @@ -334,7 +318,7 @@ sub process_rip_route_entry($) } if ($e_af != AF_INET) { - warn "$me: RIPv2 entry has unsupported AF $e_af\n"; + do_syslog("$me: RIPv2 entry has unsupported AF $e_af\n"); return 0; } @@ -351,11 +335,11 @@ sub process_rip_route_entry($) # 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); + do_syslog("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); + do_syslog("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); @@ -371,18 +355,18 @@ sub process_msg($$$) # validate packet's length if (length($msg) < RIP_HDR_LEN + RIP_ENTRY_LEN) { - warn "$me: ignored too short packet from $addr_s: " . length($msg) . "\n"; + do_syslog("$me: ignored too short packet from $addr_s: " . length($msg)); return -1; } if (length($msg) > RIP_HDR_LEN + RIP_ENTRY_LEN*25) { - warn "$me: ignored too long packet from $addr_s: " . length($msg) . "\n"; + do_syslog("$me: ignored too long packet from $addr_s: " . length($msg)); return -1; } # packet's length must be divisible by the length of an entry if ((length($msg) - RIP_HDR_LEN) % RIP_ENTRY_LEN != 0) { - warn "$me: ignored invalid length packet from $addr_s: " . length($msg) . "\n"; + do_syslog("$me: ignored invalid length packet from $addr_s: " . length($msg)); return -1; } @@ -392,15 +376,15 @@ sub process_msg($$$) 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"; + do_syslog("$me: ignored non-response RIP packet from $addr_s"); return -1; } if ($rip_version != 2) { - warn "$me: ignored RIP version $rip_version packet from $addr_s (only accept v2)\n"; + do_syslog("$me: ignored RIP version $rip_version packet from $addr_s (only accept v2)"); return -1; } if ($zero1 != 0 || $zero2 != 0) { - warn "$me: ignored RIP packet from $addr_s: zero bytes are not zero in header\n"; + do_syslog("$me: ignored RIP packet from $addr_s: zero bytes are not zero in header"); return -1; } @@ -428,9 +412,11 @@ sub process_msg($$$) ####### main ############################################# # +do_syslog("$me starting..."); + # command line parsing my %opts; -getopts('i:p:a:vdl', \%opts); +getopts('i:p:a:vd', \%opts); if (defined $opts{'i'}) { $tunnel_if = $opts{'i'}; @@ -449,9 +435,6 @@ if ($opts{'a'}) { $my_addresses{$a} = 1; } } -if ($opts{'l'}) { - $syslog = 1; -} fill_local_ifs(); @@ -460,8 +443,7 @@ fill_local_ifs(); system($ifconfig, $tunnel_if, 'multicast') == 0 or die "ifconfig $tunnel_if multicast failed: $?\n"; # Create the UDP multicast socket to receive RIP broadcasts -warn "opening UDP socket $UDP_port...\n" if ($verbose); -do_syslog("opening UDP socket $UDP_port...") if ($syslog); +do_syslog("opening UDP socket $UDP_port...") if ( $verbose >= 1 ); my $socket = IO::Socket::Multicast->new( LocalPort => $UDP_port, ReuseAddr => 1, @@ -474,8 +456,7 @@ 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); -do_syslog("entering main loop, waiting for RIPv2 datagrams") if ($syslog); +do_syslog("entering main loop, waiting for RIPv2 datagrams") if ( $verbose >= 0 ); while (1) { my $msg; my $remote_address = recv($socket, $msg, 1500, 0); @@ -488,17 +469,14 @@ while (1) { 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"; - do_syslog("ignored packet from $addr_s: $peer_port: " . length($msg) ) if ($syslog); + do_syslog("ignored packet from $addr_s: $peer_port: " . length($msg) ) if ( $verbose >= 1 ); next; } - warn "received from $addr_s: $peer_port: " . length($msg) . " bytes\n" if ($verbose); - do_syslog("received from $addr_s: $peer_port: " . length($msg) . " bytes") if ($syslog); + do_syslog("received from $addr_s: $peer_port: " . length($msg) . " bytes") if ($verbose); my $routes = process_msg($addr_s, $peer_port, $msg); - warn "processed $routes route entries\n" if ($verbose && $routes >= 0); - do_syslog("processed $routes route entries") if ($syslog); + do_syslog("processed $routes route entries") if ($verbose && $routes >= 0); # Consider expiring old routes. This is actually never run if we do not receive # any RIP broadcasts at all (the recv() is blocking) From 36a41f9f21f67a6c5d23ca9d07e0e62aec31e969 Mon Sep 17 00:00:00 2001 From: Ronald Jochems Date: Thu, 19 Jan 2012 20:23:26 +0000 Subject: [PATCH 4/6] little typo --- rip44d | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rip44d b/rip44d index 626c03c..3600152 100755 --- a/rip44d +++ b/rip44d @@ -29,7 +29,7 @@ # # - support for better authentication, if one would be supported # - support for multiple RIP masters, to fix the single point of failure -# - support for sigh-up message, to remove the routing entries again without manual intervention +# - support for sig-hup message, to remove the routing entries again without manual intervention # use strict; @@ -70,14 +70,14 @@ my $route_ttl = 7*24*60*60; my %current_routes; my $me = 'rip44d'; -my $VERSION = '1.2'; +my $VERSION = '1.3'; openlog($me, 'cons,pid', 'user'); # help and version texts $Getopt::Std::STANDARD_HELP_VERSION = 1; -# This subroutine takes care of placing messages on std output, and into syslog facility +# This subroutine takes care of placing messages on std output, and also into syslog facility sub do_syslog($) { From 9f987fded5645ca9446b54b98f266d778462e81f Mon Sep 17 00:00:00 2001 From: Ronald Jochems Date: Mon, 23 Jan 2012 09:35:31 +0000 Subject: [PATCH 5/6] fixed intends and verbose errors --- rip44d | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/rip44d b/rip44d index 3600152..3c30368 100755 --- a/rip44d +++ b/rip44d @@ -81,9 +81,9 @@ $Getopt::Std::STANDARD_HELP_VERSION = 1; sub do_syslog($) { - my($logtxt) = @_; - warn "$logtxt\n"; - syslog("info", "%s", "$logtxt"); + my($logtxt) = @_; + warn "$logtxt\n"; + syslog("info", "%s", "$logtxt"); } sub HELP_MESSAGE() @@ -119,7 +119,7 @@ sub fill_local_ifs() my $s = `$ifconfig -a`; while ($s =~ s/inet addr:(\d+\.\d+\.\d+\.\d+)//) { - do_syslog("found local address: $1") if ( $verbose >= 1 ); + do_syslog("found local address: $1") if ( $verbose >= 1 ); $my_addresses{$1} = 1; } } @@ -141,7 +141,7 @@ sub mask2prefix($) return -1 if ($bits !~ /^(1*)(0*)$/); # The amount of 1's in the beginning is the prefix length. - do_syslog("subroutine mask2prefix " . length($1)) if ($verbose > 1); + do_syslog("subroutine mask2prefix " . length($1)) if ($verbose > 1); return length($1); } @@ -159,7 +159,7 @@ sub route_delete($) $out = `$cmd 2>&1`; if ($?) { if ($verbose > 1 || $out !~ /No such process/) { - do_syslog("route del failed: '$cmd': $out"); + do_syslog("route del failed: '$cmd': $out"); } } } @@ -168,7 +168,7 @@ sub route_delete($) sub expire_routes() { - do_syslog("expiring old routes") if ($verbose); + do_syslog("expiring old routes") if ($verbose); my $exp_t = time() - $route_ttl; my $now = time(); @@ -176,7 +176,7 @@ sub expire_routes() foreach my $rkey (keys %current_routes) { if ($current_routes{$rkey}->{'t'} < $exp_t) { # expire route - do_syslog("route $rkey has expired, deleting") if ($verbose); + do_syslog("route $rkey has expired, deleting") if ($verbose); route_delete($rkey); delete $current_routes{$rkey}; } elsif ($current_routes{$rkey}->{'t'} > $now) { @@ -199,12 +199,12 @@ sub consider_route($$$$) && $current_routes{$rkey}->{'nh'} eq $nexthop && $current_routes{$rkey}->{'rtag'} eq $rtag) { # ok, current route is fine - do_syslog("route $rkey is installed and current") if ($verbose > 1); + do_syslog("route $rkey is installed and current") if ($verbose > 1); $current_routes{$rkey}->{'t'} = time(); return; } - do_syslog("route $rkey updated: via $nexthop rtag $rtag") if ($verbose > 1); + do_syslog("route $rkey updated: via $nexthop rtag $rtag") if ($verbose > 1); $current_routes{$rkey} = { 'nh' => $nexthop, @@ -218,7 +218,7 @@ sub consider_route($$$$) $cmd = "LANG=C $routebin route add $rkey via $nexthop dev $tunnel_if window $tcp_window onlink"; $out = `$cmd 2>&1\n`; if ($?) { - do_syslog("route add failed: '$cmd': $out"); + do_syslog("route add failed: '$cmd': $out"); } } @@ -230,13 +230,13 @@ sub process_rip_auth_entry($) my $e_af = unpack('n', substr($entry, 0, 2)); if ($e_af != 0xFFFF) { - do_syslog("RIPv2 first message does not contain auth password: ignoring") if ($verbose); + do_syslog("RIPv2 first message does not contain auth password: ignoring") if ($verbose); return 0; } my $e_type = unpack('n', substr($entry, 2, 2)); if ($e_type != RIP_AUTH_PASSWD) { - do_syslog("ignoring unsupported rip auth type $e_type") if ($verbose); + do_syslog("ignoring unsupported rip auth type $e_type") if ($verbose); return 0; } @@ -244,12 +244,12 @@ sub process_rip_auth_entry($) $e_passwd =~ s/\0*$//; # it's null-padded in the end if (!defined $rip_passwd) { - do_syslog("RIPv2 packet contains password $e_passwd but we require none") if ($verbose); + do_syslog("RIPv2 packet contains password $e_passwd but we require none") if ($verbose); return 0; } if ($e_passwd ne $rip_passwd) { - do_syslog("RIPv2 invalid password $e_passwd") if ($verbose); + do_syslog("RIPv2 invalid password $e_passwd") if ($verbose); return 0; } @@ -266,37 +266,37 @@ sub validate_route($$$$$) # netmask is correct and not too wide my $prefix_len = mask2prefix($e_netmask); if ($prefix_len < 0) { - do_syslog("invalid netmask: $e_netmask_s") if ($verbose); + do_syslog("invalid netmask: $e_netmask_s") if ($verbose); return (0, 'invalid netmask'); } if ($prefix_len < $minimum_prefix_len) { - do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, prefix too short") if ($verbose); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, prefix too short"); 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"; - do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, subnet-netmask pair does not make sense") if ($verbose); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, subnet-netmask pair does not make sense") if ($verbose); return (0, 'invalid subnet-netmask pair'); } # network is in 44/8 if ($e_net_s !~ /$net_44_regexp/) { - do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, non-amprnet address") if ($verbose); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, non-amprnet address") if ($verbose); return (0, 'net not in 44/8'); } # nexthop address is not in 44/8 if ($e_nexthop_s =~ /$net_44_regexp/) { - do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, nexthop is within amprnet") if ($verbose); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, nexthop is within amprnet") if ($verbose); return (0, 'nexthop is in 44/8'); } # nexthop address does not point to self if (defined $my_addresses{$e_nexthop_s}) { - do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, local gw") if ($verbose); + do_syslog("$e_net_s/$e_netmask_s => $e_nexthop_s blocked, local gw") if ($verbose); return (0, 'local gw'); } @@ -456,7 +456,7 @@ 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 -do_syslog("entering main loop, waiting for RIPv2 datagrams") if ( $verbose >= 0 ); +do_syslog("entering main loop, waiting for RIPv2 datagrams") if ($verbose); while (1) { my $msg; my $remote_address = recv($socket, $msg, 1500, 0); @@ -469,14 +469,14 @@ while (1) { my $addr_s = inet_ntoa($peer_addr); if ($addr_s ne '44.0.0.1' || $peer_port ne 520) { - do_syslog("ignored packet from $addr_s: $peer_port: " . length($msg) ) if ( $verbose >= 1 ); + do_syslog("ignored packet from $addr_s: $peer_port: " . length($msg) ); next; } - do_syslog("received from $addr_s: $peer_port: " . length($msg) . " bytes") if ($verbose); + do_syslog("received from $addr_s: $peer_port: " . length($msg) . " bytes") if ($verbose); my $routes = process_msg($addr_s, $peer_port, $msg); - do_syslog("processed $routes route entries") if ($verbose && $routes >= 0); + do_syslog("processed $routes route entries") if ($verbose && $routes >= 0); # Consider expiring old routes. This is actually never run if we do not receive # any RIP broadcasts at all (the recv() is blocking) From df4498282622243f5d880d8c196abbebe2168e42 Mon Sep 17 00:00:00 2001 From: Ronald Jochems Date: Mon, 23 Jan 2012 09:47:01 +0000 Subject: [PATCH 6/6] fixed two errors and version number --- rip44d | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rip44d b/rip44d index 3c30368..3cc7abe 100755 --- a/rip44d +++ b/rip44d @@ -70,7 +70,7 @@ my $route_ttl = 7*24*60*60; my %current_routes; my $me = 'rip44d'; -my $VERSION = '1.3'; +my $VERSION = '1.4'; openlog($me, 'cons,pid', 'user'); @@ -119,7 +119,7 @@ sub fill_local_ifs() my $s = `$ifconfig -a`; while ($s =~ s/inet addr:(\d+\.\d+\.\d+\.\d+)//) { - do_syslog("found local address: $1") if ( $verbose >= 1 ); + do_syslog("found local address: $1") if ($verbose); $my_addresses{$1} = 1; } } @@ -443,7 +443,7 @@ fill_local_ifs(); system($ifconfig, $tunnel_if, 'multicast') == 0 or die "ifconfig $tunnel_if multicast failed: $?\n"; # Create the UDP multicast socket to receive RIP broadcasts -do_syslog("opening UDP socket $UDP_port...") if ( $verbose >= 1 ); +do_syslog("opening UDP socket $UDP_port...") if ($verbose); my $socket = IO::Socket::Multicast->new( LocalPort => $UDP_port, ReuseAddr => 1,