在python中使用pcapy的网络流量监控器 [英] Network traffic monitor with pcapy in python

查看:241
本文介绍了在python中使用pcapy的网络流量监控器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我编写了简单的网络流量监控器,以B/s为单位获取传输速率和/或以B为单位获取总数据传输.但是,当我通过使用ftp传输文件(使用Total Commander)进行测试时,我只是无法使它衡量文件的总传输量.它总是比实际尺寸小得多. 我不确定我做错了什么.. 我设置的BPF过滤器是

I have written simple network traffic monitor to get transfer rate in B/s and/or total data transfer (in B). However when I test it by transferring a file with ftp (using Total Commander) I just can not make it measure total transfer as a size of the file. It always give much lower size than actual one. I am not sure if I am doing something wrong.. The BPF filter I set is

dst <IP of ftp server pc>

下面是我的源代码:

import threading
import sys
import pcapy
import time
import logging as logger

class NetMonitor(threading.Thread):

    _timeout = 1

    @classmethod
    def get_net_interfaces(cls):
        return pcapy.findalldevs()

    def __init__(self, device, bpf_filter):
        threading.Thread.__init__(self)

        self.active = True
        self._net_monitor = pcapy.open_live(device, 65535, 0, 1000) #self.timeout * 1000)
        self._net_monitor.setfilter(bpf_filter)
        #self.dumper = self.net_monitor.dump_open("pkt_dump.txt")

        self._current_bytes_rate = 0
        self.total_transfer = 0 # total number of Bytes transfered

        #<--- this is to calc average transfer B/s
        self._tmp_bytes_per_sec_sum = 0 # sums up B/s values from each dispatch iteration (eventually used to calc average value)
        self._inc = 0 # number of dispatch iterations (eventually used to calc average B/s value)
        #--->

        self._dispatch_bytes_sum = 0 # sums up packets size for one dispatch call


    def __handle_packet(self, header, data):
        # method is called for each packet by dispatch call (pcapy)
        self._dispatch_bytes_sum += len(data) #header.getlen() #len(data)
        #logger.debug("h: ({}, {}, {}), d:{}".format(header.getlen(), header.getcaplen(), header.getts(), len(data)))
        #self.dumper.dump(header, data)


    def update(self):
        self._dispatch_bytes_sum = 0
        # process packets
        packets_nr = self._net_monitor.dispatch(-1, self.__handle_packet)
        self.total_transfer += self._dispatch_bytes_sum

        self._inc += 1
        self._current_bytes_rate = self._dispatch_bytes_sum  # add single dispatch B/s -> timeout is 1 s
        self._tmp_bytes_per_sec_sum += self._current_bytes_rate

        logger.debug('inc:{}, current rate: {} B/s, avg rate: {} B/s,  total:{} B'.format(self._inc, self.current_rate, self.avg_rate, self.total_transfer))

        return self._current_bytes_rate, packets_nr



    def get_avg_bytes_rate(self):
        if self._inc:
            return self._tmp_bytes_per_sec_sum / self._inc
        else:
            return 0

    def get_current_bytes_rate(self):
        return self._current_bytes_rate


    def run(self):
        while(self.active):
            self.update()
            time.sleep(self._timeout)


    # average B/s rate
    avg_rate = property(get_avg_bytes_rate)
    # current B/s rate 
    current_rate = property(get_current_bytes_rate)





if __name__ == '__main__':

    filter = ' '.join(sys.argv[2:])
    print filter
    #nm0 = NetMonitor(pcapy.findalldevs()[0], filter)
    nm1 = NetMonitor(pcapy.findalldevs()[1], filter)

    nm1.start()
    start_time = time.time()
    while time.time() - start_time < int(sys.argv[1]):
        print "current {} B/s, avg {} B/s, total transfer {} B".format(nm1.current_rate, nm1.avg_rate, nm1.total_transfer)
        time.sleep(1)

    nm1.active = False
    nm1.join()

    print "++++++ total: {}, avg: {}".format(nm1.total_transfer, nm1.avg_rate)

任何建议都将不胜感激. 干杯.

Any advice is much appreciated. Cheers.

推荐答案

使用过滤器仅捕获有用的tcp流ftp-data:

Use a filter to capture only the useful tcp streams, ftp-data :

port ftp-data

我建议也以混杂模式捕获,仅捕获包头(您不需要完整的数据即可知道长度):

I suggest also to capture in promiscous mode, only the packet headers ( you don't need the full data to know the length ):

open_live( device, 4096, True, 100 )

在处理程序中,使用header.getlen()是正确的.

In your handler, it is correct to use header.getlen().

这篇关于在python中使用pcapy的网络流量监控器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆