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