diff --git a/scapy/interfaces.py b/scapy/interfaces.py index f9dd76b0f72..70846b91be5 100644 --- a/scapy/interfaces.py +++ b/scapy/interfaces.py @@ -293,8 +293,11 @@ def dev_from_index(self, if_index): return self.dev_from_networkname(conf.loopback_name) raise ValueError("Unknown network interface index %r" % if_index) - def _add_fake_iface(self, ifname, mac="00:00:00:00:00:00"): - # type: (str, str) -> None + def _add_fake_iface(self, + ifname, + mac="00:00:00:00:00:00", + ips=["127.0.0.1", "::"]): + # type: (str, str, List[str]) -> None """Internal function used for a testing purpose""" data = { 'name': ifname, @@ -304,7 +307,7 @@ def _add_fake_iface(self, ifname, mac="00:00:00:00:00:00"): 'dummy': True, 'mac': mac, 'flags': 0, - 'ips': ["127.0.0.1", "::"], + 'ips': ips, # Windows only 'guid': "{%s}" % uuid.uuid1(), 'ipv4_metric': 0, diff --git a/scapy/layers/l2.py b/scapy/layers/l2.py index 532cd9a5f21..05bb6ba0c2b 100644 --- a/scapy/layers/l2.py +++ b/scapy/layers/l2.py @@ -1071,17 +1071,17 @@ def arping(net: str, hint = net[0] else: hint = str(net) - psrc = conf.route.route(hint, verbose=False)[1] - if psrc == "0.0.0.0": - if "iface" in kargs: - psrc = get_if_addr(kargs["iface"]) - else: - warning( - "No route found for IPv4 destination %s. " - "Using conf.iface. Please provide an 'iface' !" % hint) - psrc = get_if_addr(conf.iface) - hwaddr = get_if_hwaddr(conf.iface) - kargs["iface"] = conf.iface + psrc = conf.route.route( + hint, + dev=kargs.get("iface", None), + verbose=False, + _internal=True, # Do not follow default routes. + )[1] + if psrc == "0.0.0.0" and "iface" not in kargs: + warning( + "Could not find the interface for destination %s based on the routes. " + "Using conf.iface. Please provide an 'iface' !" % hint + ) ans, unans = srp( Ether(dst="ff:ff:ff:ff:ff:ff", src=hwaddr) / ARP( diff --git a/test/scapy/layers/l2.uts b/test/scapy/layers/l2.uts index 5f02bf991cd..1302d5e44f6 100644 --- a/test/scapy/layers/l2.uts +++ b/test/scapy/layers/l2.uts @@ -17,6 +17,40 @@ def _test(): retry_test(_test) += Arping - interface that has no ip +~ mock + +from unittest import mock + +_old_routes = conf.route.routes +_old_ifaces = conf.ifaces.data.copy() + +try: + conf.route.routes = [ + (180996905, 4294967295, '0.0.0.0', 'eth0', '10.201.203.41', 0), + (180997119, 4294967295, '0.0.0.0', 'eth0', '10.201.203.41', 0), + (0, 0, '10.201.203.254', 'eth0', '0.0.0.0', 0), + (180996864, 4294967040, '0.0.0.0', 'eth0', '10.201.203.41', 0), + (3758096384, 4026531840, '0.0.0.0', 'eth0', '10.201.203.41', 250) + ] + conf.ifaces._add_fake_iface("toto", mac="11:22:33:aa:bb:cc", ips=[]) + + def dummy_srp(pkts, **kwargs): + assert pkts.dst == "ff:ff:ff:ff:ff:ff" + assert pkts.src == "11:22:33:aa:bb:cc" + assert pkts[ARP].psrc == "0.0.0.0" + assert pkts[ARP].pdst == Net("192.168.0.1/24") + assert pkts[ARP].hwsrc == "11:22:33:aa:bb:cc" + # No results, we don't care. + return SndRcvList([]), PacketList(pkts) + + with mock.patch("scapy.layers.l2.srp", side_effect=dummy_srp): + arping("192.168.0.1/24", iface="toto") + +finally: + conf.route.routes = _old_routes + conf.ifaces.data = _old_ifaces + = Test ARPingResult output ~ manufdb