【发布时间】:2014-02-01 10:13:11
【问题描述】:
我正在使用 scapy 嗅探镜像端口并生成前 10 名“谈话者”的列表,即在我的网络上使用最多带宽的主机列表。我知道iftop 和ntop 等工具已经可用,但我需要对输出进行更多控制。
以下脚本对 30 秒的流量进行采样,然后以“源主机 -> 目标主机:字节”的格式打印前 10 名通话者的列表。太好了,但是如何计算平均每秒字节数?
我感觉将 sample_interval 更改为 1 秒并不能对流量进行良好的采样,因此我似乎需要对其进行平均。所以我在脚本末尾尝试了这个:
每秒字节数 =(总字节数 / sample_interval)
但生成的 Bytes/s 似乎要低得多。例如,我以 1.5 MB/s 的节流速率在两台主机之间生成了 rsync,但使用上述平均计算,我的脚本继续计算这些主机之间的速率约为 200 KB/s...远低于 1.5 MB /s 如我所料。我可以通过 iftop 确认 1.5 MB/s 实际上是这两个主机之间的速率。
我是否使用 scapy 错误地汇总了数据包长度(请参阅 traffic_monitor_callbak 函数)?或者这完全是一个糟糕的解决方案:)?
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)
我不确定这是一个编程(scapy/python)问题还是更多的一般网络问题,所以我称之为网络编程问题。
【问题讨论】:
标签: python networking network-programming scapy