2010-11-11 14 views
12

Necesito saltear un paquete scapy. La mayoría de las veces esto funciona, pero a veces el recolector se queja de un objeto de función. Como regla general, los paquetes ARP son muy buenos. Algunos paquetes UDP son problemáticos.Cómo recortar un paquete escaso?

+0

fondo es el uso en combinación con el módulo 'multiprocessing'. Requiere que los objetos sean seleccionables si desea transferirlos a través de 'Queue'. –

+0

¿Podría alguien responder esta pregunta, así que puedo otorgar la recompensa? –

Respuesta

7

Mi solución (como se inspiró en la lista de correo scapy) es como sigue:

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 

en cualquier lugar que desee pasar un scapyPacket a través de un Queue simplemente lo envuelve en un PicklablePacket y __call__ se después. No estoy al tanto de los datos que no se conservan de esta manera. Sin embargo, este enfoque solo funciona con los paquetes Ethernet. (Todos los paquetes olfateados en una NIC regular (no WLAN) son Ethernet.) Probablemente también podría extenderse para funcionar para otros tipos.

+0

Gracias por publicar de nuevo. Si bien no necesitaba su solución exacta, me ayudó a encontrar la mía. –

3

(Esto es más de remisión, por lo que no califican espera) Lista

El Scapy [email protected] es bien supervisado y tiende a ser muy sensible. Si no obtiene respuestas aquí, intente allí también.

+0

Oh, ahí es donde la comunicación continúa? El rastreador de problemas parece bastante inactivo. Al menos uno de mis errores se quedó allí durante medio año sin ninguna respuesta. –

+1

como nota al margen, 500 paquetes por segundo podrían ser más que asas Scapy también. Está diseñado para la flexibilidad, no para la velocidad :) Pregunte en la lista.Realmente no lo uso mucho, así que no soy un experto. –

+0

De hecho, puedo confirmar que Scapy maneja muy bien 500 paquetes por segundo. De acuerdo, uso más de un hilo y (después de esta pregunta) más de un proceso. –

4

Si con pickle te refieres serializar genéricamente siempre puedes usar los métodos de importación/exportación pcap: rdpcap and wrpcap.

wrpcap("pkt.pcap",pkt) 
pkt = rdpcap("pkt.pcap") 

O podría iniciar su proceso y tomar los paquetes en otro proceso. Si hay algún patrón que puede coincidir, por ejemplo un puerto o fuente conocida tcpdump IP trabajarán:

tcpdump -i eth0 -w FOO.pcap host 172.20.33.12 and \(udp or arp\) 

A continuación, puede leer el PCAP generado en el anterior:

pkts = rdpcap('FOO.pcap') 
+0

1) Estoy hablando de 500 paquetes por segundo. –

+0

2) Este método en realidad pierde datos. Por ejemplo, la marca de tiempo se redondea. Esto no es necesariamente un problema, pero debe tenerse en cuenta. –

+0

¿Puede scapy incluso sacar 500 paquetes por segundo? Descubrí que al enviar paquetes es mucho menos que eso. Siempre puedes ejecutar un tcpdump en otra terminal. –

0

Usted puede monkeypatch la Packet class e inyectar los métodos __getstate__ y __setstate__ que convierten la función en el objeto desde y hacia una representación seleccionable. Vea here para más detalles.

def packet_getstate(self): 
    # todo 

def packet_setstate(self, state): 
    # todo 

from scapy.packet import Packet 
Packet.__getstate__ = packet_getstate 
Packet.__setstate__ = packet_setstate 
+1

Esto es algo obvio para mí. La parte no obvia es la parte de todo. –

+0

La inspección interactiva de un objeto 'Paquete 'que no funciona (' pprint.pprint (paquete .__ dict __)') mostraría fácilmente cuál es la función, si es una lambda, una función o un método de instancia. ¿Ya sabes qué tipo de función es? – piro

+0

El rastreo completo es demasiado largo para un comentario, pero puede reproducirlo usted mismo fácilmente. La última línea es: pickle.PicklingError: no se puede saltear en 0x8bb2bc4>: no se encuentra como scapy.layers.inet.

1

Como se inspiró en este question se puede usar la biblioteca dill (u otras como sPickle, etc. - ver pypi search pickle) para guardar los paquetes scapy. P.ej. Instale el eneldo usando sudo easy_install dill o sudo pip install dill. He aquí un escenario de uso básico:

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')) 

Uno puede también, por supuesto, sólo tiene que utilizar las funciones nativas de Scapy para volcar los paquetes a un archivo pcap (legibles por tcpdump/Wireshark etc) - Si sólo hay una serie de paquetes:

wrpcap("packets_array.pcap",packets_array) 
0

para obtener la clase PicklabePacket trabajar con scapy 3.0.0 se puede utilizar esta definición de clase:

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 
Cuestiones relacionadas