Exemplo n.º 1
0
 def __init__(self, iface=None, promisc=None, filter=None, nofilter=False,
              prog=None, *arg, **karg):
     self.outs = None
     args = ['-w', '-', '-s', '65535']
     if iface is not None:
         if WINDOWS:
             try:
                 args.extend(['-i', iface.pcap_name])
             except AttributeError:
                 args.extend(['-i', iface])
         else:
             args.extend(['-i', iface])
     elif WINDOWS or DARWIN:
         args.extend(['-i', conf.iface.pcap_name if WINDOWS else conf.iface])  # noqa: E501
     if not promisc:
         args.append('-p')
     if not nofilter:
         if conf.except_filter:
             if filter:
                 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
             else:
                 filter = "not (%s)" % conf.except_filter
     if filter is not None:
         args.append(filter)
     self.tcpdump_proc = tcpdump(None, prog=prog, args=args, getproc=True)
     self.ins = PcapReader(self.tcpdump_proc.stdout)
Exemplo n.º 2
0
 def __init__(self,
              iface=None,
              promisc=None,
              filter=None,
              nofilter=False,
              prog=None,
              *arg,
              **karg):
     self.outs = None
     args = ['-w', '-', '-s', '65535']
     if iface is None and (WINDOWS or DARWIN):
         iface = conf.iface
     self.iface = iface
     if iface is not None:
         args.extend(['-i', network_name(iface)])
     if not promisc:
         args.append('-p')
     if not nofilter:
         if conf.except_filter:
             if filter:
                 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
             else:
                 filter = "not (%s)" % conf.except_filter
     if filter is not None:
         args.append(filter)
     self.tcpdump_proc = tcpdump(None, prog=prog, args=args, getproc=True)
     self.ins = PcapReader(self.tcpdump_proc.stdout)
Exemplo n.º 3
0
def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg):
    """Sniff packets
sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
Select interface to sniff by setting conf.iface. Use show_interfaces() to see interface names.
  count: number of packets to capture. 0 means infinity
  store: wether to store sniffed packets or discard them
    prn: function to apply to each packet. If something is returned,
         it is displayed. Ex:
         ex: prn = lambda x: x.summary()
 filter: provide a BPF filter
lfilter: python function applied to each packet to determine
         if further action may be done
         ex: lfilter = lambda x: x.haslayer(Padding)
offline: pcap file to read packets from, instead of sniffing them
timeout: stop sniffing after a given time (default: None)
L2socket: use the provided L2socket
    """
    c = 0

    if offline is None:
        log_runtime.info('Sniffing on %s' % conf.iface)
        if L2socket is None:
            L2socket = conf.L2listen
        s = L2socket(type=ETH_P_ALL, *arg, **karg)
    else:
        flt = karg.get('filter')
        s = PcapReader(offline if flt is None else
                       tcpdump(offline, args=["-w", "-", flt], getfd=True))
    lst = []
    if timeout is not None:
        stoptime = time.time()+timeout
    remain = None
    while 1:
        try:
            if timeout is not None:
                remain = stoptime-time.time()
                if remain <= 0:
                    break

            try:
                p = s.recv(MTU)
            except PcapTimeoutElapsed:
                continue
            if p is None:
                break
            if lfilter and not lfilter(p):
                continue
            if store:
                lst.append(p)
            c += 1
            if prn:
                r = prn(p)
                if r is not None:
                    print r
            if 0 < count <= c:
                break
        except KeyboardInterrupt:
            break
    s.close()
    return plist.PacketList(lst,"Sniffed")
 def __init__(self,
              iface=None,
              promisc=None,
              filter=None,
              nofilter=False,
              prog=None,
              *arg,
              **karg):
     self.outs = None
     args = ['-w', '-', '-s', '65535']
     if iface is not None:
         if WINDOWS:
             try:
                 args.extend(['-i', iface.pcap_name])
             except AttributeError:
                 args.extend(['-i', iface])
         else:
             args.extend(['-i', iface])
     elif WINDOWS:
         args.extend(['-i', conf.iface.pcap_name])
     if not promisc:
         args.append('-p')
     if not nofilter:
         if conf.except_filter:
             if filter:
                 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
             else:
                 filter = "not (%s)" % conf.except_filter
     if filter is not None:
         args.append(filter)
     self.tcpdump_proc = tcpdump(None, prog=prog, args=args, getproc=True)
     self.ins = PcapReader(self.tcpdump_proc.stdout)
Exemplo n.º 5
0
 def __init__(
         self,
         iface=None,  # type: Optional[_GlobInterfaceType]
         promisc=False,  # type: bool
         filter=None,  # type: Optional[str]
         nofilter=False,  # type: bool
         prog=None,  # type: Optional[str]
         *arg,  # type: Any
         **karg  # type: Any
 ):
     # type: (...) -> None
     self.outs = None
     args = ['-w', '-', '-s', '65535']
     if iface is None and (WINDOWS or DARWIN):
         iface = conf.iface
     self.iface = iface
     if iface is not None:
         args.extend(['-i', network_name(iface)])
     if not promisc:
         args.append('-p')
     if not nofilter:
         if conf.except_filter:
             if filter:
                 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
             else:
                 filter = "not (%s)" % conf.except_filter
     if filter is not None:
         args.append(filter)
     self.tcpdump_proc = tcpdump(None, prog=prog, args=args, getproc=True)
     self.reader = PcapReader(self.tcpdump_proc.stdout)
     self.ins = self.reader  # type: ignore
Exemplo n.º 6
0
    def invoke(self, arg, from_tty):
        if Ether is None:
            print("ERROR: This command requires scapy to be installed.")
            return

        arg_list = gdb.string_to_argv(arg)
        if len(arg_list) == 0:
            print("Usage: ovs_dump_packets <struct dp_packet_batch|"
                  "dp_packet> [tcpdump options]")
            return

        symb_name = arg_list[0]
        tcpdump_args = arg_list[1:]

        if not tcpdump_args:
            # Add a sane default
            tcpdump_args = ["-n"]

        val = gdb.parse_and_eval(symb_name)
        while val.type.code == gdb.TYPE_CODE_PTR:
            val = val.dereference()

        pkt_list = []
        if str(val.type).startswith("struct dp_packet_batch"):
            for idx in range(val['count']):
                pkt_struct = val['packets'][idx].dereference()
                pkt = self.extract_pkt(pkt_struct)
                if pkt is None:
                    continue
                pkt_list.append(pkt)
        elif str(val.type) == "struct dp_packet":
            pkt = self.extract_pkt(val)
            if pkt is None:
                return
            pkt_list.append(pkt)
        else:
            print("Error, unsupported argument type: {}".format(str(val.type)))
            return

        tcpdump(pkt_list, args=tcpdump_args)
Exemplo n.º 7
0
 def __init__(self, iface=None, promisc=None, filter=None, nofilter=False,
              prog=None, *arg, **karg):
     self.outs = None
     args = ['-w', '-', '-s', '65535']
     if iface is not None:
         args.extend(['-i', iface])
     if not promisc:
         args.append('-p')
     if not nofilter:
         if conf.except_filter:
             if filter:
                 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
             else:
                 filter = "not (%s)" % conf.except_filter
     if filter is not None:
         args.append(filter)
     self.ins = PcapReader(tcpdump(None, prog=prog, args=args, getfd=True))
Exemplo n.º 8
0
 def __init__(self, iface=None, promisc=None, filter=None, nofilter=False,
              prog=None, *arg, **karg):
     self.outs = None
     args = ['-w', '-', '-s', '65535']
     if iface is not None:
         args.extend(['-i', iface])
     if not promisc:
         args.append('-p')
     if not nofilter:
         if conf.except_filter:
             if filter:
                 filter = "(%s) and not (%s)" % (filter, conf.except_filter)
             else:
                 filter = "not (%s)" % conf.except_filter
     if filter is not None:
         args.append(filter)
     self.ins = PcapReader(tcpdump(None, prog=prog, args=args, getfd=True))
Exemplo n.º 9
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()
Exemplo n.º 10
0
def sniff(count=0, store=True, offline=None, prn=None, lfilter=None,
          L2socket=None, timeout=None, opened_socket=None,
          stop_filter=None, iface=None, *arg, **karg):
    """

Sniff packets and return a list of packets.

Arguments:

  count: number of packets to capture. 0 means infinity.

  store: whether to store sniffed packets or discard them

  prn: function to apply to each packet. If something is returned, it
      is displayed.

      Ex: prn = lambda x: x.summary()

  filter: BPF filter to apply.

  lfilter: Python function applied to each packet to determine if
      further action may be done.

      Ex: lfilter = lambda x: x.haslayer(Padding)

  offline: PCAP file (or list of PCAP files) to read packets from,
      instead of sniffing them

  timeout: stop sniffing after a given time (default: None).

  L2socket: use the provided L2socket (default: use conf.L2listen).

  opened_socket: provide an object (or a list of objects) ready to use
      .recv() on.

  stop_filter: Python function applied to each packet to determine if
      we have to stop the capture after this packet.

      Ex: stop_filter = lambda x: x.haslayer(TCP)

  iface: interface or list of interfaces (default: None for sniffing
      on all interfaces).

The iface, offline and opened_socket parameters can be either an
element, a list of elements, or a dict object mapping an element to a
label (see examples below).

Examples:

  >>> sniff(filter="arp")

  >>> sniff(lfilter=lambda pkt: ARP in pkt)

  >>> sniff(iface="eth0", prn=Packet.summary)

  >>> sniff(iface=["eth0", "mon0"],
  ...       prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
  ...                                   pkt.summary()))

  >>> sniff(iface={"eth0": "Ethernet", "mon0": "Wifi"},
  ...       prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
  ...                                   pkt.summary()))

    """
    c = 0
    sniff_sockets = {}  # socket: label dict
    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 iteritems(opened_socket))
        else:
            sniff_sockets[opened_socket] = "socket0"
    if offline is not None:
        flt = karg.get('filter')
        if isinstance(offline, list):
            sniff_sockets.update((PcapReader(
                fname if flt is None else
                tcpdump(fname, args=["-w", "-", 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], getfd=True)
            ), label) for fname, label in iteritems(offline))
        else:
            sniff_sockets[PcapReader(
                offline if flt is None else
                tcpdump(offline, args=["-w", "-", flt], getfd=True)
            )] = offline
    if not sniff_sockets or iface is not None:
        if L2socket is None:
            L2socket = conf.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 iteritems(iface)
            )
        else:
            sniff_sockets[L2socket(type=ETH_P_ALL, iface=iface,
                                   *arg, **karg)] = iface
    lst = []
    if timeout is not None:
        stoptime = time.time()+timeout
    remain = None
    read_allowed_exceptions = ()
    if conf.use_bpf:
        from scapy.arch.bpf.supersocket import bpf_select
        def _select(sockets):
            return bpf_select(sockets, remain)
    elif WINDOWS:
        from scapy.arch.pcapdnet import PcapTimeoutElapsed
        read_allowed_exceptions = (PcapTimeoutElapsed,)
        def _select(sockets):
            try:
                return sockets
            except PcapTimeoutElapsed:
                return []
    else:
        def _select(sockets):
            try:
                return select(sockets, [], [], remain)[0]
            except select_error as exc:
                # Catch 'Interrupted system call' errors
                if exc[0] == errno.EINTR:
                    return []
                raise
    try:
        while sniff_sockets:
            if timeout is not None:
                remain = stoptime-time.time()
                if remain <= 0:
                    break
            ins = _select(sniff_sockets)
            for s in ins:
                try:
                    p = s.recv()
                except read_allowed_exceptions:
                    continue
                if p is None:
                    del sniff_sockets[s]
                    break
                if lfilter and not lfilter(p):
                    continue
                p.sniffed_on = sniff_sockets[s]
                if store:
                    lst.append(p)
                c += 1
                if prn:
                    r = prn(p)
                    if r is not None:
                        print(r)
                if stop_filter and stop_filter(p):
                    sniff_sockets = []
                    break
                if 0 < count <= c:
                    sniff_sockets = []
                    break
    except KeyboardInterrupt:
        pass
    if opened_socket is None:
        for s in sniff_sockets:
            s.close()
    return plist.PacketList(lst,"Sniffed")
Exemplo n.º 11
0
def sniff(count=0, store=1, offline=None, prn=None, lfilter=None,
          L2socket=None, timeout=None, opened_socket=None,
          stop_filter=None, iface=None, *arg, **karg):
    """Sniff packets
sniff([count=0,] [prn=None,] [store=1,] [offline=None,]
[lfilter=None,] + L2ListenSocket args) -> list of packets

  count: number of packets to capture. 0 means infinity
  store: whether to store sniffed packets or discard them
    prn: function to apply to each packet. If something is returned,
         it is displayed. Ex:
         ex: prn = lambda x: x.summary()
 filter: provide a BPF filter
lfilter: python function applied to each packet to determine
         if further action may be done
         ex: lfilter = lambda x: x.haslayer(Padding)
offline: pcap file to read packets from, instead of sniffing them
timeout: stop sniffing after a given time (default: None)
L2socket: use the provided L2socket
opened_socket: provide an object ready to use .recv() on
stop_filter: python function applied to each packet to determine
             if we have to stop the capture after this packet
             ex: stop_filter = lambda x: x.haslayer(TCP)
iface: interface or list of interfaces (default: None for sniffing on all
interfaces)
    """
    c = 0
    label = {}
    sniff_sockets = []
    if opened_socket is not None:
        sniff_sockets = [opened_socket]
    else:
        if offline is None:
            if L2socket is None:
                L2socket = conf.L2listen
            if isinstance(iface, list):
                for i in iface:
                    s = L2socket(type=ETH_P_ALL, iface=i, *arg, **karg)
                    label[s] = i
                    sniff_sockets.append(s)
            else:
                sniff_sockets = [L2socket(type=ETH_P_ALL, iface=iface, *arg,
                                           **karg)]
        else:
            flt = karg.get('filter')
            sniff_sockets = [PcapReader(
                offline if flt is None else
                tcpdump(offline, args=["-w", "-", flt], getfd=True)
            )]
    lst = []
    if timeout is not None:
        stoptime = time.time()+timeout
    remain = None
    try:
        stop_event = False
        while not stop_event:
            if timeout is not None:
                remain = stoptime-time.time()
                if remain <= 0:
                    break
            if conf.use_bpf:
                from scapy.arch.bpf.supersocket import bpf_select
                ins = bpf_select(sniff_sockets, remain)
            else:
                ins, _, _ = select(sniff_sockets, [], [], remain)
            for s in ins:
                p = s.recv()
                if p is None and offline is not None:
                    stop_event = True
                    break
                elif p is not None:
                    if lfilter and not lfilter(p):
                        continue
                    if s in label:
                        p.sniffed_on = label[s]
                    if store:
                        lst.append(p)
                    c += 1
                    if prn:
                        r = prn(p)
                        if r is not None:
                            print(r)
                    if stop_filter and stop_filter(p):
                        stop_event = True
                        break
                    if 0 < count <= c:
                        stop_event = True
                        break
    except KeyboardInterrupt:
        pass
    if opened_socket is None:
        for s in sniff_sockets:
            s.close()
    return plist.PacketList(lst,"Sniffed")
Exemplo n.º 12
0
def sniff(count=0,
          store=True,
          offline=None,
          prn=None,
          lfilter=None,
          L2socket=None,
          timeout=None,
          opened_socket=None,
          stop_filter=None,
          iface=None,
          started_callback=None,
          *arg,
          **karg):
    """Sniff packets and return a list of packets.

    Args:
        count: number of packets to capture. 0 means infinity.
        store: whether to store sniffed packets or discard them
        prn: function to apply to each packet. If something is returned, it
             is displayed.
             --Ex: prn = lambda x: x.summary()
        filter: BPF filter to apply.
        lfilter: Python function applied to each packet to determine if
                 further action may be done.
                 --Ex: lfilter = lambda x: x.haslayer(Padding)
        offline: PCAP file (or list of PCAP files) to read packets from,
                 instead of sniffing them
        timeout: stop sniffing after a given time (default: None).
        L2socket: use the provided L2socket (default: use conf.L2listen).
        opened_socket: provide an object (or a list of objects) ready to use
                      .recv() on.
        stop_filter: Python function applied to each packet to determine if
                     we have to stop the capture after this packet.
                     --Ex: stop_filter = lambda x: x.haslayer(TCP)
        iface: interface or list of interfaces (default: None for sniffing
               on all interfaces).
        monitor: use monitor mode. May not be available on all OS
        started_callback: called as soon as the sniffer starts sniffing
                          (default: None).

    The iface, offline and opened_socket parameters can be either an
    element, a list of elements, or a dict object mapping an element to a
    label (see examples below).

    Examples:
      >>> sniff(filter="arp")
      >>> sniff(lfilter=lambda pkt: ARP in pkt)
      >>> sniff(iface="eth0", prn=Packet.summary)
      >>> sniff(iface=["eth0", "mon0"],
      ...       prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
      ...                                   pkt.summary()))
      >>> sniff(iface={"eth0": "Ethernet", "mon0": "Wifi"},
      ...       prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
      ...                                   pkt.summary()))
    """
    c = 0
    sniff_sockets = {}  # socket: label dict
    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):
            sniff_sockets.update((PcapReader(fname if flt is None else tcpdump(
                fname, args=["-w", "-", 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], getfd=True)), label)
                                 for fname, label in six.iteritems(offline))
        else:
            sniff_sockets[PcapReader(offline if flt is None else tcpdump(
                offline, args=["-w", "-", flt], getfd=True))] = offline
    if not sniff_sockets or iface is not None:
        if L2socket is None:
            L2socket = conf.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
    lst = []
    if timeout is not None:
        stoptime = time.time() + timeout
    remain = None

    # Get select information from the sockets
    _main_socket = next(iter(sniff_sockets))
    read_allowed_exceptions = _main_socket.read_allowed_exceptions
    select_func = _main_socket.select
    # 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")
    # Now let's build the select function, used later on
    _select = lambda sockets, remain: select_func(sockets, remain)[0]

    try:
        if started_callback:
            started_callback()
        while sniff_sockets:
            if timeout is not None:
                remain = stoptime - time.time()
                if remain <= 0:
                    break
            for s in _select(sniff_sockets, remain):
                try:
                    p = s.recv()
                except socket.error as ex:
                    log_runtime.warning("Socket %s failed with '%s' and thus"
                                        " will be ignored" % (s, ex))
                    del sniff_sockets[s]
                    continue
                except read_allowed_exceptions:
                    continue
                if p is None:
                    try:
                        if s.promisc:
                            continue
                    except AttributeError:
                        pass
                    del sniff_sockets[s]
                    break
                if lfilter and not lfilter(p):
                    continue
                p.sniffed_on = sniff_sockets[s]
                if store:
                    lst.append(p)
                c += 1
                if prn:
                    r = prn(p)
                    if r is not None:
                        print(r)
                if stop_filter and stop_filter(p):
                    sniff_sockets = []
                    break
                if 0 < count <= c:
                    sniff_sockets = []
                    break
    except KeyboardInterrupt:
        pass
    if opened_socket is None:
        for s in sniff_sockets:
            s.close()
    return plist.PacketList(lst, "Sniffed")
Exemplo n.º 13
0
def sniff(count=0, store=True, offline=None, prn=None, lfilter=None,
          L2socket=None, timeout=None, opened_socket=None,
          stop_filter=None, iface=None, *arg, **karg):
    """

Sniff packets and return a list of packets.

Arguments:

  count: number of packets to capture. 0 means infinity.

  store: whether to store sniffed packets or discard them

  prn: function to apply to each packet. If something is returned, it
      is displayed.

      Ex: prn = lambda x: x.summary()

  filter: BPF filter to apply.

  lfilter: Python function applied to each packet to determine if
      further action may be done.

      Ex: lfilter = lambda x: x.haslayer(Padding)

  offline: PCAP file (or list of PCAP files) to read packets from,
      instead of sniffing them

  timeout: stop sniffing after a given time (default: None).

  L2socket: use the provided L2socket (default: use conf.L2listen).

  opened_socket: provide an object (or a list of objects) ready to use
      .recv() on.

  stop_filter: Python function applied to each packet to determine if
      we have to stop the capture after this packet.

      Ex: stop_filter = lambda x: x.haslayer(TCP)

  iface: interface or list of interfaces (default: None for sniffing
      on all interfaces).

The iface, offline and opened_socket parameters can be either an
element, a list of elements, or a dict object mapping an element to a
label (see examples below).

Examples:

  >>> sniff(filter="arp")

  >>> sniff(lfilter=lambda pkt: ARP in pkt)

  >>> sniff(iface="eth0", prn=Packet.summary)

  >>> sniff(iface=["eth0", "mon0"],
  ...       prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
  ...                                   pkt.summary()))

  >>> sniff(iface={"eth0": "Ethernet", "mon0": "Wifi"},
  ...       prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
  ...                                   pkt.summary()))

    """
    c = 0
    sniff_sockets = {}  # socket: label dict
    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 iteritems(opened_socket))
        else:
            sniff_sockets[opened_socket] = "socket0"
    if offline is not None:
        flt = karg.get('filter')
        if isinstance(offline, list):
            sniff_sockets.update((PcapReader(
                fname if flt is None else
                tcpdump(fname, args=["-w", "-", 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], getfd=True)
            ), label) for fname, label in iteritems(offline))
        else:
            sniff_sockets[PcapReader(
                offline if flt is None else
                tcpdump(offline, args=["-w", "-", flt], getfd=True)
            )] = offline
    if not sniff_sockets or iface is not None:
        if L2socket is None:
            L2socket = conf.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 iteritems(iface)
            )
        else:
            sniff_sockets[L2socket(type=ETH_P_ALL, iface=iface,
                                   *arg, **karg)] = iface
    lst = []
    if timeout is not None:
        stoptime = time.time()+timeout
    remain = None
    read_allowed_exceptions = ()
    if conf.use_bpf:
        from scapy.arch.bpf.supersocket import bpf_select
        def _select(sockets):
            return bpf_select(sockets, remain)
    elif WINDOWS:
        from scapy.arch.pcapdnet import PcapTimeoutElapsed
        read_allowed_exceptions = (PcapTimeoutElapsed,)
        def _select(sockets):
            try:
                return sockets
            except PcapTimeoutElapsed:
                return []
    else:
        def _select(sockets):
            try:
                return select(sockets, [], [], remain)[0]
            except select_error as exc:
                # Catch 'Interrupted system call' errors
                if exc[0] == errno.EINTR:
                    return []
                raise
    try:
        while sniff_sockets:
            if timeout is not None:
                remain = stoptime-time.time()
                if remain <= 0:
                    break
            ins = _select(sniff_sockets)
            for s in ins:
                try:
                    p = s.recv()
                except read_allowed_exceptions:
                    continue
                if p is None:
                    del sniff_sockets[s]
                    break
                if lfilter and not lfilter(p):
                    continue
                p.sniffed_on = sniff_sockets[s]
                if store:
                    lst.append(p)
                c += 1
                if prn:
                    r = prn(p)
                    if r is not None:
                        print(r)
                if stop_filter and stop_filter(p):
                    sniff_sockets = []
                    break
                if 0 < count <= c:
                    sniff_sockets = []
                    break
    except KeyboardInterrupt:
        pass
    if opened_socket is None:
        for s in sniff_sockets:
            s.close()
    return plist.PacketList(lst,"Sniffed")
Exemplo n.º 14
0
def sniff(count=0, store=1, offline=None, prn = None, stop_filter=None, lfilter=None, L2socket=None, timeout=None, *arg, **karg):
    """Sniff packets
sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets
Select interface to sniff by setting conf.iface. Use show_interfaces() to see interface names.
  count: number of packets to capture. 0 means infinity
  store: whether to store sniffed packets or discard them
    prn: function to apply to each packet. If something is returned,
         it is displayed. Ex:
         ex: prn = lambda x: x.summary()
 filter: provide a BPF filter
lfilter: python function applied to each packet to determine
         if further action may be done
         ex: lfilter = lambda x: x.haslayer(Padding)
offline: pcap file to read packets from, instead of sniffing them
timeout: stop sniffing after a given time (default: None)
L2socket: use the provided L2socket
stop_filter: python function applied to each packet to determine
             if we have to stop the capture after this packet
             ex: stop_filter = lambda x: x.haslayer(TCP)
    """
    c = 0

    if offline is None:
        log_runtime.info('Sniffing on %s' % conf.iface)
        if L2socket is None:
            L2socket = conf.L2listen
        s = L2socket(type=ETH_P_ALL, *arg, **karg)
    else:
        flt = karg.get('filter')
        s = PcapReader(offline if flt is None else
                       tcpdump(offline, args=["-w", "-", flt], getfd=True))
    lst = []
    if timeout is not None:
        stoptime = time.time()+timeout
    remain = None
    while True:
        try:
            if timeout is not None:
                remain = stoptime-time.time()
                if remain <= 0:
                    break

            try:
                p = s.recv(MTU)
            except PcapTimeoutElapsed:
                continue
            if p is None:
                break
            if lfilter and not lfilter(p):
                continue
            if store:
                lst.append(p)
            c += 1
            if prn:
                r = prn(p)
                if r is not None:
                    print r
            if stop_filter and stop_filter(p):
                break
            if 0 < count <= c:
                break
        except KeyboardInterrupt:
            break
    s.close()
    return plist.PacketList(lst,"Sniffed")
Exemplo n.º 15
0
    def _run(self,
             count=0,
             store=True,
             offline=None,
             prn=None,
             lfilter=None,
             L2socket=None,
             timeout=None,
             opened_socket=None,
             stop_filter=None,
             iface=None,
             started_callback=None,
             session=None,
             *arg,
             **karg):
        self.running = True
        # Start main thread
        c = 0
        session = session or DefaultSession
        session = session(prn, store)  # instantiate session
        # 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')
            from scapy.arch.common import TCPDUMP
            if not TCPDUMP and flt is not None:
                message = "tcpdump is not available. Cannot use filter!"
                raise Scapy_Exception(message)

            if isinstance(offline, list):
                sniff_sockets.update(
                    (PcapReader(fname if flt is None else tcpdump(
                        fname, args=["-w", "-", 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], getfd=True)), label)
                    for fname, label in six.iteritems(offline))
            else:
                sniff_sockets[PcapReader(offline if flt is None else tcpdump(
                    offline, args=["-w", "-", flt], getfd=True))] = offline
        if not sniff_sockets or iface is not None:
            if L2socket is None:
                L2socket = conf.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))
        read_allowed_exceptions = _main_socket.read_allowed_exceptions
        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")

        # Fill if empty
        if not read_allowed_exceptions:
            read_allowed_exceptions = (IOError, )

        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
                        dead_sockets.append(s)
                        continue
                    except read_allowed_exceptions:
                        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)
                        continue
                    if p is None:
                        continue
                    if lfilter and not lfilter(p):
                        continue
                    p.sniffed_on = sniff_sockets[s]
                    c += 1
                    # on_packet_received handles the prn/storage
                    session.on_packet_received(p)
                    # check
                    if (stop_filter and stop_filter(p)) or (0 < count <= c):
                        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()
Exemplo n.º 16
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()
Exemplo n.º 17
0
def sniff(count=0, store=True, offline=None, prn=None, lfilter=None,
          L2socket=None, timeout=None, opened_socket=None,
          stop_filter=None, iface=None, started_callback=None, *arg, **karg):
    """Sniff packets and return a list of packets.

    Args:
        count: number of packets to capture. 0 means infinity.
        store: whether to store sniffed packets or discard them
        prn: function to apply to each packet. If something is returned, it
             is displayed.
             --Ex: prn = lambda x: x.summary()
        filter: BPF filter to apply.
        lfilter: Python function applied to each packet to determine if
                 further action may be done.
                 --Ex: lfilter = lambda x: x.haslayer(Padding)
        offline: PCAP file (or list of PCAP files) to read packets from,
                 instead of sniffing them
        timeout: stop sniffing after a given time (default: None).
        L2socket: use the provided L2socket (default: use conf.L2listen).
        opened_socket: provide an object (or a list of objects) ready to use
                      .recv() on.
        stop_filter: Python function applied to each packet to determine if
                     we have to stop the capture after this packet.
                     --Ex: stop_filter = lambda x: x.haslayer(TCP)
        iface: interface or list of interfaces (default: None for sniffing
               on all interfaces).
        monitor: use monitor mode. May not be available on all OS
        started_callback: called as soon as the sniffer starts sniffing
                          (default: None).

    The iface, offline and opened_socket parameters can be either an
    element, a list of elements, or a dict object mapping an element to a
    label (see examples below).

    Examples:
      >>> sniff(filter="arp")
      >>> sniff(lfilter=lambda pkt: ARP in pkt)
      >>> sniff(iface="eth0", prn=Packet.summary)
      >>> sniff(iface=["eth0", "mon0"],
      ...       prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
      ...                                   pkt.summary()))
      >>> sniff(iface={"eth0": "Ethernet", "mon0": "Wifi"},
      ...       prn=lambda pkt: "%s: %s" % (pkt.sniffed_on,
      ...                                   pkt.summary()))
    """
    c = 0
    sniff_sockets = {}  # socket: label dict
    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):
            sniff_sockets.update((PcapReader(
                fname if flt is None else
                tcpdump(fname, args=["-w", "-", 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], getfd=True)
            ), label) for fname, label in six.iteritems(offline))
        else:
            sniff_sockets[PcapReader(
                offline if flt is None else
                tcpdump(offline, args=["-w", "-", flt], getfd=True)
            )] = offline
    if not sniff_sockets or iface is not None:
        if L2socket is None:
            L2socket = conf.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
    lst = []
    if timeout is not None:
        stoptime = time.time() + timeout
    remain = None

    # Get select information from the sockets
    _main_socket = next(iter(sniff_sockets))
    read_allowed_exceptions = _main_socket.read_allowed_exceptions
    select_func = _main_socket.select
    # 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")
    # Now let's build the select function, used later on
    _select = lambda sockets, remain: select_func(sockets, remain)[0]

    try:
        if started_callback:
            started_callback()
        while sniff_sockets:
            if timeout is not None:
                remain = stoptime - time.time()
                if remain <= 0:
                    break
            for s in _select(sniff_sockets, remain):
                try:
                    p = s.recv()
                except socket.error as ex:
                    log_runtime.warning("Socket %s failed with '%s' and thus"
                                        " will be ignored" % (s, ex))
                    del sniff_sockets[s]
                    continue
                except read_allowed_exceptions:
                    continue
                if p is None:
                    try:
                        if s.promisc:
                            continue
                    except AttributeError:
                        pass
                    del sniff_sockets[s]
                    break
                if lfilter and not lfilter(p):
                    continue
                p.sniffed_on = sniff_sockets[s]
                if store:
                    lst.append(p)
                c += 1
                if prn:
                    r = prn(p)
                    if r is not None:
                        print(r)
                if stop_filter and stop_filter(p):
                    sniff_sockets = []
                    break
                if 0 < count <= c:
                    sniff_sockets = []
                    break
    except KeyboardInterrupt:
        pass
    if opened_socket is None:
        for s in sniff_sockets:
            s.close()
    return plist.PacketList(lst, "Sniffed")