From c58e3184e2940106d5bd880bfbe8a2efeeadd4c1 Mon Sep 17 00:00:00 2001 From: Phil <phil@secdev.org> Date: Sun, 8 Mar 2009 10:56:22 +0100 Subject: [PATCH] Ability to reference a packet's fields in another packet's fields description class Test(Packet): fields_desc = [ IntField("test1",0), SNAP, IntField("test2",1) ] >>> ls(SNAP) OUI : X3BytesField = (0) code : XShortEnumField = (0) >>> ls(Test) test1 : IntField = (0) OUI : X3BytesField = (0) code : XShortEnumField = (0) test2 : IntField = (1) --- scapy/base_classes.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/scapy/base_classes.py b/scapy/base_classes.py index 1a77642e..221ada6b 100644 --- a/scapy/base_classes.py +++ b/scapy/base_classes.py @@ -122,8 +122,35 @@ class OID(Gen): class Packet_metaclass(type): def __new__(cls, name, bases, dct): + if "fields_desc" in dct: # perform resolution of references to other packets + current_fld = dct["fields_desc"] + resolved_fld = [] + for f in current_fld: + if isinstance(f, Packet_metaclass): # reference to another fields_desc + for f2 in f.fields_desc: + resolved_fld.append(f2) + else: + resolved_fld.append(f) + else: # look for a field_desc in parent classes + resolved_fld = None + for b in bases: + if hasattr(b,"fields_desc"): + resolved_fld = b.fields_desc + break + + if resolved_fld: # perform default value replacements + final_fld = [] + for f in resolved_fld: + if f.name in dct: + f = f.copy() + f.default = dct[f.name] + del(dct[f.name]) + final_fld.append(f) + + dct["fields_desc"] = final_fld + newcls = super(Packet_metaclass, cls).__new__(cls, name, bases, dct) - for f in newcls.fields_desc: + for f in newcls.fields_desc: f.register_owner(newcls) config.conf.layers.register(newcls) return newcls -- GitLab