From 5069fcff0b51e1797aeb69bce222d7bdb751e219 Mon Sep 17 00:00:00 2001 From: Pierre LALET <pierre.lalet@cea.fr> Date: Sat, 14 Jan 2017 14:30:14 +0100 Subject: [PATCH] Fix a bug in Source*Fields: p[layer].field != p.field A new test that triggers the bug (with ARPSourceMACField) has been added. --- scapy/layers/l2.py | 34 ++++++++++++++-------------------- scapy/packet.py | 8 +++++--- test/regression.uts | 6 ++++++ 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/scapy/layers/l2.py b/scapy/layers/l2.py index 0c68a4af..b26ff106 100644 --- a/scapy/layers/l2.py +++ b/scapy/layers/l2.py @@ -103,13 +103,17 @@ class DestMACField(MACField): return MACField.i2h(self, pkt, x) def i2m(self, pkt, x): return MACField.i2m(self, pkt, self.i2h(pkt, x)) - + + class SourceMACField(MACField): - def __init__(self, name): + __slots__ = ["getif"] + def __init__(self, name, getif=None): MACField.__init__(self, name, None) + self.getif = ((lambda pkt: pkt.payload.route()[0]) + if getif is None else getif) def i2h(self, pkt, x): if x is None: - iff, a, gw = pkt.payload.route() + iff = self.getif(pkt) if iff is None: iff = conf.iface if iff: @@ -122,25 +126,15 @@ class SourceMACField(MACField): return MACField.i2h(self, pkt, x) def i2m(self, pkt, x): return MACField.i2m(self, pkt, self.i2h(pkt, x)) - -class ARPSourceMACField(MACField): - def __init__(self, name): - MACField.__init__(self, name, None) - def i2h(self, pkt, x): - if x is None: - iff,a,gw = pkt.route() - if iff: - try: - x = get_if_hwaddr(iff) - except: - pass - if x is None: - x = "00:00:00:00:00:00" - return MACField.i2h(self, pkt, x) - def i2m(self, pkt, x): - return MACField.i2m(self, pkt, self.i2h(pkt, x)) +class ARPSourceMACField(SourceMACField): + def __init__(self, name): + super(ARPSourceMACField, self).__init__( + name, + getif=lambda pkt: pkt.route()[0], + ) + ### Layers diff --git a/scapy/packet.py b/scapy/packet.py index cd06247c..e2935ddb 100644 --- a/scapy/packet.py +++ b/scapy/packet.py @@ -186,10 +186,12 @@ class Packet(BasePacket): return self.get_field(attr),self.overloaded_fields[attr] if attr in self.default_fields: return self.get_field(attr),self.default_fields[attr] - return self.payload.getfield_and_val(attr) - + def __getattr__(self, attr): - fld,v = self.getfield_and_val(attr) + try: + fld, v = self.getfield_and_val(attr) + except TypeError: + return self.payload.__getattr__(attr) if fld is not None: return fld.i2h(self, v) return v diff --git a/test/regression.uts b/test/regression.uts index 9f2e5f30..2ab4eeaf 100644 --- a/test/regression.uts +++ b/test/regression.uts @@ -246,6 +246,12 @@ assert( _ == ("ABCD","c0:01:be:ef:ba:be") ) m.addfield(None, "FOO", "c0:01:be:ef:ba:be") assert( _ == "FOO\xc0\x01\xbe\xef\xba\xbe" ) += SourceMACField, ARPSourceMACField +conf.route.add(net="1.2.3.4/32", dev=conf.iface) +p = Ether() / ARP(pdst="1.2.3.4") +assert p.src == p.hwsrc == p[ARP].hwsrc == get_if_hwaddr(conf.iface) +conf.route.delt(net="1.2.3.4/32") + = IPField class ~ core field i = IPField("foo", None) -- GitLab