Skip to content

Commit 4296eee

Browse files
authored
arping(): handle scanning on a unknown IP (#4856)
1 parent 40cbcd2 commit 4296eee

File tree

3 files changed

+51
-14
lines changed

3 files changed

+51
-14
lines changed

scapy/interfaces.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,8 +293,11 @@ def dev_from_index(self, if_index):
293293
return self.dev_from_networkname(conf.loopback_name)
294294
raise ValueError("Unknown network interface index %r" % if_index)
295295

296-
def _add_fake_iface(self, ifname, mac="00:00:00:00:00:00"):
297-
# type: (str, str) -> None
296+
def _add_fake_iface(self,
297+
ifname,
298+
mac="00:00:00:00:00:00",
299+
ips=["127.0.0.1", "::"]):
300+
# type: (str, str, List[str]) -> None
298301
"""Internal function used for a testing purpose"""
299302
data = {
300303
'name': ifname,
@@ -304,7 +307,7 @@ def _add_fake_iface(self, ifname, mac="00:00:00:00:00:00"):
304307
'dummy': True,
305308
'mac': mac,
306309
'flags': 0,
307-
'ips': ["127.0.0.1", "::"],
310+
'ips': ips,
308311
# Windows only
309312
'guid': "{%s}" % uuid.uuid1(),
310313
'ipv4_metric': 0,

scapy/layers/l2.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,17 +1071,17 @@ def arping(net: str,
10711071
hint = net[0]
10721072
else:
10731073
hint = str(net)
1074-
psrc = conf.route.route(hint, verbose=False)[1]
1075-
if psrc == "0.0.0.0":
1076-
if "iface" in kargs:
1077-
psrc = get_if_addr(kargs["iface"])
1078-
else:
1079-
warning(
1080-
"No route found for IPv4 destination %s. "
1081-
"Using conf.iface. Please provide an 'iface' !" % hint)
1082-
psrc = get_if_addr(conf.iface)
1083-
hwaddr = get_if_hwaddr(conf.iface)
1084-
kargs["iface"] = conf.iface
1074+
psrc = conf.route.route(
1075+
hint,
1076+
dev=kargs.get("iface", None),
1077+
verbose=False,
1078+
_internal=True, # Do not follow default routes.
1079+
)[1]
1080+
if psrc == "0.0.0.0" and "iface" not in kargs:
1081+
warning(
1082+
"Could not find the interface for destination %s based on the routes. "
1083+
"Using conf.iface. Please provide an 'iface' !" % hint
1084+
)
10851085

10861086
ans, unans = srp(
10871087
Ether(dst="ff:ff:ff:ff:ff:ff", src=hwaddr) / ARP(

test/scapy/layers/l2.uts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,40 @@ def _test():
1717

1818
retry_test(_test)
1919

20+
= Arping - interface that has no ip
21+
~ mock
22+
23+
from unittest import mock
24+
25+
_old_routes = conf.route.routes
26+
_old_ifaces = conf.ifaces.data.copy()
27+
28+
try:
29+
conf.route.routes = [
30+
(180996905, 4294967295, '0.0.0.0', 'eth0', '10.201.203.41', 0),
31+
(180997119, 4294967295, '0.0.0.0', 'eth0', '10.201.203.41', 0),
32+
(0, 0, '10.201.203.254', 'eth0', '0.0.0.0', 0),
33+
(180996864, 4294967040, '0.0.0.0', 'eth0', '10.201.203.41', 0),
34+
(3758096384, 4026531840, '0.0.0.0', 'eth0', '10.201.203.41', 250)
35+
]
36+
conf.ifaces._add_fake_iface("toto", mac="11:22:33:aa:bb:cc", ips=[])
37+
38+
def dummy_srp(pkts, **kwargs):
39+
assert pkts.dst == "ff:ff:ff:ff:ff:ff"
40+
assert pkts.src == "11:22:33:aa:bb:cc"
41+
assert pkts[ARP].psrc == "0.0.0.0"
42+
assert pkts[ARP].pdst == Net("192.168.0.1/24")
43+
assert pkts[ARP].hwsrc == "11:22:33:aa:bb:cc"
44+
# No results, we don't care.
45+
return SndRcvList([]), PacketList(pkts)
46+
47+
with mock.patch("scapy.layers.l2.srp", side_effect=dummy_srp):
48+
arping("192.168.0.1/24", iface="toto")
49+
50+
finally:
51+
conf.route.routes = _old_routes
52+
conf.ifaces.data = _old_ifaces
53+
2054
= Test ARPingResult output
2155
~ manufdb
2256

0 commit comments

Comments
 (0)