Repository: secdev/scapy

Issue:
Test failing on OpenBSD 7.1
The test named `Check offline sniff() with a PcapNg file and a filter (by file object)`  is failing on OpenBSD 7.1 with the following error `scapy.error.Scapy_Exception: Failed to compile filter expression udp (-1)`. I will try to reproduce the issue on a local VM.

__Originally posted by @guedou in https://github.com/secdev/scapy/pull/3716#issuecomment-1220521197__


Discussion:

Resolving patch:
diff --git a/.config/ci/openssl.py b/.config/ci/openssl.py
--- a/.config/ci/openssl.py
+++ b/.config/ci/openssl.py
@@ -38,8 +38,11 @@
 """
 
 # Copy and edit
-with open(OPENSSL_CONFIG, 'rb') as fd:
-    DATA = fd.read()
+try:
+    with open(OPENSSL_CONFIG, 'rb') as fd:
+        DATA = fd.read()
+except FileNotFoundError:
+    DATA = b""
 
 DATA = HEADER + DATA + FOOTER
 
diff --git a/scapy/arch/bpf/supersocket.py b/scapy/arch/bpf/supersocket.py
--- a/scapy/arch/bpf/supersocket.py
+++ b/scapy/arch/bpf/supersocket.py
@@ -477,6 +477,15 @@ def send(self, pkt):
         # with Apple Silicon (M1).
         if DARWIN and iff.startswith('tun') and self.guessed_cls == Loopback:
             frame = raw(pkt)
+        elif FREEBSD and (iff.startswith('tun') or iff.startswith('tap')):
+            # On FreeBSD, the bpf manpage states that it is only possible
+            # to write packets to Ethernet and SLIP network interfaces
+            # using /dev/bpf
+            #
+            # Note: `open("/dev/tun0", "wb").write(raw(pkt())) should be
+            #   used
+            warning("Cannot write to %s according to the documentation!", iff)
+            return
         else:
             frame = raw(self.guessed_cls() / pkt)
 
diff --git a/scapy/utils.py b/scapy/utils.py
--- a/scapy/utils.py
+++ b/scapy/utils.py
@@ -35,7 +35,7 @@
 
 from scapy.config import conf
 from scapy.consts import DARWIN, OPENBSD, WINDOWS
-from scapy.data import MTU, DLT_EN10MB
+from scapy.data import MTU, DLT_EN10MB, DLT_RAW
 from scapy.compat import orb, plain_str, chb, bytes_base64,\
     base64_bytes, hex_bytes, lambda_tuple_converter, bytes_encode
 from scapy.error import log_runtime, Scapy_Exception, warning
@@ -2718,6 +2718,8 @@ def tcpdump(
                     try:
                         _, metadata = rd._read_packet()
                         linktype = metadata.linktype
+                        if OPENBSD and linktype == 228:
+                            linktype = DLT_RAW
                     except EOFError:
                         raise ValueError(
                             "Cannot get linktype from a PcapNg packet."


Test patch:
diff --git a/.config/ci/test.sh b/.config/ci/test.sh
--- a/.config/ci/test.sh
+++ b/.config/ci/test.sh
@@ -30,11 +30,21 @@ then
   else
     UT_FLAGS+=" -K vcan_socket"
   fi
-elif [[ "$OSTYPE" = "darwin"* ]] || [ "$TRAVIS_OS_NAME" = "osx" ]
+elif [[ "$OSTYPE" = "darwin"* ]] || [ "$TRAVIS_OS_NAME" = "osx" ] || [[ "$OSTYPE" = "FreeBSD" ]] || [[ "$OSTYPE" = *"bsd"* ]]
 then
   OSTOX="bsd"
   # Travis CI in macOS 10.13+ can't load kexts. Need this for tuntaposx.
   UT_FLAGS+=" -K tun -K tap"
+  if [[ "$OSTYPE" = "openbsd"* ]]
+  then
+    # Note: LibreSSL 3.6.* does not support X25519 according to
+    # the cryptogaphy module source code
+    UT_FLAGS+=" -K libressl"
+  fi
+  if [[ "$OSTYPE" = "netbsd" ]]
+  then
+    UT_FLAGS+=" -K not_netbsd"
+  fi
 fi
 
 # pypy
@@ -82,7 +92,7 @@ then
 fi
 
 # Configure OpenSSL
-export OPENSSL_CONF=$(python `dirname $BASH_SOURCE`/openssl.py)
+export OPENSSL_CONF=$($PYTHON `dirname $BASH_SOURCE`/openssl.py)
 
 # Dump vars (the others were already dumped in install.sh)
 echo UT_FLAGS=$UT_FLAGS
diff --git a/test/bpf.uts b/test/bpf.uts
--- a/test/bpf.uts
+++ b/test/bpf.uts
@@ -147,7 +147,10 @@ s.assigned_interface = conf.loopback_name
 s.send(IP(dst="8.8.8.8")/ICMP())
 
 = L3bpfSocket - send and sniff on loopback
-~ needs_root
+~ needs_root not_netbsd
+
+# Note: as of November 2022, it is not possible to send packet on lo0
+#       using bpf on NetBSD 9.3
 
 localhost_ip = conf.ifaces[conf.loopback_name].ips[4][0]
 
diff --git a/test/configs/bsd.utsc b/test/configs/bsd.utsc
--- a/test/configs/bsd.utsc
+++ b/test/configs/bsd.utsc
@@ -15,6 +15,7 @@
     "test/windows.uts",
     "test/contrib/automotive/ecu_am.uts",
     "test/contrib/automotive/gm/gmlanutils.uts",
+    "test/contrib/isotp_packet.uts",
     "test/contrib/isotpscan.uts"
   ],
   "onlyfailed": true,
@@ -28,6 +29,8 @@
     "linux",
     "windows",
     "ipv6",
-    "vcan_socket"
+    "vcan_socket",
+    "tun",
+    "tap"
   ]
 }
diff --git a/test/fields.uts b/test/fields.uts
--- a/test/fields.uts
+++ b/test/fields.uts
@@ -133,8 +133,9 @@ assert Test(raw(Test())).sourceip == defaddr
 
 assert IP(dst="0.0.0.0").src == defaddr
 assert IP(raw(IP(dst="0.0.0.0"))).src == defaddr
-assert IP(dst="0.0.0.0/31").src == defaddr
-assert IP(raw(IP(dst="0.0.0.0/31"))).src == defaddr
+defaddr = conf.route.route('1.1.1.1')[1]
+assert IP(dst="1.1.1.1").src == defaddr
+assert IP(raw(IP(dst="1.1.1.1"))).src == defaddr
 
 
 #= ByteField
diff --git a/test/regression.uts b/test/regression.uts
--- a/test/regression.uts
+++ b/test/regression.uts
@@ -2047,15 +2047,18 @@ os.unlink(filename)
 
 pcapng_data = b'\n\r\r\n`\x00\x00\x00M<+\x1a\x01\x00\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\x04\x009\x00TShark (Wireshark) 3.2.3 (Git v3.2.3 packaged as 3.2.3-1)\x00\x00\x00\x00\x00\x00\x00`\x00\x00\x00\x01\x00\x00\x00\x14\x00\x00\x00\xe4\x00\x00\x00\xff\xff\x00\x00\x14\x00\x00\x00\x06\x00\x00\x00<\x00\x00\x00\x00\x00\x00\x00\x98\xcd\x05\x00\x19\x83\xf7\x9e\x1c\x00\x00\x00\x1c\x00\x00\x00E\x00\x00\x1c\x00\x01\x00\x00@\x11|\xce\x7f\x00\x00\x01\x7f\x00\x00\x01\x005\x005\x00\x08\x01r<\x00\x00\x00'
 
-fdesc, filename = tempfile.mkstemp()
-os.close(fdesc)
-fd = open(filename, "wb")
-fd.write(pcapng_data)
-fd.close()
-
-packets = sniff(offline=filename, filter="udp")
-os.unlink(filename)
-assert UDP in packets[0]
+if OPENBSD:
+    # Note: OpenBSD tcpdump does not support PcapNg
+    assert True
+else:
+    fdesc, filename = tempfile.mkstemp()
+    os.close(fdesc)
+    fd = open(filename, "wb")
+    fd.write(pcapng_data)
+    fd.close()
+    packets = sniff(offline=filename, filter="udp")
+    os.unlink(filename)
+    assert UDP in packets[0]
 
 = Check offline sniff() with Packets and tcpdump with a filter
 ~ tcpdump libpcap
diff --git a/test/run_tests b/test/run_tests
--- a/test/run_tests
+++ b/test/run_tests
@@ -56,8 +56,9 @@ then
   # Run tox
   export UT_FLAGS="-K tcpdump -K manufdb -K wireshark -K ci_only -K vcan_socket -K automotive_comm -K imports -K scanner"
   export SIMPLE_TESTS="true"
+  export PYTHON
   PYVER=$($PYTHON -c "import sys; print('.'.join(sys.version.split('.')[:2]))")
-  ${DIR}/.config/ci/test.sh $PYVER non_root
+  bash ${DIR}/.config/ci/test.sh $PYVER non_root
   exit $?
 fi
 PYTHONPATH=$DIR exec "$PYTHON" ${DIR}/scapy/tools/UTscapy.py $ARGS
diff --git a/test/tls.uts b/test/tls.uts
--- a/test/tls.uts
+++ b/test/tls.uts
@@ -591,7 +591,7 @@ _all_aes_gcm_tests()
 
 
 = Crypto - AES cipher in CCM mode, checks from IEEE P1619.1
-~ crypto_advanced
+~ crypto_advanced libressl
 
 class _aes256ccm_test_1:
     k= b"\0"*32
@@ -649,7 +649,7 @@ _all_aes_ccm_tests()
 
 
 = Crypto - ChaCha20POly1305 test (test vector A.5 from RFC 7539)
-~ crypto_advanced
+~ crypto_advanced libressl
 
 import binascii
 def clean(s):
@@ -963,6 +963,8 @@ fin.load == b'\xd9\xcb,\x8cM\xfd\xbc9\xaa\x05\xf3\xd3\xf3Z\x8a-'
 
 
 = Reading TLS test session - Ticket, CCS & Finished
+~ libressl
+
 from scapy.layers.tls.handshake import TLSNewSessionTicket
 t6 = TLS(p6_tick_ccs_fin, tls_session=t5.tls_session.mirror())
 tick = t6.msg[0]
@@ -980,6 +982,7 @@ assert isinstance(rec_fin.msg[0], _TLSEncryptedContent)
 rec_fin.msg[0].load == b'7\\)`\xaa`\x7ff\xcd\x10\xa9v\xa3*\x17\x1a'
 
 = Building x25519 ecdh_Yc
+~ libressl
 
 from scapy.layers.tls.record import TLS
 from scapy.layers.tls.handshake import TLSClientKeyExchange
@@ -1000,6 +1003,7 @@ pkt.exchkeys.fill_missing()
 assert len(pkt.exchkeys.ecdh_Yc) == 32
 
 = Reading TLS test session - Extended master secret
+~ libressl
 
 # See https://github.com/secdev/scapy/issues/2784
 
@@ -1050,6 +1054,8 @@ assert isinstance(l3.msg[0], TLSFinished)
 assert l3.msg[0][TLSFinished].vdata == b'\x15\xd6\xd5\xea\x84\xee\xb3\xdd\xd6\x10\xd8\x11'
 
 = Reading TLS test session - Encrypt-then-MAC extension
+~ libressl
+
 from scapy.layers.tls.cert import PrivKey
 from scapy.layers.tls.handshake import TLSFinished
 from scapy.layers.tls.record import TLS
@@ -1080,6 +1086,7 @@ assert server_finished.vdata == hex_bytes(b'42c9765e833997b6714fec75')
 ###
 
 = Reading TLS test session - Full TLSNewSessionTicket captured
+~ libressl
 import os
 filename = scapy_path("/test/pcaps/tls_new-session-ticket.pcap")
 a = rdpcap(filename)
@@ -1089,6 +1096,7 @@ assert pkt[TLS].msg[0].ticket == b'6k\x8b{\xa8\xaf\xf0\x8aG*\xdd\xc2\xf6\t\xde\x
 assert pkt[TLS].msg[0].lifetime == 3600
 
 = Reading TLS test session - ApplicationData
+~ libressl
 t7 = TLS(p7_data, tls_session=t6.tls_session.mirror())
 assert t7.iv == b'\x00\x00\x00\x00\x00\x00\x00\x01'
 assert t7.mac == b'>\x1dLb5\x8e+\x01n\xcb\x19\xcc\x17Ey\xc8'
diff --git a/test/tls13.uts b/test/tls13.uts
--- a/test/tls13.uts
+++ b/test/tls13.uts
@@ -3,6 +3,7 @@
 # Try me with :
 # bash test/run_tests -t test/tls13.uts -F
 
+~ libressl
 
 + Read a protected TLS 1.3 session
 # /!\ These tests will not catch our 'INTEGRITY CHECK FAILED's. /!\