Good afternoon guys! This is my first post here, so have patience with the newbie;)
I am creating a DNS server taking into account the RFC 1035 specifications using the ctypes to improve code readability and make it more organized.
My problem is this. I have a class for the package header.
class DnsPacket(BigEndianStructure):
""" Class representative to DNS header.
This class handle a bytes buffer in ctypes field mode """
def __new__(cls, buffer):
return cls.from_buffer_copy(buffer)
_fields_ = [('identification', c_uint, 16),
('query_type', c_uint, 1),
('optional_code', c_uint, 4),
('authoritative_answer', c_uint, 1),
('truncation', c_uint, 1),
('recursion_desired', c_uint, 1),
('recursion_available', c_uint, 1),
('reserved_for_future', c_uint, 3),
('response_code', c_uint, 4),
('question_count', c_uint, 16),
('answer_count', c_uint, 16),
('nameserver_count', c_uint, 16),
('aditional_count', c_uint, 16)]
It turns out that after the "aditional_count" field that is the end of the header comes the section that contains the question, according to the RFC in that format.
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ QNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
This QNAME field is represented as a sequence of labels, each label consists of an octet with the label size followed by the label.
Ex: 6google3com
I would like to dynamically generate a field according to this octet so that I can instantiate the label shortly afterwards.
class QuestionSection(BigEndianStructure):
_fields_ = [('size', c_uint), # Primeiro octeto contendo o número de caracteres na label.
('name', size)] # Label em sí
I have a function that takes the domain name of the buffer only that is messed up and dynamically improves the structure and the use of the same for a future use.
def get_domain_name(self, data):
array_data = bytearray(data[sizeof(self):])
expected_lenght = array_data.pop(0)
nameserver = ''
while expected_lenght is not 0:
for _ in range(expected_lenght):
nameserver += chr(array_data.pop(0))
expected_lenght = array_data.pop(0)
if expected_lenght is not 0:
nameserver += '.'
return nameserver
Functions, methods like the above impair the readability and maintenance of the code.
I thank you all for helping me and giving me ideas to solve this problem.