--- Makefile (revision 499232) +++ Makefile (working copy) @@ -4,6 +4,7 @@ PORTNAME= scapy PORTVERSION= 2.4.2 DISTVERSIONPREFIX= v +PORTREVISION= 1 CATEGORIES= net PKGNAMEPREFIX= ${PYTHON_PKGNAMEPREFIX} --- files/patch-scapy_arch_bpf_core.py (nonexistent) +++ files/patch-scapy_arch_bpf_core.py (working copy) @@ -0,0 +1,88 @@ +--- scapy/arch/bpf/core.py.orig 2019-01-10 18:33:08 UTC ++++ scapy/arch/bpf/core.py +@@ -5,22 +5,22 @@ Scapy *BSD native support - core + """ + + from __future__ import absolute_import +-from scapy.config import conf +-from scapy.error import Scapy_Exception, warning +-from scapy.data import ARPHDR_LOOPBACK, ARPHDR_ETHER +-from scapy.arch.common import get_if, compile_filter +-from scapy.consts import LOOPBACK_NAME + +-from scapy.arch.bpf.consts import BIOCSETF, SIOCGIFFLAGS, BIOCSETIF +- ++from ctypes import cdll, cast, pointer ++from ctypes import c_int, c_ulong, c_char_p ++from ctypes.util import find_library ++import fcntl + import os ++import re + import socket +-import fcntl + import struct + +-from ctypes import cdll, cast, pointer +-from ctypes import c_int, c_ulong, c_char_p +-from ctypes.util import find_library ++from scapy.arch.bpf.consts import BIOCSETF, SIOCGIFFLAGS, BIOCSETIF ++from scapy.arch.common import get_if, compile_filter ++from scapy.config import conf ++from scapy.consts import LOOPBACK_NAME ++from scapy.data import ARPHDR_LOOPBACK, ARPHDR_ETHER ++from scapy.error import Scapy_Exception, warning + from scapy.modules.six.moves import range + + +@@ -124,6 +124,9 @@ def get_if_list(): + return interfaces + + ++_IFNUM = re.compile("([0-9]*)([ab]?)$") ++ ++ + def get_working_ifaces(): + """ + Returns an ordered list of interfaces that could be used with BPF. +@@ -154,24 +157,27 @@ def get_working_ifaces(): + if ifflags & 0x1: # IFF_UP + + # Get a BPF handle +- fd, _ = get_dev_bpf() ++ fd = get_dev_bpf()[0] + if fd is None: + raise Scapy_Exception("No /dev/bpf are available !") + + # Check if the interface can be used + try: +- fcntl.ioctl(fd, BIOCSETIF, struct.pack("16s16x", ifname.encode())) # noqa: E501 +- interfaces.append((ifname, int(ifname[-1]))) ++ fcntl.ioctl(fd, BIOCSETIF, struct.pack("16s16x", ++ ifname.encode())) + except IOError: + pass ++ else: ++ ifnum, ifab = _IFNUM.search(ifname).groups() ++ interfaces.append((ifname, int(ifnum) if ifnum else -1, ifab)) ++ finally: ++ # Close the file descriptor ++ os.close(fd) + +- # Close the file descriptor +- os.close(fd) +- + # Sort to mimic pcap_findalldevs() order +- interfaces.sort(key=lambda elt: elt[1]) ++ interfaces.sort(key=lambda elt: (elt[1], elt[2], elt[0])) + +- return interfaces ++ return [iface[0] for iface in interfaces] + + + def get_working_if(): +@@ -181,4 +187,4 @@ def get_working_if(): + if not ifaces: + # A better interface will be selected later using the routing table + return LOOPBACK_NAME +- return ifaces[0][0] ++ return ifaces[0] --- files/patch-test_bpf.uts (nonexistent) +++ files/patch-test_bpf.uts (working copy) @@ -0,0 +1,36 @@ +--- test/bpf.uts.orig 2019-04-18 06:40:42 UTC ++++ test/bpf.uts +@@ -53,6 +53,33 @@ assert len(ifworking) + assert get_working_if() == ifworking[0] + + ++= Get working network interfaces order ++ ++import mock ++from scapy.arch.bpf.core import get_working_ifaces ++ ++@mock.patch("scapy.arch.bpf.core.os.close") ++@mock.patch("scapy.arch.bpf.core.fcntl.ioctl") ++@mock.patch("scapy.arch.bpf.core.get_dev_bpf") ++@mock.patch("scapy.arch.bpf.core.get_if") ++@mock.patch("scapy.arch.bpf.core.get_if_list") ++@mock.patch("scapy.arch.bpf.core.os.getuid") ++def test_get_working_ifaces(mock_getuid, mock_get_if_list, mock_get_if, ++ mock_get_dev_bpf, mock_ioctl, mock_close): ++ mock_getuid.return_value = 0 ++ mock_get_if_list.return_value = ['igb0', 'em0', 'msk0', 'epair0a', 'igb1', ++ 'vlan20', 'igb10', 'igb2'] ++ mock_get_if.return_value = (b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' ++ b'\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00' ++ b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') ++ mock_get_dev_bpf.return_value = (31337,) ++ mock_ioctl.return_value = 0 ++ mock_close.return_value = 0 ++ return get_working_ifaces() ++ ++assert test_get_working_ifaces() == ['em0', 'igb0', 'msk0', 'epair0a', 'igb1', ++ 'igb2', 'igb10', 'vlan20'] ++ + = Misc functions + ~ needs_root +