Skip to content

Instantly share code, notes, and snippets.

@pfote
Created November 13, 2014 12:05
Show Gist options
  • Save pfote/a25509a6daaf811613ed to your computer and use it in GitHub Desktop.
Save pfote/a25509a6daaf811613ed to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
"""
statistics for netstat tcp
"""
from pprint import pformat
from optparse import OptionParser,OptionGroup
import re
import socket
import sys
def get_ip_address(ifname):
"""not used here, but the function is cool, maybe i need it some day"""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15])
)[20:24])
def getservbyport(port_,proto_='tcp'):
"""socket.getservbyport() is broken on my machine and not available on others,
so here's my little hack
"""
try:
# globals are bad, but i'm to lazy wrap it into a class'
return __SERVICE[proto_][str(port_)]
except:
SERV = re.compile(r'([\w\-\_]+)\s+(\d+)\/(tcp|udp)')
try:
lines = open('/etc/services','r').read()
results = SERV.findall(lines)
for (service,port,proto) in results:
__SERVICE[proto][port] = service
except Exception,e:
print "getservbyport parser faled: %s" % str(e)
try:
return __SERVICE[proto_][str(port_)]
except:
return proto_
def getHostName(ip):
try:
name = socket.gethostbyaddr(ip)[0]
except:
name = ip
return name
LINEREGEXP = re.compile(r'tcp\s+\d+\s+\d+\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\:(\d+)\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\:(\d+)\s+(\w+).*')
netstatCmd = 'netstat -nt'
try:
from subprocess import Popen, PIPE
pipe = Popen(netstatCmd, shell=True, stdout=PIPE).stdout
except ImportError:
# on older machines with
from os import popen
pipe = popen(netstatCmd)
__SERVICE = {'tcp' : {},'udp' : {}}# global service cache
parser = OptionParser(version='%prog V0.1b')
parser.add_option("-n","--numeric",action="store_true",
dest="numeric", default=False, help="don't resolve host names")
parser.add_option("-p","--port",
dest="port", type="int", default=0,help="list only connections with port PORT")
(options, args) = parser.parse_args()
# ****************************************************************************
# COLLECT OUTBOUND AN INBOUND CONNECTIONS
# IF NO PORT IS GIVEN, GROUP BY SYSTEM PORTS, THAT IS EITHER ON INBOUND
# OR OUTBOUND PORT THAT SI SMALLER THAN 1024
# ****************************************************************************
outbound = {}
inbound = {}
for (srcIP,srcPort,destIP,destPort,status) in LINEREGEXP.findall(pipe.read()):
if (int(destPort) == options.port) or (int(srcPort) > 1024 and int(destPort) <= 1024 and not options.port):
key = destIP +'|' + destPort + '|' + status
if not outbound.has_key(srcIP):
outbound[srcIP] = {}
if not outbound[srcIP].has_key(key):
outbound[srcIP][key] = 1
else:
outbound[srcIP][key] = outbound[srcIP][key] + 1
if (int(srcPort) == options.port) or (int(srcPort) <= 1024 and int(destPort) > 1024 and not options.port):
key = destIP + '|' + status
src = srcIP + ':' + srcPort
if not inbound.has_key(src):
inbound[src] = {}
if not inbound[src].has_key(key):
inbound[src][key] = 1
else:
inbound[src][key] = inbound[src][key] + 1
for ip,data in outbound.items():
if options.numeric:
hostnameSrc = ip
else:
hostnameSrc = getHostName(ip)
print "from %s outgoing:" % hostnameSrc
items = data.items()
try:
items.sort(cmp=lambda x,y: cmp(y[1],x[1]))
except:
#python 2.3
items.sort(lambda x,y: cmp(y[1],x[1]))
for key,cnt in items:
(destIp,port,status) = key.split('|')
service = getservbyport(port,'tcp')
if options.numeric:
hostnameDest = destIp
else:
hostnameDest = getHostName(destIp)
print " %d connections to %s:%s, status %s" % (cnt,hostnameDest,service,status)
all = 0
for ipx,data in inbound.items():
(ip,port) = ipx.split(':')
if options.numeric:
hostnameSrc = ip
else:
hostnameSrc = getHostName(ip)
service = getservbyport(port,'tcp')
print "incoming to %s:%s" % (hostnameSrc,service)
items = data.items()
try:
items.sort(cmp=lambda x,y: cmp(y[1],x[1]))
except:
#python 2.3
items.sort(lambda x,y: cmp(y[1],x[1]))
for key,cnt in items:
(destIp,status) = key.split('|')
if options.numeric:
hostnameDest = destIp
else:
hostnameDest = getHostName(destIp)
print " %d connections from %s, status %s" % (cnt,hostnameDest,status)
all += cnt
print "sum: %d" % all
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment