#!/usr/bin/perl # # Nnetstat v0.1.1 Alpha # # Author: Alexander Neptun (aneptun@yahoo.com) # # License: GPL # use Gtk; #use strict; use Socket; init Gtk; print "Nnetstat v1.1Alpha by Alexander Neptun (aneptun\@yahoo.com)\n"; my (@ctitles,@ctitles_unix,@ctitles_route,$notebooklabel); my $ifdnscheck=0; my $sockdet=0; my $localip=1; my $entryget; my ($ipaddr,$ip_address,$hostname,$tkselect); my ($tcpl,@result,@tcp_localaddr_hex,$localaddr,$ip,$ip1,$ip2,$ip3,$ip4,$hostn); my ($procfiles,$ps_dir,$proc_fd,$proc_tmp,$lfile,$ps_name,$ps_id,$ps_status,$ps_uid,$ps_user,$p_inode); @ctitles = ("Nr","Local","Port","Remote","Port","rx_q","tx_q","Status","User","Inode","PID","Program"); @ctitles_unix = ("Nr","Ref","Protocol","Flags","Type","St","Inode","Path","User","PID","Program"); @ctitles_route = ("Nr","Interface","Destination","Gateway","Mask","MTU","Status"); my $window=new Gtk::Window("toplevel"); $window->signal_connect("delete_event",sub {exit(0)}); $window->set_title( "Nnetstat v0.1.1 Alpha" ); $window->set_default_size( 700, 500 ); my @menu_items = ( { path => '/_File', type => '' }, { path => '/File/Quit', accelerator => 'Q', callback => sub { Gtk->exit( 0 ); } }, { path => '/_Options', type => '' }, { path => '/_Options/Resolve DNS', type => '', accelerator => 'd', callback => \&dns }, { path => '/_Options/View localhost ip', type => '', accelerator => 'l', callback => \&locip }, { path => '/_Options/Socket details', type => '', accelerator => 's', callback => \&sockdet }, { path => '/_Options/Send TERM to PID', accelerator => 't', callback => \&sendterm }, { path => '/_Options/Send KILL to PID', accelerator => 'k', callback => \&sendkill }, { path => '/_Help', type => '' }, { path => '/_Help/About', callback => \&about } ); my $main_vbox = new Gtk::VBox( 0, 1 ); $main_vbox->border_width( 1 ); $window->add( $main_vbox ); $main_vbox->show(); my $menubar = get_main_menu( $window ); $main_vbox->pack_start( $menubar, 0, 1, 0 ); $menubar->show(); my $mainbox=new Gtk::VBox(0,1); $main_vbox->pack_start( $mainbox, 1, 1, 0 ); my $statusbar = new Gtk::Statusbar(); $main_vbox->pack_start( $statusbar, 0, 0, 0 ); my $notebook = new Gtk::Notebook(); $mainbox->pack_start( $notebook, 1, 1, 0 ); # # Notebook frames # my $tcpframe=new Gtk::Frame("tcp"); $notebooklabel = new Gtk::Label("tcp"); $notebook->append_page( $tcpframe, $notebooklabel ); my $udpframe=new Gtk::Frame("udp"); $notebooklabel = new Gtk::Label("udp"); $notebook->append_page( $udpframe, $notebooklabel ); my $rawframe=new Gtk::Frame("raw"); $notebooklabel = new Gtk::Label("raw"); $notebook->append_page( $rawframe, $notebooklabel ); my $unixframe=new Gtk::Frame("unix"); $notebooklabel = new Gtk::Label("unix"); $notebook->append_page( $unixframe, $notebooklabel ); my $routeframe=new Gtk::Frame("route"); $notebooklabel = new Gtk::Label("route"); $notebook->append_page( $routeframe, $notebooklabel ); # # Scrolled window for tcp # my $scrolled_window_tcp = new Gtk::ScrolledWindow( "", "" ); $scrolled_window_tcp->border_width( 2 ); $scrolled_window_tcp->set_policy( "automatic", "always" ); $tcpframe->add( $scrolled_window_tcp); $scrolled_window_tcp->show(); # # Scrolled window for udp # my $scrolled_window_udp = new Gtk::ScrolledWindow( "", "" ); $scrolled_window_udp->border_width( 2 ); $scrolled_window_udp->set_policy( "automatic", "always" ); $udpframe->add( $scrolled_window_udp); $scrolled_window_udp->show(); # # Scrolled window for raw # my $scrolled_window_raw = new Gtk::ScrolledWindow( "", "" ); $scrolled_window_raw->border_width( 2 ); $scrolled_window_raw->set_policy( "automatic", "always" ); $rawframe->add( $scrolled_window_raw); $scrolled_window_raw->show(); # # Scrolled window for unix # my $scrolled_window_unix = new Gtk::ScrolledWindow( "", "" ); $scrolled_window_unix->border_width( 2 ); $scrolled_window_unix->set_policy( "automatic", "always" ); $unixframe->add( $scrolled_window_unix); $scrolled_window_unix->show(); # # Scrolled window for route # my $scrolled_window_route = new Gtk::ScrolledWindow( "", "" ); $scrolled_window_route->border_width( 2 ); $scrolled_window_route->set_policy( "automatic", "always" ); $routeframe->add( $scrolled_window_route); $scrolled_window_route->show(); # # clist # # # tcp clist # my $tcp_clist = new_with_titles Gtk::CList( @ctitles ); $tcp_clist->signal_connect( 'select_row', \&tcpselect); $tcp_clist->set_column_width( 0, 20 ); $tcp_clist->set_column_width( 1, 100 ); $tcp_clist->set_column_width( 2, 50 ); $tcp_clist->set_column_width( 3, 100 ); $tcp_clist->set_column_width( 4, 50 ); $tcp_clist->set_column_width( 5, 40 ); $tcp_clist->set_column_width( 6, 40 ); $tcp_clist->set_column_width( 7, 85 ); $tcp_clist->set_column_width( 8, 50 ); $tcp_clist->set_column_width( 9, 50 ); $tcp_clist->set_column_width( 10, 50 ); $tcp_clist->set_column_width( 11, 100 ); # # udp clist # my $udp_clist = new_with_titles Gtk::CList( @ctitles ); $udp_clist->signal_connect( 'select_row', \&udpselect); $udp_clist->set_column_width( 0, 20 ); $udp_clist->set_column_width( 1, 100 ); $udp_clist->set_column_width( 2, 50 ); $udp_clist->set_column_width( 3, 100 ); $udp_clist->set_column_width( 4, 50 ); $udp_clist->set_column_width( 5, 40 ); $udp_clist->set_column_width( 6, 40 ); $udp_clist->set_column_width( 7, 85 ); $udp_clist->set_column_width( 8, 50 ); $udp_clist->set_column_width( 9, 50 ); $udp_clist->set_column_width( 10, 50 ); $udp_clist->set_column_width( 11, 100 ); # # raw clist # my $raw_clist = new_with_titles Gtk::CList( @ctitles ); $raw_clist->signal_connect( 'select_row', \&rawselect); $raw_clist->set_column_width( 0, 20 ); $raw_clist->set_column_width( 1, 100 ); $raw_clist->set_column_width( 2, 50 ); $raw_clist->set_column_width( 3, 100 ); $raw_clist->set_column_width( 4, 50 ); $raw_clist->set_column_width( 5, 30 ); $raw_clist->set_column_width( 6, 30 ); $raw_clist->set_column_width( 7, 85 ); $raw_clist->set_column_width( 8, 50 ); $raw_clist->set_column_width( 9, 50 ); $raw_clist->set_column_width( 10, 50 ); $raw_clist->set_column_width( 11, 100 ); # # unix clist # my $unix_clist = new_with_titles Gtk::CList( @ctitles_unix ); $unix_clist->signal_connect( 'select_row', \&unixselect); $unix_clist->set_column_width( 0, 20 ); $unix_clist->set_column_width( 1, 30 ); $unix_clist->set_column_width( 2, 46 ); $unix_clist->set_column_width( 3, 60 ); $unix_clist->set_column_width( 4, 40 ); $unix_clist->set_column_width( 5, 20 ); $unix_clist->set_column_width( 6, 50 ); $unix_clist->set_column_width( 7, 160 ); $unix_clist->set_column_width( 8, 50 ); $unix_clist->set_column_width( 9, 50 ); $unix_clist->set_column_width( 10, 160 ); # # route clist # my $route_clist = new_with_titles Gtk::CList( @ctitles_route ); $route_clist->signal_connect( 'select_row', \&routeselect); $route_clist->set_column_width( 0, 20 ); $route_clist->set_column_width( 1, 55 ); $route_clist->set_column_width( 2, 100 ); $route_clist->set_column_width( 3, 100 ); $route_clist->set_column_width( 4, 100 ); $route_clist->set_column_width( 5, 40 ); $route_clist->set_column_width( 6, 50 ); $scrolled_window_tcp->add($tcp_clist); $scrolled_window_udp->add($udp_clist); $scrolled_window_raw->add($raw_clist); $scrolled_window_unix->add($unix_clist); $scrolled_window_route->add($route_clist); my $button=new Gtk::Button("Refresh"); $button->signal_connect("clicked",\&refresh); $mainbox->pack_start($button,0,0,0); $window->show_all(); &tcpopen; &udpopen; &udpopen; &unixopen; &routeopen; main Gtk; Gtk2->main(); #----------------------------------- END MAIN --------------------------------------------------- sub tcpopen { open(FD,"/proc/net/tcp") or die "Can`t open /proc/net/tcp : $!\n"; my (@localaddr,@remoteaddr,@tcpl,@cvar,$status,@proc_result,$rx,$tx,$tcpuser); my $nr=0; $tcp_clist->clear(); while () { @tcpl=split; if ($tcpl[0] =~ /\d/) { if ($tcpl[3] eq "01") {$status="ESTABLISHED"} elsif ($tcpl[3] eq "02") {$status="SYN_SENT"} elsif ($tcpl[3] eq "03") {$status="SYN_RECV"} elsif ($tcpl[3] eq "04") {$status="FIN_WAIT1"} elsif ($tcpl[3] eq "05") {$status="FIN_WAIT2"} elsif ($tcpl[3] eq "06") {$status="TIME_WAIT"} elsif ($tcpl[3] eq "07") {$status="CLOSE"} elsif ($tcpl[3] eq "08") {$status="CLOSE_WAIT"} elsif ($tcpl[3] eq "09") {$status="LAST_ACK"} elsif ($tcpl[3] eq "0A") {$status="LISTEN"} elsif ($tcpl[3] eq "0B") {$status="CLOSING"} elsif ($tcpl[3] eq "0C") {$status="UNKNOWN"} else { $status=$tcpl[3];} @localaddr=&ipextr($tcpl[1]); if (!($localaddr[0] =~ /^0/)) { $nr++; @remoteaddr=&ipextr($tcpl[2]); ($tx,$rx) = ($tcpl[4]=~/(.*):(.*)/); $tx = hex($tx); $rx = hex($rx); $tcpuser=getpwuid($tcpl[7]); if ($tcpl[9]) { @proc_result=&proc_scan($tcpl[9]); @cvar=($nr,"$localaddr[0]","$localaddr[1]","$remoteaddr[0]","$remoteaddr[1]",$rx,$tx,$status,$tcpuser,$tcpl[9],$proc_result[1],$proc_result[0]); } else { @cvar=($nr,"$localaddr[0]","$localaddr[1]","$remoteaddr[0]","$remoteaddr[1]",$rx,$tx,$status,$tcpuser,"","",""); } $tcp_clist->append(@cvar); } # my @tcp_localaddr_hex=split(/:/,$tcpl[1]); # my @tcp_remoteaddr_hex=split(/:/,$tcpl[1]); } } } sub udpopen { open(FD,"/proc/net/udp") or die "Can`t open /proc/net/udp : $!\n"; my (@localaddr,@remoteaddr,@udpl,@cvar,$status,@proc_result,$rx,$tx,$udpuser); my $nr=0; $udp_clist->clear(); while () { @udpl=split; if ($udpl[0] =~ /\d/) { $status=$udpl[3]; @localaddr=&ipextr($udpl[1]); if (!($localaddr[0] =~ /^0/)) { $nr++; @remoteaddr=&ipextr($udpl[2]); ($tx,$rx) = ($udpl[4]=~/(.*):(.*)/); $tx = hex($tx); $rx = hex($rx); $udpuser=getpwuid($udpl[7]); if ($udpl[9]) { @proc_result=&proc_scan($udpl[9]); @cvar=($nr,"$localaddr[0]","$localaddr[1]","$remoteaddr[0]","$remoteaddr[1]",$rx,$tx,$status,$udpuser,$udpl[9],$proc_result[1],$proc_result[0]); } else { @cvar=($nr,"$localaddr[0]","$localaddr[1]","$remoteaddr[0]","$remoteaddr[1]",$rx,$tx,$status,$udpuser,"","",""); } $udp_clist->append(@cvar); } } } } sub rawopen { open(FD,"/proc/net/raw") or die "Can`t open /proc/net/raw : $!\n"; my (@localaddr,@remoteaddr,@rawl,@cvar,$status,@proc_result,$rx,$tx,$rawuser); my $nr=0; $raw_clist->clear(); while () { @rawl=split; if ($rawl[0] =~ /\d/) { $status=$rawl[3]; @localaddr=&ipextr($rawl[1]); if (!($localaddr[0] =~ /^0/)) { $nr++; @remoteaddr=&ipextr($rawl[2]); ($tx,$rx) = ($rawl[4]=~/(.*):(.*)/); $tx = hex($tx); $rx = hex($rx); $rawuser=getpwuid($rawl[7]); if ($rawl[9]) { @proc_result=&proc_scan($rawl[9]); @cvar=($nr,"$localaddr[0]","$localaddr[1]","$remoteaddr[0]","$remoteaddr[1]",$rx,$tx,$status,$rawuser,$rawl[9],$proc_result[1],$proc_result[0]); } else { @cvar=($nr,"$localaddr[0]","$localaddr[1]","$remoteaddr[0]","$remoteaddr[1]",$rx,$tx,$status,$rawuser,"","",""); } $raw_clist->append(@cvar); } } } } sub unixopen { open(FD,"/proc/net/unix") or die "Can`t open /proc/net/unix : $!\n"; my ($nr,@unixl,@cvar,@proc_result,$refcount,$protocol,$flags,$type1,$ustatus,$type); $unix_clist->clear(); while () { @unixl=split; if (!($unixl[0] =~ /^Num/)) { $nr++; if (!($unixl[7])) {$unixl[7]="";} $refcount=hex($unixl[1]); $protocol=hex($unixl[2]); $flags=$unixl[3]; $type1=hex($unixl[4]); if ($type1 eq "1") {$type="STREAM"} elsif ($type1 eq "2") {$type="DGRAM"} elsif ($type1 eq "3") {$type="RAW"} elsif ($type1 eq "4") {$type="SEQPACKET"} elsif ($type1 eq "5") {$type="RDM"} elsif ($type1 eq "10") {$type="PACKET"} else { $type=$unixl[3];} if ($protocol eq "0") {$ustatus="unix"} elsif ($protocol eq "1") {$ustatus=""} else {$ustatus=$protocol} if ($sockdet) { @proc_result=&proc_scan($unixl[6]); @cvar=($nr,$refcount,$ustatus,$flags,$type,$unixl[5],$unixl[6],$unixl[7],$proc_result[3],$proc_result[1],$proc_result[0]); } else { @cvar=($nr,$refcount,$ustatus,$flags,$type,$unixl[5],$unixl[6],$unixl[7],"","",""); } $unix_clist->append(@cvar); } } close(FD); } sub routeopen { open(FD,"/proc/net/route") or die "Can`t open /proc/net/route : $!\n"; my (@routel,@cvar,@destination,@gateway,@mask,$status); my $nr=0; my $counter=0; $route_clist->clear(); while () { @routel=split; if (!($routel[0] =~ /Iface/)) { $nr++; if ($routel[3] =~ /01/) {$status="up"} elsif ($routel[3] =~ /02/) {$status="host"} elsif ($routel[3] =~ /03/) {$status="use gateway"} elsif ($routel[3] =~ /04/) {$status="reinstate"} elsif ($routel[3] =~ /05/) {$status="dynamically"} elsif ($routel[3] =~ /06/) {$status="modified"} elsif ($routel[3] =~ /07/) {$status="reject"} else { $status=$routel[3];} @destination=&ipextr($routel[1]); @gateway=&ipextr($routel[2]); @mask=&ipextr($routel[7]); @cvar=($nr,$routel[0],$destination[0],$gateway[0],$mask[0],$routel[8],$status); $route_clist->append(@cvar); } } } sub ipextr { $tcpl=shift; @tcp_localaddr_hex=split(/:/,$tcpl); $localaddr=$tcp_localaddr_hex[0]; $ip1=hex(substr($localaddr,6,2)); $ip2=hex(substr($localaddr,4,2)); $ip3=hex(substr($localaddr,2,2)); $ip4=hex(substr($localaddr,0,2)); $ip=$ip1.".".$ip2.".".$ip3.".".$ip4; if ($ip =~ /0\.0\.0\.0/) { $hostn="\*"; } elsif ($ip =~ /127\.0\.0\.1/ && $localip) { $hostn="localhost"; } elsif ($ifdnscheck) { $hostn=&dnscheck($ip); } else { $hostn=$ip; } if ($tcpl =~ /:/) { my $localport=$tcp_localaddr_hex[1]; @result=("$hostn",hex($localport)); } else { @result=("$hostn"); } return @result; } sub refresh { &tcpopen; &udpopen; &rawopen; &unixopen; &routeopen; } sub get_main_menu { my ( $window ) = @_; my $menubar; my $item_factory; my $accel_group; $accel_group = new Gtk::AccelGroup(); $item_factory = new Gtk::ItemFactory( 'Gtk::MenuBar', '
', $accel_group ); $item_factory->create_items( @menu_items ); $window->add_accel_group( $accel_group ); return ( $item_factory->get_widget( '
' ) ); } sub about { &msgdialog("Nnetstat v0.1.1 Alpha\n\r Erol Alexander Neptun\n\r Please send bug reports to: aneptun\@yahoo.com\n\r www.aneptun.com/linux/Nnetstat "); } sub msgdialog { my $msg=shift; my $dialog = new Gtk::Dialog(); $dialog->set_default_size( 200, 100 ); $dialog->set_title(""); my $dbutton = new Gtk::Button( "Close" ); $dialog->action_area->pack_start( $dbutton, 1, 1, 0 ); $dbutton->show(); $dbutton->signal_connect( "clicked", sub {$dialog->destroy();} ); my $dlabel = new Gtk::Label( $msg ); $dialog->vbox->pack_start( $dlabel, 1, 1, 0 ); $dlabel->show(); $dialog->show(); } # # proc_scan: scan /proc about more information for running processes # their running network connections. # sub proc_scan { $p_inode=shift; $ps_name=""; $ps_id=""; $ps_status=""; $ps_user=""; opendir(DH,"/proc") or die "Cant open /proc directory: $!\n"; while(defined ($procfiles=readdir(DH))) { # ignore "." or ".." next if $procfiles=~/^\.\.?$/; # print "$procfiles\n"; if ($procfiles =~ /^\d/) { $ps_dir=$procfiles; # print "$ps_dir\n"; unless (!opendir(DH_FD,"/proc/$ps_dir/fd")) { # print "DIR: $ps_dir\n"; while(defined ($proc_fd=readdir(DH_FD))) { # ignore "." or ".." next if $proc_fd=~/^\.\.?$/; # print " $proc_fd\n"; $proc_tmp="/proc/$ps_dir/fd/$proc_fd"; $lfile=readlink($proc_tmp); # print " $proc_tmp --> $lfile \n"; # # if inode the search inodes? # if ($lfile=~/\[$p_inode\]/) { # print "Information of inode $p_inode found: $proc_tmp\n"; # # open /proc/PS-ID/status for more information of PS # open(PROC_PS,"/proc/$ps_dir/status") or print "Can\'t open /proc/$ps_dir"; while() { # find process name if (/^Name:/) { ($ps_name) = /:\s*(.*)/; # print "PS-NAME:$ps_name"; } # find process id elsif (/^Pid:/) { ($ps_id) = /:\s*(.*)/; # print " ID:$ps_id\n"; } # find process status elsif (/^State:/) { ($ps_status) = /:\s*(.*)/; } # find process uid elsif (/^Uid:/) { ($ps_uid) = /:\s*(\d*)\s*/; } } close(PROC_PS); } #if ($lfile=~/$p_inode/) } closedir(DH_FD); } #else {$ps_uid="";} # if -f } } closedir(DH); if ($ps_uid) { $ps_user=getpwuid($ps_uid);} else {$ps_user=""} #print "PROCESS: $ps_name : $ps_uid : $ps_user\n"; return($ps_name,$ps_id,$ps_status,$ps_user); } sub dns { my $togglebutton = $_[0]; if ( $togglebutton->active ) { $ifdnscheck=1; } else { # If control reaches here, the toggle button is up $ifdnscheck=0; } } sub dnscheck { if ($ifdnscheck) { $entryget=shift; $ipaddr=gethostbyaddr(inet_aton($entryget),AF_INET) or $ipaddr=$entryget; } } sub sockdet { my $togglebutton = $_[0]; if ( $togglebutton->active ) { $sockdet=1; } else { $sockdet=0; } } sub locip { my $togglebutton = $_[0]; if ( $togglebutton->active ) { $localip=0; } else { $localip=1; } } sub sendterm { if ($tkselect) { my ($select,@dlist,$pid); if ($tkselect eq "1") { @dlist = $tcp_clist->selection; $pid = $tcp_clist->get_text( $dlist[0], "10" ); if ($pid) { kill("TERM",$pid); &tcpopen(); } } elsif ($tkselect eq "2") { @dlist = $udp_clist->selection; $pid = $udp_clist->get_text( $dlist[0], "10" ); if ($pid) { kill("TERM",$pid); &udpopen(); } } elsif ($tkselect eq "3") { @dlist = $raw_clist->selection; $pid = $raw_clist->get_text( $dlist[0], "10" ); if ($pid) { kill("TERM",$pid); &rawopen(); } } elsif ($tkselect eq "4") { @dlist = $unix_clist->selection; $pid = $unix_clist->get_text( $dlist[0], "9" ); if ($pid) { kill("TERM",$pid); &unixopen(); } } $tkselect=undef; } } sub sendkill { if ($tkselect) { my ($select,@dlist,$pid); if ($tkselect eq "1") { @dlist = $tcp_clist->selection; $pid = $tcp_clist->get_text( $dlist[0], "10" ); if ($pid) { kill("KILL",$pid); &tcpopen(); } } elsif ($tkselect eq "2") { @dlist = $udp_clist->selection; $pid = $udp_clist->get_text( $dlist[0], "10" ); if ($pid) { kill("KILL",$pid); &udpopen(); } } elsif ($tkselect eq "3") { @dlist = $raw_clist->selection; $pid = $raw_clist->get_text( $dlist[0], "10" ); if ($pid) { kill("KILL",$pid); &rawopen(); } } elsif ($tkselect eq "4") { @dlist = $unix_clist->selection; $pid = $unix_clist->get_text( $dlist[0], "9" ); if ($pid) { kill("KILL",$pid); &unixopen(); } } $tkselect=undef; } } sub tcpselect { $tkselect="1"; } sub udpselect { $tkselect="2"; } sub rawselect { $tkselect="3"; } sub unixselect { $tkselect="4"; } sub routeselect { $tkselect="5"; }