def compile_filter(filter_exp, iface=None, linktype=None, promisc=False): """Asks libpcap to parse the filter, then build the matching BPF bytecode. :param iface: if provided, use the interface to compile :param linktype: if provided, use the linktype to compile """ try: from scapy.libs.winpcapy import (PCAP_ERRBUF_SIZE, pcap_open_live, pcap_compile, pcap_compile_nopcap, pcap_close) from scapy.libs.structures import bpf_program except ImportError: raise Scapy_Exception( "libpcap is not available. Cannot compile filter !") root = WINDOWS or (os.geteuid() == 0) from ctypes import create_string_buffer bpf = bpf_program() bpf_filter = create_string_buffer(filter_exp.encode("utf8")) if not linktype: # Try to guess linktype to avoid root if not iface: if not conf.iface: raise Scapy_Exception( "Please provide an interface or linktype!") if WINDOWS: iface = conf.iface.pcap_name else: iface = conf.iface # Try to guess linktype to avoid requiring root try: arphd = get_if_raw_hwaddr(iface)[0] linktype = ARPHRD_TO_DLT.get(arphd) except Exception: # Failed to use linktype: use the interface if not root: raise Scapy_Exception( "Please provide a valid interface or linktype!") if linktype is not None: ret = pcap_compile_nopcap(MTU, linktype, ctypes.byref(bpf), bpf_filter, 0, -1) elif iface: if not root: raise OSError("Compiling using an interface requires root.") err = create_string_buffer(PCAP_ERRBUF_SIZE) iface = create_string_buffer(iface.encode("utf8")) pcap = pcap_open_live(iface, MTU, promisc, 0, err) ret = pcap_compile(pcap, ctypes.byref(bpf), bpf_filter, 0, -1) pcap_close(pcap) if ret == -1: raise Scapy_Exception("Failed to compile filter expression %s (%s)" % (filter_exp, ret)) if conf.use_pypy and sys.pypy_version_info <= (7, 3, 0): # PyPy < 7.3.0 has a broken behavior # https://bitbucket.org/pypy/pypy/issues/3114 return struct.pack('HL', bpf.bf_len, ctypes.addressof(bpf.bf_insns.contents)) return bpf
def setfilter(self, f): filter_exp = create_string_buffer(f.encode("utf8")) if pcap_compile(self.pcap, byref(self.bpf_program), filter_exp, 0, -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
def compile_filter( filter_exp, # type: str iface=None, # type: Optional[Union[str, 'scapy.interfaces.NetworkInterface']] # noqa: E501 linktype=None, # type: Optional[int] promisc=False # type: bool ): # type: (...) -> bpf_program """Asks libpcap to parse the filter, then build the matching BPF bytecode. :param iface: if provided, use the interface to compile :param linktype: if provided, use the linktype to compile """ try: from scapy.libs.winpcapy import (PCAP_ERRBUF_SIZE, pcap_open_live, pcap_compile, pcap_compile_nopcap, pcap_close) except OSError: raise ImportError("libpcap is not available. Cannot compile filter !") from ctypes import create_string_buffer bpf = bpf_program() bpf_filter = create_string_buffer(filter_exp.encode("utf8")) if not linktype: # Try to guess linktype to avoid root if not iface: if not conf.iface: raise Scapy_Exception( "Please provide an interface or linktype!") iface = conf.iface # Try to guess linktype to avoid requiring root try: arphd = get_if_raw_hwaddr(iface)[0] linktype = ARPHRD_TO_DLT.get(arphd) except Exception: # Failed to use linktype: use the interface pass if not linktype and conf.use_bpf: linktype = ARPHDR_ETHER if linktype is not None: ret = pcap_compile_nopcap(MTU, linktype, ctypes.byref(bpf), bpf_filter, 0, -1) elif iface: err = create_string_buffer(PCAP_ERRBUF_SIZE) iface_b = create_string_buffer(network_name(iface).encode("utf8")) pcap = pcap_open_live(iface_b, MTU, promisc, 0, err) error = bytes(bytearray(err)).strip(b"\x00") if error: raise OSError(error) ret = pcap_compile(pcap, ctypes.byref(bpf), bpf_filter, 0, -1) pcap_close(pcap) if ret == -1: raise Scapy_Exception("Failed to compile filter expression %s (%s)" % (filter_exp, ret)) return bpf