#!/usr/bin/perl
# Description:  network troubleshooter.
# cnseek@gmail.com

use Term::ReadLine;
sub show_menu {
   print "+----------------------------------+\n";
   print "1. The total number of connection.\n";
   print "2. Count Top 20 Source IP.\n";
   print "3. Count Top 20 TIME_WAIT IP.\n";
   print "4. Run Ping.\n";
   print "5. Run Traceroute.\n";
   print "6. Show Route.\n";
   print "7. Show ARP.\n";
   print "8. Show IP.\n";
   print "9. Quit/q.\n";
   print "+----------------------------------+\n";
   }

#get_info_from_terminal
sub _get_info_from_terminal {
    my($term) = shift(@_);
    my($prompt) = shift(@_) . ': ';
    my($answer) = $term->readline($prompt);
    $term->addhistory($_) if /\S/;
    return($answer);
}

##############################################################################
# strip_nasties: Strip any bad characters out of a string
#
#    Args: text
# Returns: clean_text
##############################################################################
sub strip_nasties {
	my($txt) = shift(@_);
	my($OK_CHARS) ='-a-zA-Z0-9_.@';
	$txt =~ s/[^$OK_CHARS]/_/go;
	return($txt);
}

#main
sub main_sub {
	my($term) = shift(@_);
	print "\nNetwork Troubleshooter\n";
	while(1) {
		show_menu();
		my $ans = _get_info_from_terminal($term,"Selection");
		chomp($ans);
		if($ans =~ /^1$/) {
                        count_ip($term);
		}
		elsif($ans =~ /^2/) {
                        count_sip($term);
		}
                elsif($ans =~ /^3/) {
                        count_twip();
                } 
                elsif($ans =~ /^4/) {
                        run_ping($term);
                } 
                elsif($ans =~ /^5/) {
                        run_traceroute($term);
                } 
                elsif($ans =~ /^6/) {
                        show_route($term);
                }
                elsif($ans =~ /^7/) {
                        show_arp($term);
                }
                elsif($ans =~ /^8/) {
                        show_ip($term);
                }

		elsif($ans =~ /^q/i) {
			print "Quitting\n";
			exit(0);
		}
		else {
			print "\nERROR: Selection not recognized. Please try again.\n";
		}
	}
}

#exec main
my $term = new Term::ReadLine "Network Troubleshooter";
main_sub($term);
exit(0);

#The total number of connection.
sub count_ip {
     my($term) = shift(@_);
     system("netstat -n|awk '/^tcp/{print \$6}'|sort|uniq -c|sort -rn");
}

#Count Top 20 Source IP
sub count_sip {
    my($term) = shift(@_);
    system("netstat -anlp|grep 80|grep tcp|awk '{print \$5}'|awk -F: '{print \$1}'|sort|uniq -c|sort -nr|head -n20");    
}
#Count Top 20 TIME_WAIT IP
sub count_twip {
    my($term) = shift(@_);
    system("netstat -n|grep TIME_WAIT|awk '{print \$5}'|sort|uniq -c|sort -rn|head -n20");
}
 
#run ping
sub run_ping {
	my($term) = shift(@_);
	my($host) = _get_info_from_terminal($term,"Hostname/IP");
	my($tries) = _get_info_from_terminal($term,"Number of times to ping (10)");
	$tries = 10 unless($tries =~ /^\d+$/);
	$host = strip_nasties($host);
	print "ping $host $tries times\n";
	print "\n=== ENTER CTRL+C to stop the ping before it completes ===\n\n";
	system("/bin/ping -c $tries $host");
	print "\n";
	my($ok) = _get_info_from_terminal($term,"Press Enter to return to Menu");
}

#run traceroute
sub run_traceroute {
	my($term) = shift(@_);
	my($host) = _get_info_from_terminal($term,"Hostname/IP");
	$host = strip_nasties($host);
	print "\n=== ENTER CTRL+C to stop the traceroute before it completes ===\n\n";
	system("/bin/traceroute $host");
	print "\n";
	my($ok) = _get_info_from_terminal($term,"Press Enter to return to Menu");
}

# show_route
sub show_route {
	my($term) = shift(@_);
	my($cmd) = '/bin/netstat';
	my($arg) = '-rn';
	if(-x $cmd) {
		print "\n";
		system("$cmd $arg");
		print "\n";
	}
	else {
		print "ERROR: $cmd is missing!\n";
	}
	my($ok) = _get_info_from_terminal($term,"Press Enter to return to Menu");
}

# show_arp
sub show_arp {
	my($term) = shift(@_);
	my($cmd) = '/sbin/arp';
	my($arg) = '-an';
	if(-x $cmd) {
		print "\n";
		system("$cmd $arg");
		print "\n";
	}
	else {
		print "ERROR: $cmd is missing!\n";
	}
	my($ok) = _get_info_from_terminal($term,"Press Enter to return to Menu");
}
# show_ip
sub show_ip {
	my($term) = shift(@_);
	my($cmd) = '/sbin/ifconfig';
	my($arg) = 'eth0';
	if(-x $cmd) {
		print "\n";
		system("$cmd $arg");
		print "\n";
	}
	else {
		print "ERROR: $cmd is missing!\n";
	}
	my($ok) = _get_info_from_terminal($term,"Press Enter to return to Menu");
}


