示例#1
0
def sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=False,
           retry=0, multi=False):
    if not isinstance(pkt, Gen):
        pkt = SetGen(pkt)
    if verbose is None:
        verbose = conf.verb
    debug.recv = plist.PacketList([],"Unanswered")
    debug.sent = plist.PacketList([],"Sent")
    debug.match = plist.SndRcvList([])
    nbrecv=0
    # do it here to fix random fields, so that parent and child have the same
    tobesent = [p for p in pkt]
    notans = len(tobesent)

    if retry < 0:
        retry = -retry
        autostop = retry
    else:
        autostop = 0

    while retry >= 0:
        if timeout < 0:
            timeout = None
        stopevent = threading.Event()

        thread = threading.Thread(
            target=_sndrcv_snd,
            args=(pks, timeout, inter, verbose, tobesent, stopevent),
        )
        thread.start()

        hsent, ans, nbrecv, notans = _sndrcv_rcv(pks, tobesent, stopevent, nbrecv, notans, verbose, chainCC, multi)
        thread.join()

        remain = list(itertools.chain(*six.itervalues(hsent)))
        if multi:
            remain = [p for p in remain if not hasattr(p, '_answered')]

        if autostop and len(remain) > 0 and len(remain) != len(tobesent):
            retry = autostop
            
        tobesent = remain
        if len(tobesent) == 0:
            break
        retry -= 1

    if conf.debug_match:
        debug.sent=plist.PacketList(remain[:], "Sent")
        debug.match=plist.SndRcvList(ans[:])

    # Clean the ans list to delete the field _answered
    if multi:
        for snd, _ in ans:
            if hasattr(snd, '_answered'):
                del snd._answered

    if verbose:
        print("\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans))
    return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
示例#2
0
def profile_sessions(pcap_reader):
    packets = []
    print('Getting details from packets.')
    first_timestamp = None
    last_timestamp = None
    for packet in pcap_reader:
        if IP not in packet:
            continue
        if TCP not in packet:
            continue
        if not first_timestamp:
            first_timestamp = packet.time
        if not last_timestamp:
            last_timestamp = packet.time
        if packet.time < first_timestamp:
            first_timestamp = packet.time
        elif packet.time > last_timestamp:
            last_timestamp = packet.time
        packets.append(packet)
    packets = plist.PacketList(packets)
    print('Analyzing sessions.')
    sessions = packets.sessions()
    profile = {
        'start_timestamp': float(first_timestamp),
        'end_timestamp': float(last_timestamp),
        'duration_secs': float(last_timestamp - first_timestamp),
        'total_packets': len(packets),
        'total_sessions': len(sessions)
    }
    profile['avg_pps'] = profile['duration_secs'] / profile['total_packets']
    profile['packets_to_sessions_ratio'] = profile['total_packets'] / profile[
        'total_sessions']
    return profile
示例#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")
示例#4
0
def sndrcvflood(pks, pkt, inter=0, verbose=None, chainCC=False, prn=lambda x: x):
    if not verbose:
        verbose = conf.verb
    is_single = isinstance(pkt, Gen)
    pkts = [pkt] if is_single else pkt
    tobesent = [p for p in (pkt if is_single else SetGen(pkt))]

    stopevent = threading.Event()
    count_packets = six.moves.queue.Queue()

    def send_in_loop(tobesent, stopevent, count_packets=count_packets):
        """Infinite generator that produces the same packet until stopevent is triggered."""
        while True:
            for p in tobesent:
                if stopevent.is_set():
                    raise StopIteration()
                count_packets.put(0)
                yield p

    infinite_gen = send_in_loop(tobesent, stopevent)

    for pkt in pkts:
        pkt.sent_time = None
    # We don't use _sndrcv_snd verbose (it messes the logs up as in a thread that ends after recieving)
    thread = threading.Thread(
        target=_sndrcv_snd,
        args=(pks, None, inter, False, infinite_gen, stopevent),
    )
    thread.start()

    hsent, ans, nbrecv, notans = _sndrcv_rcv(pks, tobesent, stopevent, 0, len(tobesent), verbose, chainCC, False)
    thread.join()

    ans = [(x, prn(y)) for (x, y) in ans]  # Apply prn
    to_set_time = [pkt for pkt in pkts if pkt.sent_time is None]
    if to_set_time:
        try:
            sent_time = min(p.sent_time for p in tobesent if getattr(p, "sent_time", None))
        except ValueError:
            pass
        else:
            for pkt in to_set_time:
                pkt.sent_time = sent_time

    remain = list(itertools.chain(*six.itervalues(hsent)))

    if verbose:
        print("\nReceived %i packets, got %i answers, remaining %i packets. Sent a total of %i packets." % (nbrecv+len(ans), len(ans), notans, count_packets.qsize()))
    count_packets.empty()
    del count_packets

    return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
示例#5
0
def __gen_send(s,
               x,
               inter=0,
               loop=0,
               count=None,
               verbose=None,
               realtime=None,
               return_packets=False,
               *args,
               **kargs):
    if type(x) is str:
        x = conf.raw_layer(load=x)
    if not isinstance(x, Gen):
        x = SetGen(x)
    if verbose is None:
        verbose = conf.verb
    n = 0
    if count is not None:
        loop = -count
    elif not loop:
        loop = -1
    if return_packets:
        sent_packets = plist.PacketList()
    try:
        while loop:
            dt0 = None
            for p in x:
                if realtime:
                    ct = time.time()
                    if dt0:
                        st = dt0 + p.time - ct
                        if st > 0:
                            time.sleep(st)
                    else:
                        dt0 = ct - p.time
                s.send(p)
                if return_packets:
                    sent_packets.append(p)
                n += 1
                if verbose:
                    os.write(1, ".")
                time.sleep(inter)
            if loop < 0:
                loop += 1
    except KeyboardInterrupt:
        pass
    s.close()
    if verbose:
        print "\nSent %i packets." % n
    if return_packets:
        return sent_packets
示例#6
0
def __sr_loop(srfunc, pkts, prn=lambda x:x[1].summary(), prnfail=lambda x:x.summary(), inter=1, timeout=None, count=None, verbose=None, store=1, *args, **kargs):
    n = 0
    r = 0
    ct = conf.color_theme
    if verbose is None:
        verbose = conf.verb
    parity = 0
    ans=[]
    unans=[]
    if timeout is None:
        timeout = min(2*inter, 5)
    try:
        while True:
            parity ^= 1
            col = [ct.even,ct.odd][parity]
            if count is not None:
                if count == 0:
                    break
                count -= 1
            start = time.time()
            if verbose > 1:
                print("\rsend...\r", end=' ')
            res = srfunc(pkts, timeout=timeout, verbose=0, chainCC=True, *args, **kargs)
            n += len(res[0])+len(res[1])
            r += len(res[0])
            if verbose > 1 and prn and len(res[0]) > 0:
                msg = "RECV %i:" % len(res[0])
                print("\r"+ct.success(msg), end=' ')
                for p in res[0]:
                    print(col(prn(p)))
                    print(" "*len(msg), end=' ')
            if verbose > 1 and prnfail and len(res[1]) > 0:
                msg = "fail %i:" % len(res[1])
                print("\r"+ct.fail(msg), end=' ')
                for p in res[1]:
                    print(col(prnfail(p)))
                    print(" "*len(msg), end=' ')
            if verbose > 1 and not (prn or prnfail):
                print("recv:%i  fail:%i" % tuple(map(len, res[:2])))
            if store:
                ans += res[0]
                unans += res[1]
            end=time.time()
            if end-start < inter:
                time.sleep(inter+start-end)
    except KeyboardInterrupt:
        pass
 
    if verbose and n>0:
        print(ct.normal("\nSent %i packets, received %i packets. %3.1f%% hits." % (n,r,100.0*r/n)))
    return plist.SndRcvList(ans),plist.PacketList(unans)
示例#7
0
    def mysniff(self, *arg, **karg):
        c = 0

        if self.opened_socket is not None:
            s = self.opened_socket
        else:
            if self.offline is None:
                if self.L2socket is None:
                    self.L2socket = conf.L2listen
                s = self.L2socket(type=ETH_P_ALL, *arg, **karg)
            else:
                s = PcapReader(self.offline)

        lst = []
        if self.timeout is not None:
            stoptime = time.time() + self.timeout
        remain = None
        while 1:
            if not self.running:
                break
            try:
                if self.timeout is not None:
                    remain = stoptime - time.time()
                    if remain <= 0:
                        break
                sel = select([s], [], [], remain)
                if s in sel[0]:
                    p = s.recv(MTU)
                    if p is None:
                        break
                    if self.lfilter and not self.lfilter(p):
                        continue
                    if self.store:
                        lst.append(p)
                    c += 1
                    if self.prn:
                        r = self.prn(p)
                        if r is not None:
                            print r
                    if self.stop_filter and self.stop_filter(p):
                        break
                    if 0 < self.count <= c:
                        break
            except KeyboardInterrupt:
                break
        if self.opened_socket is None:
            s.close()
        return plist.PacketList(lst, "Sniffed")
def profile_sessions(pcap_reader):
    packets = []
    print('Getting details from packets.')

    # declaring timestamps
    first_timestamp, last_timestamp = None, None
    for packet in pcap_reader:
        if IP not in packet:
            continue
        if TCP not in packet:
            continue
        if not first_timestamp:
            first_timestamp = packet.time
        if not last_timestamp:
            last_timestamp = packet.time
        if packet.time < first_timestamp:
            first_timestamp = packet.time
        elif packet.time > last_timestamp:
            last_timestamp = packet.time

        # appending timestamps (timestamp of the first and last packet) in the packet list
        packets.append(packet)

    # Scapy packet list (python object)
    packets = plist.PacketList(packets)
    print('Analyzing sessions.')

    # grabbing packets sessions
    sessions = packets.sessions()

    # calcuting the profile data
    profile = {
        'start_timestamp': float(first_timestamp),
        'end_timestamp': float(last_timestamp),
        'duration_secs': float(last_timestamp - first_timestamp),
        'total_packets': len(packets),
        'total_sessions': len(sessions)
    }

    # calculating average per second
    profile['avg_pps'] = profile['duration_secs'] / profile['total_packets']

    # calculating ratio
    profile['packets_to_sessions_ratio'] = profile['total_packets'] / profile[
        'total_sessions']
    return profile
示例#9
0
    def sniff(opened_socket,
              count=0,
              store=True,
              timeout=None,
              prn=None,
              stop_filter=None,
              lfilter=None,
              started_callback=None):
        from scapy import plist
        m = ISOTPMessageBuilder()
        c = ISOTPSniffer.Closure()
        c.max_count = count

        def internal_prn(p):
            m.feed(p)
            while not c.stop and m.count() > 0:
                rcvd = m.pop()
                on_pkt(rcvd)

        def internal_stop_filter(p):
            return c.stop

        def on_pkt(p):
            if lfilter and not lfilter(p):
                return
            p.sniffed_on = opened_socket
            if store:
                c.lst.append(p)
            c.count += 1
            if prn is not None:
                r = prn(p)
                if r is not None:
                    print(r)
            if stop_filter and stop_filter(p):
                c.stop = True
                return
            if 0 < c.max_count <= c.count:
                c.stop = True
                return

        opened_socket.sniff(timeout=timeout,
                            prn=internal_prn,
                            stop_filter=internal_stop_filter,
                            started_callback=started_callback)
        return plist.PacketList(c.lst, "Sniffed")
示例#10
0
def sniff(store=False,
          prn=None,
          lfilter=None,
          stop_event=None,
          refresh=.1,
          *args,
          **kwargs):
    """Sniff packets
sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args)

  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()
lfilter: python function applied to each packet to determine
         if further action may be done
         ex: lfilter = lambda x: x.haslayer(Padding)
stop_event: Event that stops the function when set
refresh: check stop_event.set() every refresh seconds
    """
    s = conf.L2listen(type=ETH_P_ALL, *args, **kwargs)
    lst = []
    try:
        while True:
            if stop_event and stop_event.is_set():
                break
            sel = select([s], [], [], refresh)
            if s in sel[0]:
                p = s.recv(MTU)
                if p is None:
                    break
                if lfilter and not lfilter(p):
                    continue
                if store:
                    lst.append(p)
                if prn:
                    r = prn(p)
                    if r is not None:
                        print(r)
    except KeyboardInterrupt:
        pass
    finally:
        s.close()

    return plist.PacketList(lst, "Sniffed")
示例#11
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")
示例#12
0
 def read_all(self,count=-1):
     res = RawPcapNgReader.read_all(self, count)
     from scapy import plist
     return plist.PacketList(res, name=os.path.basename(self.filename))
示例#13
0
def sniff(store=False,
          prn=None,
          lfilter=None,
          stop_event=None,
          refresh=0.1,
          offline=None,
          *args,
          **kwargs):
    """Sniff packets
sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args)
Modified version of scapy.all.sniff

store : bool
    wether to store sniffed packets or discard them

prn : None or callable
    function to apply to each packet. If something is returned,
    it is displayed.
    ex: prn = lambda x: x.summary()

lfilter : None or callable
    function applied to each packet to determine
    if further action may be done
    ex: lfilter = lambda x: x.haslayer(Padding)

stop_event : None or Event
    Event that stops the function when set

refresh : float
    check stop_event.set() every `refresh` seconds
    """
    logger.debug("Setting up sniffer...")
    if offline is None:
        L2socket = conf.L2listen
        s = L2socket(type=ETH_P_ALL, *args, **kwargs)
    else:
        s = PcapReader(offline)

    # on Windows, it is not possible to select a L2socket
    if WINDOWS:
        from scapy.arch.pcapdnet import PcapTimeoutElapsed

        read_allowed_exceptions = (PcapTimeoutElapsed, )

        def _select(sockets):
            return sockets

    else:
        read_allowed_exceptions = ()

        def _select(sockets):
            try:
                return select(sockets, [], [], refresh)[0]
            except OSError as exc:
                # Catch 'Interrupted system call' errors
                if exc.errno == errno.EINTR:
                    return []
                raise

    lst = []
    try:
        logger.debug("Started Sniffing")
        while True:
            if stop_event and stop_event.is_set():
                break
            sel = _select([s])
            if s in sel:
                try:
                    p = s.recv(MTU)
                except read_allowed_exceptions:
                    # could add a sleep(refresh) if the CPU usage
                    # is too much on windows
                    continue
                if p is None:
                    break
                if lfilter and not lfilter(p):
                    continue
                if store:
                    lst.append(p)
                if prn:
                    r = prn(p)
                    if r is not None:
                        print(r)
    except KeyboardInterrupt:
        pass
    finally:
        logger.debug("Stopped sniffing.")
        s.close()

    return plist.PacketList(lst, "Sniffed")
示例#14
0
 def plist(self, pkts=None):
     return plist.PacketList(pkts)
示例#15
0
文件: __init__.py 项目: ouje/scapy
def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0):
    if not isinstance(pkt, Gen):
        pkt = SetGen(pkt)
        
    if verbose is None:
        verbose = conf.verb
    debug.recv = plist.PacketList([],"Unanswered")
    debug.sent = plist.PacketList([],"Sent")
    debug.match = plist.SndRcvList([])
    nbrecv=0
    ans = []
    # do it here to fix random fields, so that parent and child have the same
    all_stimuli = tobesent = [p for p in pkt]
    notans = len(tobesent)

    hsent={}
    for i in tobesent:
        h = i.hashret()
        if h in hsent:
            hsent[h].append(i)
        else:
            hsent[h] = [i]
    if retry < 0:
        retry = -retry
        autostop=retry
    else:
        autostop=0


    while retry >= 0:
        found=0
    
        if timeout < 0:
            timeout = None

        pid=1
        try:
            if WINDOWS or pid == 0:
                try:
                    try:
                        i = 0
                        if verbose:
                            print("Begin emission:")
                        for p in tobesent:
                            pks.send(p)
                            i += 1
                            time.sleep(inter)
                        if verbose:
                            print("Finished to send %i packets." % i)
                    except SystemExit:
                        pass
                    except KeyboardInterrupt:
                        pass
                    except:
                        log_runtime.exception("--- Error sending packets")
                        log_runtime.info("--- Error sending packets")
                finally:
                    try:
                        sent_times = [p.sent_time for p in all_stimuli if p.sent_time]
                    except:
                        pass
            if WINDOWS or pid > 0:
                # Timeout starts after last packet is sent (as in Unix version) 
                if timeout:
                    stoptime = time.time()+timeout
                else:
                    stoptime = 0
                remaintime = None
                # inmask = [pks.ins.fd]
                try:
                    try:
                        while 1:
                            if stoptime:
                                remaintime = stoptime-time.time()
                                if remaintime <= 0:
                                    break
                            r = pks.recv(MTU)
                            if r is None:
                                continue
                            ok = 0
                            h = r.hashret()
                            if h in hsent:
                                hlst = hsent[h]
                                for i in range(len(hlst)):
                                    if r.answers(hlst[i]):
                                        ans.append((hlst[i],r))
                                        if verbose > 1:
                                            os.write(1, b"*")
                                        ok = 1                                
                                        if not multi:
                                            del(hlst[i])
                                            notans -= 1;
                                        else:
                                            if not hasattr(hlst[i], '_answered'):
                                                notans -= 1;
                                            hlst[i]._answered = 1;
                                        break
                            if notans == 0 and not multi:
                                break
                            if not ok:
                                if verbose > 1:
                                    os.write(1, b".")
                                nbrecv += 1
                                if conf.debug_match:
                                    debug.recv.append(r)
                    except KeyboardInterrupt:
                        if chainCC:
                            raise
                finally:
                    if WINDOWS:
                        for p,t in zip(all_stimuli, sent_times):
                            p.sent_time = t
        finally:
            pass

        # remain = reduce(list.__add__, hsent.values(), [])
        remain = list(itertools.chain(*[ i for i in hsent.values() ]))

        if multi:
            #remain = filter(lambda p: not hasattr(p, '_answered'), remain);
            remain = [ p for p in remain if not hasattr(p, '_answered')]
            
        if autostop and len(remain) > 0 and len(remain) != len(tobesent):
            retry = autostop
            
        tobesent = remain
        if len(tobesent) == 0:
            break
        retry -= 1
        
    if conf.debug_match:
        debug.sent=plist.PacketList(remain[:],"Sent")
        debug.match=plist.SndRcvList(ans[:])

    #clean the ans list to delete the field _answered
    if (multi):
        for s,r in ans:
            if hasattr(s, '_answered'):
                del(s._answered)
    
    if verbose:
        print("\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans))
    return plist.SndRcvList(ans),plist.PacketList(remain,"Unanswered")
示例#16
0
def sndrcv(pks,
           pkt,
           timeout=None,
           inter=0,
           verbose=None,
           chainCC=False,
           retry=0,
           multi=False):
    if not isinstance(pkt, Gen):
        pkt = SetGen(pkt)
    if verbose is None:
        verbose = conf.verb
    debug.recv = plist.PacketList([], "Unanswered")
    debug.sent = plist.PacketList([], "Sent")
    debug.match = plist.SndRcvList([])
    nbrecv = 0
    ans = []
    # do it here to fix random fields, so that parent and child have the same
    tobesent = [p for p in pkt]
    notans = len(tobesent)

    hsent = {}
    for i in tobesent:
        h = i.hashret()
        hsent.setdefault(i.hashret(), []).append(i)

    if retry < 0:
        retry = -retry
        autostop = retry
    else:
        autostop = 0

    if WINDOWS:

        def _get_pkt():
            return pks.recv(MTU)
    elif conf.use_bpf:
        from scapy.arch.bpf.supersocket import bpf_select

        def _get_pkt():
            if bpf_select([pks]):
                return pks.recv()
    elif conf.use_pcap or (not isinstance(pks, StreamSocket) and
                           (DARWIN or FREEBSD or OPENBSD)):

        def _get_pkt():
            res = pks.nonblock_recv()
            if res is None:
                time.sleep(0.05)
            return res
    else:

        def _get_pkt():
            try:
                inp, _, _ = select([pks], [], [], 0.05)
            except (IOError, select_error) as exc:
                # select.error has no .errno attribute
                if exc.args[0] != errno.EINTR:
                    raise
            else:
                if inp:
                    return pks.recv(MTU)
            if stopevent.is_set():
                raise _BreakException()

    while retry >= 0:
        if timeout < 0:
            timeout = None
        stopevent = threading.Event()

        thread = threading.Thread(
            target=_sndrcv_snd,
            args=(pks, timeout, inter, verbose, tobesent, stopevent),
        )
        thread.start()

        try:
            try:
                while True:
                    r = _get_pkt()
                    if r is None:
                        if stopevent.is_set():
                            break
                        continue
                    ok = False
                    h = r.hashret()
                    if h in hsent:
                        hlst = hsent[h]
                        for i, sentpkt in enumerate(hlst):
                            if r.answers(sentpkt):
                                ans.append((sentpkt, r))
                                if verbose > 1:
                                    os.write(1, b"*")
                                ok = True
                                if not multi:
                                    del hlst[i]
                                    notans -= 1
                                else:
                                    if not hasattr(sentpkt, '_answered'):
                                        notans -= 1
                                    sentpkt._answered = 1
                                break
                    if notans == 0 and not multi:
                        break
                    if not ok:
                        if verbose > 1:
                            os.write(1, b".")
                        nbrecv += 1
                        if conf.debug_match:
                            debug.recv.append(r)
            except KeyboardInterrupt:
                if chainCC:
                    raise
            except _BreakException:
                pass
        finally:
            stopevent.set()
            thread.join()
            pks.close()

        remain = list(itertools.chain(*six.itervalues(hsent)))
        if multi:
            remain = [p for p in remain if not hasattr(p, '_answered')]

        if autostop and len(remain) > 0 and len(remain) != len(tobesent):
            retry = autostop

        tobesent = remain
        if len(tobesent) == 0:
            break
        retry -= 1

    if conf.debug_match:
        debug.sent = plist.PacketList(remain[:], "Sent")
        debug.match = plist.SndRcvList(ans[:])

    # Clean the ans list to delete the field _answered
    if multi:
        for snd, _ in ans:
            if hasattr(snd, '_answered'):
                del snd._answered

    if verbose:
        print("\nReceived %i packets, got %i answers, remaining %i packets" %
              (nbrecv + len(ans), len(ans), notans))
    return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
示例#17
0
def sndrcvflood(pks,
                pkt,
                inter=0,
                verbose=None,
                chainCC=False,
                store_unanswered=True,
                process=None,
                timeout=None):  # noqa: E501
    if not verbose:
        verbose = conf.verb
    listable = (isinstance(pkt, Packet)
                and pkt.__iterlen__() == 1) or isinstance(pkt,
                                                          list)  # noqa: E501
    tobesent = pkt

    use_prn_mode = False
    _storage_policy = None
    if process is not None:
        use_prn_mode = True
        _storage_policy = lambda x, y: process(x, y)

    stopevent = threading.Event()
    count_packets = six.moves.queue.Queue()
    hsent = {}
    timessent = {} if listable else None

    def send_in_loop(tobesent, stopevent, count_packets=count_packets):
        """Infinite generator that produces the same packet until stopevent is triggered."""  # noqa: E501
        while True:
            for p in tobesent:
                if stopevent.is_set():
                    raise StopIteration()
                count_packets.put(0)
                yield p

    infinite_gen = send_in_loop(tobesent, stopevent)

    def _timeout(timeout):
        stopevent.wait(timeout)
        stopevent.set()

    timeout_thread = threading.Thread(target=_timeout, args=(timeout, ))
    timeout_thread.setDaemon(True)
    timeout_thread.start()

    # We don't use _sndrcv_snd verbose (it messes the logs up as in a thread that ends after receiving)  # noqa: E501
    thread = threading.Thread(
        target=_sndrcv_snd,
        args=(pks, None, inter, False, infinite_gen, hsent, timessent,
              stopevent),  # noqa: E501
    )
    thread.setDaemon(True)
    thread.start()

    hsent, ans, nbrecv, notans = _sndrcv_rcv(pks,
                                             hsent,
                                             stopevent,
                                             0,
                                             len(tobesent),
                                             verbose,
                                             chainCC,
                                             False,
                                             _storage_policy=_storage_policy)
    thread.join()

    # Restore time_sent to original packets
    if listable:
        i = 0
        for p in (pkt if isinstance(pkt, list) else [pkt]):
            p.sent_time = timessent[i]
            i += 1

    if process is not None:
        ans = [(x, process(y)) for (x, y) in ans]  # Apply process

    if store_unanswered:
        if use_prn_mode:
            remain = [
                process(x, None)
                for x in itertools.chain(*six.itervalues(hsent))
            ]  # noqa: E501
        else:
            remain = list(itertools.chain(*six.itervalues(hsent)))

    if verbose:
        print(
            "\nReceived %i packets, got %i answers, remaining %i packets. Sent a total of %i packets."
            % (nbrecv + len(ans), len(ans), notans,
               count_packets.qsize()))  # noqa: E501
    count_packets.empty()
    del count_packets

    ans_result = ans if use_prn_mode else plist.SndRcvList(ans)
    unans_result = remain if use_prn_mode else (
        None if not store_unanswered else plist.PacketList(
            remain, "Unanswered"))  # noqa: E501
    return ans_result, unans_result
示例#18
0
def sndrcv(pks,
           pkt,
           timeout=None,
           inter=0,
           verbose=None,
           chainCC=False,
           retry=0,
           multi=False,
           rcv_pks=None,
           store_unanswered=True,
           process=None,
           prebuild=False):
    """Scapy raw function to send a packet and receive its answer.
    WARNING: This is an internal function. Using sr/srp/sr1/srp is
    more appropriate in many cases.

    pks: SuperSocket instance to send/receive packets
    pkt: the packet to send
    rcv_pks: if set, will be used instead of pks to receive packets. packets will still  # noqa: E501
             be sent through pks
    nofilter: put 1 to avoid use of BPF filters
    retry:    if positive, how many times to resend unanswered packets
              if negative, how many times to retry when no more packets are answered  # noqa: E501
    timeout:  how much time to wait after the last packet has been sent
    verbose:  set verbosity level
    multi:    whether to accept multiple answers for the same stimulus
    store_unanswered: whether to store not-answered packets or not. Default True.  # noqa: E501
                      setting it to False will increase speed, and will return None  # noqa: E501
                      as the unans list.
    process:  if specified, only result from process(pkt) will be stored.
              the function should follow the following format:
                lambda sent, received: (func(sent), func2(received))
              if the packet is unanswered, `received` will be None.
              if `store_unanswered` is False, the function won't be called on un-answered packets.  # noqa: E501
    prebuild: pre-build the packets before starting to send them. Default to False. Automatically used  # noqa: E501
              when a generator is passed as the packet
    """
    if verbose is None:
        verbose = conf.verb
    use_prn_mode = False
    _storage_policy = None
    if process is not None:
        use_prn_mode = True
        _storage_policy = lambda x, y: process(x, y)
    debug.recv = plist.PacketList([], "Unanswered")
    debug.sent = plist.PacketList([], "Sent")
    debug.match = plist.SndRcvList([])
    nbrecv = 0
    ans = []
    listable = (isinstance(pkt, Packet)
                and pkt.__iterlen__() == 1) or isinstance(pkt,
                                                          list)  # noqa: E501
    # do it here to fix random fields, so that parent and child have the same
    if isinstance(pkt, types.GeneratorType) or prebuild:
        tobesent = [p for p in pkt]
        notans = len(tobesent)
    else:
        tobesent = SetGen(pkt) if not isinstance(pkt, Gen) else pkt
        notans = tobesent.__iterlen__()

    if retry < 0:
        autostop = retry = -retry
    else:
        autostop = 0

    while retry >= 0:
        if timeout is not None and timeout < 0:
            timeout = None
        stopevent = threading.Event()

        hsent = {}
        timessent = {} if listable else None

        thread = threading.Thread(
            target=_sndrcv_snd,
            args=(pks, timeout, inter, verbose, tobesent, hsent, timessent,
                  stopevent),  # noqa: E501
        )
        thread.setDaemon(True)
        thread.start()

        hsent, newans, nbrecv, notans = _sndrcv_rcv(
            (rcv_pks or pks),
            hsent,
            stopevent,
            nbrecv,
            notans,
            verbose,
            chainCC,
            multi,  # noqa: E501
            _storage_policy=_storage_policy,
        )
        thread.join()

        ans.extend(newans)

        # Restore time_sent to original packets
        if listable:
            i = 0
            for p in (pkt if isinstance(pkt, list) else [pkt]):
                p.sent_time = timessent[i]
                i += 1

        if store_unanswered:
            remain = list(itertools.chain(*six.itervalues(hsent)))
            if multi:
                remain = [p for p in remain if not hasattr(p, '_answered')]

            if autostop and len(remain) > 0 and len(remain) != len(tobesent):
                retry = autostop

            tobesent = remain
            if len(tobesent) == 0:
                break
        else:
            remain = []
        retry -= 1

    if conf.debug_match:
        debug.sent = plist.PacketList(remain[:], "Sent")
        debug.match = plist.SndRcvList(ans[:])

    # Clean the ans list to delete the field _answered
    if multi:
        for snd, _ in ans:
            if hasattr(snd, '_answered'):
                del snd._answered

    if verbose:
        print("\nReceived %i packets, got %i answers, remaining %i packets" %
              (nbrecv + len(ans), len(ans), notans))  # noqa: E501

    if store_unanswered and use_prn_mode:
        remain = [process(x, None) for x in remain]

    ans_result = ans if use_prn_mode else plist.SndRcvList(ans)
    unans_result = remain if use_prn_mode else (
        None if not store_unanswered else plist.PacketList(
            remain, "Unanswered"))  # noqa: E501
    return ans_result, unans_result
示例#19
0
文件: __init__.py 项目: zbx91/sniffer
def sniff(count=0,
          store=1,
          offline=None,
          prn=None,
          lfilter=None,
          L2socket=None,
          timeout=None,
          stopperTimeout=None,
          flag_dict=None,
          pkt_lst=pkt_lst,
          *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()
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_callback: Call every loop to determine if we need
               to stop the capture
    """
    mac = flag_dict['mac']
    up = 0
    down = 0
    c = 0
    last_time = ''
    if offline is None:
        if L2socket is None:
            L2socket = conf.L2listen
        s = L2socket(type=ETH_P_ALL, *arg, **karg)

    else:
        s = PcapReader(offline)
    global lst
    global length
    if timeout is not None:
        stoptime = time.time() + timeout
    remain = None

    if stopperTimeout is not None:
        stopperStoptime = time.time() + stopperTimeout
    remainStopper = None
    if (flag_dict['max']):
        s.recv_pkt_lst_init()
        while 1:
            try:
                if timeout is not None:
                    remain = stoptime - time.time()
                    if remain <= 0:
                        break

                if stopperTimeout is not None:
                    remainStopper = stopperStoptime - time.time()
                    if remainStopper <= 0:
                        if flag_dict['start'] == False:
                            break
                        stopperStoptime = time.time() + stopperTimeout
                        remainStopper = stopperStoptime - time.time()

                ll = s.ins.datalink()
                if ll in conf.l2types:
                    cls = conf.l2types[ll]
                else:
                    cls = conf.default_l2
                    warning(
                        "Unable to guess datalink type (interface=%s linktype=%i). Using %s"
                        % (self.iface, ll, cls.name))
                while (s.num_process >= s.num_capture):
                    if (flag_dict['start'] == False):
                        return (None)
                    pass
                pkt, t = s.pkt_lst[s.num_process][0], s.pkt_lst[
                    s.num_process][1]
                ts, pkt = pkt
                # if scapy.arch.WINDOWS and pkt is None:
                #raise PcapTimeoutElapsed

                try:
                    pkt = cls(pkt)
                except KeyboardInterrupt:
                    raise
                except:
                    if conf.debug_dissector:
                        raise
                    pkt = conf.raw_layer(pkt)
                s.num_process += 1
                p = pkt
                length = s.num_process

                if p is None:
                    break
                if lfilter and not lfilter(p):
                    continue
                if store:
                    lst.append(p)
                pkt_lst.put([bytes(p), t])
                c += 1
                if prn:
                    r = prn(p)
                    if r is not None:
                        print(r)
                if count > 0 and c >= count:
                    break
            except KeyboardInterrupt:
                break
        s.close()
        return plist.PacketList(lst, "Sniffed")
    else:
        while 1:
            try:
                if timeout is not None:
                    remain = stoptime - time.time()
                    if remain <= 0:
                        break

                if stopperTimeout is not None:
                    remainStopper = stopperStoptime - time.time()
                    if remainStopper <= 0:
                        if flag_dict['start'] == False:
                            break
                        stopperStoptime = time.time() + stopperTimeout
                        remainStopper = stopperStoptime - time.time()

                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)
                pkt_lst.put([bytes(p), datetime.now().strftime("%H:%M:%S")])
                #print (length,str(datetime.now()),bytes(p))
                c += 1
                if prn:
                    r = prn(p)
                    if r is not None:
                        print(r)
                if count > 0 and c >= count:
                    break
            except KeyboardInterrupt:
                break
        s.close()
        return plist.PacketList(lst, "Sniffed")
示例#20
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: 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()
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 type(iface) is 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:
            sniff_sockets = [PcapReader(offline)]

    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
            sel = select(sniff_sockets, [], [], remain)
            for s in sel[0]:
                p = s.recv()
                if 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")
示例#21
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

  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()
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:
        if L2socket is None:
            L2socket = conf.L2listen
        s = L2socket(type=ETH_P_ALL, *arg, **karg)
    else:
        s = PcapReader(offline)

    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 count > 0 and c >= count:
                break
        except KeyboardInterrupt:
            break
    s.close()
    return plist.PacketList(lst, "Sniffed")
示例#22
0
def sndrcv(pks,
           pkt,
           timeout=None,
           inter=0,
           verbose=None,
           chainCC=0,
           retry=0,
           multi=0):
    if not isinstance(pkt, Gen):
        pkt = SetGen(pkt)

    if verbose is None:
        verbose = conf.verb
    debug.recv = plist.PacketList([], "Unanswered")
    debug.sent = plist.PacketList([], "Sent")
    debug.match = plist.SndRcvList([])
    nbrecv = 0
    ans = []
    # do it here to fix random fields, so that parent and child have the same
    all_stimuli = tobesent = [p for p in pkt]
    notans = len(tobesent)

    hsent = {}
    for i in tobesent:
        h = i.hashret()
        if h in hsent:
            hsent[h].append(i)
        else:
            hsent[h] = [i]
    if retry < 0:
        retry = -retry
        autostop = retry
    else:
        autostop = 0

    while retry >= 0:
        found = 0

        if timeout < 0:
            timeout = None

        rdpipe, wrpipe = os.pipe()
        rdpipe = os.fdopen(rdpipe)
        wrpipe = os.fdopen(wrpipe, "w")

        pid = 1
        try:
            pid = os.fork()
            if pid == 0:
                try:
                    sys.stdin.close()
                    rdpipe.close()
                    try:
                        i = 0
                        if verbose:
                            print "Begin emission:"
                        for p in tobesent:
                            pks.send(p)
                            i += 1
                            time.sleep(inter)
                        if verbose:
                            print "Finished to send %i packets." % i
                    except SystemExit:
                        pass
                    except KeyboardInterrupt:
                        pass
                    except:
                        log_runtime.exception("--- Error in child %i" %
                                              os.getpid())
                        log_runtime.info("--- Error in child %i" % os.getpid())
                finally:
                    try:
                        os.setpgrp()  # Chance process group to avoid ctrl-C
                        sent_times = [
                            p.sent_time for p in all_stimuli if p.sent_time
                        ]
                        cPickle.dump((conf.netcache, sent_times), wrpipe)
                        wrpipe.close()
                    except:
                        pass
            elif pid < 0:
                log_runtime.error("fork error")
            else:
                wrpipe.close()
                stoptime = 0
                remaintime = None
                inmask = [rdpipe, pks]
                try:
                    try:
                        while 1:
                            if stoptime:
                                remaintime = stoptime - time.time()
                                if remaintime <= 0:
                                    break
                            r = None
                            if not isinstance(
                                    pks, StreamSocket) and (FREEBSD or DARWIN):
                                inp, out, err = select(inmask, [], [], 0.05)
                                if len(inp) == 0 or pks in inp:
                                    r = pks.nonblock_recv()
                            else:
                                inp = []
                                try:
                                    inp, out, err = select(
                                        inmask, [], [], remaintime)
                                except IOError, exc:
                                    if exc.errno != errno.EINTR:
                                        raise
                                if len(inp) == 0:
                                    break
                                if pks in inp:
                                    r = pks.recv(MTU)
                            if rdpipe in inp:
                                if timeout:
                                    stoptime = time.time() + timeout
                                del (inmask[inmask.index(rdpipe)])
                            if r is None:
                                continue
                            ok = 0
                            h = r.hashret()
                            if h in hsent:
                                hlst = hsent[h]
                                for i, sentpkt in enumerate(hlst):
                                    if r.answers(sentpkt):
                                        ans.append((sentpkt, r))
                                        if verbose > 1:
                                            os.write(1, "*")
                                        ok = 1
                                        if not multi:
                                            del hlst[i]
                                            notans -= 1
                                        else:
                                            if not hasattr(
                                                    sentpkt, '_answered'):
                                                notans -= 1
                                            sentpkt._answered = 1
                                        break
                            if notans == 0 and not multi:
                                break
                            if not ok:
                                if verbose > 1:
                                    os.write(1, ".")
                                nbrecv += 1
                                if conf.debug_match:
                                    debug.recv.append(r)
                    except KeyboardInterrupt:
                        if chainCC:
                            raise
                finally:
                    try:
                        nc, sent_times = cPickle.load(rdpipe)
                    except EOFError:
                        warning(
                            "Child died unexpectedly. Packets may have not been sent %i"
                            % os.getpid())
                    else:
                        conf.netcache.update(nc)
                        for p, t in zip(all_stimuli, sent_times):
                            p.sent_time = t
                    os.waitpid(pid, 0)
        finally:
            if pid == 0:
                os._exit(0)

        remain = list(itertools.chain(*hsent.itervalues()))
        if multi:
            remain = [p for p in remain if not hasattr(p, '_answered')]

        if autostop and len(remain) > 0 and len(remain) != len(tobesent):
            retry = autostop

        tobesent = remain
        if len(tobesent) == 0:
            break
        retry -= 1

    if conf.debug_match:
        debug.sent = plist.PacketList(remain[:], "Sent")
        debug.match = plist.SndRcvList(ans[:])

    #clean the ans list to delete the field _answered
    if (multi):
        for s, r in ans:
            if hasattr(s, '_answered'):
                del (s._answered)

    if verbose:
        print "\nReceived %i packets, got %i answers, remaining %i packets" % (
            nbrecv + len(ans), len(ans), notans)
    return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
示例#23
0
def sndrcv(pks,
           pkt,
           timeout=None,
           inter=0,
           verbose=None,
           chainCC=False,
           retry=0,
           multi=False,
           rcv_pks=None):
    """Scapy raw function to send a packet and recieve its answer.
    WARNING: This is an internal function. Using sr/srp/sr1/srp is
    more appropriate in many cases.

    pks: SuperSocket instance to send/recieve packets
    pkt: the packet to send
    rcv_pks: if set, will be used instead of pks to recieve packets. packets will still
             be sent through pks
    nofilter: put 1 to avoid use of BPF filters
    retry:    if positive, how many times to resend unanswered packets
              if negative, how many times to retry when no more packets are answered
    timeout:  how much time to wait after the last packet has been sent
    verbose:  set verbosity level
    multi:    whether to accept multiple answers for the same stimulus"""
    if not isinstance(pkt, Gen):
        pkt = SetGen(pkt)
    if verbose is None:
        verbose = conf.verb
    debug.recv = plist.PacketList([], "Unanswered")
    debug.sent = plist.PacketList([], "Sent")
    debug.match = plist.SndRcvList([])
    nbrecv = 0
    ans = []
    # do it here to fix random fields, so that parent and child have the same
    tobesent = [p for p in pkt]
    notans = len(tobesent)

    if retry < 0:
        retry = -retry
        autostop = retry
    else:
        autostop = 0

    while retry >= 0:
        if timeout is not None and timeout < 0:
            timeout = None
        stopevent = threading.Event()

        thread = threading.Thread(
            target=_sndrcv_snd,
            args=(pks, timeout, inter, verbose, tobesent, stopevent),
        )
        thread.start()

        hsent, newans, nbrecv, notans = _sndrcv_rcv(
            (rcv_pks or pks),
            tobesent,
            stopevent,
            nbrecv,
            notans,
            verbose,
            chainCC,
            multi,
        )
        thread.join()
        ans.extend(newans)

        remain = list(itertools.chain(*six.itervalues(hsent)))
        if multi:
            remain = [p for p in remain if not hasattr(p, '_answered')]

        if autostop and len(remain) > 0 and len(remain) != len(tobesent):
            retry = autostop

        tobesent = remain
        if len(tobesent) == 0:
            break
        retry -= 1

    if conf.debug_match:
        debug.sent = plist.PacketList(remain[:], "Sent")
        debug.match = plist.SndRcvList(ans[:])

    # Clean the ans list to delete the field _answered
    if multi:
        for snd, _ in ans:
            if hasattr(snd, '_answered'):
                del snd._answered

    if verbose:
        print("\nReceived %i packets, got %i answers, remaining %i packets" %
              (nbrecv + len(ans), len(ans), notans))
    return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
示例#24
0
def bridge_and_sniff(if1,
                     if2,
                     count=0,
                     store=1,
                     offline=None,
                     prn=None,
                     lfilter=None,
                     L2socket=None,
                     timeout=None,
                     stop_filter=None,
                     *args,
                     **kargs):
    """Forward traffic between two interfaces and sniff packets exchanged
bridge_and_sniff([count=0,] [prn=None,] [store=1,] [offline=None,] 
[lfilter=None,] + L2Socket args) -> list of packets

  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()
lfilter: python function applied to each packet to determine
         if further action may be done
         ex: lfilter = lambda x: x.haslayer(Padding)
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 L2socket is None:
        L2socket = conf.L2socket
    s1 = L2socket(iface=if1)
    s2 = L2socket(iface=if2)
    peerof = {s1: s2, s2: s1}
    label = {s1: if1, s2: if2}

    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
            ins, outs, errs = select([s1, s2], [], [], remain)
            for s in ins:
                p = s.recv()
                if p is not None:
                    peerof[s].send(p.original)
                    if lfilter and not lfilter(p):
                        continue
                    if store:
                        p.sniffed_on = label[s]
                        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
    finally:
        return plist.PacketList(lst, "Sniffed")
示例#25
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")