1. 程式人生 > >利用python指令碼執行tcpdump抓包,支援傳參、併發抓取多個包、檔案迴圈覆蓋抓取

利用python指令碼執行tcpdump抓包,支援傳參、併發抓取多個包、檔案迴圈覆蓋抓取

#!/usr/bin/env python
# AUTH: [email protected]

"""
tcpdump -i any -s 0 -w /opt/log/tcpdump/2018-07-19--10-43-30.pcap tcp and ip host 172.16.185.40 and port 8080
"""


import sys, subprocess, os, time
from sys import argv

Seconds = 12  # 每包要抓取的時長
RunNum = 30     # 最大同時抓包數,併發抓取多個
MaxFNum = 30  # 最大儲存檔案數

PackPath = "/opt/log/tcpdump" # save path
#p_IgnorPort = "port ! 8080 and port ! 3316 and port ! 3306 and port ! 5672"  # 8080java , 3316mysql

def CheckArgv(): #引數校驗
    """
    argv0 =
    argv1 = tcp/udp
    argv2 = ip
    argv3 = port (0 is no)
    check param
    """
    L = argv[1:]
    print(L)
    if len(L) < 3:
        print("wrong number of parameters: {} : tcp/udp ip port".format(len(L)))
        return False,L
    if L[0].lower() == "udp":
        L[0] = ("udp")
    else:
        L[0] = ("tcp")
    return True,L

def CheckPath(p):  #檔案路徑生成、校驗
    """
    :param p: file path
    :return:
    """
    if not os.path.exists(p):
        os.makedirs(p)
    return True

def getdirsize(dir):
    size = 0
    for root, dirs, files in os.walk(dir):
        size += sum([os.path.getsize(os.path.join(root, name)) for name in files])
    return size

def DelFile(p , n):  #迴圈刪除檔案
    """
    :param p: file path
    :param n: max num of saved files
    :return:
    """
    L1 = os.listdir(p)
    L2 = sorted(L1, key=lambda x: os.path.getmtime(os.path.join(p, x)) )
    if not L2:
        return False
    print("file num: {}, maxNum : {}".format(len(L2), n))
    OutOfNum = len(L2) - n +1
    if OutOfNum > 0:
        for i in range(OutOfNum):
            os.remove(os.path.join(p, L2[i]))
            print("del:{}".format(os.path.join(p, L2[i])))
    return True

def CheckPsNum():
    """
    check the linux server , dumping thread nums
    :return:
    """
    if sys.platform == "win32":
        return 0
    cmd = r'ps axu | egrep "/opt/log/tcpdump"| grep -v "grep" | wc -l'
    pro = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    rdl = pro.stdout.readlines()
    N1 = int(rdl[0])
    print("ps axu | grep tcpdump = {}".format(N1))
    return N1

def tcpdump(p, la, dur):  #抓包主體函式
    ErrCode = ""
    t1 = time.strftime("_%m-%d_%H-%M-%S", time.localtime())
    name = la[1] + t1 + "_" + la[0].upper()
    cmd1 = "tcpdump -i any -s 0 -w {0}/{1}.pcap {2} and ip host {3}".format(p, name, la[0], la[1])
    if int(la[2]) != 0:
        cmd1 = cmd1 + " and port {}".format(la[2])
    print(cmd1)

    BackN = CheckPsNum()
    if BackN >= RunNum:
        ErrCode = "Out Of Num: {}".format(BackN)
        print(ErrCode)
        return ErrCode

    pro = subprocess.Popen(cmd1, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    print("processid.{0}, stat. {1}".format(pro.pid, pro.poll()))
    if pro.poll() != None:
        ErrCode = "execute cmd error; poll()={} PID={}".format(pro.poll(),pro.pid)
    else:
        ErrCode = "execute cmd OK; poll()={}  PID={}".format(pro.poll(),pro.pid)
        time.sleep(dur)
    print(ErrCode)
    pro.terminate()
    return ErrCode

if __name__ == '__main__':
    Ret,L = CheckArgv()
    if Ret == True:
        CheckPath(PackPath)
        DelFile(PackPath, MaxFNum)
        tcpdump(PackPath, L, Seconds)