Skip to content

Commit

Permalink
rewritten warn into do_syslog
Browse files Browse the repository at this point in the history
  • Loading branch information
acfnews committed Jan 3, 2012
1 parent 356642d commit 45d26c9
Showing 1 changed file with 42 additions and 64 deletions.
106 changes: 42 additions & 64 deletions rip44d
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -77,20 +77,21 @@ 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()
{
my($fh) = @_;

print $fh "Usage:\n"
. " $me [-v] [-d] [-l] [-i <tunnelif>] [-a <localaddrs>] [-p <password>]\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"
Expand All @@ -101,7 +102,6 @@ sub HELP_MESSAGE()
. " (list contains system's local IP addresses by default)\n"
. " -p <password>\n"
. " use RIPv2 password 'authentication', defaults to none\n"
. " -l enable syslog functionality\n"
;
}

Expand All @@ -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;
}
}
Expand All @@ -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);
}

Expand All @@ -159,27 +159,24 @@ 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");
}
}
}

# expire old routes

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();

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) {
Expand All @@ -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,
Expand All @@ -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");
}
}

Expand All @@ -236,30 +230,26 @@ 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;
}

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);
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;
}

Expand All @@ -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');
}

Expand All @@ -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;
}

Expand All @@ -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);
Expand All @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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'};
Expand All @@ -449,9 +435,6 @@ if ($opts{'a'}) {
$my_addresses{$a} = 1;
}
}
if ($opts{'l'}) {
$syslog = 1;
}

fill_local_ifs();

Expand All @@ -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,
Expand All @@ -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);
Expand All @@ -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)
Expand Down

0 comments on commit 45d26c9

Please sign in to comment.