Exemple #1
0
def srpflood(x,  # type: _PacketIterable
             promisc=None,  # type: Optional[bool]
             filter=None,  # type: Optional[str]
             iface=None,  # type: Optional[_GlobInterfaceType]
             iface_hint=None,  # type: Optional[str]
             nofilter=None,  # type: Optional[bool]
             *args,  # type: Any
             **kargs  # type: Any
             ):
    # type: (...) -> Tuple[SndRcvList, PacketList]
    """Flood and receive packets at layer 2

    :param prn:      function applied to packets received
    :param unique:   only consider packets whose print
    :param nofilter: put 1 to avoid use of BPF filters
    :param filter:   provide a BPF filter
    :param iface:    listen answers only on the given interface
    """
    if iface is None and iface_hint is not None:
        iface = conf.route.route(iface_hint)[0]
    iface = resolve_iface(iface or conf.iface)
    s = iface.l2socket()(promisc=promisc, filter=filter, iface=iface, nofilter=nofilter)  # noqa: E501
    r = sndrcvflood(s, x, *args, **kargs)
    s.close()
    return r
Exemple #2
0
def _send(
        x,  # type: _PacketIterable
        _func,  # type: Callable[[NetworkInterface], Type[SuperSocket]]
        inter=0,  # type: int
        loop=0,  # type: int
        iface=None,  # type: Optional[_GlobInterfaceType]
        count=None,  # type: Optional[int]
        verbose=None,  # type: Optional[int]
        realtime=False,  # type: bool
        return_packets=False,  # type: bool
        socket=None,  # type: Optional[SuperSocket]
        **kargs  # type: Any
):
    # type: (...) -> Optional[PacketList]
    """Internal function used by send and sendp"""
    need_closing = socket is None
    iface = resolve_iface(iface or conf.iface)
    socket = socket or _func(iface)(iface=iface, **kargs)
    results = __gen_send(socket,
                         x,
                         inter=inter,
                         loop=loop,
                         count=count,
                         verbose=verbose,
                         realtime=realtime,
                         return_packets=return_packets)
    if need_closing:
        socket.close()
    return results
Exemple #3
0
def srp(
        x,  # type: Packet
        promisc=None,  # type: Optional[bool]
        iface=None,  # type: Optional[_GlobInterfaceType]
        iface_hint=None,  # type: Optional[str]
        filter=None,  # type: Optional[str]
        nofilter=0,  # type: int
        type=ETH_P_ALL,  # type: int
        *args,  # type: Any
        **kargs  # type: Any
):
    # type: (...) -> Tuple[SndRcvList, PacketList]
    """
    Send and receive packets at layer 2
    """
    if iface is None and iface_hint is not None:
        iface = conf.route.route(iface_hint)[0]
    iface = resolve_iface(iface or conf.iface)
    s = iface.l2socket()(promisc=promisc,
                         iface=iface,
                         filter=filter,
                         nofilter=nofilter,
                         type=type)
    result = sndrcv(s, x, *args, **kargs)
    s.close()
    return result
Exemple #4
0
def srp1flood(
        x,  # type: _PacketIterable
        promisc=None,  # type: Optional[bool]
        filter=None,  # type: Optional[str]
        iface=None,  # type: Optional[_GlobInterfaceType]
        nofilter=0,  # type: int
        *args,  # type: Any
        **kargs  # type: Any
):
    # type: (...) -> Optional[Packet]
    """Flood and receive packets at layer 2 and return only the first answer

    :param prn:      function applied to packets received
    :param verbose:  set verbosity level
    :param nofilter: put 1 to avoid use of BPF filters
    :param filter:   provide a BPF filter
    :param iface:    listen answers only on the given interface
    """
    iface = resolve_iface(iface or conf.iface)
    s = iface.l2socket()(promisc=promisc,
                         filter=filter,
                         nofilter=nofilter,
                         iface=iface)  # noqa: E501
    ans, _ = sndrcvflood(s, x, *args, **kargs)
    s.close()
    if len(ans) > 0:
        return cast(Packet, ans[0][1])
    return None
Exemple #5
0
def _send(x,
          _func,
          inter=0,
          loop=0,
          iface=None,
          count=None,
          verbose=None,
          realtime=None,
          return_packets=False,
          socket=None,
          **kargs):
    """Internal function used by send and sendp"""
    need_closing = socket is None
    iface = resolve_iface(iface or conf.iface)
    socket = socket or _func(iface)(iface=iface, **kargs)
    results = __gen_send(socket,
                         x,
                         inter=inter,
                         loop=loop,
                         count=count,
                         verbose=verbose,
                         realtime=realtime,
                         return_packets=return_packets)
    if need_closing:
        socket.close()
    return results
Exemple #6
0
def srpflood(x,
             promisc=None,
             filter=None,
             iface=None,
             iface_hint=None,
             nofilter=None,
             *args,
             **kargs):  # noqa: E501
    """Flood and receive packets at layer 2

    :param prn:      function applied to packets received
    :param unique:   only consider packets whose print
    :param nofilter: put 1 to avoid use of BPF filters
    :param filter:   provide a BPF filter
    :param iface:    listen answers only on the given interface
    """
    if iface is None and iface_hint is not None:
        iface = conf.route.route(iface_hint)[0]
    iface = resolve_iface(iface or conf.iface)
    s = iface.l2socket()(promisc=promisc,
                         filter=filter,
                         iface=iface,
                         nofilter=nofilter)  # noqa: E501
    r = sndrcvflood(s, x, *args, **kargs)
    s.close()
    return r
Exemple #7
0
 def _init_socket(iface, count, L2socket=L2socket):
     if isinstance(iface, SuperSocket):
         return iface, "iface%d" % count
     else:
         if not L2socket:
             iface = resolve_iface(iface or conf.iface)
             L2socket = iface.l2socket()
         return L2socket(iface=iface), iface
Exemple #8
0
def _iface_changer(attr, val, old):
    """Resolves the interface in conf.iface"""
    if isinstance(val, str):
        from scapy.interfaces import resolve_iface
        iface = resolve_iface(val)
        if old and iface.dummy:
            warning("This interface is not specified in any provider ! "
                    "See conf.ifaces output")
        return iface
    return val
Exemple #9
0
    def __repr__(self):
        rtlst = []
        for net, msk, gw, iface, addr, metric in self.routes:
            if_repr = resolve_iface(iface).description
            rtlst.append(
                (ltoa(net), ltoa(msk), gw, if_repr, addr, str(metric)))

        return pretty_list(rtlst, [
            ("Network", "Netmask", "Gateway", "Iface", "Output IP", "Metric")
        ])  # noqa: E501
Exemple #10
0
    def __repr__(self):
        # type: () -> str
        rtlst = []  # type: List[Tuple[Union[str, List[str]], ...]]
        for net, msk, gw, iface, addr, metric in self.routes:
            if_repr = cast(str, resolve_iface(iface).description)
            rtlst.append(
                (ltoa(net), ltoa(msk), gw, if_repr, addr, str(metric)))

        return pretty_list(rtlst, [
            ("Network", "Netmask", "Gateway", "Iface", "Output IP", "Metric")
        ])  # noqa: E501
Exemple #11
0
 def _init_socket(iface,  # type: _GlobInterfaceType
                  count,  # type: int
                  L2socket=L2socket  # type: Optional[Type[SuperSocket]]
                  ):
     # type: (...) -> Tuple[SuperSocket, _GlobInterfaceType]
     if isinstance(iface, SuperSocket):
         return iface, "iface%d" % count
     else:
         if not L2socket:
             iface = resolve_iface(iface or conf.iface)
             L2socket = iface.l2socket()
         return L2socket(iface=iface), iface
Exemple #12
0
    def __repr__(self):
        rtlst = []

        for net, msk, gw, iface, cset, metric in self.routes:
            if_repr = resolve_iface(iface).description
            rtlst.append(
                ('%s/%i' % (net, msk), gw, if_repr, cset, str(metric)))

        return pretty_list(
            rtlst,
            [('Destination', 'Next Hop', "Iface", "Src candidates", "Metric")
             ],  # noqa: E501
            sortBy=1)
def srp(x, promisc=None, iface=None, iface_hint=None, filter=None,
        nofilter=0, type=ETH_P_ALL, *args, **kargs):
    """
    Send and receive packets at layer 2
    """
    if iface is None and iface_hint is not None:
        iface = conf.route.route(iface_hint)[0]
    iface = resolve_iface(iface or conf.iface)
    s = iface.l2socket()(promisc=promisc, iface=iface,
                         filter=filter, nofilter=nofilter, type=type)
    result = sndrcv(s, x, *args, **kargs)
    s.close()
    return result
def srp1flood(x, promisc=None, filter=None, iface=None, nofilter=0, *args, **kargs):  # noqa: E501
    """Flood and receive packets at layer 2 and return only the first answer

    :param prn:      function applied to packets received
    :param verbose:  set verbosity level
    :param nofilter: put 1 to avoid use of BPF filters
    :param filter:   provide a BPF filter
    :param iface:    listen answers only on the given interface
    """
    iface = resolve_iface(iface or conf.iface)
    s = iface.l2socket()(promisc=promisc, filter=filter, nofilter=nofilter, iface=iface)  # noqa: E501
    ans, _ = sndrcvflood(s, x, *args, **kargs)
    s.close()
    if len(ans) > 0:
        return ans[0][1]
Exemple #15
0
    def __repr__(self):
        # type: () -> str
        rtlst = []  # type: List[Tuple[Union[str, List[str]], ...]]

        for net, msk, gw, iface, cset, metric in self.routes:
            if_repr = cast(str, resolve_iface(iface).description)
            rtlst.append(('%s/%i' % (net, msk),
                          gw,
                          if_repr,
                          cset,
                          str(metric)))

        return pretty_list(rtlst,
                           [('Destination', 'Next Hop', "Iface", "Src candidates", "Metric")],  # noqa: E501
                           sortBy=1)
Exemple #16
0
 def open_pcap(iface, *args, **kargs):
     """open_pcap: Windows routine for creating a pcap from an interface.
     This function is also responsible for detecting monitor mode.
     """
     iface = resolve_iface(iface)
     iface_network_name = iface.network_name
     if not iface:
         raise Scapy_Exception(
             "Interface is invalid (no pcap match found) !")
     # Only check monitor mode when manually specified.
     # Checking/setting for monitor mode will slow down the process, and the
     # common is case is not to use monitor mode
     kw_monitor = kargs.get("monitor", None)
     if conf.use_npcap and kw_monitor is not None:
         monitored = iface.ismonitor()
         if kw_monitor is not monitored:
             # The monitor param is specified, and not matching the current
             # interface state
             iface.setmonitor(kw_monitor)
     return _orig_open_pcap(iface_network_name, *args, **kargs)
Exemple #17
0
    def _run(self,
             count=0,  # type: int
             store=True,  # type: bool
             offline=None,  # type: Any
             quiet=False,  # type: bool
             prn=None,  # type: Optional[Callable[[Packet], Any]]
             lfilter=None,  # type: Optional[Callable[[Packet], bool]]
             L2socket=None,  # type: Optional[Type[SuperSocket]]
             timeout=None,  # type: Optional[int]
             opened_socket=None,  # type: Optional[SuperSocket]
             stop_filter=None,  # type: Optional[Callable[[Packet], bool]]
             iface=None,  # type: Optional[_GlobInterfaceType]
             started_callback=None,  # type: Optional[Callable[[], Any]]
             session=None,  # type: Optional[_GlobSessionType]
             session_kwargs={},  # type: Dict[str, Any]
             **karg  # type: Any
             ):
        # type: (...) -> None
        self.running = True
        # Start main thread
        # instantiate session
        if not isinstance(session, DefaultSession):
            session = session or DefaultSession
            session = session(prn=prn, store=store,
                              **session_kwargs)
        else:
            session.prn = prn
            session.store = store
        # sniff_sockets follows: {socket: label}
        sniff_sockets = {}  # type: Dict[SuperSocket, _GlobInterfaceType]
        if opened_socket is not None:
            if isinstance(opened_socket, list):
                sniff_sockets.update(
                    (s, "socket%d" % i)
                    for i, s in enumerate(opened_socket)
                )
            elif isinstance(opened_socket, dict):
                sniff_sockets.update(
                    (s, label)
                    for s, label in six.iteritems(opened_socket)
                )
            else:
                sniff_sockets[opened_socket] = "socket0"
        if offline is not None:
            flt = karg.get('filter')

            if isinstance(offline, str):
                # Single file
                offline = [offline]
            if isinstance(offline, list) and \
                    all(isinstance(elt, str) for elt in offline):
                # List of files
                sniff_sockets.update((PcapReader(
                    fname if flt is None else
                    tcpdump(fname,
                            args=["-w", "-"],
                            flt=flt,
                            getfd=True,
                            quiet=quiet)
                ), fname) for fname in offline)
            elif isinstance(offline, dict):
                # Dict of files
                sniff_sockets.update((PcapReader(
                    fname if flt is None else
                    tcpdump(fname,
                            args=["-w", "-"],
                            flt=flt,
                            getfd=True,
                            quiet=quiet)
                ), label) for fname, label in six.iteritems(offline))
            elif isinstance(offline, (Packet, PacketList, list)):
                # Iterables (list of packets, PacketList..)
                offline = IterSocket(offline)
                sniff_sockets[offline if flt is None else PcapReader(
                    tcpdump(offline,
                            args=["-w", "-"],
                            flt=flt,
                            getfd=True,
                            quiet=quiet)
                )] = offline
            else:
                # Other (file descriptors...)
                sniff_sockets[PcapReader(
                    offline if flt is None else
                    tcpdump(offline,
                            args=["-w", "-"],
                            flt=flt,
                            getfd=True,
                            quiet=quiet)
                )] = offline
        if not sniff_sockets or iface is not None:
            # The _RL2 function resolves the L2socket of an iface
            _RL2 = lambda i: L2socket or resolve_iface(i).l2listen()  # type: Callable[[_GlobInterfaceType], Callable[..., SuperSocket]]  # noqa: E501
            if isinstance(iface, list):
                sniff_sockets.update(
                    (_RL2(ifname)(type=ETH_P_ALL, iface=ifname, **karg),
                     ifname)
                    for ifname in iface
                )
            elif isinstance(iface, dict):
                sniff_sockets.update(
                    (_RL2(ifname)(type=ETH_P_ALL, iface=ifname, **karg),
                     iflabel)
                    for ifname, iflabel in six.iteritems(iface)
                )
            else:
                iface = iface or conf.iface
                sniff_sockets[_RL2(iface)(type=ETH_P_ALL, iface=iface,
                                          **karg)] = iface

        # Get select information from the sockets
        _main_socket = next(iter(sniff_sockets))
        select_func = _main_socket.select
        nonblocking_socket = _main_socket.nonblocking_socket
        # We check that all sockets use the same select(), or raise a warning
        if not all(select_func == sock.select for sock in sniff_sockets):
            warning("Warning: inconsistent socket types ! "
                    "The used select function "
                    "will be the one of the first socket")

        if not nonblocking_socket:
            # select is blocking: Add special control socket
            from scapy.automaton import ObjectPipe
            close_pipe = ObjectPipe()
            sniff_sockets[close_pipe] = "control_socket"

            def stop_cb():
                # type: () -> None
                if self.running:
                    close_pipe.send(None)
                self.continue_sniff = False
            self.stop_cb = stop_cb
        else:
            # select is non blocking
            def stop_cb():
                # type: () -> None
                self.continue_sniff = False
            self.stop_cb = stop_cb
            close_pipe = None

        try:
            if started_callback:
                started_callback()
            self.continue_sniff = True

            # Start timeout
            if timeout is not None:
                stoptime = time.time() + timeout
            remain = None

            while sniff_sockets and self.continue_sniff:
                if timeout is not None:
                    remain = stoptime - time.time()
                    if remain <= 0:
                        break
                sockets = select_func(list(sniff_sockets.keys()), remain)
                dead_sockets = []
                for s in sockets:
                    if s is close_pipe:
                        break
                    try:
                        p = s.recv()
                    except EOFError:
                        # End of stream
                        try:
                            s.close()
                        except Exception:
                            pass
                        dead_sockets.append(s)
                        continue
                    except Exception as ex:
                        msg = " It was closed."
                        try:
                            # Make sure it's closed
                            s.close()
                        except Exception as ex2:
                            msg = " close() failed with '%s'" % ex2
                        warning(
                            "Socket %s failed with '%s'." % (s, ex) + msg
                        )
                        dead_sockets.append(s)
                        if conf.debug_dissector >= 2:
                            raise
                        continue
                    if p is None:
                        continue
                    if lfilter and not lfilter(p):
                        continue
                    p.sniffed_on = sniff_sockets[s]
                    # on_packet_received handles the prn/storage
                    session.on_packet_received(p)
                    # check
                    if (stop_filter and stop_filter(p)) or \
                            (0 < count <= session.count):
                        self.continue_sniff = False
                        break
                # Removed dead sockets
                for s in dead_sockets:
                    del sniff_sockets[s]
        except KeyboardInterrupt:
            pass
        self.running = False
        if opened_socket is None:
            for s in sniff_sockets:
                s.close()
        elif close_pipe:
            close_pipe.close()
        self.results = session.toPacketList()
Exemple #18
0
def get_if_raw_hwaddr(iface):
    iface = resolve_iface(iface)
    return ARPHDR_ETHER, mac2str(iface.mac)
Exemple #19
0
def get_if_raw_addr(iff):
    """Return the raw IPv4 address of interface"""
    iff = resolve_iface(iff)
    if not iff.ip:
        return None
    return inet_pton(socket.AF_INET, iff.ip)
Exemple #20
0
 def __init__(self,
              iface=None,
              proto=socket.IPPROTO_IP,
              ttl=128,
              ipv6=False,
              promisc=True,
              **kwargs):
     from scapy.layers.inet import IP
     from scapy.layers.inet6 import IPv6
     for kwarg in kwargs:
         warning("Dropping unsupported option: %s" % kwarg)
     af = socket.AF_INET6 if ipv6 else socket.AF_INET
     self.proto = proto
     if ipv6:
         from scapy.arch import get_if_addr6
         self.host_ip6 = get_if_addr6(conf.iface) or "::1"
         if proto == socket.IPPROTO_IP:
             # We'll restrict ourselves to UDP, as TCP isn't bindable
             # on AF_INET6
             self.proto = socket.IPPROTO_UDP
     # On Windows, with promisc=False, you won't get much
     self.ipv6 = ipv6
     self.cls = IPv6 if ipv6 else IP
     self.promisc = promisc
     # Notes:
     # - IPPROTO_RAW only works to send packets.
     # - IPPROTO_IPV6 exists in MSDN docs, but using it will result in
     # no packets being received. Same for its options (IPV6_HDRINCL...)
     # However, using IPPROTO_IP with AF_INET6 will still receive
     # the IPv6 packets
     try:
         self.ins = socket.socket(af, socket.SOCK_RAW, self.proto)
         self.outs = socket.socket(af, socket.SOCK_RAW, socket.IPPROTO_RAW)
     except OSError as e:
         if e.errno == 10013:
             raise OSError("Windows native L3 Raw sockets are only "
                           "usable as administrator ! "
                           "Install Winpcap/Npcap to workaround !")
         raise
     self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30)
     self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30)
     # IOCTL Include IP headers
     self.ins.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
     self.outs.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
     # set TTL
     self.ins.setsockopt(socket.IPPROTO_IP, socket.IP_TTL, ttl)
     self.outs.setsockopt(socket.IPPROTO_IP, socket.IP_TTL, ttl)
     # Bind on all ports
     iface = resolve_iface(iface) or conf.iface
     host = iface.ip if iface.ip else socket.gethostname()
     self.ins.bind((host, 0))
     self.ins.setblocking(False)
     # Get as much data as possible: reduce what is cropped
     if ipv6:
         try:  # Not all Windows versions
             self.ins.setsockopt(socket.IPPROTO_IPV6,
                                 socket.IPV6_RECVTCLASS, 1)
             self.ins.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_HOPLIMIT,
                                 1)
         except (OSError, socket.error):
             pass
     else:
         try:  # Not Windows XP
             self.ins.setsockopt(socket.IPPROTO_IP, socket.IP_RECVDSTADDR,
                                 1)
         except (OSError, socket.error):
             pass
         try:  # Windows 10+ recent builds only
             self.ins.setsockopt(socket.IPPROTO_IP, socket.IP_RECVTTL, 1)
         except (OSError, socket.error):
             pass
     if promisc:
         # IOCTL Receive all packets
         self.ins.ioctl(socket.SIO_RCVALL, socket.RCVALL_ON)
Exemple #21
0
    def _run(self,
             count=0,
             store=True,
             offline=None,
             quiet=False,
             prn=None,
             lfilter=None,
             L2socket=None,
             timeout=None,
             opened_socket=None,
             stop_filter=None,
             iface=None,
             started_callback=None,
             session=None,
             session_args=[],
             session_kwargs={},
             *arg,
             **karg):
        self.running = True
        # Start main thread
        # instantiate session
        if not isinstance(session, DefaultSession):
            session = session or DefaultSession
            session = session(prn=prn,
                              store=store,
                              *session_args,
                              **session_kwargs)
        else:
            session.prn = prn
            session.store = store
        # sniff_sockets follows: {socket: label}
        sniff_sockets = {}
        if opened_socket is not None:
            if isinstance(opened_socket, list):
                sniff_sockets.update(
                    (s, "socket%d" % i) for i, s in enumerate(opened_socket))
            elif isinstance(opened_socket, dict):
                sniff_sockets.update(
                    (s, label) for s, label in six.iteritems(opened_socket))
            else:
                sniff_sockets[opened_socket] = "socket0"
        if offline is not None:
            flt = karg.get('filter')

            if isinstance(offline, list) and \
                    all(isinstance(elt, str) for elt in offline):
                sniff_sockets.update(
                    (PcapReader(fname if flt is None else tcpdump(
                        fname, args=["-w", "-"], flt=flt, getfd=True)), fname)
                    for fname in offline)
            elif isinstance(offline, dict):
                sniff_sockets.update(
                    (PcapReader(fname if flt is None else tcpdump(
                        fname, args=["-w", "-"], flt=flt, getfd=True)), label)
                    for fname, label in six.iteritems(offline))
            else:
                # Write Scapy Packet objects to a pcap file
                def _write_to_pcap(packets_list):
                    filename = get_temp_file(autoext=".pcap")
                    wrpcap(filename, offline)
                    return filename, filename

                if isinstance(offline, Packet):
                    tempfile_written, offline = _write_to_pcap([offline])
                elif isinstance(offline, list) and \
                        all(isinstance(elt, Packet) for elt in offline):
                    tempfile_written, offline = _write_to_pcap(offline)

                sniff_sockets[PcapReader(offline if flt is None else tcpdump(
                    offline,
                    args=["-w", "-"],
                    flt=flt,
                    getfd=True,
                    quiet=quiet))] = offline
        if not sniff_sockets or iface is not None:
            iface = resolve_iface(iface or conf.iface)
            if L2socket is None:
                L2socket = iface.l2listen()
            if isinstance(iface, list):
                sniff_sockets.update(
                    (L2socket(type=ETH_P_ALL, iface=ifname, *arg, **karg),
                     ifname) for ifname in iface)
            elif isinstance(iface, dict):
                sniff_sockets.update(
                    (L2socket(type=ETH_P_ALL, iface=ifname, *arg, **karg),
                     iflabel) for ifname, iflabel in six.iteritems(iface))
            else:
                sniff_sockets[L2socket(type=ETH_P_ALL,
                                       iface=iface,
                                       *arg,
                                       **karg)] = iface

        # Get select information from the sockets
        _main_socket = next(iter(sniff_sockets))
        select_func = _main_socket.select
        _backup_read_func = _main_socket.__class__.recv
        nonblocking_socket = _main_socket.nonblocking_socket
        # We check that all sockets use the same select(), or raise a warning
        if not all(select_func == sock.select for sock in sniff_sockets):
            warning("Warning: inconsistent socket types ! "
                    "The used select function "
                    "will be the one of the first socket")

        if nonblocking_socket:
            # select is non blocking
            def stop_cb():
                self.continue_sniff = False

            self.stop_cb = stop_cb
            close_pipe = None
        else:
            # select is blocking: Add special control socket
            from scapy.automaton import ObjectPipe
            close_pipe = ObjectPipe()
            sniff_sockets[close_pipe] = "control_socket"

            def stop_cb():
                if self.running:
                    close_pipe.send(None)
                self.continue_sniff = False

            self.stop_cb = stop_cb

        try:
            if started_callback:
                started_callback()
            self.continue_sniff = True

            # Start timeout
            if timeout is not None:
                stoptime = time.time() + timeout
            remain = None

            while sniff_sockets and self.continue_sniff:
                if timeout is not None:
                    remain = stoptime - time.time()
                    if remain <= 0:
                        break
                sockets, read_func = select_func(sniff_sockets, remain)
                read_func = read_func or _backup_read_func
                dead_sockets = []
                for s in sockets:
                    if s is close_pipe:
                        break
                    try:
                        p = read_func(s)
                    except EOFError:
                        # End of stream
                        try:
                            s.close()
                        except Exception:
                            pass
                        dead_sockets.append(s)
                        continue
                    except Exception as ex:
                        msg = " It was closed."
                        try:
                            # Make sure it's closed
                            s.close()
                        except Exception as ex:
                            msg = " close() failed with '%s'" % ex
                        warning("Socket %s failed with '%s'." % (s, ex) + msg)
                        dead_sockets.append(s)
                        if conf.debug_dissector >= 2:
                            raise
                        continue
                    if p is None:
                        continue
                    if lfilter and not lfilter(p):
                        continue
                    p.sniffed_on = sniff_sockets[s]
                    # on_packet_received handles the prn/storage
                    session.on_packet_received(p)
                    # check
                    if (stop_filter and stop_filter(p)) or \
                            (0 < count <= session.count):
                        self.continue_sniff = False
                        break
                # Removed dead sockets
                for s in dead_sockets:
                    del sniff_sockets[s]
        except KeyboardInterrupt:
            pass
        self.running = False
        if opened_socket is None:
            for s in sniff_sockets:
                s.close()
        elif close_pipe:
            close_pipe.close()
        self.results = session.toPacketList()