def __repr__(self): lst = [] for num, layer in six.iteritems(self.num2layer): if layer in self.layer2num and self.layer2num[layer] == num: dir = "<->" else: dir = " ->" lst.append((num, "%#6x %s %-20s (%s)" % (num, dir, layer.__name__, layer._name))) for layer, num in six.iteritems(self.layer2num): if num not in self.num2layer or self.num2layer[num] != layer: lst.append((num, "%#6x <- %-20s (%s)" % (num, layer.__name__, layer._name))) lst.sort() return "\n".join(y for x, y in lst)
def update(self, other): for key, value in six.iteritems(other): # We only update an element from `other` either if it does # not exist in `self` or if the entry in `self` is older. if key not in self or self._timetable[key] < other._timetable[key]: dict.__setitem__(self, key, value) self._timetable[key] = other._timetable[key]
def _load(module, globals_dict=None, symb_list=None): # type: (str, Optional[Dict[str, Any]], Optional[List[str]]) -> None """Loads a Python module to make variables, objects and functions available globally. The idea is to load the module using importlib, then copy the symbols to the global symbol table. """ if globals_dict is None: globals_dict = six.moves.builtins.__dict__ try: mod = importlib.import_module(module) if '__all__' in mod.__dict__: # import listed symbols for name in mod.__dict__['__all__']: if symb_list is not None: symb_list.append(name) globals_dict[name] = mod.__dict__[name] else: # only import non-private symbols for name, sym in six.iteritems(mod.__dict__): if _validate_local(name): if symb_list is not None: symb_list.append(name) globals_dict[name] = sym except Exception: log_interactive.error("Loading module %s", module, exc_info=True)
def __getattr__(self, attr): try: return object.__getattribute__(self, attr) except AttributeError: for k, v in six.iteritems(self.__dict__): if self.ident(v) == attr: return k
def __repr__(self): s = [] if self: mk = max(len(k) for k in six.iterkeys(self.__dict__)) fmt = "%%-%is %%s" % (mk + 1) for item in six.iteritems(self.__dict__): s.append(fmt % item) return "\n".join(s)
def multiplot(self, f, lfilter=None, plot_xy=False, **kargs): # type: (Callable, Optional[Callable], bool, Any) -> Line2D """Uses a function that returns a label and a value for this label, then plots all the values label by label. A list of matplotlib.lines.Line2D is returned. """ # Python 2 backward compatibility f = lambda_tuple_converter(f) lfilter = lambda_tuple_converter(lfilter) # Get the list of packets if lfilter is None: lst_pkts = (f(*e) for e in self.res) else: lst_pkts = (f(*e) for e in self.res if lfilter(*e)) # Apply the function f to the packets d = {} # type: Dict[str, List[float]] for k, v in lst_pkts: d.setdefault(k, []).append(v) # Mimic the default gnuplot output if not kargs: kargs = MATPLOTLIB_DEFAULT_PLOT_KARGS if plot_xy: lines = [ plt.plot(*zip(*pl), **dict(kargs, label=k)) for k, pl in six.iteritems(d) ] else: lines = [ plt.plot(pl, **dict(kargs, label=k)) for k, pl in six.iteritems(d) ] plt.legend(loc="center right", bbox_to_anchor=(1.5, 0.5)) # Call show() if matplotlib is not inlined if not MATPLOTLIB_INLINED: plt.show() return lines
def reverse_lookup(self, name, case_sensitive=False): """ Find all MACs registered to a OUI :param name: the OUI name :param case_sensitive: default to False :returns: a dict of mac:tuples (Name, Extended Name) """ if case_sensitive: filtr = lambda x, l: any(x == z for z in l) else: name = name.lower() filtr = lambda x, l: any(x == z.lower() for z in l) return {k: v for k, v in six.iteritems(self.__dict__) if filtr(name, v)}
def conversations(self, getsrcdst=None, **kargs): """Graphes a conversations between sources and destinations and display it (using graphviz and imagemagick) :param getsrcdst: a function that takes an element of the list and returns the source, the destination and optionally a label. By default, returns the IP source and destination from IP and ARP layers :param type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option :param target: filename or redirect. Defaults pipe to Imagemagick's display program :param prog: which graphviz program to use """ if getsrcdst is None: def getsrcdst(pkt): """Extract src and dst addresses""" if 'IP' in pkt: return (pkt['IP'].src, pkt['IP'].dst) if 'IPv6' in pkt: return (pkt['IPv6'].src, pkt['IPv6'].dst) if 'ARP' in pkt: return (pkt['ARP'].psrc, pkt['ARP'].pdst) raise TypeError() conv = {} for p in self.res: p = self._elt2pkt(p) try: c = getsrcdst(p) except Exception: # No warning here: it's OK that getsrcdst() raises an # exception, since it might be, for example, a # function that expects a specific layer in each # packet. The try/except approach is faster and # considered more Pythonic than adding tests. continue if len(c) == 3: conv.setdefault(c[:2], set()).add(c[2]) else: conv[c] = conv.get(c, 0) + 1 gr = 'digraph "conv" {\n' for (s, d), l in six.iteritems(conv): gr += '\t "%s" -> "%s" [label="%s"]\n' % (s, d, ', '.join( str(x) for x in l) if isinstance(l, set) else l) gr += "}\n" return do_graph(gr, **kargs)
def load(self): if not get_if_list(): # Try a restart NetworkInterfaceDict._pcap_check() windows_interfaces = dict() for i in get_windows_if_list(): # Detect Loopback interface if "Loopback" in i['name']: i['name'] = conf.loopback_name if i['guid']: if conf.use_npcap and i['name'] == conf.loopback_name: i['guid'] = NPCAP_LOOPBACK_NAME windows_interfaces[i['guid']] = i index = 0 for pcap_name, if_data in six.iteritems(conf.cache_iflist): name, ips, flags = if_data guid = _pcapname_to_guid(pcap_name) data = windows_interfaces.get(guid, None) if data: # Exists in Windows registry data['pcap_name'] = pcap_name data['ips'].extend(ips) data['flags'] = flags data['invalid'] = False else: # Only in [Wi]npcap index -= 1 data = { 'name': name, 'pcap_name': pcap_name, 'description': name, 'win_index': index, 'guid': guid, 'invalid': False, 'mac': '00:00:00:00:00:00', 'ipv4_metric': 0, 'ipv6_metric': 0, 'ips': list(set(ips)), 'flags': flags } # No KeyError will happen here, as we get it from cache self.data[guid] = NetworkInterface(data)
def build_graph(self): s = 'digraph "%s" {\n' % self.__class__.__name__ se = "" # Keep initial nodes at the beginning for better rendering for st in six.itervalues(self.states): if st.atmt_initial: se = ('\t"%s" [ style=filled, fillcolor=blue, shape=box, root=true];\n' % st.atmt_state) + se # noqa: E501 elif st.atmt_final: se += '\t"%s" [ style=filled, fillcolor=green, shape=octagon ];\n' % st.atmt_state # noqa: E501 elif st.atmt_error: se += '\t"%s" [ style=filled, fillcolor=red, shape=octagon ];\n' % st.atmt_state # noqa: E501 s += se for st in six.itervalues(self.states): for n in st.atmt_origfunc.__code__.co_names + st.atmt_origfunc.__code__.co_consts: # noqa: E501 if n in self.states: s += '\t"%s" -> "%s" [ color=green ];\n' % (st.atmt_state, n) # noqa: E501 for c, k, v in ([("purple", k, v) for k, v in self.conditions.items()] + # noqa: E501 [("red", k, v) for k, v in self.recv_conditions.items()] + # noqa: E501 [("orange", k, v) for k, v in self.ioevents.items()]): for f in v: for n in f.__code__.co_names + f.__code__.co_consts: if n in self.states: line = f.atmt_condname for x in self.actions[f.atmt_condname]: line += "\\l>[%s]" % x.__name__ s += '\t"%s" -> "%s" [label="%s", color=%s];\n' % (k, n, line, c) # noqa: E501 for k, v in six.iteritems(self.timeout): for t, f in v: if f is None: continue for n in f.__code__.co_names + f.__code__.co_consts: if n in self.states: line = "%s/%.1fs" % (f.atmt_condname, t) for x in self.actions[f.atmt_condname]: line += "\\l>[%s]" % x.__name__ s += '\t"%s" -> "%s" [label="%s",color=blue];\n' % (k, n, line) # noqa: E501 s += "}\n" return s
def values(self): if self.timeout is None: return list(six.itervalues(self)) t0 = time.time() return [v for (k, v) in six.iteritems(self.__dict__) if t0 - self._timetable[k] < self.timeout] # noqa: E501
def items(self): if self.timeout is None: return dict.items(self) t0 = time.time() return [(k, v) for (k, v) in six.iteritems(self.__dict__) if t0 - self._timetable[k] < self.timeout] # noqa: E501
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: 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)) 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 pocsuite3.thirdparty.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 #print("stop_filter and stop_filter(p) is ",stop_filter and stop_filter(p)) 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 update(self, *args, **kwargs): for k, v in six.iteritems(dict(*args, **kwargs)): self[k] = v
def __new__(cls, name, bases, dct): cls = super(Automaton_metaclass, cls).__new__(cls, name, bases, dct) cls.states = {} cls.state = None cls.recv_conditions = {} cls.conditions = {} cls.ioevents = {} cls.timeout = {} cls.actions = {} cls.initial_states = [] cls.ionames = [] cls.iosupersockets = [] members = {} classes = [cls] while classes: c = classes.pop(0) # order is important to avoid breaking method overloading # noqa: E501 classes += list(c.__bases__) for k, v in six.iteritems(c.__dict__): if k not in members: members[k] = v decorated = [v for v in six.itervalues(members) if isinstance(v, types.FunctionType) and hasattr(v, "atmt_type")] # noqa: E501 for m in decorated: if m.atmt_type == ATMT.STATE: s = m.atmt_state cls.states[s] = m cls.recv_conditions[s] = [] cls.ioevents[s] = [] cls.conditions[s] = [] cls.timeout[s] = [] if m.atmt_initial: cls.initial_states.append(m) elif m.atmt_type in [ATMT.CONDITION, ATMT.RECV, ATMT.TIMEOUT, ATMT.IOEVENT]: # noqa: E501 cls.actions[m.atmt_condname] = [] for m in decorated: if m.atmt_type == ATMT.CONDITION: cls.conditions[m.atmt_state].append(m) elif m.atmt_type == ATMT.RECV: cls.recv_conditions[m.atmt_state].append(m) elif m.atmt_type == ATMT.IOEVENT: cls.ioevents[m.atmt_state].append(m) cls.ionames.append(m.atmt_ioname) if m.atmt_as_supersocket is not None: cls.iosupersockets.append(m) elif m.atmt_type == ATMT.TIMEOUT: cls.timeout[m.atmt_state].append((m.atmt_timeout, m)) elif m.atmt_type == ATMT.ACTION: for c in m.atmt_cond: cls.actions[c].append(m) for v in six.itervalues(cls.timeout): v.sort(key=lambda x: x[0]) v.append((None, None)) for v in itertools.chain(six.itervalues(cls.conditions), six.itervalues(cls.recv_conditions), six.itervalues(cls.ioevents)): v.sort(key=lambda x: x.atmt_prio) for condname, actlst in six.iteritems(cls.actions): actlst.sort(key=lambda x: x.atmt_cond[condname]) for ioev in cls.iosupersockets: setattr(cls, ioev.atmt_as_supersocket, _ATMT_to_supersocket(ioev.atmt_as_supersocket, ioev.atmt_ioname, cls)) # noqa: E501 return cls
def __repr__(self): return "<Message %s>" % " ".join("%s=%r" % (k, v) for (k, v) in six.iteritems(self.__dict__) # noqa: E501 if not k.startswith("_"))