Lines 1-171
Link Here
|
1 |
From 5ff17673eec7fc200a16552e3686015e99d10b5e Mon Sep 17 00:00:00 2001 |
|
|
2 |
From: Pierre LALET <pierre.lalet@cea.fr> |
3 |
Date: Tue, 16 Apr 2019 16:08:15 +0200 |
4 |
Subject: [PATCH 1/2] BPF: fix get_working_ifaces() |
5 |
|
6 |
It was broken when an interface name did not end by a digit. |
7 |
|
8 |
It was also incorrect when an interface name ended by more than one |
9 |
digit. |
10 |
--- |
11 |
scapy/arch/bpf/core.py | 46 ++++++++++++++++++++++++------------------ |
12 |
test/bpf.uts | 6 ++---- |
13 |
2 files changed, 28 insertions(+), 24 deletions(-) |
14 |
|
15 |
diff --git scapy/arch/bpf/core.py scapy/arch/bpf/core.py |
16 |
index cc4732f52..4c9e9470a 100644 |
17 |
--- scapy/arch/bpf/core.py |
18 |
+++ scapy/arch/bpf/core.py |
19 |
@@ -5,22 +5,22 @@ |
20 |
""" |
21 |
|
22 |
from __future__ import absolute_import |
23 |
-from scapy.config import conf |
24 |
-from scapy.error import Scapy_Exception, warning |
25 |
-from scapy.data import ARPHDR_LOOPBACK, ARPHDR_ETHER |
26 |
-from scapy.arch.common import get_if, compile_filter |
27 |
-from scapy.consts import LOOPBACK_NAME |
28 |
- |
29 |
-from scapy.arch.bpf.consts import BIOCSETF, SIOCGIFFLAGS, BIOCSETIF |
30 |
|
31 |
+from ctypes import cdll, cast, pointer |
32 |
+from ctypes import c_int, c_ulong, c_char_p |
33 |
+from ctypes.util import find_library |
34 |
+import fcntl |
35 |
import os |
36 |
+import re |
37 |
import socket |
38 |
-import fcntl |
39 |
import struct |
40 |
|
41 |
-from ctypes import cdll, cast, pointer |
42 |
-from ctypes import c_int, c_ulong, c_char_p |
43 |
-from ctypes.util import find_library |
44 |
+from scapy.arch.bpf.consts import BIOCSETF, SIOCGIFFLAGS, BIOCSETIF |
45 |
+from scapy.arch.common import get_if, compile_filter |
46 |
+from scapy.config import conf |
47 |
+from scapy.consts import LOOPBACK_NAME |
48 |
+from scapy.data import ARPHDR_LOOPBACK, ARPHDR_ETHER |
49 |
+from scapy.error import Scapy_Exception, warning |
50 |
from scapy.modules.six.moves import range |
51 |
|
52 |
|
53 |
@@ -126,6 +126,9 @@ def get_if_list(): |
54 |
return interfaces |
55 |
|
56 |
|
57 |
+_IFNUM = re.compile("([0-9]*)([ab]?)$") |
58 |
+ |
59 |
+ |
60 |
def get_working_ifaces(): |
61 |
""" |
62 |
Returns an ordered list of interfaces that could be used with BPF. |
63 |
@@ -156,24 +159,27 @@ def get_working_ifaces(): |
64 |
if ifflags & 0x1: # IFF_UP |
65 |
|
66 |
# Get a BPF handle |
67 |
- fd, _ = get_dev_bpf() |
68 |
+ fd = get_dev_bpf()[0] |
69 |
if fd is None: |
70 |
raise Scapy_Exception("No /dev/bpf are available !") |
71 |
|
72 |
# Check if the interface can be used |
73 |
try: |
74 |
- fcntl.ioctl(fd, BIOCSETIF, struct.pack("16s16x", ifname.encode())) # noqa: E501 |
75 |
- interfaces.append((ifname, int(ifname[-1]))) |
76 |
+ fcntl.ioctl(fd, BIOCSETIF, struct.pack("16s16x", |
77 |
+ ifname.encode())) |
78 |
except IOError: |
79 |
pass |
80 |
- |
81 |
- # Close the file descriptor |
82 |
- os.close(fd) |
83 |
+ else: |
84 |
+ ifnum, ifab = _IFNUM.search(ifname).groups() |
85 |
+ interfaces.append((ifname, int(ifnum) if ifnum else -1, ifab)) |
86 |
+ finally: |
87 |
+ # Close the file descriptor |
88 |
+ os.close(fd) |
89 |
|
90 |
# Sort to mimic pcap_findalldevs() order |
91 |
- interfaces.sort(key=lambda elt: elt[1]) |
92 |
+ interfaces.sort(key=lambda elt: (elt[1], elt[2], elt[0])) |
93 |
|
94 |
- return interfaces |
95 |
+ return [iface[0] for iface in interfaces] |
96 |
|
97 |
|
98 |
def get_working_if(): |
99 |
@@ -183,4 +189,4 @@ def get_working_if(): |
100 |
if not ifaces: |
101 |
# A better interface will be selected later using the routing table |
102 |
return LOOPBACK_NAME |
103 |
- return ifaces[0][0] |
104 |
+ return ifaces[0] |
105 |
diff --git test/bpf.uts test/bpf.uts |
106 |
index 19e06bb14..45d36fd83 100644 |
107 |
--- test/bpf.uts |
108 |
+++ test/bpf.uts |
109 |
@@ -47,12 +47,10 @@ len(iflist) > 0 |
110 |
= Get working network interfaces |
111 |
~ needs_root |
112 |
|
113 |
-from scapy.arch.bpf.core import get_working_ifaces |
114 |
+from scapy.arch.bpf.core import get_working_if, get_working_ifaces |
115 |
ifworking = get_working_ifaces() |
116 |
assert len(ifworking) |
117 |
- |
118 |
-from scapy.arch.bpf.core import get_working_if |
119 |
-assert len(ifworking) and get_working_if() == ifworking[0][0] |
120 |
+assert get_working_if() == ifworking[0] |
121 |
|
122 |
|
123 |
= Misc functions |
124 |
|
125 |
From afa5776ecf83f7a427fc1af763005fe249f450f9 Mon Sep 17 00:00:00 2001 |
126 |
From: Pierre LALET <pierre.lalet@cea.fr> |
127 |
Date: Wed, 17 Apr 2019 10:22:16 +0200 |
128 |
Subject: [PATCH 2/2] BPF: test get_working_ifaces() |
129 |
|
130 |
--- |
131 |
test/bpf.uts | 27 +++++++++++++++++++++++++++ |
132 |
1 file changed, 27 insertions(+) |
133 |
|
134 |
diff --git test/bpf.uts test/bpf.uts |
135 |
index 45d36fd83..23022530e 100644 |
136 |
--- test/bpf.uts |
137 |
+++ test/bpf.uts |
138 |
@@ -53,6 +53,33 @@ assert len(ifworking) |
139 |
assert get_working_if() == ifworking[0] |
140 |
|
141 |
|
142 |
+= Get working network interfaces order |
143 |
+ |
144 |
+import mock |
145 |
+from scapy.arch.bpf.core import get_working_ifaces |
146 |
+ |
147 |
+@mock.patch("scapy.arch.bpf.core.os.close") |
148 |
+@mock.patch("scapy.arch.bpf.core.fcntl.ioctl") |
149 |
+@mock.patch("scapy.arch.bpf.core.get_dev_bpf") |
150 |
+@mock.patch("scapy.arch.bpf.core.get_if") |
151 |
+@mock.patch("scapy.arch.bpf.core.get_if_list") |
152 |
+@mock.patch("scapy.arch.bpf.core.os.getuid") |
153 |
+def test_get_working_ifaces(mock_getuid, mock_get_if_list, mock_get_if, |
154 |
+ mock_get_dev_bpf, mock_ioctl, mock_close): |
155 |
+ mock_getuid.return_value = 0 |
156 |
+ mock_get_if_list.return_value = ['igb0', 'em0', 'msk0', 'epair0a', 'igb1', |
157 |
+ 'vlan20', 'igb10', 'igb2'] |
158 |
+ mock_get_if.return_value = (b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' |
159 |
+ b'\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00' |
160 |
+ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') |
161 |
+ mock_get_dev_bpf.return_value = (31337,) |
162 |
+ mock_ioctl.return_value = 0 |
163 |
+ mock_close.return_value = 0 |
164 |
+ return get_working_ifaces() |
165 |
+ |
166 |
+assert test_get_working_ifaces() == ['em0', 'igb0', 'msk0', 'epair0a', 'igb1', |
167 |
+ 'igb2', 'igb10', 'vlan20'] |
168 |
+ |
169 |
= Misc functions |
170 |
~ needs_root |
171 |
|