def encode_message(self): message = b'' message += self.header.encode_header() question = DNSQuestion(self.q_type, self.host_name) message += question.encode_question() return message
def test_question_data(self): data = b'\x06yandex\x02ru\x00\x00\x1c\x00\x01\xc0\x0c\x00' \ b'\x1c\x00\x01\x00\x00\x00C\x00\x10*\x02\x06\xb8\x00' \ b'\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\n' question = DNSQuestion(is_IPv6=True, host_name='') question.decode_question(data, 0) self.assertEqual('yandex.ru', question.host_name) self.assertEqual(28, question.type) self.assertEqual(1, question.request_class)
def encode_message(self, is_TCP): message = b'' message += self.header.encode_header() question = DNSQuestion(self.q_type, self.host_name) message += question.encode_question() if is_TCP: message = struct.pack('!H', len(message)) + message return message
def __init__(self, message, offset): data = DNSQuestion.decode_domain_name(message, offset) self.primary_name_server = data[0] offset = data[1] data = DNSQuestion.decode_domain_name(message, offset) self.authority_mailbox = data[0] offset = data[1] self.serial_number = str( struct.unpack('!I', message[offset:offset + 4])[0]) offset += 4 self.refresh_interval = str( struct.unpack('!I', message[offset:offset + 4])[0]) offset += 4 self.retry_interval = struct.unpack('!I', message[offset:offset + 4])[0] offset += 4 self.expire_limit = struct.unpack('!I', message[offset:offset + 4])[0] offset += 4 self.minimum_TTL = struct.unpack('!I', message[offset:offset + 4])[0]
def decode_info(self, message, offset): name_offset = struct.unpack_from('!H', message, offset)[0] & 0x1fff self.host_name = DNSQuestion.decode_domain_name(message, name_offset)[0] offset += 2 self.type = struct.unpack('!H', message[offset:offset + 2])[0] offset += 2 self.request_class = struct.unpack('!H', message[offset:offset + 2])[0] offset += 2 self.ttl = struct.unpack('!I', message[offset:offset + 4])[0] offset += 4 self.data_length = struct.unpack('!H', message[offset:offset + 2])[0] offset += 2 for i in range(self.data_length): self.address += str( struct.unpack_from('!B', message, offset + i)[0]) + '.' self.address = self.address[:-1] self.request = Request(self.data_length, self.type, message, offset) return offset + self.data_length
def decode_message(self, message): self.header.decode_header(message) offset = self.header.length for i in range(self.header.questions_count): self.questions.append(DNSQuestion(self.q_type, self.host_name)) offset = self.questions[i].decode_question(message, offset) for i in range(self.header.answers_count): self.answers.append(Answer()) offset = self.answers[i].decode_info(message, offset) for i in range(self.header.access_rights_count): self.authority_rrs.append(Answer()) offset = self.authority_rrs[i].decode_info(message, offset) for i in range(self.header.additional_info_count): self.additional_rrs.append(Answer()) offset = self.additional_rrs[i].decode_info(message, offset)
def start_working(self): with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: sock.settimeout(15) sock.bind((self.server_ip, 1024)) with open(self.cache_file, 'rb') as f: self.cache = pickle.load(f) while True: try: data, self.client_ip = sock.recvfrom(1024) print('Пакет получен!') # раскодировать пакет и достать имя и тип запроса hostname, q_type = DNSQuestion.decode_s_question(data, 12) # если лежит в кэше current_time = int(time.time()) if self.is_exist_in_cache(q_type, hostname) and self.cache[q_type][hostname][1] >= current_time: print('In if!') # to take data from cache print(self.cache[q_type][hostname]) sock.sendto(self.cache[q_type][hostname][0], self.client_ip) print('Пакет отправлен!\n') elif self.is_exist_in_cache(q_type, hostname) and self.cache[q_type][hostname][1] < current_time: self.cache[q_type].pop(hostname) print('In else!') data_from_dns = self.ask_to_dns(q_type, hostname) sock.sendto(data_from_dns, self.client_ip) print('Пакет отправлен!\n') else: print('In else!') data_from_dns = self.ask_to_dns(q_type, hostname) sock.sendto(data_from_dns, self.client_ip) print('Пакет отправлен!\n') except socket.timeout or KeyboardInterrupt: with open(self.cache_file, 'wb') as f: pickle.dump(self.cache, f) break
def __init__(self, message, offset): self.name_server = DNSQuestion.decode_domain_name(message, offset)[0]
def __init__(self, message, offset): self.priority = struct.unpack('!H', message[offset:offset + 2])[0] offset += 2 self.mail_exchanger = DNSQuestion.decode_domain_name( message, offset + 2)[0]
def __init__(self, message, offset): self.mailbox = DNSQuestion.decode_domain_name(message, offset)[0]
def __init__(self, message, offset): self.name = DNSQuestion.decode_domain_name(message, offset)[0] print(' PTR: {0}'.format(self.name)) exit(0)