Мне нужно разжечь пакет scapy
. Большую часть времени это работает, но иногда pickler жалуется на объект функции. Как правило: ARP-пакеты хорошо разборчивы. Некоторые пакеты UDP являются проблематичными.
Как рассортировать scapy-пакет?
Ответ 1
Мое решение (как вдохновлено скопированным списком рассылки) выглядит следующим образом:
class PicklablePacket:
"""A container for scapy packets that can be pickled (in contrast
to scapy packets themselves)."""
def __init__(self, pkt):
self.contents = bytes(pkt)
self.time = pkt.time
def __call__(self):
"""Get the original scapy packet."""
pkt = scapy.Ether(self.contents)
pkt.time = self.time
return pkt
В любом месте, где я хочу передать scapy
Packet
через Queue
, я просто переношу его в PicklablePacket
и __call__
после этого. Я не знаю данных, которые не сохраняются таким образом. Однако этот подход работает только с пакетами Ethernet
. (Все пакеты, принюхиваемые на обычном сетевом адаптере (не WLAN), являются Ethernet.) Вероятно, он может быть расширен и для других типов.
Ответ 2
Если с помощью pickle вы имеете в виду обобщенную сериализацию, вы всегда можете использовать методы импорта/экспорта pcap: rdpcap и wrpcap.
wrpcap("pkt.pcap",pkt)
pkt = rdpcap("pkt.pcap")
Или вы можете запустить свой процесс и захватить пакеты в другом процессе. Если есть какой-то шаблон, который вы можете сопоставить, скажем, известный порт или источник IP tcpdump будет работать:
tcpdump -i eth0 -w FOO.pcap host 172.20.33.12 and \(udp or arp\)
Затем вы можете прочитать сгенерированный файл pcap, как указано выше:
pkts = rdpcap('FOO.pcap')
Ответ 3
(Это больше для справки, поэтому ожидаемых голосов не было)
Список Scapy [email protected] хорошо контролируется и, как правило, очень отзывчив. Если вы не получите ответы здесь, попробуйте также.
Ответ 4
Вдохновленный этим question, можно использовать dill (или другие, такие как sPickle и т.д. - см. pypi search pickle) для сохранения scapy-пакетов. Например. Установите укроп с помощью sudo easy_install dill
или sudo pip install dill
. Вот базовый сценарий использования:
import dill as pickle
# E.g. Dump an array of packets stored in variable mypackets to a file
pickle.dump(mypackets, open('mypackets.dill-pickle', 'w'))
# Restore them from the file
mypackets = pickle.load(open('mypackets.dill-pickle', 'rb'))
Кроме того, можно, конечно, просто использовать scapy native функции, чтобы сбрасывать пакеты в файл pcap (читаемый tcpdump/wireshark и т.д.) - если у вас есть только массив пакетов:
wrpcap("packets_array.pcap",packets_array)
Ответ 5
Вы можете обезвредить класс Packet
и вставить методы __getstate__
и __setstate__
, которые преобразуют функцию в объект из и в представление picklable. Подробнее см. здесь.
def packet_getstate(self):
# todo
def packet_setstate(self, state):
# todo
from scapy.packet import Packet
Packet.__getstate__ = packet_getstate
Packet.__setstate__ = packet_setstate
Ответ 6
Чтобы получить класс PicklabePacket для работы с scapy 3.0.0, вы можете использовать это определение класса:
class PicklablePacket:
"""A container for scapy packets that can be pickled (in contrast
to scapy packets themselves).
This works for python 3.5.1 and scapy 3.0.0 """
def __init__(self, pkt):
self.__contents = pkt.__bytes__()
self.__time = pkt.time
def __call__(self):
"""Get the original scapy packet."""
pkt = scapy.all.Ether(self.__contents)
pkt.time = self.__time
return pkt