Skip to content

Commit 11832de

Browse files
authored
Travis cleanup / TunTap fixes / Mypy 3.9 (#3182)
* Use 3.9 for Mypy * Improve tuntap tests - Fix
1 parent cadc083 commit 11832de

File tree

10 files changed

+68
-65
lines changed

10 files changed

+68
-65
lines changed

.github/workflows/unittests.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ jobs:
4949
- name: Setup Python
5050
uses: actions/setup-python@v2
5151
with:
52-
python-version: 3.8
52+
python-version: 3.9
5353
- name: Install tox
5454
run: pip install tox
5555
- name: Run mypy

.travis.yml

-8
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,6 @@ jobs:
1414
env:
1515
- TOXENV=py38-isotp_kernel_module,codecov
1616

17-
# warnings/deprecations
18-
- os: linux
19-
python: 3.8
20-
env:
21-
- SCAPY_PY_OPTS="-Werror -X tracemalloc" TOXENV=py38-linux_root
22-
allow_failures:
23-
- env: SCAPY_PY_OPTS="-Werror -X tracemalloc" TOXENV=py38-linux_root
24-
2517
install:
2618
- bash .config/ci/install.sh
2719
- python -c "from scapy.all import conf; print(repr(conf))"

scapy/arch/__init__.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,13 @@
1313
from scapy.compat import orb
1414
from scapy.config import conf, _set_conf_sockets
1515
from scapy.consts import LINUX, SOLARIS, WINDOWS, BSD
16-
from scapy.data import ARPHDR_ETHER, ARPHDR_LOOPBACK, IPV6_ADDR_GLOBAL
16+
from scapy.data import (
17+
ARPHDR_ETHER,
18+
ARPHDR_LOOPBACK,
19+
ARPHDR_PPP,
20+
ARPHDR_TUN,
21+
IPV6_ADDR_GLOBAL
22+
)
1723
from scapy.error import Scapy_Exception
1824
from scapy.interfaces import NetworkInterface
1925
from scapy.pton_ntop import inet_pton, inet_ntop
@@ -72,7 +78,7 @@ def get_if_hwaddr(iff):
7278
Returns the MAC (hardware) address of an interface
7379
"""
7480
addrfamily, mac = get_if_raw_hwaddr(iff) # type: ignore # noqa: F405
75-
if addrfamily in [ARPHDR_ETHER, ARPHDR_LOOPBACK]:
81+
if addrfamily in [ARPHDR_ETHER, ARPHDR_LOOPBACK, ARPHDR_PPP, ARPHDR_TUN]:
7682
return str2mac(mac)
7783
else:
7884
raise Scapy_Exception("Unsupported address family (%i) for interface [%s]" % (addrfamily, iff)) # noqa: E501

scapy/arch/common.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def get_if_raw_hwaddr(iff, # type: Union[NetworkInterface, str]
8383
from scapy.arch import SIOCGIFHWADDR # type: ignore
8484
siocgifhwaddr = SIOCGIFHWADDR
8585
return struct.unpack( # type: ignore
86-
"16xh6s8x",
86+
"16xH6s8x",
8787
get_if(iff, siocgifhwaddr)
8888
)
8989

scapy/arch/linux.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ def get_alias_address(iface_name, # type: str
210210

211211
# Extract interfaces names
212212
out = struct.unpack("iL", ifreq)[0]
213-
names_b = names_ar.tobytes() if six.PY3 else names_ar.tostring()
213+
names_b = names_ar.tobytes() if six.PY3 else names_ar.tostring() # type: ignore # noqa: E501
214214
names = [names_b[i:i + offset].split(b'\0', 1)[0] for i in range(0, out, name_len)] # noqa: E501
215215

216216
# Look for the IP address

scapy/layers/tuntap.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ def __init__(self, iface=None, mode_tun=None, default_read_size=MTU,
186186
flags = LINUX_IFF_TAP | LINUX_IFF_NO_PI
187187

188188
tsetiff = raw(LinuxTunIfReq(
189-
ifrn_name=bytes_encode(self.iface),
189+
ifrn_name=self.iface,
190190
ifru_flags=flags))
191191

192192
ioctl(sock, LINUX_TUNSETIFF, tsetiff)
@@ -226,6 +226,7 @@ def recv_raw(self, x=None):
226226
return r
227227

228228
def send(self, x):
229+
# type: (Packet) -> int
229230
if hasattr(x, "sent_time"):
230231
x.sent_time = time.time()
231232

@@ -240,8 +241,9 @@ def send(self, x):
240241
sx = raw(x)
241242

242243
try:
243-
self.outs.write(sx)
244+
r = self.outs.write(sx)
244245
self.outs.flush()
246+
return r
245247
except socket.error:
246248
log_runtime.error("%s send",
247249
self.__class__.__name__, exc_info=True)

scapy/tools/UTscapy.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1079,7 +1079,7 @@ def main():
10791079
pass
10801080

10811081
if conf.use_pcap:
1082-
KW_KO.append("not_pcapdnet")
1082+
KW_KO.append("not_libpcap")
10831083
if VERB > 2:
10841084
print(" " + arrow + " libpcap mode")
10851085

scapy/utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ def corrupt_bytes(data, p=0.01, n=None):
10561056
n = max(1, int(s_len * p))
10571057
for i in random.sample(range(s_len), n):
10581058
s[i] = (s[i] + random.randint(1, 255)) % 256
1059-
return s.tostring() if six.PY2 else s.tobytes()
1059+
return s.tostring() if six.PY2 else s.tobytes() # type: ignore
10601060

10611061

10621062
@conf.commands.register
@@ -1072,7 +1072,7 @@ def corrupt_bits(data, p=0.01, n=None):
10721072
n = max(1, int(s_len * p))
10731073
for i in random.sample(range(s_len), n):
10741074
s[i // 8] ^= 1 << (i % 8)
1075-
return s.tostring() if six.PY2 else s.tobytes()
1075+
return s.tostring() if six.PY2 else s.tobytes() # type: ignore
10761076

10771077

10781078
#############################

test/sendsniff.uts

+1-1
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ else:
114114
############
115115
+ Test bridge_and_sniff() using tun sockets
116116

117-
~ tun not_pcapdnet
117+
~ tun not_libpcap
118118

119119
= Create two tun interfaces
120120

test/tuntap.uts

+49-46
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
#######
66
+ Test Linux-specific protocol headers for TunTap
7-
~ linux tun
7+
~ linux tun not_libpcap
88

99
= Linux-specific protocol headers
1010

@@ -26,7 +26,7 @@ assert isinstance(p.payload, IPv6)
2626
#######
2727
+ Test tun device
2828

29-
~ tun netaccess
29+
~ tun netaccess not_libpcap
3030

3131
= Create a tun interface
3232

@@ -47,32 +47,31 @@ elif BSD:
4747
else:
4848
raise NotImplementedError()
4949

50+
conf.ifaces.reload()
51+
conf.route.resync()
52+
conf.route6.resync()
53+
5054
= Setup ICMPEcho_am on the interface
5155

5256
am = tun0.am(ICMPEcho_am, count=3)
5357
am.defoptsniff['timeout'] = 5
5458
t_am = Thread(target=am)
5559
t_am.start()
56-
time.sleep(1)
5760

5861
= Send ping packets from OS into scapy
5962

60-
# ping returns non-zero exit code on 100% packet loss
61-
assert subprocess.check_call(["ping", "-c3", "192.0.2.2"]) == 0
63+
send(IP(dst="192.0.2.2")/ICMP(seq=(1,3)))
6264

6365
= Cleanup
6466

6567
t_am.join(timeout=3)
6668

6769
tun0.close()
68-
if not conf.use_pypy:
69-
# See https://pypy.readthedocs.io/en/latest/cpython_differences.html
70-
del tun0
7170

7271
#######
7372
+ Test strip_packet_info=False on Linux
7473

75-
~ tun linux netaccess
74+
~ tun linux netaccess not_libpcap
7675

7776
= Create a tun interface
7877

@@ -88,17 +87,18 @@ assert subprocess.check_call([
8887
"ip", "addr", "change",
8988
"192.0.2.1", "peer", "192.0.2.2", "dev", "tun0"]) == 0
9089

91-
= Send ping packets from Linux into Scapy
90+
conf.ifaces.reload()
91+
conf.route.resync()
92+
conf.route6.resync()
9293

93-
t = AsyncSniffer(opened_socket=tun0)
94-
t.start()
94+
= Send ping packets from Linux into Scapy
9595

96-
# We expect this to return exit code 1, because there's nothing in Scapy that
97-
# responds to these packets.
98-
assert subprocess.call(["ping", "-c3", "192.0.2.2"]) == 1
96+
def cb():
97+
send(IP(dst="192.0.2.2")/ICMP(seq=(1,3)))
9998

100-
time.sleep(1)
101-
t.stop()
99+
t = AsyncSniffer(opened_socket=tun0, lfilter=lambda x: IP in x, started_callback=cb, count=3)
100+
t.start()
101+
t.join(timeout=3)
102102

103103
assert len(t.results) >= 3
104104
icmp4_sequences = set()
@@ -118,13 +118,10 @@ assert len(icmp4_sequences) == 3
118118

119119
= Delete the tun interface
120120
tun0.close()
121-
if not conf.use_pypy:
122-
# See https://pypy.readthedocs.io/en/latest/cpython_differences.html
123-
del tun0
124121

125122
+ Test strip_packet_info=True and IPv6
126123

127-
~ tun netaccess ipv6
124+
~ tun netaccess ipv6 not_libpcap
128125

129126
= Create a tun interface with IPv4 + IPv6
130127

@@ -149,19 +146,19 @@ elif BSD:
149146
else:
150147
raise NotImplementedError()
151148

152-
= Send ping packets from OS into Scapy
149+
conf.ifaces.reload()
150+
conf.route.resync()
151+
conf.route6.resync()
153152

154-
t = AsyncSniffer(opened_socket=tun0)
155-
t.start()
153+
= Send ping packets from OS into Scapy
156154

157-
# There's nothing in Scapy that responds, but we expect the packets to be sent
158-
# successfully. Linux and BSD (incl. macOS) have different exit codes.
159-
EXPECTED_EXIT = 1 if LINUX else 2
160-
assert subprocess.call(["ping", "-c3", "192.0.2.2"]) == EXPECTED_EXIT
161-
assert subprocess.call(["ping6", "-c3", "2001:db8::2"]) == EXPECTED_EXIT
155+
def cb():
156+
send(IP(dst="192.0.2.2")/ICMP(seq=(1,3)))
157+
send(IPv6(dst="2001:db8::2")/ICMPv6EchoRequest(seq=(1,3)))
162158

163-
time.sleep(1)
164-
t.stop()
159+
t = AsyncSniffer(opened_socket=tun0, lfilter=lambda x: ICMP in x or ICMPv6EchoRequest in x, started_callback=cb, count=6)
160+
t.start()
161+
t.join(timeout=3)
165162

166163
assert len(t.results) >= 6
167164
icmp4_sequences = set()
@@ -187,13 +184,10 @@ assert len(icmp6_sequences) == 3, (
187184

188185
= Delete the tun interface
189186
tun0.close()
190-
if not conf.use_pypy:
191-
# See https://pypy.readthedocs.io/en/latest/cpython_differences.html
192-
del tun0
193187

194188
+ Test tap interfaces
195189

196-
~ tap netaccess
190+
~ tap netaccess not_libpcap
197191

198192
= Create a tap interface with IPv4
199193

@@ -215,18 +209,21 @@ else:
215209
assert subprocess.check_call([
216210
"arp", "-s", "192.0.2.2", "20:00:00:20:00:00", "temp"]) == 0
217211

212+
conf.ifaces.reload()
213+
conf.route.resync()
214+
conf.route6.resync()
215+
218216
= Send ping packets from OS into Scapy
219217

220-
t = AsyncSniffer(opened_socket=tap0)
221-
t.start()
218+
conf.ifaces
219+
conf.route
222220

223-
# There's nothing in Scapy that responds, but we expect the packets to be sent
224-
# successfully. Linux and BSD (incl. macOS) have different exit codes.
225-
EXPECTED_EXIT = 1 if LINUX else 2
226-
assert subprocess.call(["ping", "-c3", "192.0.2.2"]) == EXPECTED_EXIT
221+
def cb():
222+
sendp(Ether(dst="ff:ff:ff:ff:ff:ff")/IP(dst="192.0.2.2")/ICMP(seq=(1,3)), iface="tap0")
227223

228-
time.sleep(1)
229-
t.stop()
224+
t = AsyncSniffer(opened_socket=tap0, lfilter=lambda x: ICMP in x, started_callback=cb, count=3)
225+
t.start()
226+
t.join(timeout=3)
230227

231228
assert len(t.results) >= 3
232229
icmp4_sequences = set()
@@ -245,6 +242,12 @@ assert len(icmp4_sequences) == 3, (
245242

246243
= Delete the tap interface
247244
tap0.close()
248-
if not conf.use_pypy:
249-
# See https://pypy.readthedocs.io/en/latest/cpython_differences.html
250-
del tap0
245+
246+
+ Refresh interfaces
247+
~ linux tun tap not_libpcap
248+
249+
= Cleanup
250+
251+
conf.ifaces.reload()
252+
conf.route.resync()
253+
conf.route6.resync()

0 commit comments

Comments
 (0)