Мне нужно замариновать scapy
пакет. В большинстве случаев это работает, но иногда сборщик жалуется на объект функции. Эмпирическое правило: пакеты ARP хорошо травятся. Некоторые пакеты UDP вызывают проблемы.
Как замариновать скапи пакет?
Ответы (6)
Мое решение (вдохновленное списком рассылки scapy) выглядит следующим образом:
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.) Вероятно, его можно было бы расширить для работы и с другими типами.
Если под pickle вы подразумеваете общую сериализацию, вы всегда можете использовать методы импорта/экспорта pcap: rdpcap и вркап.
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')
threading
вместо multiprocessing
и вообще не пришлось бы травить.
- person Helmut Grohne; 07.12.2010
(Это больше для справки, поэтому голосов не ожидается)
Список Scapy [email protected] хорошо контролируется и, как правило, очень отзывчив. Если вы не получили ответы здесь, попробуйте и там.
Вдохновленный этим вопросом, можно использовать 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 для сброса пакетов в файл pcap (доступный для чтения tcpdump/wireshark и т. д.) - если у вас просто есть массив пакетов:
wrpcap("packets_array.pcap",packets_array)
Вы можете изменить класс Packet
и внедрить методы __getstate__
и __setstate__
, которые преобразуют функцию в объекте из и в доступное для выбора представление. Подробнее см. здесь.
def packet_getstate(self):
# todo
def packet_setstate(self, state):
# todo
from scapy.packet import Packet
Packet.__getstate__ = packet_getstate
Packet.__setstate__ = packet_setstate
Packet
, который не прошел травление (pprint.pprint(packet.__dict__)
), легко покажет, что это за функция, будь то лямбда, функция или метод экземпляра. Вы уже знаете, что это за функция?
- person piro; 24.11.2010
Чтобы заставить класс 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
multiprocessing
. Он требует, чтобы объекты были доступны для обработки, если вы хотите передать их черезQueue
. - person Helmut Grohne   schedule 16.11.2010