Scapy help ?
Hi any scapy aficionados here?
I'm having an issue, I had created a new layer to decode some ipfix packets ages ago in scapy 1.x I think it was at the time. Using python 2.x. This still works but I'm trying to get it to work in python 3.9 using the latest scapy libraries and I am having an issue.
The basic code snippet is below.
Example in Python 2.x:
# p is a string of bytes
IPFIXHeader(p)
result:
<IPFIXHeader version=10 length=556 exportTime=1657194691 sequenceNumber=15 observationDomainId=20054017 sets=[<SetHeader setID=2 setLength=224 records=[ etc..... it's quite long so chopped for brevity.
Example in Python 3.x
IPFIXHeader(p)
result:
<IPFIXHeader version=10 length=556 exportTime=1657194691 sequenceNumber=15 observationDomainId=20054017 sets=[<Raw load='\x00\x02\x00\\x etc..... it's quite long so chopped for brevity.
It seems it doesn't continue on and process the next chunk as it should in 3.x
class SetHeader(Packet):
name = "Set Header"fields_desc = [ ShortField("setID", 0),
FieldLenField("setLength", None, length_of="records"),
PacketListField("records", None, None, length_from=lambda pkt:pkt.setLength-4) ]
def extract_padding(self, s):
return "", s
def do_dissect(self, s):
flist = self.fields_desc[:]
flist.reverse()
while s and flist:
f = flist.pop()
s,fval = f.getfield(self, s)
self.fields[f.name] = fval
if f.name == "setID":
if fval == 2:
print("Should call TemplateHeader", flush=True)
max(flist).cls = TemplateHeader
class TemplateHeader(Packet):
name = "Template Header"
fields_desc = [ ShortField("templateID", 1000),
ShortField("fieldCount", 21) ]
def guess_payload_class(self, payload):
print("I am in the TemplateHeader Now", flush=True)
if (self.templateID >= 1000 and self.templateID <= 1999):
return VolumeTemplate
class IPFIXHeader(Packet):
name = "IPFIX Header"
fields_desc = [ ShortField("version", 10),
FieldLenField("length",None, length_of="sets"),
IntField("exportTime", 0),
IntField("sequenceNumber", 0),
IntField("observationDomainId", 0),
PacketListField("sets",None, SetHeader, length_from=lambda pkt:pkt.length-16) ]
def post_build(self, p, pay):
if self.length is None:
l = len(p)+len(pay)
p = p[:2]+struct.pack("!H", l)+p[4:]
return p+pay
def extract_padding(self, s):
return "", s