#!/usr/bin/perl -w # # peek.pl - walk up the IP stack looking for problems. # # 6/7/06 bet use strict; # Definitions my $localnet="127.0.0.1"; # Should get this from "hosts" file. my $router = "192.168.0.1"; # Your DSL gateway here. # # Files we need. my $resolv = "/etc/resolv.conf"; # To get the nameservers from. my $hosts = "/etc/hosts"; # To get "localhost" from. # # Commands my $short_ping = "ping -t1 -c1 -n "; my $dig_cmd = "dig"; my $dig_options = "+short +tries=1 +time=2"; my $config_cmd = "ifconfig"; my $status_cmd = "netstat -rn"; # # Hold found routes. my @net; my $token; my $host; # # Subroutines # sub check_interface { # ( -d|-u , "message" ) my $option = shift @_; my $message = shift @_; my $ifs=` $config_cmd $option | perl -lne '\$\\=" "; print \$1 if m/^([a-z]+[0-9])[:]/' `; my @ifs=split / /, $ifs; print scalar @ifs, $message; print "\t$_\n" foreach @ifs; return @ifs } sub ping_host { my $host = shift @_; `$short_ping $host`; print '', ($?==0)?'working.':'***FAILED***', "\n"; } # Abnomal exit point. Used for network errors. Use "die" for program errors. sub bail { # Tell the user we can't continue. print shift @_; print "\nCan't continue tests.\n"; exit 1; } # # main - program starts here # `uname` =~ /FreeBSD/ or die "Program is for FreeBSD"; # Find any interfaces marked "down" check_interface( "-d", " interfaces down:\n" ); # Find any interfaces marked "up" my @ifs = check_interface( "-u", " interfaces up:\n" ); # Check localhost direct printf "%-26s%-15s", "Checking localnet:", $localnet; ping_host ( $localnet ); # Check local host via lookup printf "%-41s", 'Checking "localhost" '; ping_host( "localhost" ); # Find address of remaining interfaces. # Check it my $count=0; foreach my $ifs (@ifs) { do { @net = grep m/inet /, split /\n/, `$config_cmd $ifs`; if ( scalar @net != 1 ) { print "$ifs: No inet record found.\n"; next }; if ($net[0] =~ m/([0-9]+[.][0-9]+[.][0-9]+[.][0-9]+)/) { printf "%-26s%-15s", "Checking interface $ifs:", $1; `$short_ping $1`; if ($?==0) { $count++; print "working.\n"; } else { print "***FAILED***\n"; } } } unless ( $ifs eq "lo0" ); } if($count == 0) { bail "No external interfaces!!!" }; print "$count external interface", ($count==1)?'':'s', " found.\n"; # Find default route and check @net = grep m/default/, split '\n', `$status_cmd`; if ( scalar @net == 0 ) { bail "No default route!" }; if ( scalar @net >= 2 ) { bail "Multiple default routes!" }; # Could be on different subnets?? ($token, $host) = split ' ', $net[0]; #awk compatible pattern. printf "%-26s%-15s", "Checking Default route:", $host; ping_host ( $host ); # Ping router printf "%-26s%-15s", "Checking default router:", $router; ping_host ( $router ); # Could we maybe use TTL to resolve next hop? So we don't hardcode it. # Otherwice we have to get it from the router. # "ping -m3 $DNS" works, but would break if ??. # lookup DNS in /etc/resolv.conf # Check DNS # -e $resolv or die "Resolv.conf file ***missing ***"; open FH, $resolv or die "Open $resolv failed: $!"; while () { next if ( length $_ < 10 ); ($token, $host) = split ' '; #awk compatible pattern. if ( $token eq "nameserver" ) { printf "%-26s", "Checking DNS host:"; `$dig_cmd \@$host -x $host $dig_options` =~ m/([\w]|[.])+/; if ($?==0 ) { print "$& working.\n"; } else { print "$host ***FAILED***!\n"; } } } close FH; # Normal program termination. exit 0; __END__