def get_rddata(self, l, type, dlen, beg_index): if beg_index + dlen > len(l): raise Trunc('(dns) truncated rdata') # A if type == 1: if dlen != 4: raise Exception('(dns) invalid a data size', system='packet') return IPAddr(l[beg_index:beg_index + 4]) # AAAA elif type == 28: if dlen != 16: raise Exception('(dns) invalid a data size', system='packet') return IPAddr6(l[beg_index:beg_index + dlen]) # NS elif type == 2: return self.read_dns_name_from_index(l, beg_index)[1] # PTR elif type == 12: return self.read_dns_name_from_index(l, beg_index)[1] # CNAME elif type == 5: return self.read_dns_name_from_index(l, beg_index)[1] # MX elif type == 15: #TODO: Save priority (don't just jump past it) return self.read_dns_name_from_index(l, beg_index + 2)[1] else: return l[beg_index:beg_index + dlen]
def next_question(self, l, index): array_len = len(l) index, name = self.read_dns_name_from_index(l, index) if index + 4 > array_len: raise Trunc("next_question: truncated") (qtype, qclass) = struct.unpack('!HH', l[index:index + 4]) self.questions.append(dns.question(name, qtype, qclass)) return index + 4
def next_rr(self, l, index, rr_list): array_len = len(l) # verify whether name is offset within packet if index > array_len: raise Trunc("next_rr: name truncated") index,name = self.read_dns_name_from_index(l, index) if index + 10 > array_len: raise Trunc("next_rr: truncated") (qtype,qclass,ttl,rdlen) = struct.unpack('!HHIH', l[index:index+10]) if index+10+rdlen > array_len: raise Trunc("next_rr: data truncated") rddata = self.get_rddata(l, qtype, rdlen, index + 10) rr_list.append(dns.rr(name, qtype, qclass,ttl,rdlen,rddata)) return index + 10 + rdlen
def _read_dns_name_from_index(cls, l, index, retlist): try: while True: chunk_size = ord(l[index]) # check whether we have an internal pointer if (chunk_size & 0xc0) == 0xc0: # pull out offset from last 14 bits offset = ((ord(l[index]) & 0x3) << 8) | ord(l[index + 1]) cls._read_dns_name_from_index(l, offset, retlist) index += 1 break if chunk_size == 0: break index += 1 retlist.append(l[index:index + chunk_size]) index += chunk_size return index except IndexError: raise Trunc("incomplete name")