Scapy数据包分类规则、Received访问方法及Answered收发标准咨询
嘿,针对你关于Scapy数据包分类的问题,我整理了详细的解释和解决方案,希望能帮到你:
Scapy数据包分类(Received/Answered/Remaining)详解
一、Answered数据包的收发判定标准
Scapy判定发送包与接收包属于“Answered”(已响应)的核心逻辑是请求-响应的关联匹配,默认规则如下:
- IP层匹配:发送包的目的IP是接收包的源IP,发送包的源IP是接收包的目的IP(地址完全互换);
- 传输层/协议层匹配:
- TCP:源端口与目的端口互换,且状态对应(比如发送SYN包收到SYN-ACK,发送数据报收到ACK);
- UDP:源端口与目的端口互换(默认逻辑相对宽松,可自定义负载匹配规则);
- ICMP:类型对应(如Echo Request(类型8)匹配Echo Reply(类型0)),且标识符、序列号完全一致。
你也可以通过自定义session参数来修改匹配逻辑,满足特定场景的需求。
二、三类数据包的划分依据
Scapy里这三类数据包的划分逻辑是基于「发送包-接收包」的关联关系:
- Answered:发送出去的数据包成功收到了对应的响应包,且通过上述匹配规则完成了关联,最终以「(发送包, 响应包)」的元组形式存在;
- Remaining(Unanswered):发送出去的数据包没有收到任何能匹配上的响应包,这类发送包会被归类到Remaining(也就是Scapy官方术语里的Unanswered)集合;
- Received:指在监听过程中捕获到的所有接收数据包的总和——既包括Answered里的响应包,也包括网络中无关的数据包(比如其他设备的广播包、非目标响应的报文等)。
三、如何访问Received数据包
默认的sr()/sr1()等函数确实只返回Answered和Remaining(Unanswered)集合,但你可以通过两种方式获取所有Received数据包:
方法1:结合sniff()函数捕获所有包
先启动嗅探,再发送数据包,最后收集所有捕获到的接收包:
from scapy.all import sniff, send, IP, ICMP # 超时5秒捕获所有数据包,store=True表示保存到内存 all_received = sniff(timeout=5, store=True) # 发送测试包(可以放在sniff之前,超时会自动结束捕获) send(IP(dst="8.8.8.8")/ICMP()) # 遍历查看所有Received数据包 for pkt in all_received: pkt.show()
方法2:自定义Session类记录接收包
通过继承默认Session类,重写包接收的方法来记录所有捕获到的包:
from scapy.all import sr, IP, ICMP, DefaultSession class CaptureAllSession(DefaultSession): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.all_received_pkts = [] # 用来存储所有接收的包 def on_packet_received(self, pkt): self.all_received_pkts.append(pkt) super().on_packet_received(pkt) # 保留原有的匹配逻辑 # 使用自定义Session执行发送操作 answered, unanswered = sr(IP(dst="8.8.8.8")/ICMP(), session=CaptureAllSession) # 从Session实例中获取所有Received数据包 all_received = answered.session.all_received_pkts for pkt in all_received: pkt.show()
如果你的当前函数(比如sr1())只返回单个Answered响应包,用上面的方法就能拿到所有接收的数据包啦。
内容的提问来源于stack exchange,提问作者Austin A
相关产品推荐
相关产品推荐

