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")
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
def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg): """Sniff packets sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets Select interface to sniff by setting conf.iface. Use show_interfaces() to see interface names. count: number of packets to capture. 0 means infinity store: wether to store sniffed packets or discard them prn: function to apply to each packet. If something is returned, it is displayed. Ex: ex: prn = lambda x: x.summary() filter: provide a BPF filter lfilter: python function applied to each packet to determine if further action may be done ex: lfilter = lambda x: x.haslayer(Padding) offline: pcap file to read packets from, instead of sniffing them timeout: stop sniffing after a given time (default: None) L2socket: use the provided L2socket """ c = 0 if offline is None: log_runtime.info('Sniffing on %s' % conf.iface) if L2socket is None: L2socket = conf.L2listen s = L2socket(type=ETH_P_ALL, *arg, **karg) else: flt = karg.get('filter') s = PcapReader(offline if flt is None else tcpdump(offline, args=["-w", "-", flt], getfd=True)) lst = [] if timeout is not None: stoptime = time.time()+timeout remain = None while 1: try: if timeout is not None: remain = stoptime-time.time() if remain <= 0: break try: p = s.recv(MTU) except PcapTimeoutElapsed: continue if p is None: break if lfilter and not lfilter(p): continue if store: lst.append(p) c += 1 if prn: r = prn(p) if r is not None: print r if 0 < count <= c: break except KeyboardInterrupt: break s.close() return plist.PacketList(lst,"Sniffed")
def 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")
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
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)
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
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")
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")
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")
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))
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")
def plist(self, pkts=None): return plist.PacketList(pkts)
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")
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")
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
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
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")
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")
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")
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")
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")
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")
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")