我正在尝试使用dpkt分析python中的pcap文件。我想要得到1)唯一IP地址的数量,2)计算每个流的字节总数,3)每个流的数据包总数和4)每个流的平均数据包大小
如果有人能帮我解决上述问题的python代码,我将不胜感激。谢谢
这就是我到目前为止所做的
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))发布于 2020-01-16 14:41:09
我参与了您的初始代码,并添加了一个初始功能,该功能按流收集IP4-TCP数据包,然后打印每个流的总字节数。您需要为IP6和UDP添加处理,还需要为收集剩余的统计信息添加处理,但希望这能最大限度地帮助您实现此目标。这假设流完全由4元组(src IP, src port, DST IP, DST port)定义。在现实生活中,这些值可以(最终)在多个流中重用,所以这个假设并不完全成立,但还是希望这能让你继续前进。
编辑
希望这能满足您的需求:
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)https://stackoverflow.com/questions/59741466
复制相似问题