Summarise Netstat Inbound and Outbound Traffic
If connection tuple's (localhost:localport - remotehost:remoteport) localport is one of the listening ports, we can say that the connection is an inbound, else outbound. At first I tried to use ephemeral port to figure out the in/out bound, but find it not very reliable 'cos software can listen to a high port too. Also, you need to run netstat with -n (Show network addresses as numbers) in order to figure out the numeric port number.
The "getlisten" shell function is a trick that I normally used to dynamically create the
AWK
BEGIN content. In this case, I parse the "netstat" output and set the "listen" array variable in AWK to 1. This function will be invoked by the shell (not inside AWK) and shell will 'glue' them together with the
AWK
code. '`getlisten`'
- first single quote is to temporary terminate AWK, follow by backquote to run the shell function, then open a single quote to continue the AWK. Remember no space is allowed between the single quote and backquote.
#! /bin/sh # # Summary netstat information by inbound and outbound traffic TMPFILE=/tmp/.netstat-$$ trap "rm -f $TMPFILE" 0 1 2 3 9 15 netstat -a -finet -Ptcp > $TMPFILE timestamp=`date '+%Y%m%dT%H%M%S'` # # shell function to create AWK BEGIN block for all the listening ports # eg. listen["123"]=1; # getlisten() { awk '$NF=="LISTEN" {n=split($1,a,".");printf("listen[\"%s\"]=1;",a[n])}' $TMPFILE } nawk -v timestamp=$timestamp ' function getport (hostport, n) { n=split(hostport,a,".") return a[n] } function gethost (hostport, n, h) { n=split(hostport,a,".") h=a[1] for(i=2;i<n;++i) { h=sprintf("%s.%s",h,a[i]) } return h } BEGIN {'`getlisten`'} NR>4 && $NF!~/(IDLE|BOUND|LISTEN)$/ { lh=gethost($1) lp=getport($1) rh=gethost($2) rp=getport($2) # if local port is one of the listen ports # is inbound # else # is outbound if ( listen[lp] == 1 ) { key=sprintf("%s:%s<-%s %s ",lh,lp,rh,$NF) ++inbound[key] } else { key=sprintf("%s->%s:%s %s ",lh,rh,rp,$NF) ++outbound[key] } } END { for(i in inbound) { print timestamp, i, inbound[i] } for(i in outbound) { print timestamp, i, outbound[i] } } ' $TMPFILE
Sample output:
$./n.sh 20080822T163621 sgehost:sge_qmaster<-sgehost ESTABLISHED 1 20080822T163621 sgehost:ldap<-sgehost ESTABLISHED 12 20080822T163621 sgehost:ssh<-remote_server ESTABLISHED 1 20080822T163621 sgehost:sge_qmaster<-sgeexec2 ESTABLISHED 1 20080822T163621 sgehost:sge_qmaster<-sgeexec0 ESTABLISHED 1 20080822T163621 sgehost:sge_qmaster<-sgeexec1 ESTABLISHED 1 20080822T163621 sgehost->sgehost:ldap ESTABLISHED 12 20080822T163621 sgehost->sgehost:sge_qmaster ESTABLISHED 1
BTW, this script is developed on a Solaris platform.
Labels: awk, shell script, Solaris