加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

python通过解析tcpdump输出,以IP维度给出服务器上的流量数据

发布时间:2020-12-17 17:31:25 所属栏目:Python 来源:网络整理
导读:今天PHP站长网 52php.cn把收集自互联网的代码分享给大家,仅供参考。 #!/bin/env pythonimport timeimport datetimeimport subprocess as subfrom optparse import OptionParserimport os,sysimport socketdef dump_dict(

以下代码由PHP站长网 52php.cn收集自互联网

现在PHP站长网小编把它分享给大家,仅供参考

#!/bin/env python
import time
import datetime
import subprocess as sub
from optparse import OptionParser
import os,sys
import socket

def dump_dict(flow_dict,timestr,log_file,top_n,debug):
    try:
        timestamp = datetime.datetime.fromtimestamp(int(time.time())).strftime(timestr)
    except Exception as e:
        print(e)
        sys.exit(1)

    #get top values
    top_n_list = sorted(flow_dict.iteritems(),key=lambda x:-x[1])[:top_n]
    for item in top_n_list:
        line = 'time=%s`src_ip=%s`src_port=%s`dst_ip=%s`dst_port=%s`bytes=%s' %(timestamp,item[0][0],item[0][1],item[0][2],item[0][3],item[1])
        log_file.write(line + 'n')
        if debug: print(line)
    log_file.flush()

def get_host_ip():
    return socket.gethostbyname(socket.gethostname())

def add_bytes_to_dict(line_list,flow_dict):
    '''
    accept a list which contains tcpdump info,and set into the dictionary given as the second arg.
    the tcpdump info line is like this:
    ['IP','10.46.64.148.9922','>','100.84.32.188.56300:','tcp','100']
    '''

    src_ip = '.'.join(line_list[1].split('.')[0:4])
    src_port = line_list[1].split('.')[4]
    dst_ip = '.'.join(line_list[3].split('.')[0:4])
    dst_port = line_list[3].split('.')[4].strip(':')
    bytes = int(line_list[5])
    tmp_key = (src_ip,src_port,dst_ip,dst_port)
    if tmp_key in flow_dict.keys():
        flow_dict[tmp_key] +=  bytes
    else:
        flow_dict[tmp_key] =  bytes

def x_parser():
    parser = OptionParser()
    parser.add_option("-i","--interval",action="store",dest="INTERVAL",help="dump result every INTERVAL seconds,default 60")
    parser.add_option("-f","--file",dest="FILE",help="Where the data file should be,REQUIRED")
    parser.add_option("-D","--debug",action="store_true",dest="isDebug",default=False,help="open debug mode if selected(only print to stddin)")
    parser.add_option("-n","--topn",dest="TOPN",help="top n values to dump,default 50")
    parser.add_option("-e","--expression",dest="EXPRESSION",help="this arg will pass to tcpdump,ext. 'tcp src port 80',REQUIRED")
    parser.add_option("-T","--timeStr",dest="TIMESTR",help="timeStamp format,default is like 'date +"%Y-%m-%d %H:%M:%S"'")
    return parser

def main():
    parser = x_parser()
    (options,args) = parser.parse_args()
    interval = int(options.INTERVAL or 60)
    timestr = options.TIMESTR or '''%Y-%m-%d %H:%M:%S'''
    top_n = int(options.TOPN) or 50
    if not options.FILE:
        print("NO log file given,exit.")
        sys.exit(1)
    else:
        log_file = open(options.FILE,'w')

    #dictionary use to keep the flow data,'(src_ip,dst_port)' as a key,value 'bytes'
    flow_dict_in = {}
    flow_dict_out = {}
    my_ip = get_host_ip()
    t1 = time.time()
    if options.EXPRESSION:
        #please refer to tcpdump's man page for details,we don't need the packet's info when it's an ACK/SYN,so have this expression: (((ip[2:2]....!= 0)
        #and also shuld make tcpdump line buffer,that's why  we use '-l'
        p = sub.Popen(['tcpdump','(((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0) and tcp and ',options.EXPRESSION,'-l','-nn','-q','-t'],stdout=sub.PIPE)
    else:
        print("No expression given,exit.")
        sys.exit(1)


    for line in iter(p.stdout.readline,b''):
        #the line contains 'n',hate it...
        line_list = line.strip().split(' ')
        if my_ip in line_list[1]:
            add_bytes_to_dict(line_list,flow_dict_out)
        elif my_ip in line_list[3]:
            add_bytes_to_dict(line_list,flow_dict_in)
        else:
            print("ERROR,don't know what it is: %s." %(line))
        t2 = time.time()

        #print the result every interval seconds,and zero out the dictionary,start again
        if t2 - t1 > interval:
           t1 = time.time()
           dump_dict(flow_dict_in,options.isDebug)
           dump_dict(flow_dict_out,options.isDebug)
           flow_dict_in = {}
           flow_dict_out = {}
    log_file.close()


if __name__ == '__main__':
    main()

以上内容由PHP站长网【52php.cn】收集整理供大家参考研究

如果以上内容对您有帮助,欢迎收藏、点赞、推荐、分享。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读