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
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)
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)
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)
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
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
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)
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
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")