diff options
Diffstat (limited to 'src/dns.c')
-rw-r--r-- | src/dns.c | 64 |
1 files changed, 54 insertions, 10 deletions
@@ -7,9 +7,9 @@ int dns_parse_packet ( char* _buffer, int _bufflen, struct dns_message* _msg ) if ( _bufflen < 12 ) return 1; //Too short to contain a DNS header - + //TODO test - _msg->header.id = *( (uint16_t*) _buffer ); + _msg->header.id = *( (uint16_t*) _buffer ); _msg->header.QR = ( 0x80 & *( (uint8_t*) (_buffer + 2)) ) >> 7; _msg->header.OPCODE = (0x78 & *( (uint8_t*) (_buffer + 2))) >> 3; _msg->header.AA = (0x04 & *( (uint8_t*) (_buffer + 2))) >> 2; @@ -18,17 +18,41 @@ int dns_parse_packet ( char* _buffer, int _bufflen, struct dns_message* _msg ) _msg->header.RA = (0x80 & *( (uint8_t*) (_buffer + 3))) >> 7; _msg->header.Z = (0x70 & *( (uint8_t*) (_buffer + 3))) >> 4; _msg->header.RCODE = (0x0F & *( (uint8_t*) (_buffer + 3))); - _msg->header.question_count = (*((uint8_t*) (_buffer + 4)) << 8) | *((uint8_t*) (_buffer + 5)); - _msg->header.answer_count = (*((uint8_t*) (_buffer + 6)) << 8) | *((uint8_t*) (_buffer + 7)); - _msg->header.authorative_count = (*((uint8_t*) (_buffer + 8)) << 8) | *((uint8_t*) (_buffer + 9)); + _msg->header.question_count = (*((uint8_t*) (_buffer + 4 )) << 8) | *((uint8_t*) (_buffer + 5 )); + _msg->header.answer_count = (*((uint8_t*) (_buffer + 6 )) << 8) | *((uint8_t*) (_buffer + 7 )); + _msg->header.authorative_count = (*((uint8_t*) (_buffer + 8 )) << 8) | *((uint8_t*) (_buffer + 9 )); _msg->header.additional_count = (*((uint8_t*) (_buffer + 10)) << 8) | *((uint8_t*) (_buffer + 11)); - + //TODO remove printf("ANSWER %i\n", _msg->header.answer_count); printf("QUESTI %i\n", _msg->header.question_count); printf("AUTHOR %i\n", _msg->header.authorative_count); printf("ADDITI %i\n", _msg->header.additional_count); - - return 1; + + //Allocate question array + //TODO Only implements question section. + size_t qsize = sizeof(typeof(*(_msg->question))) * _msg->question_count; + _msg->question_count = _msg->header.question_count; + _msg->question = malloc ( qsize ); + memset( _msg->question, 0, qsize ); + + int ptr = 12; //byte counter + for (int i = 0; i < _msg->question_count; i++) { + int qname_len = qname_check ( (_buffer + ptr), _bufflen - ptr); + + if (qname_len <= 0) //Check for faulty QNAME + return 1; + + _msg->question[i].qname = _buffer + ptr; + ptr += qname_len; + _msg->question[i].qtype = (uint16_t*) (_buffer + ptr); + ptr += 2; + _msg->question[i].qclass = (uint16_t*) (_buffer + ptr); + + if( ptr >= _bufflen ) //Out of bounds check + return 1; + } + + return 0; } int fqdn_to_qname( char* _source, int _sourcelen, char* _sink ,int _sinklen ) @@ -60,7 +84,7 @@ int fqdn_to_qname( char* _source, int _sourcelen, char* _sink ,int _sinklen ) _sink[lastdot] = i - lastdot; _sink[i + 1] = 0; - return i+2; + return i+2; } @@ -85,8 +109,28 @@ int qname_to_fqdn( char* _source, int _sourcelen, char* _sink, int _sinklen ) } else { _sink[i-1] = _source[i]; } + } + return i-1; +} + +int qname_check( char* _source, int _sourcelen ) +{ + if (!_sourcelen) + return -1; + int next_dot = 0; + + for (int i = 0; i < _sourcelen; i++) { + if ( i == next_dot ) { + if (_source[i]) { //Not last dot + next_dot = _source[i] + i + 1; + } else { //last dot + return i+1; + } + } else if (!_source[i]) { //Invalid qname + return -1; + } } - return i-1; + return -1; } |