I am trying to correctly dissect PPPoE Discovery packets with Scapy. Here's how Scapy displays example PADI packet:
>>> 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'
I want to parse that Raw payload. This payload is just a list PPPoE tags. Each tags consists of two byte code field, two byte length field and a value (it's length given by previous field, of course).
This is my attempt at representing all this:
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)
Not quite sure if it's the right and best way. Any advice on improving?
I would do this instead, just like with Scapy's Dot11Elt implementation (plus it correctly understands bytes after End-Of-List
tag as 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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With