如何从套接字(AF_INET6、SOCK_RAW、IPPROTO_ICMPv6)的原始字节串创建 ICMPv6 scapy object?

How to create an ICMPv6 scapy object from raw bytestring from a socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPv6)?

我想 check/analyse 在 Python 程序中使用 Python ICMPv6 路由器通告 (RA),我在其中获得(并非如此)原始数据包数据如下:

import socket
sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_ICMPV6)
p, addr = sock.recvfrom(4096)

收到 ICMPv6 数据包时,数据包 p 将仅包含(!)ICMPv6 部分本身,而不包含任何其他外部元素,因此没有 IPv6 header,没有以太网 header , ...

如何从我的(不是这样)原始数据包数据创建正确的 Scapy ICMPv6 派生数据包 class? _ICMPv6 似乎只是后备 class。是否有某种工厂可以从中获得正确的子class(例如ICMPv6ND_RA)?

在 scapy 中从较低层(第二层或第三层)剖析数据包实际上更容易,因为剖析方法有多么不同。

你可以试试 hacky

a = IPv6(nh=58)
cls = a.default_payload_class(p)
pkt = cls(p)

阅读 Scapy 的源代码后 inet6.py 我注意到有更多 "direct" ——但不一定 "cleaner" —— 获取正确的 Scapy ICMPv6 消息对象的方法比Cukic0d 的回答很好:从某种意义上说,有一种替代方法不需要 "fake" 外部 IPv6 对象 shell(尽管我真的很欣赏 Cukic0d 的回答,因为它是转储的好地方发件人地址改成!):

from scapy.layers.inet6 import *

icmpv6_packet = icmp6typescls.get(p[0], ICMPv6Unknown)(p)

这使用 icmp6typescls 字典将 ICMPv6(消息)类型映射到其对应的 Scapy ICMPv6 消息 class .. .然后调用构造函数,将payload交给它。

当 ICMPv6(消息)类型无法映射到已知消息时,class ICMPv6Unknown 是 Scapy 默认使用的 class class。这确保始终有一个合理的构造函数被调用,即使我们不了解接收到的数据包的全部细节。