You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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。

解决方案

  1. 同时判断数据包是否包含IP(IPv4)或IPv6层
  2. 针对不同协议层分别提取目标地址(或源地址,按需选择)
  3. 加入异常捕获机制,跳过无法识别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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 11:35:20