diff --git a/scapy/layers/l2.py b/scapy/layers/l2.py index 0c68a4af0097132878bef96a981cbb028d000b2a..b26ff106b90580cb5853a282aaec881cad4f5684 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 cd06247c7086781002202b068add7df1c1174e1d..e2935ddb9fbe1baa2fdd4863a0bf9e1c98484a42 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 9f2e5f308536b5881ff28b0cb1eaf73eea0f929c..2ab4eeaf906955336a17a0ac8a7630b5e85fd6bd 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)