首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >计算每个IP的带宽使用情况,如果是典型的话。

计算每个IP的带宽使用情况,如果是典型的话。
EN

Stack Overflow用户
提问于 2014-01-13 15:32:57
回答 2查看 7.5K关注 0票数 7

我正在使用替罪羊嗅探镜像端口,并生成前10位“健谈者”的列表,即使用我网络上带宽最多的主机列表。我知道已有的工具,如如果顶ntop,但我需要对输出进行更多的控制。

下面的脚本对通信量进行30秒的采样,然后以“源主机->目标主机:字节”的格式打印前10位说话者的列表。这很好,但是如何计算每秒平均字节()?

我有一种感觉,将sample_interval降低到1秒并不允许对流量进行良好的采样,所以我似乎需要将其平均化。因此,我在脚本的末尾尝试了这个:

每秒字节=(总字节/ sample_interval)

但由此产生的Bytes/s似乎要低得多。例如,我以1.5MB/s的节流速率在两个主机之间生成了一个rsync,但是使用上述平均计算,我的脚本一直计算这些主机之间的速率大约为200 KB/s……比我预期的1.5MB/s要低得多。我可以向iftop确认1.5MB/s实际上是这两个主机之间的速率。

我是否不正确地用scapy计算数据包长度(请参阅traffic_monitor_callbak函数)?或者这是一个糟糕的解决方案:)?

代码语言:javascript
复制
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)

我不确定这是一个编程问题(替罪羊/python)问题,还是更多的一般网络问题,所以我称之为网络编程问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-22 14:09:32

嗨,

首先,在您发布的代码中有一个bug :您可能指的是host_total = traffic_sorted[x][3],而不是host_total = traffic_sorted[x][1]

然后,有一个错误:忘记将host_total除以sample_interval值。

由于您还想添加接收方到发送方的通信量和发送方对接收方之间的通信量,我认为最好的方法是使用“有序”元组(顺序本身在这里并不重要,字典顺序可能很好,但您也可以使用算术顺序,因为IP地址是4个八进制整数)作为Counter对象的键。这似乎挺好的:

代码语言:javascript
复制
#! /usr/bin/env python

sample_interval = 10
interface="eth1"

from scapy.all import *
from collections import Counter


# Counter is a *much* better option for what you're doing here. See
# http://docs.python.org/2/library/collections.html#collections.Counter
traffic = Counter()
# You should probably use a cache for your IP resolutions
hosts = {}

def human(num):
    for x in ['', 'k', 'M', 'G', 'T']:
        if num < 1024.: return "%3.1f %sB" % (num, x)
        num /= 1024.
    # just in case!
    return  "%3.1f PB" % (num)

def traffic_monitor_callback(pkt):
    if IP in pkt:
        pkt = pkt[IP]
        # You don't want to use sprintf here, particularly as you're
        # converting .len after that!
        # Here is the first place where you're happy to use a Counter!
        # We use a tuple(sorted()) because a tuple is hashable (so it
        # can be used as a key in a Counter) and we want to sort the
        # addresses to count mix sender-to-receiver traffic together
        # with receiver-to-sender
        traffic.update({tuple(sorted(map(atol, (pkt.src, pkt.dst)))): pkt.len})

sniff(iface=interface, prn=traffic_monitor_callback, store=False,
      timeout=sample_interval)

# ... and now comes the second place where you're happy to use a
# Counter!
# Plus you can use value unpacking in your for statement.
for (h1, h2), total in traffic.most_common(10):
    # Let's factor out some code here
    h1, h2 = map(ltoa, (h1, h2))
    for host in (h1, h2):
        if host not in hosts:
            try:
                rhost = socket.gethostbyaddr(host)
                hosts[host] = rhost[0]
            except:
                hosts[host] = None
    # Get a nice output
    h1 = "%s (%s)" % (hosts[h1], h1) if hosts[h1] is not None else h1
    h2 = "%s (%s)" % (hosts[h2], h2) if hosts[h2] is not None else h2
    print "%s/s: %s - %s" % (human(float(total)/sample_interval), h1, h2)

很可能Scapy不够快来完成这项工作。可以肯定的是,使用例如tcpdump -w,您可以在sample_interval秒内捕获文件的流量,然后运行(顺便说一句,看看将函数应用于数据包的方法,我认为知道是否经常使用sample_interval是一件好事):

代码语言:javascript
复制
#! /usr/bin/env python

sample_interval = 10
filename="capture.cap"

from scapy.all import *
from collections import Counter

traffic = Counter()
hosts = {}

def human(num):
    for x in ['', 'k', 'M', 'G', 'T']:
        if num < 1024.: return "%3.1f %sB" % (num, x)
        num /= 1024.
    return  "%3.1f PB" % (num)

def traffic_monitor_callback(pkt):
    if IP in pkt:
        pkt = pkt[IP]
        traffic.update({tuple(sorted(map(atol, (pkt.src, pkt.dst)))): pkt.len})

# A trick I like: don't use rdpcap() that would waste your memory;
# iterate over a PcapReader object instead.
for p in PcapReader("capture.cap"):
    traffic_monitor_callback(p)

for (h1, h2), total in traffic.most_common(10):
    h1, h2 = map(ltoa, (h1, h2))
    for host in (h1, h2):
        if host not in hosts:
            try:
                rhost = socket.gethostbyaddr(host)
                hosts[host] = rhost[0]
            except:
                hosts[host] = None
    h1 = "%s (%s)" % (hosts[h1], h1) if hosts[h1] is not None else h1
    h2 = "%s (%s)" % (hosts[h2], h2) if hosts[h2] is not None else h2
    print "%s/s: %s - %s" % (human(float(total)/sample_interval), h1, h2)
票数 4
EN

Stack Overflow用户

发布于 2014-01-13 15:47:28

这可能不是它,但您是否混淆了超级比特每秒(Mb/s)和兆*字节*每秒(MB/s)?您似乎在测量以字节发送的数据量,然后将其转换为MB/s,但我想知道您是否将ws规范设置为1.5Mb/s。如果是这样的话,你的脚本给你200 kB/s的事实至少在大约1.5MB/s的正确范围内.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21095134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档