如何在pyshark实时抓包过程中添加计数器统计相同数据包接收次数
PyShark ARP实时抓包按特征计数实现方案
需求说明
使用pyshark进行ARP实时抓包,每次相同(mac地址、ip)组合的数据包到达时,自动更新该组合的接收次数并打印。
现有问题
原有代码仅会首次打印新出现的(mac、ip)组合,无法统计重复出现的同特征包的接收次数。
原有代码
# from collections import Counter capture = pyshark.LiveCapture(interface='wlo2', bpf_filter='arp') capture.sniff(timeout=5) keys = {} e_mac = '00:00:00:00:00:00' or 'ff:ff:ff:ff:ff:ff' already_seen = [] count = 0 for packet in capture: keys['ip'] = packet.arp.dst_proto_ipv4 keys['mac'] = packet.arp.dst_hw_mac seen = keys['mac'], keys['ip'] if keys['mac'] != e_mac: if seen not in already_seen: already_seen.append(seen) print(packet.sniff_time, keys['mac'], keys['ip'])
原有输出
2021-12-06 18:59:55.325859 28:d1:27:1a:12:c0 192.168.1.3 2021-12-06 18:59:58.704726 f8:c4:f3:56:a3:70 192.168.1.1 2021-12-06 19:00:02.286922 ff:ff:ff:ff:ff:ff 192.168.1.1 2021-12-06 19:02:15.854700 44:af:28:2c:6d:6b 192.168.1.195 2021-12-06 19:07:02.440235 90:e8:68:f2:00:c1 192.168.1.13
预期输出格式
Dec 06 16:07:45 2 28:d1:27:1a:12:c0 192.168.1.3 Dec 06 16:08:01 4 f8:c4:f3:56:a3:70 192.168.1.1
修改后可实现需求的代码
import pyshark from datetime import datetime capture = pyshark.LiveCapture(interface='wlo2', bpf_filter='arp') capture.sniff(timeout=5) # 用字典存每个(mac,ip)组合的计数 packet_counter = {} # 过滤的mac地址集合,修复原or逻辑的错误 exclude_macs = {'00:00:00:00:00:00', 'ff:ff:ff:ff:ff:ff'} for packet in capture: dst_ip = packet.arp.dst_proto_ipv4 dst_mac = packet.arp.dst_hw_mac feature = (dst_mac, dst_ip) if dst_mac not in exclude_macs: # 计数自增,不存在的key默认从0开始加1 packet_counter[feature] = packet_counter.get(feature, 0) + 1 # 格式化时间为预期的月 日 时分秒格式 format_time = datetime.fromtimestamp(float(packet.sniff_timestamp)).strftime("%b %d %H:%M:%S") # 按预期格式打印 print(f"{format_time} {packet_counter[feature]} {dst_mac} {dst_ip}")
核心修改说明
- 替换原有的存储已出现特征的列表为计数字典,直接以(mac, ip)元组作为键,对应值为该特征的出现次数,查询和更新效率更高
- 修复原代码中过滤mac的逻辑错误:原
e_mac = 'a' or 'b'的写法只会得到第一个mac值,改为用集合存储需要过滤的mac,直接判断是否在集合内即可 - 每次收到符合条件的包就更新计数,同时把时间戳格式化为要求的
月 日 时分秒格式输出
内容的提问来源于stack exchange,提问作者roXx
相关产品推荐
相关产品推荐

