def __init__(self, iface=None, promisc=None, filter=None, nofilter=False, prog=None, *arg, **karg): self.outs = None args = ['-w', '-', '-s', '65535'] if iface is not None: if WINDOWS: try: args.extend(['-i', iface.pcap_name]) except AttributeError: args.extend(['-i', iface]) else: args.extend(['-i', iface]) elif WINDOWS or DARWIN: args.extend(['-i', conf.iface.pcap_name if WINDOWS else conf.iface]) # noqa: E501 if not promisc: args.append('-p') if not nofilter: if conf.except_filter: if filter: filter = "(%s) and not (%s)" % (filter, conf.except_filter) else: filter = "not (%s)" % conf.except_filter if filter is not None: args.append(filter) self.tcpdump_proc = tcpdump(None, prog=prog, args=args, getproc=True) self.ins = PcapReader(self.tcpdump_proc.stdout)
def __init__(self, iface=None, promisc=None, filter=None, nofilter=False, prog=None, *arg, **karg): self.outs = None args = ['-w', '-', '-s', '65535'] if iface is None and (WINDOWS or DARWIN): iface = conf.iface self.iface = iface if iface is not None: args.extend(['-i', network_name(iface)]) if not promisc: args.append('-p') if not nofilter: if conf.except_filter: if filter: filter = "(%s) and not (%s)" % (filter, conf.except_filter) else: filter = "not (%s)" % conf.except_filter if filter is not None: args.append(filter) self.tcpdump_proc = tcpdump(None, prog=prog, args=args, getproc=True) self.ins = PcapReader(self.tcpdump_proc.stdout)
def sniff(count=0, store=1, offline=None, prn = None, lfilter=None, L2socket=None, timeout=None, *arg, **karg): """Sniff packets sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets Select interface to sniff by setting conf.iface. Use show_interfaces() to see interface names. count: number of packets to capture. 0 means infinity store: wether to store sniffed packets or discard them prn: function to apply to each packet. If something is returned, it is displayed. Ex: ex: prn = lambda x: x.summary() filter: provide a BPF filter lfilter: python function applied to each packet to determine if further action may be done ex: lfilter = lambda x: x.haslayer(Padding) offline: pcap file to read packets from, instead of sniffing them timeout: stop sniffing after a given time (default: None) L2socket: use the provided L2socket """ c = 0 if offline is None: log_runtime.info('Sniffing on %s' % conf.iface) if L2socket is None: L2socket = conf.L2listen s = L2socket(type=ETH_P_ALL, *arg, **karg) else: flt = karg.get('filter') s = PcapReader(offline if flt is None else tcpdump(offline, args=["-w", "-", flt], getfd=True)) lst = [] if timeout is not None: stoptime = time.time()+timeout remain = None while 1: try: if timeout is not None: remain = stoptime-time.time() if remain <= 0: break try: p = s.recv(MTU) except PcapTimeoutElapsed: continue if p is None: break if lfilter and not lfilter(p): continue if store: lst.append(p) c += 1 if prn: r = prn(p) if r is not None: print r if 0 < count <= c: break except KeyboardInterrupt: break s.close() return plist.PacketList(lst,"Sniffed")
def __init__(self, iface=None, promisc=None, filter=None, nofilter=False, prog=None, *arg, **karg): self.outs = None args = ['-w', '-', '-s', '65535'] if iface is not None: if WINDOWS: try: args.extend(['-i', iface.pcap_name]) except AttributeError: args.extend(['-i', iface]) else: args.extend(['-i', iface]) elif WINDOWS: args.extend(['-i', conf.iface.pcap_name]) if not promisc: args.append('-p') if not nofilter: if conf.except_filter: if filter: filter = "(%s) and not (%s)" % (filter, conf.except_filter) else: filter = "not (%s)" % conf.except_filter if filter is not None: args.append(filter) self.tcpdump_proc = tcpdump(None, prog=prog, args=args, getproc=True) self.ins = PcapReader(self.tcpdump_proc.stdout)
def __init__( self, iface=None, # type: Optional[_GlobInterfaceType] promisc=False, # type: bool filter=None, # type: Optional[str] nofilter=False, # type: bool prog=None, # type: Optional[str] *arg, # type: Any **karg # type: Any ): # type: (...) -> None self.outs = None args = ['-w', '-', '-s', '65535'] if iface is None and (WINDOWS or DARWIN): iface = conf.iface self.iface = iface if iface is not None: args.extend(['-i', network_name(iface)]) if not promisc: args.append('-p') if not nofilter: if conf.except_filter: if filter: filter = "(%s) and not (%s)" % (filter, conf.except_filter) else: filter = "not (%s)" % conf.except_filter if filter is not None: args.append(filter) self.tcpdump_proc = tcpdump(None, prog=prog, args=args, getproc=True) self.reader = PcapReader(self.tcpdump_proc.stdout) self.ins = self.reader # type: ignore
def invoke(self, arg, from_tty): if Ether is None: print("ERROR: This command requires scapy to be installed.") return arg_list = gdb.string_to_argv(arg) if len(arg_list) == 0: print("Usage: ovs_dump_packets <struct dp_packet_batch|" "dp_packet> [tcpdump options]") return symb_name = arg_list[0] tcpdump_args = arg_list[1:] if not tcpdump_args: # Add a sane default tcpdump_args = ["-n"] val = gdb.parse_and_eval(symb_name) while val.type.code == gdb.TYPE_CODE_PTR: val = val.dereference() pkt_list = [] if str(val.type).startswith("struct dp_packet_batch"): for idx in range(val['count']): pkt_struct = val['packets'][idx].dereference() pkt = self.extract_pkt(pkt_struct) if pkt is None: continue pkt_list.append(pkt) elif str(val.type) == "struct dp_packet": pkt = self.extract_pkt(val) if pkt is None: return pkt_list.append(pkt) else: print("Error, unsupported argument type: {}".format(str(val.type))) return tcpdump(pkt_list, args=tcpdump_args)
def __init__(self, iface=None, promisc=None, filter=None, nofilter=False, prog=None, *arg, **karg): self.outs = None args = ['-w', '-', '-s', '65535'] if iface is not None: args.extend(['-i', iface]) if not promisc: args.append('-p') if not nofilter: if conf.except_filter: if filter: filter = "(%s) and not (%s)" % (filter, conf.except_filter) else: filter = "not (%s)" % conf.except_filter if filter is not None: args.append(filter) self.ins = PcapReader(tcpdump(None, prog=prog, args=args, getfd=True))
def _run(self, count=0, # type: int store=True, # type: bool offline=None, # type: Any quiet=False, # type: bool prn=None, # type: Optional[Callable[[Packet], Any]] lfilter=None, # type: Optional[Callable[[Packet], bool]] L2socket=None, # type: Optional[Type[SuperSocket]] timeout=None, # type: Optional[int] opened_socket=None, # type: Optional[SuperSocket] stop_filter=None, # type: Optional[Callable[[Packet], bool]] iface=None, # type: Optional[_GlobInterfaceType] started_callback=None, # type: Optional[Callable[[], Any]] session=None, # type: Optional[_GlobSessionType] session_kwargs={}, # type: Dict[str, Any] **karg # type: Any ): # type: (...) -> None self.running = True # Start main thread # instantiate session if not isinstance(session, DefaultSession): session = session or DefaultSession session = session(prn=prn, store=store, **session_kwargs) else: session.prn = prn session.store = store # sniff_sockets follows: {socket: label} sniff_sockets = {} # type: Dict[SuperSocket, _GlobInterfaceType] if opened_socket is not None: if isinstance(opened_socket, list): sniff_sockets.update( (s, "socket%d" % i) for i, s in enumerate(opened_socket) ) elif isinstance(opened_socket, dict): sniff_sockets.update( (s, label) for s, label in six.iteritems(opened_socket) ) else: sniff_sockets[opened_socket] = "socket0" if offline is not None: flt = karg.get('filter') if isinstance(offline, str): # Single file offline = [offline] if isinstance(offline, list) and \ all(isinstance(elt, str) for elt in offline): # List of files sniff_sockets.update((PcapReader( fname if flt is None else tcpdump(fname, args=["-w", "-"], flt=flt, getfd=True, quiet=quiet) ), fname) for fname in offline) elif isinstance(offline, dict): # Dict of files sniff_sockets.update((PcapReader( fname if flt is None else tcpdump(fname, args=["-w", "-"], flt=flt, getfd=True, quiet=quiet) ), label) for fname, label in six.iteritems(offline)) elif isinstance(offline, (Packet, PacketList, list)): # Iterables (list of packets, PacketList..) offline = IterSocket(offline) sniff_sockets[offline if flt is None else PcapReader( tcpdump(offline, args=["-w", "-"], flt=flt, getfd=True, quiet=quiet) )] = offline else: # Other (file descriptors...) sniff_sockets[PcapReader( offline if flt is None else tcpdump(offline, args=["-w", "-"], flt=flt, getfd=True, quiet=quiet) )] = offline if not sniff_sockets or iface is not None: # The _RL2 function resolves the L2socket of an iface _RL2 = lambda i: L2socket or resolve_iface(i).l2listen() # type: Callable[[_GlobInterfaceType], Callable[..., SuperSocket]] # noqa: E501 if isinstance(iface, list): sniff_sockets.update( (_RL2(ifname)(type=ETH_P_ALL, iface=ifname, **karg), ifname) for ifname in iface ) elif isinstance(iface, dict): sniff_sockets.update( (_RL2(ifname)(type=ETH_P_ALL, iface=ifname, **karg), iflabel) for ifname, iflabel in six.iteritems(iface) ) else: iface = iface or conf.iface sniff_sockets[_RL2(iface)(type=ETH_P_ALL, iface=iface, **karg)] = iface # Get select information from the sockets _main_socket = next(iter(sniff_sockets)) select_func = _main_socket.select nonblocking_socket = _main_socket.nonblocking_socket # We check that all sockets use the same select(), or raise a warning if not all(select_func == sock.select for sock in sniff_sockets): warning("Warning: inconsistent socket types ! " "The used select function " "will be the one of the first socket") if not nonblocking_socket: # select is blocking: Add special control socket from scapy.automaton import ObjectPipe close_pipe = ObjectPipe() sniff_sockets[close_pipe] = "control_socket" def stop_cb(): # type: () -> None if self.running: close_pipe.send(None) self.continue_sniff = False self.stop_cb = stop_cb else: # select is non blocking def stop_cb(): # type: () -> None self.continue_sniff = False self.stop_cb = stop_cb close_pipe = None try: if started_callback: started_callback() self.continue_sniff = True # Start timeout if timeout is not None: stoptime = time.time() + timeout remain = None while sniff_sockets and self.continue_sniff: if timeout is not None: remain = stoptime - time.time() if remain <= 0: break sockets = select_func(list(sniff_sockets.keys()), remain) dead_sockets = [] for s in sockets: if s is close_pipe: break try: p = s.recv() except EOFError: # End of stream try: s.close() except Exception: pass dead_sockets.append(s) continue except Exception as ex: msg = " It was closed." try: # Make sure it's closed s.close() except Exception as ex2: msg = " close() failed with '%s'" % ex2 warning( "Socket %s failed with '%s'." % (s, ex) + msg ) dead_sockets.append(s) if conf.debug_dissector >= 2: raise continue if p is None: continue if lfilter and not lfilter(p): continue p.sniffed_on = sniff_sockets[s] # on_packet_received handles the prn/storage session.on_packet_received(p) # check if (stop_filter and stop_filter(p)) or \ (0 < count <= session.count): self.continue_sniff = False break # Removed dead sockets for s in dead_sockets: del sniff_sockets[s] except KeyboardInterrupt: pass self.running = False if opened_socket is None: for s in sniff_sockets: s.close() elif close_pipe: close_pipe.close() self.results = session.toPacketList()
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 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 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")
def sniff(count=0, store=1, offline=None, prn = None, stop_filter=None, lfilter=None, L2socket=None, timeout=None, *arg, **karg): """Sniff packets sniff([count=0,] [prn=None,] [store=1,] [offline=None,] [lfilter=None,] + L2ListenSocket args) -> list of packets Select interface to sniff by setting conf.iface. Use show_interfaces() to see interface names. count: number of packets to capture. 0 means infinity store: whether to store sniffed packets or discard them prn: function to apply to each packet. If something is returned, it is displayed. Ex: ex: prn = lambda x: x.summary() filter: provide a BPF filter lfilter: python function applied to each packet to determine if further action may be done ex: lfilter = lambda x: x.haslayer(Padding) offline: pcap file to read packets from, instead of sniffing them timeout: stop sniffing after a given time (default: None) L2socket: use the provided L2socket stop_filter: python function applied to each packet to determine if we have to stop the capture after this packet ex: stop_filter = lambda x: x.haslayer(TCP) """ c = 0 if offline is None: log_runtime.info('Sniffing on %s' % conf.iface) if L2socket is None: L2socket = conf.L2listen s = L2socket(type=ETH_P_ALL, *arg, **karg) else: flt = karg.get('filter') s = PcapReader(offline if flt is None else tcpdump(offline, args=["-w", "-", flt], getfd=True)) lst = [] if timeout is not None: stoptime = time.time()+timeout remain = None while True: try: if timeout is not None: remain = stoptime-time.time() if remain <= 0: break try: p = s.recv(MTU) except PcapTimeoutElapsed: continue if p is None: break if lfilter and not lfilter(p): continue if store: lst.append(p) c += 1 if prn: r = prn(p) if r is not None: print r if stop_filter and stop_filter(p): break if 0 < count <= c: break except KeyboardInterrupt: break s.close() return plist.PacketList(lst,"Sniffed")
def _run(self, count=0, store=True, offline=None, prn=None, lfilter=None, L2socket=None, timeout=None, opened_socket=None, stop_filter=None, iface=None, started_callback=None, session=None, *arg, **karg): self.running = True # Start main thread c = 0 session = session or DefaultSession session = session(prn, store) # instantiate session # sniff_sockets follows: {socket: label} sniff_sockets = {} if opened_socket is not None: if isinstance(opened_socket, list): sniff_sockets.update( (s, "socket%d" % i) for i, s in enumerate(opened_socket)) elif isinstance(opened_socket, dict): sniff_sockets.update( (s, label) for s, label in six.iteritems(opened_socket)) else: sniff_sockets[opened_socket] = "socket0" if offline is not None: flt = karg.get('filter') from scapy.arch.common import TCPDUMP if not TCPDUMP and flt is not None: message = "tcpdump is not available. Cannot use filter!" raise Scapy_Exception(message) if isinstance(offline, list): sniff_sockets.update( (PcapReader(fname if flt is None else tcpdump( fname, args=["-w", "-", flt], getfd=True)), fname) for fname in offline) elif isinstance(offline, dict): sniff_sockets.update( (PcapReader(fname if flt is None else tcpdump( fname, args=["-w", "-", flt], getfd=True)), label) for fname, label in six.iteritems(offline)) else: sniff_sockets[PcapReader(offline if flt is None else tcpdump( offline, args=["-w", "-", flt], getfd=True))] = offline if not sniff_sockets or iface is not None: if L2socket is None: L2socket = conf.L2listen if isinstance(iface, list): sniff_sockets.update( (L2socket(type=ETH_P_ALL, iface=ifname, *arg, **karg), ifname) for ifname in iface) elif isinstance(iface, dict): sniff_sockets.update( (L2socket(type=ETH_P_ALL, iface=ifname, *arg, **karg), iflabel) for ifname, iflabel in six.iteritems(iface)) else: sniff_sockets[L2socket(type=ETH_P_ALL, iface=iface, *arg, **karg)] = iface # Get select information from the sockets _main_socket = next(iter(sniff_sockets)) read_allowed_exceptions = _main_socket.read_allowed_exceptions select_func = _main_socket.select _backup_read_func = _main_socket.__class__.recv nonblocking_socket = _main_socket.nonblocking_socket # We check that all sockets use the same select(), or raise a warning if not all(select_func == sock.select for sock in sniff_sockets): warning("Warning: inconsistent socket types ! " "The used select function " "will be the one of the first socket") # Fill if empty if not read_allowed_exceptions: read_allowed_exceptions = (IOError, ) if nonblocking_socket: # select is non blocking def stop_cb(): self.continue_sniff = False self.stop_cb = stop_cb close_pipe = None else: # select is blocking: Add special control socket from scapy.automaton import ObjectPipe close_pipe = ObjectPipe() sniff_sockets[close_pipe] = "control_socket" def stop_cb(): if self.running: close_pipe.send(None) self.continue_sniff = False self.stop_cb = stop_cb try: if started_callback: started_callback() self.continue_sniff = True # Start timeout if timeout is not None: stoptime = time.time() + timeout remain = None while sniff_sockets and self.continue_sniff: if timeout is not None: remain = stoptime - time.time() if remain <= 0: break sockets, read_func = select_func(sniff_sockets, remain) read_func = read_func or _backup_read_func dead_sockets = [] for s in sockets: if s is close_pipe: break try: p = read_func(s) except EOFError: # End of stream dead_sockets.append(s) continue except read_allowed_exceptions: continue except Exception as ex: msg = " It was closed." try: # Make sure it's closed s.close() except Exception as ex: msg = " close() failed with '%s'" % ex warning("Socket %s failed with '%s'." % (s, ex) + msg) dead_sockets.append(s) continue if p is None: continue if lfilter and not lfilter(p): continue p.sniffed_on = sniff_sockets[s] c += 1 # on_packet_received handles the prn/storage session.on_packet_received(p) # check if (stop_filter and stop_filter(p)) or (0 < count <= c): self.continue_sniff = False break # Removed dead sockets for s in dead_sockets: del sniff_sockets[s] except KeyboardInterrupt: pass self.running = False if opened_socket is None: for s in sniff_sockets: s.close() elif close_pipe: close_pipe.close() self.results = session.toPacketList()
def _run(self, count=0, store=True, offline=None, quiet=False, prn=None, lfilter=None, L2socket=None, timeout=None, opened_socket=None, stop_filter=None, iface=None, started_callback=None, session=None, session_args=[], session_kwargs={}, *arg, **karg): self.running = True # Start main thread # instantiate session if not isinstance(session, DefaultSession): session = session or DefaultSession session = session(prn=prn, store=store, *session_args, **session_kwargs) else: session.prn = prn session.store = store # sniff_sockets follows: {socket: label} sniff_sockets = {} if opened_socket is not None: if isinstance(opened_socket, list): sniff_sockets.update( (s, "socket%d" % i) for i, s in enumerate(opened_socket)) elif isinstance(opened_socket, dict): sniff_sockets.update( (s, label) for s, label in six.iteritems(opened_socket)) else: sniff_sockets[opened_socket] = "socket0" if offline is not None: flt = karg.get('filter') if isinstance(offline, list) and \ all(isinstance(elt, str) for elt in offline): sniff_sockets.update( (PcapReader(fname if flt is None else tcpdump( fname, args=["-w", "-"], flt=flt, getfd=True)), fname) for fname in offline) elif isinstance(offline, dict): sniff_sockets.update( (PcapReader(fname if flt is None else tcpdump( fname, args=["-w", "-"], flt=flt, getfd=True)), label) for fname, label in six.iteritems(offline)) else: # Write Scapy Packet objects to a pcap file def _write_to_pcap(packets_list): filename = get_temp_file(autoext=".pcap") wrpcap(filename, offline) return filename, filename if isinstance(offline, Packet): tempfile_written, offline = _write_to_pcap([offline]) elif isinstance(offline, list) and \ all(isinstance(elt, Packet) for elt in offline): tempfile_written, offline = _write_to_pcap(offline) sniff_sockets[PcapReader(offline if flt is None else tcpdump( offline, args=["-w", "-"], flt=flt, getfd=True, quiet=quiet))] = offline if not sniff_sockets or iface is not None: iface = resolve_iface(iface or conf.iface) if L2socket is None: L2socket = iface.l2listen() if isinstance(iface, list): sniff_sockets.update( (L2socket(type=ETH_P_ALL, iface=ifname, *arg, **karg), ifname) for ifname in iface) elif isinstance(iface, dict): sniff_sockets.update( (L2socket(type=ETH_P_ALL, iface=ifname, *arg, **karg), iflabel) for ifname, iflabel in six.iteritems(iface)) else: sniff_sockets[L2socket(type=ETH_P_ALL, iface=iface, *arg, **karg)] = iface # Get select information from the sockets _main_socket = next(iter(sniff_sockets)) select_func = _main_socket.select _backup_read_func = _main_socket.__class__.recv nonblocking_socket = _main_socket.nonblocking_socket # We check that all sockets use the same select(), or raise a warning if not all(select_func == sock.select for sock in sniff_sockets): warning("Warning: inconsistent socket types ! " "The used select function " "will be the one of the first socket") if nonblocking_socket: # select is non blocking def stop_cb(): self.continue_sniff = False self.stop_cb = stop_cb close_pipe = None else: # select is blocking: Add special control socket from scapy.automaton import ObjectPipe close_pipe = ObjectPipe() sniff_sockets[close_pipe] = "control_socket" def stop_cb(): if self.running: close_pipe.send(None) self.continue_sniff = False self.stop_cb = stop_cb try: if started_callback: started_callback() self.continue_sniff = True # Start timeout if timeout is not None: stoptime = time.time() + timeout remain = None while sniff_sockets and self.continue_sniff: if timeout is not None: remain = stoptime - time.time() if remain <= 0: break sockets, read_func = select_func(sniff_sockets, remain) read_func = read_func or _backup_read_func dead_sockets = [] for s in sockets: if s is close_pipe: break try: p = read_func(s) except EOFError: # End of stream try: s.close() except Exception: pass dead_sockets.append(s) continue except Exception as ex: msg = " It was closed." try: # Make sure it's closed s.close() except Exception as ex: msg = " close() failed with '%s'" % ex warning("Socket %s failed with '%s'." % (s, ex) + msg) dead_sockets.append(s) if conf.debug_dissector >= 2: raise continue if p is None: continue if lfilter and not lfilter(p): continue p.sniffed_on = sniff_sockets[s] # on_packet_received handles the prn/storage session.on_packet_received(p) # check if (stop_filter and stop_filter(p)) or \ (0 < count <= session.count): self.continue_sniff = False break # Removed dead sockets for s in dead_sockets: del sniff_sockets[s] except KeyboardInterrupt: pass self.running = False if opened_socket is None: for s in sniff_sockets: s.close() elif close_pipe: close_pipe.close() self.results = session.toPacketList()
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")