Exemplo n.º 1
0
        def __init__(self, device, snaplen, promisc, to_ms, monitor=None):
            device = network_name(device)
            self.errbuf = create_string_buffer(PCAP_ERRBUF_SIZE)
            self.iface = create_string_buffer(device.encode("utf8"))
            self.dtl = None
            if monitor:
                if WINDOWS and not conf.use_npcap:
                    raise OSError("On Windows, this feature requires NPcap !")
                # Npcap-only functions
                from scapy.libs.winpcapy import pcap_create, \
                    pcap_set_snaplen, pcap_set_promisc, \
                    pcap_set_timeout, pcap_set_rfmon, pcap_activate
                self.pcap = pcap_create(self.iface, self.errbuf)
                pcap_set_snaplen(self.pcap, snaplen)
                pcap_set_promisc(self.pcap, promisc)
                pcap_set_timeout(self.pcap, to_ms)
                if pcap_set_rfmon(self.pcap, 1) != 0:
                    log_runtime.error("Could not set monitor mode")
                if pcap_activate(self.pcap) != 0:
                    raise OSError("Could not activate the pcap handler")
            else:
                self.pcap = pcap_open_live(self.iface, snaplen, promisc, to_ms,
                                           self.errbuf)
                error = bytes(bytearray(self.errbuf)).strip(b"\x00")
                if error:
                    raise OSError(error)

            if WINDOWS:
                # Winpcap/Npcap exclusive: make every packet to be instantly
                # returned, and not buffered within Winpcap/Npcap
                pcap_setmintocopy(self.pcap, 0)

            self.header = POINTER(pcap_pkthdr)()
            self.pkt_data = POINTER(c_ubyte)()
            self.bpf_program = bpf_program()
Exemplo n.º 2
0
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
Exemplo n.º 3
0
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