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
def _get_pkt(): if bpf_select([pks]): return pks.recv()
def _select(sockets): return bpf_select(sockets, remain)
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")
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")
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")
def _select(sockets): return bpf_select(sockets, remainStopper)