11

Scapyを使用してPPPoEディスカバリパケットを正しく分析しようとしています。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タグです。各タグは、2バイトのコードフィールド、2バイトの長さのフィールド、および値(もちろん、前のフィールドで指定された長さ)で構成されます。

これは、これらすべてを表現するための私の試みです。

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)

それが正しい最善の方法であるかどうかはよくわかりません。改善に関するアドバイスはありますか?

4

2 に答える 2

1

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)
于 2014-01-24T13:55:55.013 に答える
-1

同様に低レベルの問題(SOT、EOT、NULL、BELLなどのASCII制御コードベースの情報区切り文字を使用してシリアルポートプロトコルの生ストリームを解析する)の独自のコードでは、正規表現と標準コンパレータのセットを使用しました。他の人が理解できるようにコードを構造化するのは簡単で、プリコンパイルされた正規表現を使用するのも非常に迅速でした。

座って正確なpythonをコーディングせずに、システム以外の依存関係を追加せずにフィールドを取得したい場合は、おおよそこの擬似コードのようなものを使用します。

    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
于 2013-03-18T03:56:15.713 に答える