首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用dpkt和python分析pcap文件

使用dpkt和python分析pcap文件
EN

Stack Overflow用户
提问于 2020-01-15 04:39:45
回答 1查看 3.3K关注 0票数 0

我正在尝试使用dpkt分析python中的pcap文件。我想要得到1)唯一IP地址的数量,2)计算每个流的字节总数,3)每个流的数据包总数和4)每个流的平均数据包大小

如果有人能帮我解决上述问题的python代码,我将不胜感激。谢谢

这就是我到目前为止所做的

代码语言:javascript
复制
if __name__ == "__main__":

    # Packet Counters
    counter=0
    ipcounter=0
    nonipcounter=0    
    tcpcounter=0
    udpcounter=0
    httpcounter=0
    httpscounter=0
    ipv4counter=0
    ipv6counter=0

    # Subnet Dictionary
    subnets = {}

    # Open file

    # Packet processing loop
    for ts,pkt in dpkt.pcap.Reader(open('tesst.pcap','rb')):
        counter+=1

        # Parse ethernet packet
        eth=dpkt.ethernet.Ethernet(pkt)
        ip=eth.data       

        #check if IP packet or non-ip packet
        if eth.type == dpkt.ethernet.ETH_TYPE_IP or eth.type == dpkt.ethernet.ETH_TYPE_IP6:
            ipcounter = ipcounter + 1
        else:
            nonipcounter = nonipcounter + 1    

        # IPV6 packets
        if eth.type==dpkt.ethernet.ETH_TYPE_IP6: 
            ipv6counter+=1     


        # IPV4 packets
        elif eth.type==dpkt.ethernet.ETH_TYPE_IP:
            ipv4counter+=1

            # Extract destination
            string = socket.inet_ntoa(ip.dst)
            address = '.'.join(string.split(".")[:]) 
            if address in subnets: #increase count in dict
                subnets[address] = subnets[address] + 1
            else: #insert key, value in dict
                subnets[address] = 1            

            # TCP packets
            if ip.p==dpkt.ip.IP_PROTO_TCP: #ip.p == 6: 
                tcpcounter+=1
                tcp=ip.data

                # HTTP uses port 80
                if tcp.dport == 80 or tcp.sport == 80:
                    httpcounter+=1

                # HTTPS uses port 443
                elif tcp.dport == 443 or tcp.sport == 443:
                    httpscounter+=1


            # UDP packets
            elif ip.p==dpkt.ip.IP_PROTO_UDP: #ip.p==17:
                udpcounter+=1
                udp=ip.data


    # Print packet totals
    print ("Total number of ETHERNET packets in the PCAP file :", counter)
    print ("\tTotal number of IP packets :", ipcounter)
    print ("\t\tTotal number of TCP packets :", tcpcounter)
    print ("\t\t\tTotal number of HTTP packets :", httpcounter)
    print ("\t\t\tTotal number of HTTPS packets :", httpscounter)
    print ("\t\t\tTotal number of IPV6 packets :", ipv6counter)
    print ("\t\tTotal number of UDP packets :", udpcounter)    
    print ("\t\tTotal number of IPV4 packets :", ipv4counter)
    print ("\tTotal number of NON-IP packets :", nonipcounter)
    print ("--------------------------------------------------------------")
    other = counter-(arpcounter+httpcounter+httpscounter+ipv6counter)



    # Print addresses
    print ("Address \t \t Occurences")
    for key, value in sorted(subnets.items(), key=lambda t: int(t[0].split(".")[0])):
        print ("%s/16 \t = \t %s" %(key, value))
EN

回答 1

Stack Overflow用户

发布于 2020-01-16 14:41:09

我参与了您的初始代码,并添加了一个初始功能,该功能按流收集IP4-TCP数据包,然后打印每个流的总字节数。您需要为IP6和UDP添加处理,还需要为收集剩余的统计信息添加处理,但希望这能最大限度地帮助您实现此目标。这假设流完全由4元组(src IP, src port, DST IP, DST port)定义。在现实生活中,这些值可以(最终)在多个流中重用,所以这个假设并不完全成立,但还是希望这能让你继续前进。

编辑

希望这能满足您的需求:

代码语言:javascript
复制
import dpkt
from functools import reduce
import socket

tflows = {}
uflows = {}
ips = set()

def dumpFlow(flows, flow):
    print(f'Data for flow: {flow}:')
    bytes = reduce(lambda x, y: x+y,
                   map(lambda e: e['byte_count'], flows[flow]))
    duration = sorted(map(lambda e: e['ts'], flows[flow]))
    duration = duration[-1] - duration[0]
    print(f"\tTotal Bytes: {bytes}")
    print(f"\tAverage Bytes: {bytes / len(flows[flow])}")
    print(f"\tTotal Duration: {duration}")


for ts,pkt in dpkt.pcap.Reader(open('/tmp/tcpdump.pcap','rb')):
    eth=dpkt.ethernet.Ethernet(pkt)

    if eth.type==dpkt.ethernet.ETH_TYPE_IP:

        ip=eth.data

        # determine transport layer type
        if ip.p==dpkt.ip.IP_PROTO_TCP:
            flows = tflows
        elif ip.p==dpkt.ip.IP_PROTO_UDP:
            flows = **uflows**

        # extract IP and transport layer data
        src_ip = socket.inet_ntoa(ip.src)
        src_port = ip.data.sport
        dst_ip = socket.inet_ntoa(ip.dst)
        dst_port = ip.data.dport

        # keeping set of unique IPs
        ips.add(src_ip)
        ips.add(dst_ip)

        # store flow data
        flow = sorted([(src_ip, src_port), (dst_ip, dst_port)])
        flow = (flow[0], flow[1])
        flow_data = {
            'byte_count': len(eth),
            'ts': ts
        }

        if flows.get(flow):
            flows[flow].append(flow_data)
        else:
            flows[flow] = [flow_data]


print(f'Total TCP flows: {len(tflows.keys())}')
print(f'Total UDP flows: {len(uflows.keys())}')
print(f'Total IPs: {len(ips)}')

for k in tflows.keys():
    dumpFlow(tflows, k)
for k in uflows.keys():
    dumpFlow(uflows, k)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59741466

复制
相关文章

相似问题

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