def pack_hdr(self): """Return packed header string.""" try: return _st_pack(self.__hdr_fmt__, *[ getattr(self, k) for k in self.__hdr_fields__ ]) except _st_error: vals = [] for k in self.__hdr_fields__: v = getattr(self, k) if isinstance(v, tuple): vals.extend(v) else: vals.append(v) return _st_pack(self.__hdr_fmt__, *vals)
def pack_hdr(self): """Return packed header string.""" try: return _st_pack(self.__hdr_fmt__, *[getattr(self, k) for k in self.__hdr_fields__]) except _st_error: vals = [] for k in self.__hdr_fields__: v = getattr(self, k) if isinstance(v, tuple): vals.extend(v) else: vals.append(v) return _st_pack(self.__hdr_fmt__, *vals)
def encode_name(name): """Return the NetBIOS first-level encoded name.""" l = [] for c in _st_pack('16s', name): c = ord(c) l.append(chr((c >> 4) + 0x41)) l.append(chr((c & 0xf) + 0x41)) return ''.join(l)
def __str__(self): # XXX - compress names on the fly self.index = {} buf = _st_pack(self.__hdr_fmt__, self.id, self.op, len(self.qd), len(self.an), len(self.ns), len(self.ar)) for q in self.qd: buf = self.pack_q(buf, q) for x in ('an', 'ns', 'ar'): for rr in getattr(self, x): buf = self.pack_rr(buf, rr) del self.index return buf
def pack_name(self, buf, name): """Append compressed DNS name and return buf.""" labels = name.split('.') labels.append('') for i, label in enumerate(labels): key = '.'.join(labels[i:]).upper() ptr = self.index.get(key, None) if not ptr: if len(key) > 1: ptr = len(buf) if ptr < 0xc000: self.index[key] = ptr i = len(label) buf += chr(i) + label else: buf += _st_pack('>H', (0xc000 | ptr)) break return buf
def pack_rr(self, buf, rr): """Append packed DNS RR and return buf.""" buf = self.pack_name(buf, rr.name) buf += _st_pack('>HHIH', rr.type, rr.cls, rr.ttl, len(rr.rdata)) buf += rr.rdata return buf
def pack_q(self, buf, q): """Append packed DNS question and return buf.""" buf = self.pack_name(buf, q.name) buf += _st_pack('>HH', q.type, q.cls) return buf