コード例 #1
0
    def test_create_domain_name_query(self):
        """
        Test case to create a DNS query to ask for a particular domain name from a dns server.
        """
        encoded_dns_message: BytesIO = DNSMessageUtilities.create_domain_name_query(
            'www.cs.ubc.ca', 12345, 15)

        encoded_dns_message.seek(
            0
        )  # need to start reading the dns message from the start of the BytesIO object
        dns_message = DNSMessage.decode_dns_message(encoded_dns_message)

        # Check that the query id is correct
        self.assertEqual(dns_message.query_id, 12345)

        # Check that flags are correct
        self.assertEqual(dns_message.is_response, False)
        self.assertEqual(dns_message.opcode, 0)
        self.assertEqual(dns_message.authoritative, False)
        self.assertEqual(dns_message.is_truncated, False)
        self.assertEqual(dns_message.recursion_desired, False)
        self.assertEqual(dns_message.recursion_available, False)
        self.assertEqual(dns_message.rcode, 0)

        # Check that record/question counts are correct
        self.assertEqual(dns_message.question_count, 1)
        self.assertEqual(dns_message.answer_count, 0)
        self.assertEqual(dns_message.nameserver_count, 0)
        self.assertEqual(dns_message.additional_count, 0)

        # Check that the question was properly decoded
        self.assertEqual(dns_message.dns_questions[0].name, 'www.cs.ubc.ca')
        self.assertEqual(dns_message.dns_questions[0].type, 15)
        self.assertEqual(dns_message.dns_questions[0].response_class, 1)
コード例 #2
0
    def _handle_tracing_for_dns_query(self, domain_name_query: BytesIO,
                                      next_dns_server_ip: str) -> None:
        """
        If the resolver is set to verbose, then print tracing information for the dns query.

        :param domain_name_query: the domain name query that is sent to the next_dns_server_ip.
        :param next_dns_server_ip: the dns server we send the domain name query to.
        :return: None
        """
        if self.verbose:
            print('')
            print('')
            domain_name_query.seek(
                0)  # need to ensure we are at the start of the writer
            # to be able to correctly decode into a DNS Question
            DNSMessage.decode_dns_message(domain_name_query).print_dns_query(
                next_dns_server_ip)
コード例 #3
0
    def test_decode_dns_message(self):
        """
        Test case to decode an entire dns message. This dns message contains resource records with pointers.
        """
        dns_message: DNSMessage = DNSMessage.decode_dns_message(
            BytesIO(self.dns_message_encoded))

        # Check that the query id is correct
        self.assertEqual(dns_message.query_id, 1)

        # Check that flags are correct
        self.assertEqual(dns_message.is_response, True)
        self.assertEqual(dns_message.opcode, 0)
        self.assertEqual(dns_message.authoritative, False)
        self.assertEqual(dns_message.is_truncated, False)
        self.assertEqual(dns_message.recursion_desired, False)
        self.assertEqual(dns_message.recursion_available, True)
        self.assertEqual(dns_message.rcode, 0)

        # Check that record/question counts are correct
        self.assertEqual(dns_message.question_count, 1)
        self.assertEqual(dns_message.answer_count, 0)
        self.assertEqual(dns_message.nameserver_count, 4)
        self.assertEqual(dns_message.additional_count, 8)

        # Check that the question was properly decoded
        self.assertEqual(dns_message.dns_questions[0].name, 'www.cs.ubc.ca')
        self.assertEqual(dns_message.dns_questions[0].type, 1)
        self.assertEqual(dns_message.dns_questions[0].response_class, 1)

        # Check that the first name server record was correctly decoded
        self.assertEqual(dns_message.name_server_records[0].name, 'ca')
        self.assertEqual(dns_message.name_server_records[0].type, 2)
        self.assertEqual(dns_message.name_server_records[0].response_class, 1)
        self.assertEqual(dns_message.name_server_records[0].ttl, 150873)
        self.assertEqual(dns_message.name_server_records[0].rdlength, 15)
        self.assertEqual(dns_message.name_server_records[0].rdata,
                         'x.ca-servers.ca')

        # Check that the first additional record was correctly decoded
        self.assertEqual(dns_message.additional_records[0].name,
                         'x.ca-servers.ca')
        self.assertEqual(dns_message.additional_records[0].type, 1)
        self.assertEqual(dns_message.additional_records[0].response_class, 1)
        self.assertEqual(dns_message.additional_records[0].ttl, 150873)
        self.assertEqual(dns_message.additional_records[0].rdlength, 4)
        self.assertEqual(dns_message.additional_records[0].rdata,
                         '199.253.250.68')
コード例 #4
0
    def _receive_dns_message(self, expected_query_id: int) -> DNSMessage:
        """
        Receives and decodes a dns message from a dns server.

        If the received dns message does not have the expected query_id or is not a response, then simply wait for the
        next message received.

        :param expected_query_id: the query id we expect the incoming dns response to possess.
        :return: the dns response that has been received, successfully decoded, and has the correct query_id and is_
        response value.
        """
        received_data: bytes = self.udp_socket.recv(1024)
        received_dns_message: DNSMessage = DNSMessage.decode_dns_message(
            BytesIO(received_data))

        if (received_dns_message.query_id !=
                expected_query_id) or not received_dns_message.is_response:
            received_dns_message = self._receive_dns_message(expected_query_id)

        return received_dns_message