[scapy]: Patch scapy 2.4.5 for sniffing on intfs (#10644)

Apply scapy fix (https://github.com/secdev/scapy/pull/3240) since it is not available in release yet

Signed-off-by: Lawrence Lee <lawlee@microsoft.com>
This commit is contained in:
Lawrence Lee 2022-05-18 13:01:27 -07:00 committed by Qi Luo
parent e659cfb2de
commit 5205a379e4
2 changed files with 113 additions and 0 deletions

View File

@ -0,0 +1,112 @@
From 430f8942fe086553fcd6ad1444e886a343bfd658 Mon Sep 17 00:00:00 2001
From: Guillaume Valadon <guillaume@valadon.net>
Date: Mon, 10 May 2021 12:02:32 +0200
Subject: [PATCH] Do not resolve the interface name globally
---
doc/scapy/usage.rst | 2 ++
scapy/sendrecv.py | 16 ++++++++--------
test/regression.uts | 31 +++++++++++++++++++++++++++++--
3 files changed, 39 insertions(+), 10 deletions(-)
diff --git a/doc/scapy/usage.rst b/doc/scapy/usage.rst
index 45266430fe..c6cb273f62 100644
--- a/doc/scapy/usage.rst
+++ b/doc/scapy/usage.rst
@@ -711,6 +711,8 @@ We can sniff and do passive OS fingerprinting::
The number before the OS guess is the accuracy of the guess.
+.. note:: When sniffing on several interfaces (e.g. ``iface=["eth0", ...]``), you can check what interface a packet was sniffed on by using the ``sniffed_on`` attribute, as shown in one of the examples above.
+
Asynchronous Sniffing
---------------------
diff --git a/scapy/sendrecv.py b/scapy/sendrecv.py
index 503c6a3b15..f97fc4153e 100644
--- a/scapy/sendrecv.py
+++ b/scapy/sendrecv.py
@@ -1108,24 +1108,24 @@ def _run(self,
quiet=quiet)
)] = offline
if not sniff_sockets or iface is not None:
- iface = resolve_iface(iface or conf.iface)
- if L2socket is None:
- L2socket = iface.l2listen()
+ # The _RL2 function resolves the L2socket of an iface
+ _RL2 = lambda i: L2socket or resolve_iface(i).l2listen() # type: Callable[[_GlobInterfaceType], Callable[..., SuperSocket]] # noqa: E501
if isinstance(iface, list):
sniff_sockets.update(
- (L2socket(type=ETH_P_ALL, iface=ifname, **karg),
+ (_RL2(ifname)(type=ETH_P_ALL, iface=ifname, **karg),
ifname)
for ifname in iface
)
elif isinstance(iface, dict):
sniff_sockets.update(
- (L2socket(type=ETH_P_ALL, iface=ifname, **karg),
+ (_RL2(ifname)(type=ETH_P_ALL, iface=ifname, **karg),
iflabel)
for ifname, iflabel in six.iteritems(iface)
)
else:
- sniff_sockets[L2socket(type=ETH_P_ALL, iface=iface,
- **karg)] = iface
+ iface = iface or conf.iface
+ sniff_sockets[_RL2(iface)(type=ETH_P_ALL, iface=iface,
+ **karg)] = iface
# Get select information from the sockets
_main_socket = next(iter(sniff_sockets))
@@ -1248,7 +1248,7 @@ def stop(self, join=True):
return self.results
return None
else:
- raise Scapy_Exception("Not started !")
+ raise Scapy_Exception("Not running ! (check .running attr)")
def join(self, *args, **kwargs):
# type: (*Any, **Any) -> None
diff --git a/test/regression.uts b/test/regression.uts
index 38644b7d75..972af2f8cd 100644
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -1379,9 +1379,36 @@ def _test():
assert (ans.time - req.sent_time) >= 0
assert (ans.time - req.sent_time) <= 1e-3
-retry_test(_test)
+try:
+ retry_test(_test)
+finally:
+ conf.L3socket = sock
+
+= Test sniffing on multiple sockets
+~ netaccess needs_root sniff
+
+# This test sniffs on the same interface twice at the same time, to
+# simulate sniffing on multiple interfaces.
+
+iface = conf.route.route("www.google.com")[0]
+port = int(RandShort())
+pkt = IP(dst="www.google.com")/TCP(sport=port, dport=80, flags="S")
+
+def cb():
+ sr1(pkt, timeout=3)
+
+sniffer = AsyncSniffer(started_callback=cb,
+ iface=[iface, iface],
+ lfilter=lambda x: TCP in x and x[TCP].dport == port,
+ prn=lambda x: x.summary(),
+ count=2)
+sniffer.start()
+sniffer.join(timeout=3)
+
+assert len(sniffer.results) == 2
-conf.L3socket = sock
+for pkt in sniffer.results:
+ assert pkt.sniffed_on == iface
= Sending a TCP syn 'forever' at layer 2 and layer 3
~ netaccess IP

View File

@ -1,2 +1,3 @@
0001-Fix-version-string-generation-when-scapy-is-a-submod.patch
0002-Check-if-the-network-interface-still-exists.patch
0003-Do-not-resolve-the-interface-name-globally.patch