Разбор тегов PPPoE с помощью Scapy - PullRequest
11 голосов
/ 04 января 2012

Я пытаюсь правильно анализировать пакеты обнаружения 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'

Я хочу проанализировать эту полезную нагрузку Raw.Эта полезная нагрузка представляет собой список тегов 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)

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

Ответы [ 2 ]

1 голос
/ 24 января 2014

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

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)
0 голосов
/ 18 марта 2013

В своем собственном коде для аналогичной проблемы низкого уровня (анализ необработанного потока протокола последовательного порта с использованием разделителей информации на основе кода управления 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
...