使用pyshark提取IP地址遇IPv6包触发KeyError,如何解决?
解决Pyshark遍历数据包时IPv6触发KeyError的问题
问题背景
我想用Pyshark把所有IP源/目的地址存入列表,后续用Matplotlib分析哪个IP的收发流量最多(不统计双向)。但遍历捕获包时,遇到目的地址为ff02::fb的IPv6包会触发错误:KeyError: 'layer does not exist in packet'。
错误原因
你的代码仅判断了数据包是否包含IP层(对应IPv4协议),但IPv6数据包在Pyshark中对应的层是IPv6而非IP,直接调用packet['ip']访问IPv6包会触发KeyError。
解决方案
- 同时判断数据包是否包含
IP(IPv4)或IPv6层 - 针对不同协议层分别提取目标地址(或源地址,按需选择)
- 加入异常捕获机制,跳过无法识别IP层的数据包
完整实现代码
import pyshark from collections import Counter import matplotlib.pyplot as plt # 读取pcap文件 cap = pyshark.FileCapture('p-02.pcap') # 用Counter统计IP出现次数,比列表更高效 ip_counter = Counter() for packet in cap: try: # 处理IPv4数据包 if 'IP' in packet: # 如需统计源地址,改为packet['ip'].src ip_addr = packet['ip'].dst ip_counter[ip_addr] += 1 # 处理IPv6数据包 elif 'IPv6' in packet: # 如需统计源地址,改为packet['ipv6'].src ip_addr = packet['ipv6'].dst ip_counter[ip_addr] += 1 except KeyError: # 跳过无法识别IP层的异常数据包 continue # 提取出现次数最多的前10个IP(可按需调整数量) top_n = 10 top_ips = ip_counter.most_common(top_n) ips = [item[0] for item in top_ips] counts = [item[1] for item in top_ips] # 绘制柱状图 plt.figure(figsize=(12, 6)) plt.bar(ips, counts, color='skyblue') plt.xlabel('IP地址') plt.ylabel('流量包数量') plt.title(f'出现次数最多的前{top_n}个IP地址') # 旋转x轴标签避免重叠 plt.xticks(rotation=45, ha='right') plt.tight_layout() plt.show()
代码说明
- 使用
collections.Counter替代列表统计,能更高效地计算IP出现频次 - 加入
try-except块捕获异常,避免程序因未知层报错中断 - 同时兼容IPv4和IPv6协议的地址提取
- 集成Matplotlib直接生成可视化统计图表,无需额外处理列表数据
内容的提问来源于stack exchange,提问作者brotherbrick
相关产品推荐
相关产品推荐

