I use scapy to sniff the mirror port and create a list of the top 10 talking speakers, i.e. list of hosts using high bandwidth on my network. I know existing tools like iftop and ntop , but I need more control over the output.
The following script exemplifies traffic for 30 seconds, and then prints a list of the 10 most popular speakers in the format "source host β host host: bytes". This is great, but how can I calculate the average byte per second ?
I realized that changing sample_interval to 1 second does not allow me to select traffic well, so it seems to me that I need to average it. So I tried this at the end of the script:
bytes per second = (total byte / sample _interval)
but the received / s bytes seem much lower. For example, I generated rsync between two hosts with a throttle rate of 1.5 MB / s, but using average calculation, my script continued to calculate the speed between these hosts as around 200 KB / s ... much lower than 1.5 MB / with as i expected. I can confirm with iftop that 1.5 MB / s is actually the speed between the two nodes.
Am I summing the packet length incorrectly using scapy (see the traffic_monitor_callbak function)? Or is this a bad decision overall :)?
from scapy.all import * from collections import defaultdict import socket from pprint import pprint from operator import itemgetter sample_interval = 30 # how long to capture traffic, in seconds # initialize traffic dict traffic = defaultdict(list) # return human readable units given bytes def human(num): for x in ['bytes','KB','MB','GB','TB']: if num < 1024.0: return "%3.1f %s" % (num, x) num /= 1024.0 # callback function to process each packet # get total packets for each source->destination combo def traffic_monitor_callbak(pkt): if IP in pkt: src = pkt.sprintf("%IP.src%") dst = pkt.sprintf("%IP.dst%") size = pkt.sprintf("%IP.len%") # initialize if (src, dst) not in traffic: traffic[(src, dst)] = 0 else: traffic[(src, dst)] += int(size) sniff(iface="eth1", prn=traffic_monitor_callbak, store=0, timeout=sample_interval) # sort by total bytes, descending traffic_sorted = sorted(traffic.iteritems(), key=itemgetter(1), reverse=True) # print top 10 talkers for x in range(0, 10): src = traffic_sorted[x][0][0] dst = traffic_sorted[x][0][1] host_total = traffic_sorted[x][3] # get hostname from IP try: src_hostname = socket.gethostbyaddr(src) except: src_hostname = src try: dst_hostname = socket.gethostbyaddr(dst) except: dst_hostname = dst print "%s: %s (%s) -> %s (%s)" % (human(host_total), src_hostname[0], src, dst_hostname[0], dst)
I'm not sure if this is a programming issue (scapy / python) or a more general network issue, so I call this a network programming issue.