def to_text(self, origin=None, relativize=True, **kw): """Convert the message to text. The I{origin}, I{relativize}, and any other keyword arguments are passed to the rrset to_wire() method. @rtype: string """ s = cStringIO.StringIO() print >> s, 'id %d' % self.id print >> s, 'opcode %s' % \ opcode.to_text(opcode.from_flags(self.flags)) rc = rcode.from_flags(self.flags, self.ednsflags) print >> s, 'rcode %s' % rcode.to_text(rc) print >> s, 'flags %s' % flags.to_text(self.flags) if self.edns >= 0: print >> s, 'edns %s' % self.edns if self.ednsflags != 0: print >> s, 'eflags %s' % \ flags.edns_to_text(self.ednsflags) print >> s, 'payload', self.payload is_update = opcode.is_update(self.flags) if is_update: print >> s, ';ZONE' else: print >> s, ';QUESTION' for rrset in self.question: print >> s, rrset.to_text(origin, relativize, **kw) if is_update: print >> s, ';PREREQ' else: print >> s, ';ANSWER' for rrset in self.answer: print >> s, rrset.to_text(origin, relativize, **kw) if is_update: print >> s, ';UPDATE' else: print >> s, ';AUTHORITY' for rrset in self.authority: print >> s, rrset.to_text(origin, relativize, **kw) print >> s, ';ADDITIONAL' for rrset in self.additional: print >> s, rrset.to_text(origin, relativize, **kw) # # We strip off the final \n so the caller can print the result without # doing weird things to get around eccentricities in Python print # formatting # return s.getvalue()[:-1]
def _header_line(self, section): """Process one line from the text format header section.""" token = self.tok.get() what = token.value if what == 'id': self.message.id = self.tok.get_int() elif what == 'flags': while True: token = self.tok.get() if not token.is_identifier(): self.tok.unget(token) break self.message.flags = self.message.flags | \ flags.from_text(token.value) if opcode.is_update(self.message.flags): self.updating = True elif what == 'edns': self.message.edns = self.tok.get_int() self.message.ednsflags = self.message.ednsflags | \ (self.message.edns << 16) elif what == 'eflags': if self.message.edns < 0: self.message.edns = 0 while True: token = self.tok.get() if not token.is_identifier(): self.tok.unget(token) break self.message.ednsflags = self.message.ednsflags | \ flags.edns_from_text(token.value) elif what == 'payload': self.message.payload = self.tok.get_int() if self.message.edns < 0: self.message.edns = 0 elif what == 'opcode': text = self.tok.get_string() self.message.flags = self.message.flags | \ opcode.to_flags(opcode.from_text(text)) elif what == 'rcode': text = self.tok.get_string() self.message.set_rcode(rcode.from_text(text)) else: raise UnknownHeaderField self.tok.get_eol()
def is_response(self, other): """Is other a response to self? @rtype: bool""" if other.flags & flags.QR == 0 or \ self.id != other.id or \ opcode.from_flags(self.flags) != \ opcode.from_flags(other.flags): return False if rcode.from_flags(other.flags, other.ednsflags) != \ rcode.NOERROR: return True if opcode.is_update(self.flags): return True for n in self.question: if n not in other.question: return False for n in other.question: if n not in self.question: return False return True
def read(self): """Read a wire format DNS message and build a message.Message object.""" l = len(self.wire) if l < 12: raise ShortHeader (self.message.id, self.message.flags, qcount, ancount, aucount, adcount) = struct.unpack('!HHHHHH', self.wire[:12]) self.current = 12 if opcode.is_update(self.message.flags): self.updating = True self._get_question(qcount) if self.question_only: return self._get_section(self.message.answer, ancount) self._get_section(self.message.authority, aucount) self._get_section(self.message.additional, adcount) if not self.ignore_trailing and self.current != l: raise TrailingJunk if self.message.multi and self.message.tsig_ctx and \ not self.message.had_tsig: self.message.tsig_ctx.update(self.wire)