Разбор тегов PPPoE с помощью Scapy

Я пытаюсь правильно анализировать пакеты обнаружения PPPoE с помощью Scapy. Вот как Scapy отображает пример пакета PADI:

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

Я хочу проанализировать эту необработанную полезную нагрузку. Эта полезная нагрузка представляет собой просто список тегов PPPoE. Каждый тег состоит из двухбайтового поля кода, двухбайтового поля длины и значения (конечно, его длина задается предыдущим полем).

Это моя попытка представить все это:

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)

Не совсем уверен, что это правильный и лучший способ. Есть совет по улучшению?


person thor    schedule 04.01.2012    source источник
comment
На самом деле не стоит предоставлять это как ответ, поскольку он не относится конкретно к Scapy, но у dpkt немного другой подход, который может дать вам здесь некоторые идеи. code.google.com/p/dpkt/source/browse/trunk/dpkt/pppoe.py   -  person synthesizerpatel    schedule 05.01.2012
comment
Вы спрашиваете общий совет или у вас есть конкретный вопрос?   -  person Moshe    schedule 15.03.2013
comment
@Moshe: мой конкретный вопрос заключался в том, как правильно анализировать теги PPPoE с помощью Scapy. Но в итоге я перешел на разбор всей информации из пакета PPPoE вручную без каких-либо библиотек, так как это оказалось довольно просто.   -  person thor    schedule 15.03.2013


Ответы (2)


В моем собственном коде для аналогичной проблемы низкого уровня (анализ необработанного потока протокола последовательного порта с использованием разделителей информации на основе управляющего кода ASCII, таких как SOT, EOT, NULL, BELL и т. д.), я использовал набор регулярных выражений и стандартных компараторов. Это было легко структурировать в коде для понимания другими, а также довольно быстро, используя предварительно скомпилированные регулярные выражения.

Не садясь и не кодируя для него точный питон, если бы я хотел получить поля без добавления каких-либо несистемных зависимостей, я бы использовал что-то примерно похожее на этот псевдокод.

    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
person Techdragon    schedule 18.03.2013
comment
Примерно так я и поступил в итоге. В любом случае, принимая ваш ответ, чтобы закрыть этот вопрос. - person thor; 18.03.2013
comment
Теперь есть то, что вы не видите каждый день - принятый ответ с отрицательной оценкой - person Mawg says reinstate Monica; 10.02.2016

Вместо этого я бы сделал это, как и в случае реализации Scapy Dot11Elt (плюс он правильно понимает байты после тега End-Of-List как заполнение):

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)
person Pierre    schedule 24.01.2014