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, 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 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