2012-01-04 12 views
11

Estoy tratando de analizar correctamente los paquetes de PPPoE Discovery con Scapy. Así es como Scapy muestra el paquete PADI de ejemplo:Analizando etiquetas PPPoE con Scapy

>>> p = Ether("\xff\xff\xff\xff\xff\xff\x08\x00'\xf3<5\x88c\x11\t\x00\x00\x00\x0c\x01\x01\x00\x00\x01\x03\x00\x04\xe0\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") 
>>> p.show() 
###[ Ethernet ]### 
    dst= ff:ff:ff:ff:ff:ff 
    src= 08:00:27:f3:3c:35 
    type= 0x8863 
###[ PPP over Ethernet Discovery ]### 
    version= 1L 
    type= 1L 
    code= PADI 
    sessionid= 0x0 
    len= 12 
###[ Raw ]### 
     load= '\x01\x01\x00\x00\x01\x03\x00\x04\xe0\x07\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 

Quiero analizar esa carga bruta. Esta carga útil es solo una lista de etiquetas PPPoE. Cada etiqueta consta de un campo de código de dos bytes, un campo de dos bytes de longitud y un valor (por supuesto, es la longitud dada por el campo anterior).

Este es mi intento de representación de todo esto:

from scapy.all import * 

class PPPoETag(Packet): 
    name = "PPPoE Tag" 
    fields_desc = [ ShortEnumField('tag_type', None, 
            {0x0000: 'End-Of-List', 
            0x0101: 'Service-Name', 
            0x0102: 'AC-Name', 
            0x0103: 'Host-Uniq', 
            0x0104: 'AC-Cookie', 
            0x0105: 'Vendor-Specific', 
            0x0110: 'Relay-Session-Id', 
            0x0201: 'Service-Name-Error', 
            0x0202: 'AC-System-Error', 
            0x0203: 'Generic-Error'}), 
        FieldLenField('tag_len', None, length_of='tag_value', fmt='H'), 
        StrLenField('tag_value', '', length_from=lambda pkt:pkt.tag_len)] 
    def extract_padding(self, s): 
     return '', s 

class PPPoED_Tags(Packet): 
    name = "PPPoE Tag List" 
    fields_desc = [ PacketListField('tag_list', None, PPPoETag) ] 

bind_layers(PPPoED, PPPoED_Tags, type=1) 

No estoy seguro de si es el correcto y mejor manera. ¿Algún consejo para mejorar?

+1

No merece la pena manera que esto sea una respuesta, ya que doesn No se aplica específicamente a Scapy, pero dpkt tiene un enfoque ligeramente diferente que podría brindarle algunas ideas aquí. http://code.google.com/p/dpkt/source/browse/trunk/dpkt/pppoe.py – synthesizerpatel

+1

¿Estás pidiendo un consejo general o tienes una pregunta específica? – Moshe

+0

@Moshe: mi pregunta específica era cómo analizar correctamente las etiquetas PPPoE con Scapy. Pero al final he cambiado a analizar toda la información del paquete PPPoE manualmente sin ninguna biblioteca, ya que resulta bastante simple. – thor

Respuesta

-1

En mi propio código para un problema de nivel similar (analizar el flujo de puerto en serie mediante el código de control ASCII basado en delimitadores de información como SOT, EOT, NULL, BELL, etc.) utilicé un conjunto de expresiones regulares y estándar comparadores. Fue fácil estructurar en el código para la comprensión de otros, y también bastante rápido utilizando las expresiones regulares precompiladas.

Sin sentarse & codificando el pitón exacto para ello, si quisiera obtener los campos sin agregar ninguna dependencia del sistema, Id usar algo más o menos como este pseudocódigo.

Start Loop over packet content. 
     Match any Tag 
      Match specific tag type 
       set array index based on tag type 
      extract length of value 
      extract tag value 
      store value in array at the index set above 
      slice off all the entire now matched & extracted tag. 
     Loop until end no more tags match. 
    End of loop 
+0

Eso es más o menos cómo lo hice al final. De todos modos, acepte su respuesta para cerrar esta pregunta. – thor

+0

Ahora, hay algo que no ves todos los días: una respuesta aceptada con un puntaje negativo – Mawg

1

Me gustaría hacer esto en su lugar, al igual que con la implementación Dot11Elt de Scapy (además de que entiende correctamente bytes después End-Of-List etiqueta como relleno):

class PPPoE_Tag(Packet): 
    name = "PPPoE Tag" 
    fields_desc = [ ShortEnumField('tag_type', None, 
            {0x0000: 'End-Of-List', 
            0x0101: 'Service-Name', 
            0x0102: 'AC-Name', 
            0x0103: 'Host-Uniq', 
            0x0104: 'AC-Cookie', 
            0x0105: 'Vendor-Specific', 
            0x0110: 'Relay-Session-Id', 
            0x0201: 'Service-Name-Error', 
            0x0202: 'AC-System-Error', 
            0x0203: 'Generic-Error'}), 
        FieldLenField('tag_len', None, length_of='tag_value', fmt='H'), 
        StrLenField('tag_value', '', length_from=lambda pkt:pkt.tag_len)] 

bind_layers(PPPoED, PPPoE_Tag, type=1) 
bind_layers(PPPoE_Tag, Padding, tag_type=0) 
bind_layers(PPPoE_Tag, PPPoE_Tag)