Friday, October 14, 2005

[Tcl] Network Connection Statistics

#! /usr/local/bin/tclsh
#
# find out netstat states via SNMP
#
#

if { $argc < 1 || $argc > 3 } {
 puts "Usage: $argv0  \[interval\] \[iteration\]\n"
 puts {       interval [60]}
 puts {       iteration [10]}
 exit
}


package require Tnm
namespace import Tnm::*


set host [lindex $argv 0]
set interval [lindex $argv 1]
set iteration [lindex $argv 2]
if { [string length $interval] == 0 } {
 set interval 60
}
if { [string length $iteration] == 0 } {
 set iteration 10
}


set snmp [snmp generator -address $host -timeout 1 -retries 1]
if { [catch {$snmp get sysUpTime.0}] != 0 } {
 puts "Error. SNMP service not available at \"$host\"\n"
 exit 2
}


proc getServices { {f /etc/services} } {
 global services

 set fp [open $f r] 
 while { [gets $fp line] >= 0 } {
  if { [regexp {(^\s*$)|(^\s*#)} $line] } {
   continue
  }

  if { [regexp {^\s*(\w+)\s+(\d+)/tcp} $line dummy name port] } {
   set services($port) $name
  }
 }
 close $fp
}


proc getTcpListen { snmp } {
 set dot {.}
 set rc {}
 $snmp walk x tcpConnState {
  set oid [snmp oid $x]
  set val [snmp value $x]
  if { [string equal listen $val] } {
   set loid [split $oid $dot]
   lappend rc [join [lrange $loid 14 14] $dot]
  }
 }
 return $rc
}


proc printTcpListen { listen } {
 global services

 set txt {}
 set count 0
 foreach port [lsort -integer $listen] {
  incr count
  if { [info exists services($port)] } {
   append txt "$port ($services($port))\n"
  } else {
   append txt  "$port\n"
  }
 }
 return $txt
}


proc getTcpState { snmp } {

 set dot {.}

 # Tnm::mib oid tcpConnState
 # 1.3.6.1.2.1.6.13.1.1
 $snmp walk x tcpConnState {
  set oid [snmp oid $x]
  set val [snmp value $x]
  set loid [split $oid $dot]
  set lip [join [lrange $loid 10 13] $dot]
  set rip [join [lrange $loid 15 18] $dot]

  # local <-> remote
  if { ![string equal $lip $rip] } {
   if { [info exists rc($val)] } {
    incr rc($val)
   } else {
    set rc($val) 1
   }
  }
 }

 return [array get rc]
}


proc printTcpState { snmp } {
 set rc {}
 foreach { s v } [getTcpState $snmp] { lappend rc [list $s $v] }

 puts -nonewline "[clock format [clock seconds] -format {%H:%M:%S}]  "
 foreach i [lsort -index 0 -dictionary $rc] {
  puts -nonewline "[lindex $i 0] ([lindex $i 1])  "
 }
 puts ""
}


getServices port.txt

puts "TCP Listening ports:"
puts [printTcpListen [getTcpListen $snmp]]

puts "\n\nTCP Connection State:"
job create -interval [expr $interval*1000]  -command "printTcpState $snmp"  -iterations $iteration  -exit { set forever {} }


vwait forever





# Sample output
# ./netstat.tcl 192.168.0.1 5 10
# TCP Listening ports:
# 21 (ftp)
# 22 (SSH_Remote_Login_Protocol)
# 23 (telnet)
# 79 (finger)
# 80 (http)
# 111 (sunrpc)
# 513 (login)
# 514 (shell)
# 536
# 898
# 3306 (MySQL)
# 4045 (lockd)
# 5987
# 5988
# 7100 (fs)
# 8005
# 8009
# 8080 (HTTP)
# 32771 (Sun_RPC)
# 32772
# 32773
# 32774
# 32778
# 32779
# 32780 (RPC)
# 32781
# 32782
#  
#  
#  
# TCP Connection State:
# 13:49:15  established (17)  listen (1)  timeWait (4)
# 13:49:20  established (20)  listen (1)  timeWait (4)
# 13:49:25  established (20)  listen (1)  timeWait (4)
# 13:49:30  established (21)  listen (1)  timeWait (4)
# 13:49:35  established (21)  listen (1)  timeWait (4)
# 13:49:40  established (21)  listen (1)  timeWait (4)
# 13:49:45  established (21)  listen (1)  timeWait (4)
# 13:49:50  established (21)  listen (1)
# 13:49:55  established (17)  finWait2 (4)  listen (1)
# 13:50:00  established (17)  listen (1)  timeWait (4)

0 Comments:

Post a Comment

<< Home