def _read_routes_xp(): # The InterfaceIndex in Win32_IP4RouteTable does not match the # InterfaceIndex in Win32_NetworkAdapter under some platforms # (namely Windows XP): let's try an IP association routes = [] partial_routes = [] # map local IP addresses to interfaces local_addresses = {iface.ip: iface for iface in six.itervalues(IFACES)} iface_indexes = {} for line in exec_query(['Get-WmiObject', 'Win32_IP4RouteTable'], ['Name', 'Mask', 'NextHop', 'InterfaceIndex', 'Metric1']): if line[2] in local_addresses: iface = local_addresses[line[2]] # This gives us an association InterfaceIndex <-> interface iface_indexes[line[3]] = iface routes.append((atol(line[0]), atol(line[1]), "0.0.0.0", iface, iface.ip, int(line[4]))) else: partial_routes.append((atol(line[0]), atol(line[1]), line[2], line[3], int(line[4]))) for dst, mask, gw, ifidx, metric in partial_routes: if ifidx in iface_indexes: iface = iface_indexes[ifidx] routes.append((dst, mask, gw, iface, iface.ip, metric)) return routes
def _get_valid_guid(): if scapy.consts.LOOPBACK_INTERFACE: return scapy.consts.LOOPBACK_INTERFACE.guid else: for i in six.itervalues(IFACES): if not i.is_invalid(): return i.guid
def auth_encrypt(self, P, A, seq_num=None): """ Encrypt the data then prepend the explicit part of the nonce. The authentication tag is directly appended with the most recent crypto API. Additional data may be authenticated without encryption (as A). The 'seq_num' should never be used here, it is only a safeguard needed because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py actually is a _AEADCipher_TLS13 (even though others are not). """ if False in six.itervalues(self.ready): raise CipherError(P, A) if hasattr(self, "pc_cls"): self._cipher.mode._initialization_vector = self._get_nonce() self._cipher.mode._tag = None encryptor = self._cipher.encryptor() encryptor.authenticate_additional_data(A) res = encryptor.update(P) + encryptor.finalize() res += encryptor.tag else: if isinstance(self._cipher, AESCCM): res = self._cipher.encrypt(self._get_nonce(), P, A, tag_length=self.tag_len) else: res = self._cipher.encrypt(self._get_nonce(), P, A) nonce_explicit = pkcs_i2osp(self.nonce_explicit, self.nonce_explicit_len) self._update_nonce_explicit() return nonce_explicit + res
def auth_encrypt(self, P, A, seq_num): """ Encrypt the data, and append the computed authentication code. TLS 1.3 does not use additional data, but we leave this option to the user nonetheless. Note that the cipher's authentication tag must be None when encrypting. """ if False in six.itervalues(self.ready): raise CipherError(P, A) if hasattr(self, "pc_cls"): self._cipher.mode._tag = None self._cipher.mode._initialization_vector = self._get_nonce(seq_num) encryptor = self._cipher.encryptor() encryptor.authenticate_additional_data(A) res = encryptor.update(P) + encryptor.finalize() res += encryptor.tag else: if (conf.crypto_valid_advanced and isinstance(self._cipher, AESCCM)): res = self._cipher.encrypt(self._get_nonce(seq_num), P, A, tag_length=self.tag_len) else: res = self._cipher.encrypt(self._get_nonce(seq_num), P, A) return res
def dev_from_pcapname(self, pcap_name): """Return Windows device name for given pcap device name.""" try: return next(iface for iface in six.itervalues(self) if iface.pcap_name == pcap_name) except StopIteration: raise ValueError("Unknown pypcap network interface %r" % pcap_name)
def __init__(self, objlist=None): self.objlist = [ x._asn1_obj for x in six.itervalues(ASN1_Class_UNIVERSAL.__rdict__) if hasattr(x, "_asn1_obj") ] if objlist is None else objlist self.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" # noqa: E501
def getfield(self, pkt, s): if (pkt.tls_session.rcs.cipher.type != "aead" and False in six.itervalues(pkt.tls_session.rcs.cipher.ready)): # XXX Find a more proper way to handle the still-encrypted case return s, b"" tmp_len = pkt.tls_session.rcs.mac_len return s[tmp_len:], self.m2i(pkt, s[:tmp_len])
def dev_from_name(self, name): """Return the first pcap device name for a given Windows device name. """ for iface in six.itervalues(self): if iface.name == name: return iface raise ValueError("Unknown network interface %r" % name)
def dev_from_name(self, name): """Return the first pcap device name for a given Windows device name. """ try: return next(iface for iface in six.itervalues(self) if iface.name == name) except StopIteration: raise ValueError("Unknown network interface %r" % name)
def encrypt(self, data): """ Encrypt the data. Also, update the cipher iv. This is needed for SSLv3 and TLS 1.0. For TLS 1.1/1.2, it is overwritten in TLS.post_build(). """ if False in six.itervalues(self.ready): raise CipherError(data) encryptor = self._cipher.encryptor() tmp = encryptor.update(data) + encryptor.finalize() self.iv = tmp[-self.block_size:] return tmp
def dev_from_index(self, if_index): """Return interface name from interface index""" try: return next(iface for iface in six.itervalues(self) if iface.win_index == str(if_index)) except StopIteration: if str(if_index) == "1": # Test if the loopback interface is set up if isinstance(scapy.consts.LOOPBACK_INTERFACE, NetworkInterface): # noqa: E501 return scapy.consts.LOOPBACK_INTERFACE raise ValueError("Unknown network interface index %r" % if_index)
def randval(self): randchoices = [] for p in six.itervalues(self.choices): if hasattr(p, "ASN1_root"): # should be ASN1_Packet class randchoices.append(packet.fuzz(p())) elif hasattr(p, "ASN1_tag"): if isinstance(p, type): # should be (basic) ASN1F_field class # noqa: E501 randchoices.append(p("dummy", None).randval()) else: # should be ASN1F_PACKET instance randchoices.append(p.randval()) return RandChoice(*randchoices)
def graph(self, **kargs): s = 'digraph "%s" {\n' % self.__class__.__name__ se = "" # Keep initial nodes at the begining 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 elif st.atmt_final: se += '\t"%s" [ style=filled, fillcolor=green, shape=octagon ];\n' % st.atmt_state elif st.atmt_error: se += '\t"%s" [ style=filled, fillcolor=red, shape=octagon ];\n' % st.atmt_state s += se for st in six.itervalues(self.states): for n in st.atmt_origfunc.__code__.co_names+st.atmt_origfunc.__code__.co_consts: if n in self.states: s += '\t"%s" -> "%s" [ color=green ];\n' % (st.atmt_state,n) for c,k,v in ([("purple",k,v) for k,v in self.conditions.items()]+ [("red",k,v) for k,v in self.recv_conditions.items()]+ [("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: l = f.atmt_condname for x in self.actions[f.atmt_condname]: l += "\\l>[%s]" % x.__name__ s += '\t"%s" -> "%s" [label="%s", color=%s];\n' % (k,n,l,c) 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: l = "%s/%.1fs" % (f.atmt_condname,t) for x in self.actions[f.atmt_condname]: l += "\\l>[%s]" % x.__name__ s += '\t"%s" -> "%s" [label="%s",color=blue];\n' % (k,n,l) s += "}\n" return do_graph(s, **kargs)
def decrypt(self, data): """ Decrypt the data. Also, update the cipher iv. This is needed for SSLv3 and TLS 1.0. For TLS 1.1/1.2, it is overwritten in TLS.pre_dissect(). If we lack the key, we raise a CipherError which contains the input. """ if False in six.itervalues(self.ready): raise CipherError(data) decryptor = self._cipher.decryptor() tmp = decryptor.update(data) + decryptor.finalize() self.iv = data[-self.block_size:] return tmp
def post_dissection(self, r): if not self.tls_session.frozen and self.server_share.pubkey: # if there is a pubkey, we assume the crypto library is ok pubshare = self.tls_session.tls13_server_pubshare if len(pubshare) > 0: pkt_info = r.firstlayer().summary() log_runtime.info("TLS: overwriting previous server key share [%s]", pkt_info) # noqa: E501 group_name = _tls_named_groups[self.server_share.group] pubshare[group_name] = self.server_share.pubkey if group_name in self.tls_session.tls13_client_privshares: pubkey = self.server_share.pubkey privkey = self.tls_session.tls13_client_privshares[group_name] if group_name in six.itervalues(_tls_named_ffdh_groups): pms = privkey.exchange(pubkey) elif group_name in six.itervalues(_tls_named_curves): if group_name == "x25519": pms = privkey.exchange(pubkey) else: pms = privkey.exchange(ec.ECDH(), pubkey) self.tls_session.tls13_dhe_secret = pms return super(TLS_Ext_KeyShare_SH, self).post_dissection(r)
def auth_decrypt(self, A, C, seq_num=None, add_length=True): """ Decrypt the data and authenticate the associated data (i.e. A). If the verification fails, an AEADTagError is raised. It is the user's responsibility to catch it if deemed useful. If we lack the key, we raise a CipherError which contains the encrypted input. Note that we add the TLSCiphertext length to A although we're supposed to add the TLSCompressed length. Fortunately, they are the same, but the specifications actually messed up here. :'( The 'add_length' switch should always be True for TLS, but we provide it anyway (mostly for test cases, hum). The 'seq_num' should never be used here, it is only a safeguard needed because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py actually is a _AEADCipher_TLS13 (even though others are not). """ nonce_explicit_str, C, mac = (C[:self.nonce_explicit_len], C[self.nonce_explicit_len:-self.tag_len], C[-self.tag_len:]) if False in six.itervalues(self.ready): raise CipherError(nonce_explicit_str, C, mac) self.nonce_explicit = pkcs_os2ip(nonce_explicit_str) if add_length: A += struct.pack("!H", len(C)) if hasattr(self, "pc_cls"): self._cipher.mode._initialization_vector = self._get_nonce() self._cipher.mode._tag = mac decryptor = self._cipher.decryptor() decryptor.authenticate_additional_data(A) P = decryptor.update(C) try: decryptor.finalize() except InvalidTag: raise AEADTagError(nonce_explicit_str, P, mac) else: try: if isinstance(self._cipher, AESCCM): P = self._cipher.decrypt(self._get_nonce(), C + mac, A, tag_length=self.tag_len) else: P = self._cipher.decrypt(self._get_nonce(), C + mac, A) except InvalidTag: raise AEADTagError(nonce_explicit_str, "<unauthenticated data>", mac) return nonce_explicit_str, P, mac
def getfield(self, pkt, s): """ If the decryption of the content did not fail with a CipherError, we begin a loop on the clear content in order to get as much messages as possible, of the type advertised in the record header. This is notably important for several TLS handshake implementations, which may for instance pack a server_hello, a certificate, a server_key_exchange and a server_hello_done, all in one record. Each parsed message may update the TLS context through their method .post_dissection_tls_session_update(). If the decryption failed with a CipherError, presumably because we missed the session keys, we signal it by returning a _TLSEncryptedContent packet which simply contains the ciphered data. """ tmp_len = self.length_from(pkt) lst = [] ret = b"" remain = s if tmp_len is not None: remain, ret = s[:tmp_len], s[tmp_len:] if remain == b"": if (((pkt.tls_session.tls_version or 0x0303) > 0x0200) and hasattr(pkt, "type") and pkt.type == 23): return ret, [TLSApplicationData(data=b"")] else: return ret, [Raw(load=b"")] if False in six.itervalues(pkt.tls_session.rcs.cipher.ready): return ret, _TLSEncryptedContent(remain) else: while remain: raw_msg = remain p = self.m2i(pkt, remain) if Padding in p: pad = p[Padding] remain = pad.load del(pad.underlayer.payload) if len(remain) != 0: raw_msg = raw_msg[:-len(remain)] else: remain = b"" if isinstance(p, _GenericTLSSessionInheritance): if not p.tls_session.frozen: p.post_dissection_tls_session_update(raw_msg) lst.append(p) return remain + ret, lst
def i2repr(self, pkt, x): v = self.depends_on(pkt) if v in self.names: these_names = self.names[v] else: these_names = {} r = set() for flag_set in x: for i in six.itervalues(these_names): if i.short == flag_set: r.add("{} ({})".format(i.long, i.short)) break else: r.add(flag_set) return repr(r)
def sndrcvflood(pks, pkt, inter=0, verbose=None, chainCC=False, prn=lambda x: x): if not verbose: verbose = conf.verb if not isinstance(pkt, Gen): pkt = SetGen(pkt) tobesent = [p for p in pkt] received = plist.SndRcvList() seen = {} 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) # 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() remain = list(itertools.chain(*six.itervalues(hsent))) # Apply prn ans = [(x, prn(y)) for (x, y) in ans] 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 any2i(self, pkt, x): assert isinstance(x, six.integer_types + (set,)), 'set expected' if pkt is not None: if isinstance(x, six.integer_types): x = self.m2i(pkt, x) else: v = self.depends_on(pkt) if v is not None: assert v in self.names, 'invalid dependency' these_names = self.names[v] s = set() for i in x: for val in six.itervalues(these_names): if val.short == i: s.add(i) break else: assert False, 'Unknown flag "{}" with this dependency'.format(i) continue x = s return x
def auth_decrypt(self, A, C, seq_num): """ Decrypt the data and verify the authentication code (in this order). Note that TLS 1.3 is not supposed to use any additional data A. If the verification fails, an AEADTagError is raised. It is the user's responsibility to catch it if deemed useful. If we lack the key, we raise a CipherError which contains the encrypted input. """ C, mac = C[:-self.tag_len], C[-self.tag_len:] if False in six.itervalues(self.ready): raise CipherError(C, mac) if hasattr(self, "pc_cls"): self._cipher.mode._initialization_vector = self._get_nonce(seq_num) self._cipher.mode._tag = mac decryptor = self._cipher.decryptor() decryptor.authenticate_additional_data(A) P = decryptor.update(C) try: decryptor.finalize() except InvalidTag: raise AEADTagError(P, mac) else: try: if (conf.crypto_valid_advanced and isinstance(self._cipher, AESCCM)): P = self._cipher.decrypt(self._get_nonce(seq_num), C + mac, A, # noqa: E501 tag_length=self.tag_len) else: if (conf.crypto_valid_advanced and isinstance(self, Cipher_CHACHA20_POLY1305)): A += struct.pack("!H", len(C)) P = self._cipher.decrypt(self._get_nonce(seq_num), C + mac, A) # noqa: E501 except InvalidTag: raise AEADTagError("<unauthenticated data>", mac) return P, mac
IntField("vendor", 0) ] class OFPTFeaturesRequest(_ofp_header): name = "OFPT_FEATURES_REQUEST" fields_desc = [ ByteEnumField("version", 0x01, ofp_version), ByteEnumField("type", 5, ofp_type), ShortField("len", None), IntField("xid", 0) ] ofp_action_types_flags = [ v for v in six.itervalues(ofp_action_types) if v != 'OFPAT_VENDOR' ] class OFPTFeaturesReply(_ofp_header): name = "OFPT_FEATURES_REPLY" fields_desc = [ ByteEnumField("version", 0x01, ofp_version), ByteEnumField("type", 6, ofp_type), ShortField("len", None), IntField("xid", 0), LongField("datapath_id", 0), IntField("n_buffers", 0), ByteField("n_tables", 1), X3BytesField("pad", 0), FlagsField("capabilities", 0, 32, [
def itervalues(self): if self.timeout is None: return six.itervalues(self.__dict__) t0=time.time() return (v for (k,v) in six.iteritems(self.__dict__) if t0-self._timetable[k] < self.timeout)
def itervalues(self): # type: () -> Iterator[Tuple[str, Any]] if self.timeout is None: return six.itervalues(self.__dict__) # type: ignore t0 = time.time() return (v for (k, v) in six.iteritems(self.__dict__) if t0 - self._timetable[k] < self.timeout) # noqa: E501
def decrypt(self, data): if False in six.itervalues(self.ready): raise CipherError(data) self._dec_updated_with += data return self.decryptor.update(data)
def __init__( self, pks, # type: SuperSocket pkt, # type: _PacketIterable timeout=None, # type: Optional[int] inter=0, # type: int verbose=None, # type: Optional[int] chainCC=False, # type: bool retry=0, # type: int multi=False, # type: bool rcv_pks=None, # type: Optional[SuperSocket] prebuild=False, # type: bool _flood=None, # type: Optional[Tuple[int, Callable[[], None]]] # noqa: E501 threaded=False, # type: bool session=None # type: Optional[_GlobSessionType] ): # type: (...) -> None # Instantiate all arguments if verbose is None: verbose = conf.verb if conf.debug_match: debug.recv = PacketList([], "Received") debug.sent = PacketList([], "Sent") debug.match = SndRcvList([], "Matched") self.nbrecv = 0 self.ans = [] # type: List[QueryAnswer] self.pks = pks self.rcv_pks = rcv_pks or pks self.inter = inter self.verbose = verbose self.chainCC = chainCC self.multi = multi self.timeout = timeout self.session = session # Instantiate packet holders if _flood: self.tobesent = pkt # type: Union[_PacketIterable, SetGen[Packet]] self.notans = _flood[0] else: if isinstance(pkt, types.GeneratorType) or prebuild: self.tobesent = list(pkt) self.notans = len(self.tobesent) else: self.tobesent = (SetGen(pkt) if not isinstance(pkt, Gen) else pkt) self.notans = self.tobesent.__iterlen__() if retry < 0: autostop = retry = -retry else: autostop = 0 if timeout is not None and timeout < 0: self.timeout = None while retry >= 0: self.hsent = {} # type: Dict[bytes, List[Packet]] if threaded or _flood: # Send packets in thread. # https://github.com/secdev/scapy/issues/1791 snd_thread = Thread(target=self._sndrcv_snd) snd_thread.daemon = True # Start routine with callback self._sndrcv_rcv(snd_thread.start) # Ended. Let's close gracefully if _flood: # Flood: stop send thread _flood[1]() snd_thread.join() else: self._sndrcv_rcv(self._sndrcv_snd) if multi: remain = [ p for p in itertools.chain(*six.itervalues(self.hsent)) if not hasattr(p, '_answered') ] else: remain = list(itertools.chain(*six.itervalues(self.hsent))) if autostop and len(remain) > 0 and \ len(remain) != len(self.tobesent): retry = autostop self.tobesent = remain if len(self.tobesent) == 0: break retry -= 1 if conf.debug_match: debug.sent = PacketList(remain[:], "Sent") debug.match = SndRcvList(self.ans[:]) # Clean the ans list to delete the field _answered if multi: for snd, _ in self.ans: if hasattr(snd, '_answered'): del snd._answered if verbose: print("\nReceived %i packets, got %i answers, " "remaining %i packets" % (self.nbrecv + len(self.ans), len(self.ans), self.notans)) self.ans_result = SndRcvList(self.ans) self.unans_result = PacketList(remain, "Unanswered")
def itervalues(self): # type: () -> Iterator[_V] return six.itervalues(self.d) # type: ignore
def consider_read_padding(self): # Return True if padding is needed. Used by TLSPadField. return (self.rcs.cipher.type == "block" and not (False in six.itervalues(self.rcs.cipher.ready)))
def __init__(self, pks, pkt, timeout=None, inter=0, verbose=None, chainCC=False, retry=0, multi=False, rcv_pks=None, prebuild=False, _flood=None, session=None): # Instantiate all arguments if verbose is None: verbose = conf.verb if conf.debug_match: debug.recv = PacketList([], "Received") debug.sent = PacketList([], "Sent") debug.match = SndRcvList([], "Matched") self.nbrecv = 0 self.ans = [] self.pks = pks self.rcv_pks = rcv_pks or pks self.inter = inter self.verbose = verbose self.chainCC = chainCC self.multi = multi self.timeout = timeout self.session = session # Instantiate packet holders if _flood: self.tobesent = pkt self.notans = _flood[0] else: if isinstance(pkt, types.GeneratorType) or prebuild: self.tobesent = [p for p in pkt] self.notans = len(self.tobesent) else: self.tobesent = (SetGen(pkt) if not isinstance(pkt, Gen) else pkt) self.notans = self.tobesent.__iterlen__() if retry < 0: autostop = retry = -retry else: autostop = 0 if timeout is not None and timeout < 0: self.timeout = None while retry >= 0: self.hsent = {} # Send packets in thread. # https://github.com/secdev/scapy/issues/1791 snd_thread = Thread(target=self._sndrcv_snd) snd_thread.setDaemon(True) # Start routine with callback self._sndrcv_rcv(snd_thread.start) # Ended. Let's close gracefully if _flood: # Flood: stop send thread _flood[1]() snd_thread.join() if multi: remain = [ p for p in itertools.chain(*six.itervalues(self.hsent)) if not hasattr(p, '_answered') ] else: remain = list(itertools.chain(*six.itervalues(self.hsent))) if autostop and len(remain) > 0 and \ len(remain) != len(self.tobesent): retry = autostop self.tobesent = remain if len(self.tobesent) == 0: break retry -= 1 if conf.debug_match: debug.sent = PacketList(remain[:], "Sent") debug.match = SndRcvList(self.ans[:]) # Clean the ans list to delete the field _answered if multi: for snd, _ in self.ans: if hasattr(snd, '_answered'): del snd._answered if verbose: print("\nReceived %i packets, got %i answers, " "remaining %i packets" % (self.nbrecv + len(self.ans), len(self.ans), self.notans)) self.ans_result = SndRcvList(self.ans) self.unans_result = PacketList(remain, "Unanswered")
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 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""" is_single = isinstance(pkt, Gen) pkts = [pkt] if is_single else 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 if is_single else SetGen(pkt))] notans = len(tobesent) if retry < 0: autostop = retry = -retry else: autostop = 0 for pkt in pkts: pkt.sent_time = None 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) 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 = itertools.chain(*six.itervalues(hsent)) remain = [p for p in remain if not hasattr(p, '_answered')] if multi else list(remain) if not remain: break if autostop and len(remain) != len(tobesent): retry = autostop tobesent = 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)) return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
def _get_valid_guid(): if scapy.consts.LOOPBACK_INTERFACE: return scapy.consts.LOOPBACK_INTERFACE.guid else: return next((i.guid for i in six.itervalues(IFACES) if not i.is_invalid()), None)
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.stop_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) if m.atmt_stop: cls.stop_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 sndrcv(pks, pkt, timeout=None, inter=0, verbose=None, chainCC=0, retry=0, multi=0): if not isinstance(pkt, Gen): pkt = SetGen(pkt) if verbose is None: verbose = conf.verb debug.recv = plist.PacketList([], "Unanswered") debug.sent = plist.PacketList([], "Sent") debug.match = plist.SndRcvList([]) nbrecv = 0 ans = [] # do it here to fix random fields, so that parent and child have the same all_stimuli = tobesent = [p for p in pkt] notans = len(tobesent) hsent = {} for i in tobesent: h = i.hashret() if h in hsent: hsent[h].append(i) else: hsent[h] = [i] if retry < 0: retry = -retry autostop = retry else: autostop = 0 while retry >= 0: found = 0 if timeout < 0: timeout = None rdpipe, wrpipe = os.pipe() rdpipe = os.fdopen(rdpipe) wrpipe = os.fdopen(wrpipe, "w") pid = 1 try: pid = os.fork() if pid == 0: try: sys.stdin.close() rdpipe.close() try: i = 0 if verbose: print("Begin emission:") for p in tobesent: pks.send(p) i += 1 time.sleep(inter) if verbose: print("Finished to send %i packets." % i) except SystemExit: pass except KeyboardInterrupt: pass except: log_runtime.exception("--- Error in child %i" % os.getpid()) log_runtime.info("--- Error in child %i" % os.getpid()) finally: try: os.setpgrp() # Chance process group to avoid ctrl-C sent_times = [ p.sent_time for p in all_stimuli if p.sent_time ] six.moves.cPickle.dump((conf.netcache, sent_times), wrpipe) wrpipe.close() except: pass elif pid < 0: log_runtime.error("fork error") else: wrpipe.close() stoptime = 0 remaintime = None inmask = [rdpipe, pks] try: try: while True: if stoptime: remaintime = stoptime - time.time() if remaintime <= 0: break r = None if conf.use_bpf: from scapy.arch.bpf.supersocket import bpf_select inp = bpf_select(inmask) if pks in inp: r = pks.recv() elif not isinstance(pks, StreamSocket) and ( FREEBSD or DARWIN or OPENBSD): inp, out, err = select(inmask, [], [], 0.05) if len(inp) == 0 or pks in inp: r = pks.nonblock_recv() else: inp = [] try: inp, out, err = select( inmask, [], [], remaintime) except (IOError, select_error) as exc: # select.error has no .errno attribute if exc.args[0] != errno.EINTR: raise if len(inp) == 0: break if pks in inp: r = pks.recv(MTU) if rdpipe in inp: if timeout: stoptime = time.time() + timeout del (inmask[inmask.index(rdpipe)]) if r is None: continue ok = 0 h = r.hashret() if h in hsent: hlst = hsent[h] for i, sentpkt in enumerate(hlst): if r.answers(sentpkt): ans.append((sentpkt, r)) if verbose > 1: os.write(1, b"*") 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, b".") nbrecv += 1 if conf.debug_match: debug.recv.append(r) except KeyboardInterrupt: if chainCC: raise finally: try: nc, sent_times = six.moves.cPickle.load(rdpipe) except EOFError: warning( "Child died unexpectedly. Packets may have not been sent %i" % os.getpid()) else: conf.netcache.update(nc) for p, t in zip(all_stimuli, sent_times): p.sent_time = t os.waitpid(pid, 0) finally: if pid == 0: os._exit(0) remain = list(itertools.chain(*six.itervalues(hsent))) if multi: remain = [p for p in remain if not hasattr(p, '_answered')] if autostop and len(remain) > 0 and len(remain) != len(tobesent): retry = autostop tobesent = remain if len(tobesent) == 0: break retry -= 1 if conf.debug_match: debug.sent = plist.PacketList(remain[:], "Sent") debug.match = plist.SndRcvList(ans[:]) #clean the ans list to delete the field _answered if (multi): for s, r in ans: if hasattr(s, '_answered'): del (s._answered) if verbose: print("\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv + len(ans), len(ans), notans)) return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
def 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 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 encrypt(self, data): if False in six.itervalues(self.ready): raise CipherError, data return self.encryptor.update(data)
def dev_from_pcapname(self, pcap_name): """Return Windows device name for given pcap device name.""" for iface in six.itervalues(self): if iface.pcap_name == pcap_name: return iface raise ValueError("Unknown pypcap network interface %r" % pcap_name)
def __new__(cls, name, bases, dct): # type: ignore # type: (str, Tuple[Any], Dict[str, Any]) -> Type[Automaton] cls = super(Automaton_metaclass, cls).__new__(cls, name, bases, dct) cls.states = {} cls.recv_conditions = {} # type: Dict[str, List[_StateWrapper]] cls.conditions = {} # type: Dict[str, List[_StateWrapper]] cls.ioevents = {} # type: Dict[str, List[_StateWrapper]] cls.timeout = { } # type: Dict[str, List[Tuple[int, _StateWrapper]]] # noqa: E501 cls.actions = {} # type: Dict[str, List[_StateWrapper]] cls.initial_states = [] # type: List[_StateWrapper] cls.stop_states = [] # type: List[_StateWrapper] 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 hasattr(v, "atmt_type") ] 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) if m.atmt_stop: cls.stop_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 co in m.atmt_cond: cls.actions[co].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, cast(Type["Automaton"], cls))) # Inject signature try: import inspect cls.__signature__ = inspect.signature( cls.parse_args) # type: ignore # noqa: E501 except (ImportError, AttributeError): pass return cast(Type["Automaton"], cls)
fields_desc = [ByteEnumField("version", 0x01, ofp_version), ByteEnumField("type", 4, ofp_type), ShortField("len", None), IntField("xid", 0), IntField("vendor", 0)] class OFPTFeaturesRequest(_ofp_header): name = "OFPT_FEATURES_REQUEST" fields_desc = [ByteEnumField("version", 0x01, ofp_version), ByteEnumField("type", 5, ofp_type), ShortField("len", None), IntField("xid", 0)] ofp_action_types_flags = [v for v in six.itervalues(ofp_action_types) if v != 'OFPAT_VENDOR'] class OFPTFeaturesReply(_ofp_header): name = "OFPT_FEATURES_REPLY" fields_desc = [ByteEnumField("version", 0x01, ofp_version), ByteEnumField("type", 6, ofp_type), ShortField("len", None), IntField("xid", 0), LongField("datapath_id", 0), IntField("n_buffers", 0), ByteField("n_tables", 1), X3BytesField("pad", 0), FlagsField("capabilities", 0, 32, ["FLOW_STATS", "TABLE_STATS",
] DNSRR_DISPATCHER = { 41: DNSRROPT, # RFC 1671 43: DNSRRDS, # RFC 4034 46: DNSRRRSIG, # RFC 4034 47: DNSRRNSEC, # RFC 4034 48: DNSRRDNSKEY, # RFC 4034 50: DNSRRNSEC3, # RFC 5155 51: DNSRRNSEC3PARAM, # RFC 5155 250: DNSRRTSIG, # RFC 2845 32769: DNSRRDLV, # RFC 4431 } DNSSEC_CLASSES = tuple(six.itervalues(DNSRR_DISPATCHER)) def isdnssecRR(obj): return isinstance(obj, DNSSEC_CLASSES) class DNSRR(InheritOriginDNSStrPacket): name = "DNS Resource Record" show_indent = 0 fields_desc = [ DNSStrField("rrname", ""), ShortEnumField("type", 1, dnstypes), ShortEnumField("rclass", 1, dnsclasses), IntField("ttl", 0), RDLenField("rdlen"),
def afterglow(self, src=None, event=None, dst=None, **kargs): """Experimental clone attempt of http://sourceforge.net/projects/afterglow each datum is reduced as src -> event -> dst and the data are graphed. by default we have IP.src -> IP.dport -> IP.dst""" if src is None: src = lambda x: x['IP'].src if event is None: event = lambda x: x['IP'].dport if dst is None: dst = lambda x: x['IP'].dst sl = {} el = {} dl = {} for i in self.res: try: s, e, d = src(i), event(i), dst(i) if s in sl: n, l = sl[s] n += 1 if e not in l: l.append(e) sl[s] = (n, l) else: sl[s] = (1, [e]) if e in el: n, l = el[e] n += 1 if d not in l: l.append(d) el[e] = (n, l) else: el[e] = (1, [d]) dl[d] = dl.get(d, 0) + 1 except: continue import math def normalize(n): return 2 + math.log(n) / 4.0 def minmax(x): m, M = reduce(lambda a, b: (min(a[0], b[0]), max(a[1], b[1])), ((a, a) for a in x)) if m == M: m = 0 if M == 0: M = 1 return m, M mins, maxs = minmax(x for x, _ in six.itervalues(sl)) mine, maxe = minmax(x for x, _ in six.itervalues(el)) mind, maxd = minmax(six.itervalues(dl)) gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n' gr += "# src nodes\n" for s in sl: n, l = sl[s] n = 1 + float(n - mins) / (maxs - mins) gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (repr(s), repr(s), n, n) # noqa: E501 gr += "# event nodes\n" for e in el: n, l = el[e] n = n = 1 + float(n - mine) / (maxe - mine) gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (repr(e), repr(e), n, n) # noqa: E501 for d in dl: n = dl[d] n = n = 1 + float(n - mind) / (maxd - mind) gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (repr(d), repr(d), n, n) # noqa: E501 gr += "###\n" for s in sl: n, l = sl[s] for e in l: gr += ' "src.%s" -> "evt.%s";\n' % (repr(s), repr(e)) for e in el: n, l = el[e] for d in l: gr += ' "evt.%s" -> "dst.%s";\n' % (repr(e), repr(d)) gr += "}" return do_graph(gr, **kargs)
def __init__(self, objlist=None): self.objlist = [ x._asn1_obj for x in six.itervalues(ASN1_Class_UNIVERSAL.__rdict__) if hasattr(x, "_asn1_obj") ] if objlist is None else objlist self.chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
def afterglow(self, src=None, event=None, dst=None, **kargs): """Experimental clone attempt of http://sourceforge.net/projects/afterglow each datum is reduced as src -> event -> dst and the data are graphed. by default we have IP.src -> IP.dport -> IP.dst""" if src is None: src = lambda x: x['IP'].src if event is None: event = lambda x: x['IP'].dport if dst is None: dst = lambda x: x['IP'].dst sl = {} el = {} dl = {} for i in self.res: try: s,e,d = src(i),event(i),dst(i) if s in sl: n,l = sl[s] n += 1 if e not in l: l.append(e) sl[s] = (n,l) else: sl[s] = (1,[e]) if e in el: n,l = el[e] n+=1 if d not in l: l.append(d) el[e] = (n,l) else: el[e] = (1,[d]) dl[d] = dl.get(d,0)+1 except: continue import math def normalize(n): return 2+math.log(n)/4.0 def minmax(x): m, M = reduce(lambda a, b: (min(a[0], b[0]), max(a[1], b[1])), ((a, a) for a in x)) if m == M: m = 0 if M == 0: M = 1 return m, M mins, maxs = minmax(x for x, _ in six.itervalues(sl)) mine, maxe = minmax(x for x, _ in six.itervalues(el)) mind, maxd = minmax(six.itervalues(dl)) gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n' gr += "# src nodes\n" for s in sl: n,l = sl[s]; n = 1+float(n-mins)/(maxs-mins) gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (repr(s),repr(s),n,n) gr += "# event nodes\n" for e in el: n,l = el[e]; n = n = 1+float(n-mine)/(maxe-mine) gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (repr(e),repr(e),n,n) for d in dl: n = dl[d]; n = n = 1+float(n-mind)/(maxd-mind) gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (repr(d),repr(d),n,n) gr += "###\n" for s in sl: n,l = sl[s] for e in l: gr += ' "src.%s" -> "evt.%s";\n' % (repr(s),repr(e)) for e in el: n,l = el[e] for d in l: gr += ' "evt.%s" -> "dst.%s";\n' % (repr(e),repr(d)) gr += "}" return do_graph(gr, **kargs)
def itervalues(self): return six.itervalues(self.__dict__)
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. """ 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 = PacketList([], "Unanswered") debug.sent = PacketList([], "Sent") debug.match = 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 _sndrcv_snd(pks, timeout, inter, verbose, tobesent, hsent, timessent, stopevent) hsent, newans, nbrecv, notans = _sndrcv_rcv( (rcv_pks or pks), hsent, stopevent, nbrecv, notans, verbose, chainCC, multi, _storage_policy=_storage_policy, ) 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 = PacketList(remain[:], "Sent") debug.match = 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 SndRcvList(ans) unans_result = remain if use_prn_mode else ( None if not store_unanswered else 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): """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 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) 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( 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 sndrcv(pks, pkt, timeout = None, inter = 0, verbose=None, chainCC=0, retry=0, multi=0): if not isinstance(pkt, Gen): pkt = SetGen(pkt) if verbose is None: verbose = conf.verb debug.recv = plist.PacketList([],"Unanswered") debug.sent = plist.PacketList([],"Sent") debug.match = plist.SndRcvList([]) nbrecv=0 ans = [] # do it here to fix random fields, so that parent and child have the same all_stimuli = tobesent = [p for p in pkt] notans = len(tobesent) hsent={} for i in tobesent: h = i.hashret() if h in hsent: hsent[h].append(i) else: hsent[h] = [i] if retry < 0: retry = -retry autostop=retry else: autostop=0 while retry >= 0: found=0 if timeout < 0: timeout = None rdpipe,wrpipe = os.pipe() rdpipe=os.fdopen(rdpipe) wrpipe=os.fdopen(wrpipe,"w") pid=1 try: pid = os.fork() if pid == 0: try: sys.stdin.close() rdpipe.close() try: i = 0 if verbose: print("Begin emission:") for p in tobesent: pks.send(p) i += 1 time.sleep(inter) if verbose: print("Finished to send %i packets." % i) except SystemExit: pass except KeyboardInterrupt: pass except: log_runtime.exception("--- Error in child %i" % os.getpid()) log_runtime.info("--- Error in child %i" % os.getpid()) finally: try: os.setpgrp() # Chance process group to avoid ctrl-C sent_times = [p.sent_time for p in all_stimuli if p.sent_time] six.moves.cPickle.dump( (conf.netcache,sent_times), wrpipe ) wrpipe.close() except: pass elif pid < 0: log_runtime.error("fork error") else: wrpipe.close() stoptime = 0 remaintime = None inmask = [rdpipe,pks] try: try: while True: if stoptime: remaintime = stoptime-time.time() if remaintime <= 0: break r = None if conf.use_bpf: from scapy.arch.bpf.supersocket import bpf_select inp = bpf_select(inmask) if pks in inp: r = pks.recv() elif not isinstance(pks, StreamSocket) and (FREEBSD or DARWIN or OPENBSD): inp, out, err = select(inmask,[],[], 0.05) if len(inp) == 0 or pks in inp: r = pks.nonblock_recv() else: inp = [] try: inp, out, err = select(inmask,[],[], remaintime) except (IOError, select_error) as exc: # select.error has no .errno attribute if exc.args[0] != errno.EINTR: raise if len(inp) == 0: break if pks in inp: r = pks.recv(MTU) if rdpipe in inp: if timeout: stoptime = time.time()+timeout del(inmask[inmask.index(rdpipe)]) if r is None: continue ok = 0 h = r.hashret() if h in hsent: hlst = hsent[h] for i, sentpkt in enumerate(hlst): if r.answers(sentpkt): ans.append((sentpkt, r)) if verbose > 1: os.write(1, "*") ok = 1 if not multi: del hlst[i] notans -= 1 else: if not hasattr(sentpkt, '_answered'): notans -= 1 sentpkt._answered = 1 break if notans == 0 and not multi: break if not ok: if verbose > 1: os.write(1, ".") nbrecv += 1 if conf.debug_match: debug.recv.append(r) except KeyboardInterrupt: if chainCC: raise finally: try: nc,sent_times = six.moves.cPickle.load(rdpipe) except EOFError: warning("Child died unexpectedly. Packets may have not been sent %i"%os.getpid()) else: conf.netcache.update(nc) for p,t in zip(all_stimuli, sent_times): p.sent_time = t os.waitpid(pid,0) finally: if pid == 0: os._exit(0) remain = list(itertools.chain(*six.itervalues(hsent))) if multi: remain = [p for p in remain if not hasattr(p, '_answered')] if autostop and len(remain) > 0 and len(remain) != len(tobesent): retry = autostop tobesent = remain if len(tobesent) == 0: break retry -= 1 if conf.debug_match: debug.sent=plist.PacketList(remain[:],"Sent") debug.match=plist.SndRcvList(ans[:]) #clean the ans list to delete the field _answered if (multi): for s,r in ans: if hasattr(s, '_answered'): del(s._answered) if verbose: print("\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans)) return plist.SndRcvList(ans),plist.PacketList(remain,"Unanswered")
def 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 from scapy.sendrecv import debug 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 try: try: while True: 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, 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: if WINDOWS: for p, t in zip(all_stimuli, sent_times): p.sent_time = t finally: pass remain = list(itertools.chain(*six.itervalues(hsent))) if multi: remain = [p for p in remain if not hasattr(p, '_answered')] if autostop and len(remain) > 0 and len(remain) != len(tobesent): retry = autostop tobesent = remain if len(tobesent) == 0: break retry -= 1 if conf.debug_match: debug.sent = plist.PacketList(remain[:], "Sent") debug.match = plist.SndRcvList(ans[:]) #clean the ans list to delete the field _answered if (multi): for s, r in ans: if hasattr(s, '_answered'): del (s._answered) if verbose: print "\nReceived %i packets, got %i answers, remaining %i packets" % ( nbrecv + len(ans), len(ans), notans) return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
def 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 afterglow(self, src=None, event=None, dst=None, **kargs): # type: (Optional[Callable], Optional[Callable], Optional[Callable], Any) -> None # noqa: E501 """Experimental clone attempt of http://sourceforge.net/projects/afterglow each datum is reduced as src -> event -> dst and the data are graphed. by default we have IP.src -> IP.dport -> IP.dst""" if src is None: src = lambda x: x['IP'].src if event is None: event = lambda x: x['IP'].dport if dst is None: dst = lambda x: x['IP'].dst sl = {} # type: Dict[IPField, Tuple[int, List[ShortEnumField]]] el = {} # type: Dict[ShortEnumField, Tuple[int, List[IPField]]] dl = {} # type: Dict[IPField, ShortEnumField] for i in self.res: try: s, e, d = src(i), event(i), dst(i) if s in sl: n, lst = sl[s] n += 1 if e not in lst: lst.append(e) sl[s] = (n, lst) else: sl[s] = (1, [e]) if e in el: n, lst = el[e] n += 1 if d not in lst: lst.append(d) el[e] = (n, lst) else: el[e] = (1, [d]) dl[d] = dl.get(d, 0) + 1 except Exception: continue def minmax(x): m, M = reduce(lambda a, b: (min(a[0], b[0]), max(a[1], b[1])), ((a, a) for a in x)) if m == M: m = 0 if M == 0: M = 1 return m, M mins, maxs = minmax(x for x, _ in six.itervalues(sl)) mine, maxe = minmax(x for x, _ in six.itervalues(el)) mind, maxd = minmax(six.itervalues(dl)) gr = 'digraph "afterglow" {\n\tedge [len=2.5];\n' gr += "# src nodes\n" for s in sl: n, _ = sl[s] n = 1 + float(n - mins) / (maxs - mins) gr += '"src.%s" [label = "%s", shape=box, fillcolor="#FF0000", style=filled, fixedsize=1, height=%.2f,width=%.2f];\n' % (repr(s), repr(s), n, n) # noqa: E501 gr += "# event nodes\n" for e in el: n, _ = el[e] n = 1 + float(n - mine) / (maxe - mine) gr += '"evt.%s" [label = "%s", shape=circle, fillcolor="#00FFFF", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (repr(e), repr(e), n, n) # noqa: E501 for d in dl: n = dl[d] n = 1 + float(n - mind) / (maxd - mind) gr += '"dst.%s" [label = "%s", shape=triangle, fillcolor="#0000ff", style=filled, fixedsize=1, height=%.2f, width=%.2f];\n' % (repr(d), repr(d), n, n) # noqa: E501 gr += "###\n" for s in sl: n, lst = sl[s] for e in lst: gr += ' "src.%s" -> "evt.%s";\n' % (repr(s), repr(e)) for e in el: n, lst = el[e] for d in lst: gr += ' "evt.%s" -> "dst.%s";\n' % (repr(e), repr(d)) gr += "}" return do_graph(gr, **kargs)
DNSRR_DISPATCHER = { 33: DNSRRSRV, # RFC 2782 41: DNSRROPT, # RFC 1671 43: DNSRRDS, # RFC 4034 46: DNSRRRSIG, # RFC 4034 47: DNSRRNSEC, # RFC 4034 48: DNSRRDNSKEY, # RFC 4034 50: DNSRRNSEC3, # RFC 5155 51: DNSRRNSEC3PARAM, # RFC 5155 250: DNSRRTSIG, # RFC 2845 32769: DNSRRDLV, # RFC 4431 } DNSSEC_CLASSES = tuple(six.itervalues(DNSRR_DISPATCHER)) def isdnssecRR(obj): return isinstance(obj, DNSSEC_CLASSES) class DNSRR(InheritOriginDNSStrPacket): name = "DNS Resource Record" show_indent=0 fields_desc = [ DNSStrField("rrname",""), ShortEnumField("type", 1, dnstypes), ShortEnumField("rclass", 1, dnsclasses), IntField("ttl", 0), RDLenField("rdlen"), RDataField("rdata", "", length_from=lambda pkt:pkt.rdlen) ]
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(): return 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 __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=cmp_to_key(lambda t1_f1, t2_f2: cmp(t1_f1[0], t2_f2[0]))) # noqa: E501 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=cmp_to_key(lambda c1, c2: cmp(c1.atmt_prio, c2.atmt_prio))) # noqa: E501 for condname, actlst in six.iteritems(cls.actions): actlst.sort(key=cmp_to_key(lambda c1, c2: cmp(c1.atmt_cond[condname], c2.atmt_cond[condname]))) # noqa: E501 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