Пример #1
0
 def loop(todo, done, self=self):
     if todo:
         eltname = todo.pop()
         elt = self.getfieldval(eltname)
         if not isinstance(elt, Gen):
             if self.get_field(eltname).islist:
                 elt = SetGen([elt])
             else:
                 elt = SetGen(elt)
         for e in elt:
             done[eltname] = e
             for x in loop(todo[:], done):
                 yield x
     else:
         if isinstance(self.payload, NoPayload):
             payloads = [None]
         else:
             payloads = self.payload
         for payl in payloads:
             done2 = done.copy()
             for k in done2:
                 if isinstance(done2[k], VolatileValue):
                     done2[k] = done2[k]._fix()
             pkt = self.clone_with(payload=payl, **done2)
             yield pkt
Пример #2
0
 def getlayer(self, cls, nb=1, _track=None):
     """Return the nb^th layer that is an instance of cls."""
     if type(cls) is int:
         nb = cls + 1
         cls = None
     if type(cls) is str and "." in cls:
         ccls, fld = cls.split(".", 1)
     else:
         ccls, fld = cls, None
     if cls is None or self.__class__ == cls or self.__class__.name == ccls:
         if nb == 1:
             if fld is None:
                 return self
             else:
                 return self.getfieldval(fld)
         else:
             nb -= 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):
                 track = []
                 ret = fvalue.getlayer(cls, nb, _track=track)
                 if ret is not None:
                     return ret
                 nb = track[0]
     return self.payload.getlayer(cls, nb, _track=_track)
Пример #3
0
 def show(self, indent=3, lvl="", label_lvl=""):
     """Prints a hierarchical view of the packet. "indent" gives the size of indentation for each layer."""
     ct = conf.color_theme
     print "%s%s %s %s" % (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):
             print "%s  \\%-10s\\" % (label_lvl+lvl, ncol(f.name))
             fvalue_gen = SetGen(fvalue,_iterpacket=0)
             for fvalue in fvalue_gen:
                 fvalue.show(indent=indent, label_lvl=label_lvl+lvl+"   |")
         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))
             print "%s%s" % (begn,vcol(reprval))
     self.payload.show(indent=indent, lvl=lvl+(" "*indent*self.show_indent), label_lvl=label_lvl)
Пример #4
0
 def dump_offsets_tree(self, indent='', base_offset=0):
     ct = conf.color_theme
     print("%s%s %s %s" % (indent, 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
         fvalue = self.getfieldval(f.name)
         if isinstance(fvalue, Packet) or (f.islist and f.holds_packets
                                           and type(fvalue) is list):
             print('\n%s  %s: %s' %
                   (indent, f.name, base_offset + f._offset))
             fvalue_gen = SetGen(fvalue, _iterpacket=0)
             fvalue_bu = None
             for fvalue in fvalue_gen:
                 if fvalue_bu:
                     fvalue._offset = fvalue_bu._offset + len(fvalue_bu)
                     print('%s  %s: %s' %
                           (indent, fvalue.name,
                            base_offset + f._offset + fvalue._offset))
                 fvalue.dump_offsets_tree(
                     '    ' + indent,
                     base_offset + f._offset + fvalue._offset)
                 fvalue_bu = fvalue
         else:
             print('%s    %s: %s' %
                   (indent, f.name, base_offset + f._offset))
     if self.payload:
         print('---- payload ----')
         self.payload.dump_offsets_tree(indent, base_offset + self._length)
Пример #5
0
def sndrcvflood(pks,
                pkt,
                prn=lambda (s, r): r.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 1:
            for p in tobesent:
                yield p

    packets_to_send = send_in_loop(tobesent)

    ssock = rsock = pks.fileno()

    try:
        while 1:
            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
Пример #6
0
def __gen_send(s,
               x,
               inter=0,
               loop=0,
               count=None,
               verbose=None,
               realtime=None,
               return_packets=False,
               *args,
               **kargs):
    if type(x) is 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, ".")
                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
Пример #7
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)
Пример #8
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:
            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
Пример #9
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 arch.FREEBSD or arch.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 Exception,e:
                                    if e[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 in range(len(hlst)):
                                    if r.answers(hlst[i]):
                                        ans.append((hlst[i],r))
                                        if verbose > 1:
                                            os.write(1, "*")
                                        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, ".")
                                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 = reduce(list.__add__, hsent.values(), [])
        if multi:
            remain = filter(lambda p: not hasattr(p, '_answered'), remain);
            
        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")