Как создать scapy-объект ICMPv6 из необработанной тестовой строки из сокета (AF_INET6, SOCK_RAW, IPPROTO_ICMPv6)?
Я хочу проверить / проанализировать объявления маршрутизаторов ICMPv6 (RA) в программе Python, использующей Python, где я получаю (не очень) необработанные пакетные данные следующим образом:
import socket
sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW, socket.IPPROTO_ICMPV6)
p, addr = sock.recvfrom(4096)
Когда пакет ICMPv6 будет получен, пакет p будет содержать только (!) Саму часть ICMPv6, но не любые другие внешние элементы, поэтому нет заголовка IPv6, заголовка Ethernet, ...
Как мне создать правильный класс пакетов, полученный из Scapy ICMPv6, из моих (не очень) необработанных пакетных данных? _ICMPv6
кажется, просто запасной класс. Есть ли какая-то фабрика, чтобы получить правильный подкласс (такой как ICMPv6ND_RA
) от?
2 ответа
Прочитав исходный код inet6.py в Scapy, я заметил, что есть более "прямой", но не обязательно "чистый" способ получения правильного объекта сообщения Scapy ICMPv6, чем точный ответ Cukic0d: в том смысле, что есть альтернативный способ, который не требует "поддельной" внешней оболочки объекта IPv6 (хотя я действительно ценю ответ Cukic0d, так как это было бы хорошим местом для выгрузки адреса отправителя!):
from scapy.layers.inet6 import *
icmpv6_packet = icmp6typescls.get(p[0], ICMPv6Unknown)(p)
Это использует icmp6typescls
словарь отображает тип ICMPv6 (сообщения), который находится в первом октете пакета, возвращенного из сокета, в соответствующий класс сообщений Scapy ICMPv6... и затем вызывает конструктор, передавая ему полезную нагрузку.
Класс ICMPv6Unknown
это класс по умолчанию, используемый Scapy, когда тип ICMPv6 (сообщения) не может быть сопоставлен с известным классом сообщений. Это гарантирует, что всегда будет разумный конструктор для вызова, даже если мы не понимаем пакет, полученный в его полных деталях.
Обычно в scapy проще рассекать пакет из нижнего уровня (второго или третьего) из-за того, насколько разными могут быть методы рассечения.
Вы можете попробовать взломать
a = IPv6(nh=58)
cls = a.default_payload_class(p)
pkt = cls(p)