使用PyShark捕获数据包时如何打印全部协议类型(含ICMP、ARP等)
解决PyShark捕获全类型协议数据包的问题
你的代码只能获取TCP/UDP,是因为packet.transport_layer仅针对传输层协议,像ARP(数据链路层)、ICMP(网络层)这类非传输层协议会被忽略,甚至直接报错(比如ARP包没有ip层,ICMP包没有传输层端口)。下面是修正后的代码,能识别并打印ARP、ICMP、TCP、UDP等常见协议:
首先补上缺失的time模块导入,然后通过判断数据包的层级来适配不同协议:
import pyshark import time capture = pyshark.LiveCapture(interface='eth0') capture.sniff(timeout=50) for packet in capture.sniff_continuously(): localtime = time.asctime(time.localtime(time.time())) protocol = "" src_addr = "" src_port = "" dst_addr = "" dst_port = "" # 处理ARP协议(数据链路层) if hasattr(packet, 'arp'): protocol = "ARP" src_addr = packet.arp.src_proto_ipv4 dst_addr = packet.arp.dst_proto_ipv4 # 处理ICMP协议(网络层) elif hasattr(packet, 'icmp'): protocol = "ICMP" src_addr = packet.ip.src dst_addr = packet.ip.dst # 处理TCP/UDP协议(传输层) elif packet.transport_layer: protocol = packet.transport_layer src_addr = packet.ip.src src_port = packet[packet.transport_layer].srcport dst_addr = packet.ip.dst dst_port = packet[packet.transport_layer].dstport # 其他协议(可选:打印未匹配的层信息) else: layer_names = [layer.layer_name for layer in packet.layers] protocol = f"OTHER ({'/'.join(layer_names)})" # 打印结果,空字段自动留空 print(f"{localtime}\t{protocol}\t{src_addr}\t{src_port}\t{dst_addr}\t{dst_port}")
关键修改点说明:
- 用
hasattr()判断数据包是否包含某层(比如ARP、ICMP),避免不存在该层时抛出异常 - 针对不同协议的字段结构,分别获取源/目标地址、端口(非传输层协议没有端口,自然留空)
- 增加了"OTHER"分支,用于捕获未明确处理的协议,可通过遍历
packet.layers查看所有层级的协议名
内容的提问来源于stack exchange,提问作者user20828450
相关产品推荐
相关产品推荐

