Example #1
0
def sndrcvflood(pks, pkt, prn=lambda s_r:s_r[1].summary(), chainCC=0, store=1, unique=0):
    if not isinstance(pkt, Gen):
        pkt = SetGen(pkt)
    tobesent = [p for p in pkt]
    received = plist.SndRcvList()
    seen = {}

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

    def send_in_loop(tobesent):
        while True:
            for p in tobesent:
                yield p

    packets_to_send = send_in_loop(tobesent)

    ssock = rsock = pks.fileno()

    try:
        while True:
            if conf.use_bpf:
                from scapy.arch.bpf.supersocket import bpf_select
                readyr = bpf_select([rsock])
                _, readys, _ = select([], [ssock], [])
            else:
                readyr, readys, _ = select([rsock], [ssock], [])

            if ssock in readys:
                pks.send(packets_to_send.next())
                
            if rsock in readyr:
                p = pks.recv(MTU)
                if p is None:
                    continue
                h = p.hashret()
                if h in hsent:
                    hlst = hsent[h]
                    for i in hlst:
                        if p.answers(i):
                            res = prn((i,p))
                            if unique:
                                if res in seen:
                                    continue
                                seen[res] = None
                            if res is not None:
                                print(res)
                            if store:
                                received.append((i,p))
    except KeyboardInterrupt:
        if chainCC:
            raise
    return received
Example #2
0
 def _get_pkt():
     if bpf_select([pks]):
         return pks.recv()
Example #3
0
 def _select(sockets):
     return bpf_select(sockets, remain)
Example #4
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: 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()
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
            if conf.use_bpf:
                from scapy.arch.bpf.supersocket import bpf_select
                ins = bpf_select([s1, s2], remain)
            else:
                ins, _, _ = 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")
Example #5
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")
Example #6
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]
                        six.moves.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 True:
                            if stoptime:
                                remaintime = stoptime-time.time()
                                if remaintime <= 0:
                                    break
                            r = None
                            if conf.use_bpf:
                                from scapy.arch.bpf.supersocket import bpf_select
                                inp = bpf_select(inmask)
                                if pks in inp:
                                    r = pks.recv()
                            elif not isinstance(pks, StreamSocket) and (FREEBSD or DARWIN or OPENBSD):
                                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, select_error) as exc:
                                    # select.error has no .errno attribute
                                    if exc.args[0] != 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 = six.moves.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(*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 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")
Example #7
0
 def _get_pkt():
     if bpf_select([pks]):
         return pks.recv()
Example #8
0
 def _select(sockets):
     return bpf_select(sockets, remain)
Example #9
0
 def _select(sockets):
     return bpf_select(sockets, remainStopper)