|
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 |
|