如何使用Scapy编程实现类似Wireshark的流量捕获与筛选?
嘿,这个需求我太熟了!用Scapy实现和Wireshark里ip.src/ip.dst一样的流量筛选其实很简单,分两种最常用的场景给你拆解清楚,直接上代码和实用解释:
1. 实时捕获并筛选IP流量
如果想和Wireshark一样实时抓包并筛选,Scapy的sniff函数直接支持Wireshark同款的BPF过滤规则,上手毫无门槛:
首先导入必要的模块:
from scapy.all import sniff, IP
然后定义一个回调函数,用来处理每一个符合筛选条件的数据包(你可以改成保存、分析等操作):
def handle_packet(packet): # 打印包的摘要信息,想看完整细节可以用packet.show() print(packet.summary()) # 如果要保存包到文件,后面会讲
接下来设置筛选规则——和你在Wireshark里写的ip.src == x or ip.dst == y逻辑一致,只不过BPF语法里是ip src和ip dst:
# 比如筛选源IP为192.168.1.100 或者 目标IP为203.0.113.5的流量 filter_rule = "ip src 192.168.1.100 or ip dst 203.0.113.5" # 开始实时捕获:iface指定网卡(比如"eth0"或"Wi-Fi"),不指定则用默认网卡;store=0避免占内存 sniff(filter=filter_rule, prn=handle_packet, store=0, iface="Wi-Fi")
2. 读取已保存的PCAP文件并筛选
如果已经用Wireshark抓了PCAP文件,想事后用Scapy批量筛选,用列表推导式就能轻松搞定:
from scapy.all import rdpcap, IP # 读取本地的PCAP捕获文件 all_packets = rdpcap("your_wireshark_capture.pcap") # 筛选符合条件的包:先判断是IP包,再匹配源/目标IP target_src = "192.168.1.100" target_dst = "203.0.113.5" filtered_packets = [ pkt for pkt in all_packets if IP in pkt and (pkt[IP].src == target_src or pkt[IP].dst == target_dst) ] # 处理筛选结果:比如统计数量、打印IP信息 print(f"总共筛选出 {len(filtered_packets)} 个符合条件的数据包") for pkt in filtered_packets: print(f"源IP: {pkt[IP].src} → 目标IP: {pkt[IP].dst}")
一些实用小技巧
- 如果要匹配多个IP,用列表判断更高效:
allowed_src_ips = ["192.168.1.100", "192.168.1.101"] allowed_dst_ips = ["203.0.113.5", "203.0.113.6"] filtered_packets = [ pkt for pkt in all_packets if IP in pkt and (pkt[IP].src in allowed_src_ips or pkt[IP].dst in allowed_dst_ips) ] - 实时捕获时想保存筛选后的包到PCAP:
from scapy.all import wrpcap saved_packets = [] def capture_and_save(packet): saved_packets.append(packet) print(packet.summary()) # 捕获60秒后自动停止,然后保存 sniff(filter=filter_rule, prn=capture_and_save, store=0, timeout=60) wrpcap("filtered_traffic.pcap", saved_packets)
内容的提问来源于stack exchange,提问作者HappyCoding
相关产品推荐
相关产品推荐

