From 30298a7dc0e5173a879439ca8a50a0ad96d7b30f Mon Sep 17 00:00:00 2001 From: gpotter2 <10530980+gpotter2@users.noreply.github.com> Date: Wed, 31 Jan 2024 11:28:26 +0100 Subject: [PATCH] Correctly raise on bad filter --- scapy/arch/bpf/supersocket.py | 4 ++-- scapy/arch/libpcap.py | 19 ++++++++++--------- scapy/arch/linux.py | 2 +- test/regression.uts | 9 +++++++++ 4 files changed, 22 insertions(+), 12 deletions(-) diff --git a/scapy/arch/bpf/supersocket.py b/scapy/arch/bpf/supersocket.py index 06a6dbc9012..c4085669cf3 100644 --- a/scapy/arch/bpf/supersocket.py +++ b/scapy/arch/bpf/supersocket.py @@ -214,8 +214,8 @@ def __init__(self, try: attach_filter(self.bpf_fd, filter, self.iface) filter_attached = True - except ImportError as ex: - warning("Cannot set filter: %s" % ex) + except (ImportError, Scapy_Exception) as ex: + raise Scapy_Exception("Cannot set filter: %s" % ex) if NETBSD and filter_attached is False: # On NetBSD, a filter must be attached to an interface, otherwise # no frame will be received by os.read(). When no filter has been diff --git a/scapy/arch/libpcap.py b/scapy/arch/libpcap.py index ee25b16334c..25120dbc347 100644 --- a/scapy/arch/libpcap.py +++ b/scapy/arch/libpcap.py @@ -160,6 +160,7 @@ def close(self): pcap_datalink, pcap_findalldevs, pcap_freealldevs, + pcap_geterr, pcap_if_t, pcap_lib_version, pcap_next_ex, @@ -386,16 +387,16 @@ def fileno(self): return cast(int, pcap_get_selectable_fd(self.pcap)) def setfilter(self, f): - # type: (str) -> bool + # type: (str) -> None filter_exp = create_string_buffer(f.encode("utf8")) - if pcap_compile(self.pcap, byref(self.bpf_program), filter_exp, 1, -1) == -1: # noqa: E501 - log_runtime.error("Could not compile filter expression %s", f) - return False - else: - if pcap_setfilter(self.pcap, byref(self.bpf_program)) == -1: - log_runtime.error("Could not set filter %s", f) - return False - return True + if pcap_compile(self.pcap, byref(self.bpf_program), filter_exp, 1, -1) >= 0: # noqa: E501 + if pcap_setfilter(self.pcap, byref(self.bpf_program)) >= 0: + # Success + return + errstr = decode_locale_str( + bytearray(pcap_geterr(self.pcap)).strip(b"\x00") + ) + raise Scapy_Exception("Cannot set filter: %s" % errstr) def setnonblock(self, i): # type: (bool) -> None diff --git a/scapy/arch/linux.py b/scapy/arch/linux.py index b79cda1315e..566916ff2ad 100644 --- a/scapy/arch/linux.py +++ b/scapy/arch/linux.py @@ -507,7 +507,7 @@ def __init__(self, try: attach_filter(self.ins, filter, self.iface) except (ImportError, Scapy_Exception) as ex: - log_runtime.error("Cannot set filter: %s", ex) + raise Scapy_Exception("Cannot set filter: %s" % ex) if self.promisc: set_promisc(self.ins, self.iface) self.ins.bind((self.iface, type)) diff --git a/test/regression.uts b/test/regression.uts index 3d0e3bd92b5..c42e278dc77 100644 --- a/test/regression.uts +++ b/test/regression.uts @@ -2261,6 +2261,15 @@ except Scapy_Exception: else: assert False += Check online sniff() with a bad filter +~ needs_root tcpdump libpcap +try: + sniff(timeout=0, filter="bad filter") +except Scapy_Exception: + pass +else: + assert False + = Check offline sniff with lfilter assert len(sniff(offline=[IP()/UDP(), IP()/TCP()], lfilter=lambda x: TCP in x)) == 1