捕获MAC-IP对计数器异常:打印值始终为0的问题求助
MAC-IP对计数器始终显示0的问题排查与解决
问题描述
尝试为捕获的ARP/DHCP包中的MAC-IP对添加计数器,调试时确认计数器能记录条目接收次数,但实际打印时计数器值始终为0。相关代码、当前输出及期望输出如下:
原代码
import pyshark from collections import Counter # Creating a file capture, give path of your captured file, adding display filter capture = pyshark.LiveCapture(interface='Wi-Fi', display_filter='arp or udp.port eq 67') capture.sniff_continuously() d = dict() count1 = Counter() empty_mac = ('00:00:00:00:00:00', 'ff:ff:ff:ff:ff:ff') # Running for loop for extracting fields from captured packets for packet in capture: try: d["Arp_IP"] = packet.arp.dst_proto_ipv4 d["Arp_Mac"] = packet.arp.dst_hw_mac #milli_time = packet.sniff_timestamp except AttributeError: pass count1.update([(d['Arp_IP'], d['Arp_Mac'])]) if d["Arp_Mac"] not in empty_mac: print(packet.sniff_timestamp, count1[(d['Arp_Mac'], d['Arp_IP'])], d['Arp_Mac'], d['Arp_IP'])
当前输出
1672138792.786440000 0 14:13:3x:42:xx:xx 192.168.1.5 1672138793.365195000 0 14:13:3x:42:xx:xx 192.168.1.10 1672138792.786440000 0 14:13:3x:42:xx:xx 192.168.1.5 1672138793.365195000 0 14:13:3x:42:xx:xx 192.168.1.10
期望输出
1672138792.786440000 1 14:13:3x:42:xx:xx 192.168.1.5 1672138793.365195000 1 14:13:3x:42:xx:xx 192.168.1.10 1672138792.786440000 2 14:13:3x:42:xx:xx 192.168.1.5 1672138793.365195000 2 14:13:3x:42:xx:xx 192.168.1.10
错误原因
- 计数器键顺序不匹配:更新计数器时使用的元组是
(d['Arp_IP'], d['Arp_Mac']),但查询时用的是(d['Arp_Mac'], d['Arp_IP'])。元组是有序结构,这两个是完全不同的键,因此查询不到对应的计数,返回默认值0。 - 全局字典复用导致旧值干扰:字典
d定义在循环外部,处理非ARP包(如DHCP的udp 67端口包)时,try块会触发AttributeError并pass,此时d中保留的是上一个ARP包的旧值,会导致计数器错误累加旧的MAC-IP对。
修正后的代码
import pyshark from collections import Counter capture = pyshark.LiveCapture(interface='Wi-Fi', display_filter='arp or udp.port eq 67') count1 = Counter() empty_mac = ('00:00:00:00:00:00', 'ff:ff:ff:ff:ff:ff') for packet in capture.sniff_continuously(): # 每次循环初始化字典,避免旧值干扰 d = dict() try: d["Arp_IP"] = packet.arp.dst_proto_ipv4 d["Arp_Mac"] = packet.arp.dst_hw_mac except AttributeError: # 非ARP包直接跳过后续逻辑 continue # 统一计数器的键顺序:(MAC, IP) mac_ip_pair = (d['Arp_Mac'], d['Arp_IP']) count1.update([mac_ip_pair]) if d["Arp_Mac"] not in empty_mac: print(packet.sniff_timestamp, count1[mac_ip_pair], d['Arp_Mac'], d['Arp_IP'])
修正说明
- 将字典
d移到循环内部,每次处理新包时重新初始化,彻底避免旧数据干扰。 - 统一计数器的键顺序为
(MAC, IP),更新和查询使用同一个元组,确保计数匹配。 - 非ARP包触发
AttributeError后直接continue跳过计数逻辑,避免无效的计数器更新。 - 移除了多余的
capture.sniff_continuously()单独调用,直接在循环中使用capture.sniff_continuously()迭代。
内容的提问来源于stack exchange,提问作者roXx
相关产品推荐
相关产品推荐

