Beispiel #1
0
def __gen_send(s,
               x,
               inter=0,
               loop=0,
               count=None,
               verbose=None,
               realtime=None,
               return_packets=False,
               *args,
               **kargs):  # noqa: E501
    if isinstance(x, str):
        x = conf.raw_layer(load=x)
    if not isinstance(x, Gen):
        x = SetGen(x)
    if verbose is None:
        verbose = conf.verb
    n = 0
    if count is not None:
        loop = -count
    elif not loop:
        loop = -1
    if return_packets:
        sent_packets = plist.PacketList()
    try:
        while loop:
            dt0 = None
            for p in x:
                if realtime:
                    ct = time.time()
                    if dt0:
                        st = dt0 + p.time - ct
                        if st > 0:
                            time.sleep(st)
                    else:
                        dt0 = ct - p.time
                s.send(p)
                if return_packets:
                    sent_packets.append(p)
                n += 1
                if verbose:
                    os.write(1, b".")
                time.sleep(inter)
            if loop < 0:
                loop += 1
    except KeyboardInterrupt:
        pass
    s.close()
    if verbose:
        print("\nSent %i packets." % n)
    if return_packets:
        return sent_packets
Beispiel #2
0
    def _show_or_dump(self, dump=False, indent=3, lvl="", label_lvl="", first_call=True):
        """
        Internal method that shows or dumps a hierachical view of a packet.
        Called by show.
        """

        if dump:
            from scapy.themes import AnsiColorTheme
            ct = AnsiColorTheme()  # No color for dump output
        else:
            ct = conf.color_theme
        s = "%s%s %s %s \n" % (label_lvl,
                               ct.punct("###["),
                               ct.layer_name(self.name),
                               ct.punct("]###"))
        for f in self.fields_desc:
            if isinstance(f, ConditionalField) and not f._evalcond(self):
                continue
            if isinstance(f, Emph) or f in conf.emph:
                ncol = ct.emph_field_name
                vcol = ct.emph_field_value
            else:
                ncol = ct.field_name
                vcol = ct.field_value
            fvalue = self.getfieldval(f.name)
            if isinstance(fvalue, Packet) or (f.islist and f.holds_packets and type(fvalue) is list):
                s += "%s  \\%-10s\\\n" % (label_lvl + lvl, ncol(f.name))
                fvalue_gen = SetGen(fvalue, _iterpacket=0)
                for fvalue in fvalue_gen:
                    s += fvalue._show_or_dump(dump=dump, indent=indent,
                                              label_lvl=label_lvl + lvl + "   |", first_call=False)
            else:
                begn = "%s  %-10s%s " % (label_lvl + lvl,
                                         ncol(f.name),
                                         ct.punct("="),)
                reprval = f.i2repr(self, fvalue)
                if type(reprval) is str:
                    reprval = reprval.replace("\n", "\n" + " " * (len(label_lvl)
                                                                  + len(lvl)
                                                                  + len(f.name)
                                                                  + 4))
                s += "%s%s\n" % (begn, vcol(reprval))
        if self.payload:
            s += self.payload._show_or_dump(dump=dump, indent=indent, lvl=lvl + (
                " " * indent * self.show_indent), label_lvl=label_lvl, first_call=False)

        if first_call and not dump:
            print s
        else:
            return s
Beispiel #3
0
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]

    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")
Beispiel #4
0
def __kb_send(kb,
              x,
              channel=None,
              inter=0,
              loop=0,
              count=None,
              verbose=None,
              realtime=None,
              *args,
              **kargs):
    if type(x) is str:
        x = Raw(load=x)
    if not isinstance(x, Gen):
        x = SetGen(x)
    if verbose is None:
        verbose = conf.verb

    n = 0
    if count is not None:
        loop = -count
    elif not loop:
        loop = -1
    dt0 = None
    try:
        while loop:
            for p in x:
                if realtime:
                    ct = time.time()
                    if dt0:
                        st = dt0 + p.time - ct
                        if st > 0:
                            time.sleep(st)
                    else:
                        dt0 = ct - p.time
                # Make sure the packet has 2 bytes for FCS before TX
                if not p.haslayer(Dot15d4FCS):
                    p /= Raw("\x00\x00")
                kb.inject(p.do_build()[:-2], channel=None, count=1,
                          delay=0)  # [:-2] because the firmware adds the FCS
                n += 1
                if verbose:
                    os.write(1, ".")
                time.sleep(inter)
            if loop < 0:
                loop += 1
    except KeyboardInterrupt:
        pass
    return n
Beispiel #5
0
 def haslayer(self, cls):
     """true if self has a layer that is an instance of cls. Superseded by "cls in self" syntax."""
     if self.__class__ == cls or self.__class__.__name__ == cls:
         return 1
     for f in self.packetfields:
         fvalue_gen = self.getfieldval(f.name)
         if fvalue_gen is None:
             continue
         if not f.islist:
             fvalue_gen = SetGen(fvalue_gen,_iterpacket=0)
         for fvalue in fvalue_gen:
             if isinstance(fvalue, Packet):
                 ret = fvalue.haslayer(cls)
                 if ret:
                     return ret
     return self.payload.haslayer(cls)
Beispiel #6
0
def __kb_send(kb,
              x,
              channel=None,
              inter=0,
              loop=0,
              count=None,
              verbose=None,
              realtime=None,
              *args,
              **kargs):
    if type(x) is str:
        x = Raw(load=x)
    if not isinstance(x, Gen):
        x = SetGen(x)
    if verbose is None:
        verbose = conf.verb

    n = 0
    if count is not None:
        loop = -count
    elif not loop:
        loop = -1
    dt0 = None
    try:
        while loop:
            for p in x:
                if realtime:
                    ct = time.time()
                    if dt0:
                        st = dt0 + p.time - ct
                        if st > 0:
                            time.sleep(st)
                    else:
                        dt0 = ct - p.time
                # Soteria: changed setting the channel to None to the input channel
                # kb.inject(p.do_build()[:-2], channel = None, count = 1, delay = 0)  # [:-2] because the firmware adds the FCS
                kb.inject(p.do_build()[:-2], channel, count=1,
                          delay=0)  # [:-2] because the firmware adds the FCS
                n += 1
                if verbose:
                    os.write(1, ".")
                time.sleep(inter)
            if loop < 0:
                loop += 1
    except KeyboardInterrupt:
        pass
    return n
def pkt_as_dict(pkt, indent=3, lvl="", label_lvl="", first_call=True):
    # based on scapy show() method
    # returns: dict of pkt attributes normally printed by show() plus time
    if first_call is True:
        ret = {}
    else:
        ret = first_call

    for f in pkt.fields_desc:
        if isinstance(f, ConditionalField) and not f._evalcond(pkt):
            continue

        fvalue = pkt.getfieldval(f.name)
        if isinstance(fvalue,
                      Packet) or (f.islist and f.holds_packets
                                  and isinstance(fvalue, list)):  # noqa: E501
            key = "{}_{}".format(label_lvl + lvl, f.name)
            fvalue_gen = SetGen(fvalue, _iterpacket=0)  # type: SetGen[Packet]
            for fvalue in fvalue_gen:
                if key in keep_features:
                    ret[key] = pkt_as_dict(fvalue,
                                           indent=indent,
                                           label_lvl=label_lvl + lvl + "   |",
                                           first_call=ret)  # noqa: E501
        else:
            key = "{}_{}_{}".format(pkt.name, label_lvl + lvl, f.name)
            if isinstance(fvalue, str):
                fvalue = fvalue.replace(
                    "\n",
                    "\n" + " " * (
                        len(label_lvl) +  # noqa: E501
                        len(lvl) + len(f.name) + 4))

            if key in keep_features:
                ret[key] = fvalue
    if pkt.payload:
        pkt_as_dict(
            pkt.payload,
            indent=indent,
            lvl=lvl,  # + (" " * indent * pkt.show_indent),
            label_lvl=label_lvl,
            first_call=ret)

    ret["time"] = float(pkt.time)
    return ret
Beispiel #8
0
    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.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()
            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")
Beispiel #9
0
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")
Beispiel #10
0
def sndrcvflood(pks,
                pkt,
                prn=lambda s_r: s_r[1].summary(),
                chainCC=0,
                store=1,
                unique=0):
    if not isinstance(pkt, Gen):
        pkt = SetGen(pkt)
    tobesent = [p for p in pkt]
    received = plist.SndRcvList()
    seen = {}

    hsent = {}
    for i in tobesent:
        h = i.hashret()
        if h in hsent:
            hsent[h].append(i)
        else:
            hsent[h] = [i]

    def send_in_loop(tobesent):
        while True:
            for p in tobesent:
                yield p

    packets_to_send = send_in_loop(tobesent)

    ssock = rsock = pks.fileno()

    try:
        while True:
            if conf.use_bpf:
                from scapy.arch.bpf.supersocket import bpf_select
                readyr = bpf_select([rsock])
                _, readys, _ = select([], [ssock], [])
            else:
                readyr, readys, _ = select([rsock], [ssock], [])

            if ssock in readys:
                pks.send(packets_to_send.next())

            if rsock in readyr:
                p = pks.recv(MTU)
                if p is None:
                    continue
                h = p.hashret()
                if h in hsent:
                    hlst = hsent[h]
                    for i in hlst:
                        if p.answers(i):
                            res = prn((i, p))
                            if unique:
                                if res in seen:
                                    continue
                                seen[res] = None
                            if res is not None:
                                print(res)
                            if store:
                                received.append((i, p))
    except KeyboardInterrupt:
        if chainCC:
            raise
    return received
Beispiel #11
0
def sndrcv(pks, pkt, timeout = 2, inter = 0, verbose=None, chainCC=0, retry=0, multi=0):
    if not isinstance(pkt, Gen):
        pkt = SetGen(pkt)
        
    if verbose is None:
        verbose = conf.verb
    debug.recv = plist.PacketList([],"Unanswered")
    debug.sent = plist.PacketList([],"Sent")
    debug.match = plist.SndRcvList([])
    nbrecv=0
    ans = []
    # do it here to fix random fields, so that parent and child have the same
    all_stimuli = tobesent = [p for p in pkt]
    notans = len(tobesent)

    hsent={}
    for i in tobesent:
        h = i.hashret()
        if h in hsent:
            hsent[h].append(i)
        else:
            hsent[h] = [i]
    if retry < 0:
        retry = -retry
        autostop=retry
    else:
        autostop=0


    while retry >= 0:
        found=0
    
        if timeout < 0:
            timeout = None

        pid=1
        try:
            if WINDOWS or pid == 0:
                try:
                    try:
                        i = 0
                        if verbose:
                            print("Begin emission:")
                        for p in tobesent:
                            pks.send(p)
                            i += 1
                            time.sleep(inter)
                        if verbose:
                            print("Finished to send %i packets." % i)
                    except SystemExit:
                        pass
                    except KeyboardInterrupt:
                        pass
                    except:
                        log_runtime.exception("--- Error sending packets")
                        log_runtime.info("--- Error sending packets")
                finally:
                    try:
                        sent_times = [p.sent_time for p in all_stimuli if p.sent_time]
                    except:
                        pass
            if WINDOWS or pid > 0:
                # Timeout starts after last packet is sent (as in Unix version) 
                if timeout:
                    stoptime = time.time()+timeout
                else:
                    stoptime = 0
                remaintime = None
                # inmask = [pks.ins.fd]
                try:
                    try:
                        while 1:
                            if stoptime:
                                remaintime = stoptime-time.time()
                                if remaintime <= 0:
                                    break
                            r = pks.recv(MTU)
                            if r is None:
                                continue
                            ok = 0
                            h = r.hashret()
                            if h in hsent:
                                hlst = hsent[h]
                                for i in range(len(hlst)):
                                    if r.answers(hlst[i]):
                                        ans.append((hlst[i],r))
                                        if verbose > 1:
                                            os.write(1, b"*")
                                        ok = 1                                
                                        if not multi:
                                            del(hlst[i])
                                            notans -= 1;
                                        else:
                                            if not hasattr(hlst[i], '_answered'):
                                                notans -= 1;
                                            hlst[i]._answered = 1;
                                        break
                            if notans == 0 and not multi:
                                break
                            if not ok:
                                if verbose > 1:
                                    os.write(1, b".")
                                nbrecv += 1
                                if conf.debug_match:
                                    debug.recv.append(r)
                    except KeyboardInterrupt:
                        if chainCC:
                            raise
                finally:
                    if WINDOWS:
                        for p,t in zip(all_stimuli, sent_times):
                            p.sent_time = t
        finally:
            pass

        # remain = reduce(list.__add__, hsent.values(), [])
        remain = list(itertools.chain(*[ i for i in hsent.values() ]))

        if multi:
            #remain = filter(lambda p: not hasattr(p, '_answered'), remain);
            remain = [ p for p in remain if not hasattr(p, '_answered')]
            
        if autostop and len(remain) > 0 and len(remain) != len(tobesent):
            retry = autostop
            
        tobesent = remain
        if len(tobesent) == 0:
            break
        retry -= 1
        
    if conf.debug_match:
        debug.sent=plist.PacketList(remain[:],"Sent")
        debug.match=plist.SndRcvList(ans[:])

    #clean the ans list to delete the field _answered
    if (multi):
        for s,r in ans:
            if hasattr(s, '_answered'):
                del(s._answered)
    
    if verbose:
        print("\nReceived %i packets, got %i answers, remaining %i packets" % (nbrecv+len(ans), len(ans), notans))
    return plist.SndRcvList(ans),plist.PacketList(remain,"Unanswered")
Beispiel #12
0
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
Beispiel #13
0
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")
Beispiel #14
0
    def __init__(self,
                 pks,
                 pkt,
                 timeout=None,
                 inter=0,
                 verbose=None,
                 chainCC=False,
                 retry=0,
                 multi=False,
                 rcv_pks=None,
                 prebuild=False,
                 _flood=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
        # 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")
Beispiel #15
0
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
Beispiel #16
0
def sndrcv(pks,
           pkt,
           timeout=None,
           inter=0,
           verbose=None,
           chainCC=0,
           retry=0,
           multi=0):
    if not isinstance(pkt, Gen):
        pkt = SetGen(pkt)

    if verbose is None:
        verbose = conf.verb
    debug.recv = plist.PacketList([], "Unanswered")
    debug.sent = plist.PacketList([], "Sent")
    debug.match = plist.SndRcvList([])
    nbrecv = 0
    ans = []
    # do it here to fix random fields, so that parent and child have the same
    all_stimuli = tobesent = [p for p in pkt]
    notans = len(tobesent)

    hsent = {}
    for i in tobesent:
        h = i.hashret()
        if h in hsent:
            hsent[h].append(i)
        else:
            hsent[h] = [i]
    if retry < 0:
        retry = -retry
        autostop = retry
    else:
        autostop = 0

    while retry >= 0:
        found = 0

        if timeout < 0:
            timeout = None

        rdpipe, wrpipe = os.pipe()
        rdpipe = os.fdopen(rdpipe)
        wrpipe = os.fdopen(wrpipe, "w")

        pid = 1
        try:
            pid = os.fork()
            if pid == 0:
                try:
                    sys.stdin.close()
                    rdpipe.close()
                    try:
                        i = 0
                        if verbose:
                            print "Begin emission:"
                        for p in tobesent:
                            pks.send(p)
                            i += 1
                            time.sleep(inter)
                        if verbose:
                            print "Finished to send %i packets." % i
                    except SystemExit:
                        pass
                    except KeyboardInterrupt:
                        pass
                    except:
                        log_runtime.exception("--- Error in child %i" %
                                              os.getpid())
                        log_runtime.info("--- Error in child %i" % os.getpid())
                finally:
                    try:
                        os.setpgrp()  # Chance process group to avoid ctrl-C
                        sent_times = [
                            p.sent_time for p in all_stimuli if p.sent_time
                        ]
                        cPickle.dump((conf.netcache, sent_times), wrpipe)
                        wrpipe.close()
                    except:
                        pass
            elif pid < 0:
                log_runtime.error("fork error")
            else:
                wrpipe.close()
                stoptime = 0
                remaintime = None
                inmask = [rdpipe, pks]
                try:
                    try:
                        while 1:
                            if stoptime:
                                remaintime = stoptime - time.time()
                                if remaintime <= 0:
                                    break
                            r = None
                            if not isinstance(
                                    pks, StreamSocket) and (FREEBSD or DARWIN):
                                inp, out, err = select(inmask, [], [], 0.05)
                                if len(inp) == 0 or pks in inp:
                                    r = pks.nonblock_recv()
                            else:
                                inp = []
                                try:
                                    inp, out, err = select(
                                        inmask, [], [], remaintime)
                                except IOError, exc:
                                    if exc.errno != errno.EINTR:
                                        raise
                                if len(inp) == 0:
                                    break
                                if pks in inp:
                                    r = pks.recv(MTU)
                            if rdpipe in inp:
                                if timeout:
                                    stoptime = time.time() + timeout
                                del (inmask[inmask.index(rdpipe)])
                            if r is None:
                                continue
                            ok = 0
                            h = r.hashret()
                            if h in hsent:
                                hlst = hsent[h]
                                for i, sentpkt in enumerate(hlst):
                                    if r.answers(sentpkt):
                                        ans.append((sentpkt, r))
                                        if verbose > 1:
                                            os.write(1, "*")
                                        ok = 1
                                        if not multi:
                                            del hlst[i]
                                            notans -= 1
                                        else:
                                            if not hasattr(
                                                    sentpkt, '_answered'):
                                                notans -= 1
                                            sentpkt._answered = 1
                                        break
                            if notans == 0 and not multi:
                                break
                            if not ok:
                                if verbose > 1:
                                    os.write(1, ".")
                                nbrecv += 1
                                if conf.debug_match:
                                    debug.recv.append(r)
                    except KeyboardInterrupt:
                        if chainCC:
                            raise
                finally:
                    try:
                        nc, sent_times = cPickle.load(rdpipe)
                    except EOFError:
                        warning(
                            "Child died unexpectedly. Packets may have not been sent %i"
                            % os.getpid())
                    else:
                        conf.netcache.update(nc)
                        for p, t in zip(all_stimuli, sent_times):
                            p.sent_time = t
                    os.waitpid(pid, 0)
        finally:
            if pid == 0:
                os._exit(0)

        remain = list(itertools.chain(*hsent.itervalues()))
        if multi:
            remain = [p for p in remain if not hasattr(p, '_answered')]

        if autostop and len(remain) > 0 and len(remain) != len(tobesent):
            retry = autostop

        tobesent = remain
        if len(tobesent) == 0:
            break
        retry -= 1

    if conf.debug_match:
        debug.sent = plist.PacketList(remain[:], "Sent")
        debug.match = plist.SndRcvList(ans[:])

    #clean the ans list to delete the field _answered
    if (multi):
        for s, r in ans:
            if hasattr(s, '_answered'):
                del (s._answered)

    if verbose:
        print "\nReceived %i packets, got %i answers, remaining %i packets" % (
            nbrecv + len(ans), len(ans), notans)
    return plist.SndRcvList(ans), plist.PacketList(remain, "Unanswered")
Beispiel #17
0
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
Beispiel #18
0
def __gen_send_mod(s,
                   x,
                   inter=0,
                   loop=0,
                   count=None,
                   verbose=None,
                   realtime=None,
                   return_packets=False,
                   port_random_flag=False,
                   size_random_flag=False,
                   src_random_flag=False,
                   specific_subnet_random=False,
                   source_addr='Default',
                   pcktcount=None,
                   log=None,
                   *args,
                   **kargs):  # noqa: E501
    totaltimeelapsedns = 0.0
    totaltimeelapseds = 0.0
    if isinstance(x, str):
        x = conf.raw_layer(load=x)
    if not isinstance(x, Gen):
        x = SetGen(x)
    if verbose is None:
        verbose = conf.verb
    n = 0
    if count is not None:
        loop = -count
    elif not loop:
        loop = -1
    if return_packets:
        sent_packets = PacketList()
    try:
        startVelkoSec = time.time()
        while loop:
            dt0 = None
            for p in x:
                if realtime:
                    ct = time.time()
                    if dt0:
                        st = dt0 + p.time - ct
                        if st > 0:
                            time.sleep(st)
                    else:
                        dt0 = ct - p.time

                if (p.proto == 1):
                    p.type = int(random.randrange(0, 255))
                    p.code = int(random.randrange(0, 255))
                if (port_random_flag):
                    targ_port = int(random.randrange(0, 65535))
                    p.dport = targ_port
                if (size_random_flag):
                    packet_size = int(
                        random.randrange(0, 6550)
                    )  # 7 I removed 7 because there seems to be some boundary crossing(bleeding)
                    p.add_payload((str(_generatePacket(packet_size))).encode())
                if (src_random_flag):
                    p.src = socket.inet_ntoa(
                        struct.pack('>I', random.randint(1, 0xffffffff)))
                elif (specific_subnet_random):
                    try:
                        subnet = IPv4Network(source_addr)
                        bits = random.getrandbits(subnet.max_prefixlen -
                                                  subnet.prefixlen)
                        p.src = str(IPv4Address(subnet.network_address + bits))

                    except ValueError:
                        print("Something is wrong!sendrcv ")

                if ((n % int(pcktcount)) == 0):

                    endVelkoSec = time.time()
                    totaltimeelapseds += (endVelkoSec - startVelkoSec)

                    print("\n+++TIMESTAMP+++\nTimestamp taken after:", n,
                          "packets")

                    #print('{:%Y-%m-%d_%H:%M:%S}'.format(datetime.datetime.now())+"\n")
                    print((datetime.datetime.now()
                           ).strftime('%Y-%m-%d %H:%M:%S.%f')[:-2] +
                          " (UTC)\n")
                    print("TIME(s): ", (endVelkoSec - startVelkoSec))
                    print("TIME(ns): ",
                          (endVelkoSec - startVelkoSec) * 1000000000)
                    print("TOTAL TIME(s): ", totaltimeelapseds)
                    print(
                        "+++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
                    )


#LOG SECTION
# file_name=log
# f = open(file_name, 'a+')
# f.write("\n+++TIMESTAMP+++\nTimestamp taken after: "+str(n)+"\n")
# f.write(datetime.datetime.utcnow().strftime('%Y-%m-%d %H-%M-%S_%f')[:-2]+" (UTC)\n")
# f.write("TIME(ns): "+str((endVelkoSec - startVelkoSec)*1000000000)+"\n")
# f.write("TIME(s): "+ str(endVelkoSec-startVelkoSec)+"\n")
# f.write("TOTAL TIME ELAPSED(s): "+str(totaltimeelapseds)+"\n")
# f.write("\n===WholePacket===\n")
# tmp=p.show(dump=True)
# f.write(str(tmp))
# f.close()
# TODO: Should log only if log is activated

#log_packet(p,log)
#END LOG SECTION
                s.send(p)
                if (p.proto == 1):
                    print(
                        datetime.datetime.utcnow().strftime(
                            '%Y-%m-%d_%H-%M-%S_%f')[:-2] + "(UTC)\t", "proto",
                        p.proto, "\tsrc", p.src, "\tdst", p.dst, "\tcode",
                        p.code, "\ttype", p.type, "\tLength(b)", len(p))
                else:
                    print(
                        datetime.datetime.utcnow().strftime(
                            '%Y-%m-%d_%H-%M-%S_%f')[:-2] + "(UTC)\t", "proto",
                        p.proto, "\tsrc", p.src, "\tsport", p.sport, "\tdst",
                        p.dst, "\tdport", p.dport, "\tLength(b)", len(p))
                # time.sleep(5)
                if return_packets:
                    sent_packets.append(p)
                n += 1
                if verbose:
                    os.write(1, b".")
                time.sleep(inter)
            if loop < 0:
                loop += 1
    except KeyboardInterrupt:
        pass
    if verbose:
        print("\nSent %i packets." % n)
    if return_packets:
        return sent_packets
Beispiel #19
0
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")
Beispiel #20
0
def kbgetnetworkkey(pkts):
    """
    Search packets for a plaintext key exchange returns the first one found.
    """
    if not isinstance(pkts, Gen):
        pkts = SetGen(pkts)
    for packet in pkts:
        packet = str(packet)
        zmac = Dot154PacketParser()
        znwk = ZigBeeNWKPacketParser()
        zaps = ZigBeeAPSPacketParser()
        try:
            # Process MAC layer details
            zmacpayload = zmac.pktchop(packet)[-1]
            if zmacpayload == None:
                continue

            # Process NWK layer details
            znwkpayload = znwk.pktchop(zmacpayload)[-1]
            if znwkpayload == None:
                continue

            # Process the APS layer details
            zapschop = zaps.pktchop(znwkpayload)
            if zapschop == None:
                continue

            # See if this is an APS Command frame
            apsfc = ord(zapschop[0])
            if (apsfc & ZBEE_APS_FCF_FRAME_TYPE) != ZBEE_APS_FCF_CMD:
                continue

            # Delivery mode is Normal Delivery (0)
            apsdeliverymode = (apsfc & ZBEE_APS_FCF_DELIVERY_MODE) >> 2
            if apsdeliverymode != 0:
                continue

            # Ensure Security is Disabled
            if (apsfc & ZBEE_APS_FCF_SECURITY) == 1:
                continue

            zapspayload = zapschop[-1]

            # Check payload length, must be at least 35 bytes
            # APS cmd | key type | key | sequence number | dest addr | src addr
            if len(zapspayload) < 35:
                continue

            # Check for APS command identifier Transport Key (0x05)
            if ord(zapspayload[0]) != 5:
                continue

            # Transport Key Frame, get the key type.  Network Key is 0x01, no
            # other keys should be sent in plaintext
            if ord(zapspayload[1]) != 1:
                continue

            # Reverse these fields
            networkkey = zapspayload[2:18][::-1]
            destaddr = zapspayload[19:27][::-1]
            srcaddr = zapspayload[27:35][::-1]

            key_bytes = []
            dst_mac_bytes = []
            src_mac_bytes = []
            key = {}
            key['key'] = ':'.join("%02x" % ord(networkkey[x])
                                  for x in xrange(16))
            key['dst'] = ':'.join("%02x" % ord(destaddr[x]) for x in xrange(8))
            key['src'] = ':'.join("%02x" % ord(srcaddr[x]) for x in xrange(8))
            return key
        except:
            continue
    return {}
Beispiel #21
0
def __gen_send(s,  # type: SuperSocket
               x,  # type: _PacketIterable
               inter=0,  # type: int
               loop=0,  # type: int
               count=None,  # type: Optional[int]
               verbose=None,  # type: Optional[int]
               realtime=False,  # type: bool
               return_packets=False,  # type: bool
               *args,  # type: Any
               **kargs  # type: Any
               ):
    # type: (...) -> Optional[PacketList]
    """
    An internal function used by send/sendp to actually send the packets,
    implement the send logic...

    It will take care of iterating through the different packets
    """
    if isinstance(x, str):
        x = conf.raw_layer(load=x)
    if not isinstance(x, Gen):
        x = SetGen(x)
    if verbose is None:
        verbose = conf.verb
    n = 0
    if count is not None:
        loop = -count
    elif not loop:
        loop = -1
    sent_packets = PacketList() if return_packets else None
    p = None
    try:
        while loop:
            dt0 = None
            for p in x:
                if realtime:
                    ct = time.time()
                    if dt0:
                        st = dt0 + float(p.time) - ct
                        if st > 0:
                            time.sleep(st)
                    else:
                        dt0 = ct - float(p.time)
                s.send(p)
                if sent_packets is not None:
                    sent_packets.append(p)
                n += 1
                if verbose:
                    os.write(1, b".")
                time.sleep(inter)
            if loop < 0:
                loop += 1
    except KeyboardInterrupt:
        pass
    finally:
        try:
            cast(Packet, x).sent_time = cast(Packet, p).sent_time
        except AttributeError:
            pass
    if verbose:
        print("\nSent %i packets." % n)
    return sent_packets