diff options
-rw-r--r-- | src/database.c | 21 | ||||
-rw-r--r-- | src/dns.c | 79 | ||||
-rw-r--r-- | src/dns.h | 3 | ||||
-rw-r--r-- | src/log.h | 2 | ||||
-rw-r--r-- | src/main.c | 18 | ||||
-rw-r--r-- | src/server.c | 8 | ||||
-rw-r--r-- | src/server.h | 2 | ||||
-rw-r--r-- | src/tree.c | 21 | ||||
-rw-r--r-- | src/zonefile.c | 12 | ||||
-rw-r--r-- | src/zonefile.h | 11 |
10 files changed, 105 insertions, 72 deletions
diff --git a/src/database.c b/src/database.c index 7fcd10c..5c865d8 100644 --- a/src/database.c +++ b/src/database.c @@ -8,12 +8,13 @@ static int database_init ( database_t* _database ) { unsigned int i = 0; + size_t rr_size; /* Initialize 2D array of tree_node pointers, paranoia style */ if ( !( _database->zone = malloc( sizeof( tree_node_t** ) * DB_CLASS_LEN ) ) ) return 1; - size_t rr_size = sizeof( struct tree_node* ) * DB_RR_LEN; + rr_size = sizeof( struct tree_node* ) * DB_RR_LEN; for ( i = 0; i < DB_CLASS_LEN; i++ ) { if ( !( _database->zone[i] = malloc( rr_size ) ) ) return 1; @@ -24,10 +25,11 @@ static int database_init ( database_t* _database ) { return 0; } -int database_populate ( - database_t* _database, - char* _zonefile -) { +int database_populate ( database_t* _database, char* _zonefile ) { + char* qname; + int len; + void* data; + if ( database_init( _database ) ) { LOGPRINTF(_LOG_ERROR, "Failed to initialize database."); return 1; @@ -35,14 +37,14 @@ int database_populate ( /* TODO parsing */ - char* qname = malloc(32); + qname = malloc(32); - int len = fqdn_to_qname( "test.example.com", 17, qname, 32 ); + len = fqdn_to_qname( "test.example.com", 17, qname, 32 ); if ( len <= 0 ) return 1; - void* data = malloc( 10 ); + data = malloc( 10 ); *((uint32_t*)data) = 1800; *((uint16_t*)(data+4)) = 4; @@ -85,6 +87,7 @@ int database_query ( uint16_t _qclass ) { uint16_t type, class; + void* data; /* _qtype and _qclass start at 1, so they are invalid when 0. */ @@ -105,7 +108,7 @@ int database_query ( type = _qtype - 1; class = _qclass - 1; - void* data = tree_get( &_database->zone[class][type], _qname ); + data = tree_get( &_database->zone[class][type], _qname ); if ( !data ) { LOGPRINTF(_LOG_DEBUG, "No matching RR found"); @@ -12,19 +12,19 @@ int dns_construct_header ( char* _buffer, int _bufflen, dns_header_t* _header ) *((uint16_t*)_buffer) = _header->id; /* Since only copied, no flipping necessary */ _buffer[2] = - ((_header->QR & 0x01) << 7) | - ((_header->OPCODE & 0x0F) << 3) | - ((_header->AA & 0x01) << 2) | - ((_header->TC & 0x01) << 1) | - ( _header->RD & 0x01); + (char)((_header->QR & 0x01) << 7) | + (char)((_header->OPCODE & 0x0F) << 3) | + (char)((_header->AA & 0x01) << 2) | + (char)((_header->TC & 0x01) << 1) | + (char)( _header->RD & 0x01); _buffer[3] = - ((_header->RA & 0x01) << 7) | - ((_header->Z & 0x07) << 4) | - ( _header->RCODE & 0x0F); - *((uint16_t*)(_buffer + 4 )) = FLIP_BYTES(_header->question_count); - *((uint16_t*)(_buffer + 6 )) = FLIP_BYTES(_header->answer_count); - *((uint16_t*)(_buffer + 8 )) = FLIP_BYTES(_header->authorative_count); - *((uint16_t*)(_buffer + 10)) = FLIP_BYTES(_header->additional_count); + (char)((_header->RA & 0x01) << 7) | + (char)((_header->Z & 0x07) << 4) | + (char)( _header->RCODE & 0x0F); + *((uint16_t*)(_buffer + 4 )) = (uint16_t)FLIP_BYTES(_header->question_count); + *((uint16_t*)(_buffer + 6 )) = (uint16_t)FLIP_BYTES(_header->answer_count); + *((uint16_t*)(_buffer + 8 )) = (uint16_t)FLIP_BYTES(_header->authorative_count); + *((uint16_t*)(_buffer + 10)) = (uint16_t)FLIP_BYTES(_header->additional_count); return DNS_HEADER_LEN; } @@ -43,14 +43,14 @@ int dns_construct_answer ( if ( _answer->qname_len + _answer->rdlength + 10 > _bufflen ) return -1; - memcpy( _buffer, _answer->qname, _answer->qname_len ); + memcpy( _buffer, _answer->qname, (unsigned)_answer->qname_len ); ret += _answer->qname_len; - *((uint16_t*)(_buffer + ret + 0 )) = FLIP_BYTES(_answer->type); - *((uint16_t*)(_buffer + ret + 2 )) = FLIP_BYTES(_answer->class); - *((uint16_t*)(_buffer + ret + 4 )) = FLIP_BYTES((uint16_t)((_answer->ttl << 16) & 0xffff)); - *((uint16_t*)(_buffer + ret + 6 )) = FLIP_BYTES((uint16_t)(_answer->ttl & 0xffff)); - *((uint16_t*)(_buffer + ret + 8 )) = FLIP_BYTES(_answer->rdlength); + *((uint16_t*)(_buffer + ret + 0 )) = (uint16_t)FLIP_BYTES(_answer->type); + *((uint16_t*)(_buffer + ret + 2 )) = (uint16_t)FLIP_BYTES(_answer->class); + *((uint16_t*)(_buffer + ret + 4 )) = (uint16_t)FLIP_BYTES((uint16_t)((_answer->ttl << 16) & 0xffff)); + *((uint16_t*)(_buffer + ret + 6 )) = (uint16_t)FLIP_BYTES((uint16_t)(_answer->ttl & 0xffff)); + *((uint16_t*)(_buffer + ret + 8 )) = (uint16_t)FLIP_BYTES(_answer->rdlength); ret += 10; memcpy( _buffer + ret, _answer->rdata, _answer->rdlength ); @@ -74,11 +74,11 @@ int dns_construct_questoin ( if ( _question->qname_len + 4 > _bufflen ) return -1; - memcpy( _buffer, _question->qname, _question->qname_len ); + memcpy( _buffer, _question->qname, (unsigned)_question->qname_len ); ret += _question->qname_len; - *((uint16_t*)(_buffer + ret + 0 )) = FLIP_BYTES(_question->qtype); - *((uint16_t*)(_buffer + ret + 2 )) = FLIP_BYTES(_question->qclass); + *((uint16_t*)(_buffer + ret + 0 )) = (uint16_t)FLIP_BYTES(_question->qtype); + *((uint16_t*)(_buffer + ret + 2 )) = (uint16_t)FLIP_BYTES(_question->qclass); ret += 4; return ret; @@ -116,6 +116,8 @@ int dns_destroy_struct ( dns_message_t* _msg ) int dns_parse_packet ( char* _buffer, int _bufflen, dns_message_t* _msg ) { int i = 0; + size_t qsize; + int ptr; /* TODO refactor */ if ( !_buffer || !_bufflen || !_msg ) @@ -134,10 +136,10 @@ int dns_parse_packet ( char* _buffer, int _bufflen, dns_message_t* _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->question_count = _msg->header.question_count = (*((uint8_t*) (_buffer + 4 )) << 8) | *((uint8_t*) (_buffer + 5 )); - _msg->answer_count = _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)); + _msg->question_count = _msg->header.question_count = (uint16_t)(*((uint8_t*) (_buffer + 4 )) << 8) | *((uint8_t*) (_buffer + 5 )); + _msg->answer_count = _msg->header.answer_count = (uint16_t)(*((uint8_t*) (_buffer + 6 )) << 8) | *((uint8_t*) (_buffer + 7 )); + _msg->header.authorative_count = (uint16_t)(*((uint8_t*) (_buffer + 8 )) << 8) | *((uint8_t*) (_buffer + 9 )); + _msg->header.additional_count = (uint16_t)(*((uint8_t*) (_buffer + 10)) << 8) | *((uint8_t*) (_buffer + 11)); /* TODO remove */ /*printf("ANSWER %i\n", _msg->header.answer_count); @@ -158,7 +160,7 @@ int dns_parse_packet ( char* _buffer, int _bufflen, dns_message_t* _msg ) * Allocate question array * TODO Only implements question section. */ - size_t qsize = sizeof(*(_msg->question)) * _msg->question_count; + qsize = sizeof(*(_msg->question)) * (unsigned)_msg->question_count; _msg->question_count = _msg->header.question_count; _msg->question = malloc ( qsize ); memset( _msg->question, 0, qsize ); @@ -166,7 +168,7 @@ int dns_parse_packet ( char* _buffer, int _bufflen, dns_message_t* _msg ) if (!_msg->question) /* malloc failed */ return 1; - int ptr = 12; /* byte counter */ + ptr = 12; /* byte counter */ /* TODO refactor */ for ( i = 0; i < _msg->question_count; i++ ) { @@ -182,9 +184,9 @@ int dns_parse_packet ( char* _buffer, int _bufflen, dns_message_t* _msg ) if( ptr >= (_bufflen - 4) ) /* Out of bounds check */ return 1; - _msg->question[i].qtype = ((uint8_t)*(_buffer + ptr) << 8) | ((uint8_t)*(_buffer + ptr + 1)); + _msg->question[i].qtype = (uint16_t)((uint8_t)*(_buffer + ptr) << 8) | ((uint8_t)*(_buffer + ptr + 1)); ptr += 2; - _msg->question[i].qclass = ((uint8_t)*(_buffer + ptr) << 8) | ((uint8_t)*(_buffer + ptr + 1)); + _msg->question[i].qclass = (uint16_t)((uint8_t)*(_buffer + ptr) << 8) | ((uint8_t)*(_buffer + ptr + 1)); ptr += 2; } @@ -213,12 +215,12 @@ int fqdn_to_qname( char* _source, int _sourcelen, char* _sink ,int _sinklen ) for (o = 0; o < i; o++) { if( _sink[o] == '.') { - _sink[lastdot] = o - lastdot - 1; + _sink[lastdot] = (char)(o - lastdot - 1); lastdot = o; } } - _sink[lastdot] = i - lastdot; + _sink[lastdot] = (char)(i - lastdot); _sink[i + 1] = 0; return i+2; @@ -226,15 +228,17 @@ int fqdn_to_qname( char* _source, int _sourcelen, char* _sink ,int _sinklen ) int qname_to_fqdn( char* _source, int _sourcelen, char* _sink, int _sinklen ) { - unsigned int next_dot = _source[0] + 1; - int i = 1; + unsigned int next_dot; + unsigned int i = 1; if ( !_sourcelen || !_sinklen ) { return -1; } - for(i = 1; i < _sourcelen; i++) { - if( i > _sinklen){ /* Output too small. Not >= bc sink[i-1] is used */ + next_dot = (unsigned)_source[0] + 1; + + for(i = 1; i < (unsigned)_sourcelen; i++) { + if( i > (unsigned)_sinklen){ /* Output too small. Not >= bc sink[i-1] is used */ return -1; } if ( !_source[i] ) { @@ -242,12 +246,13 @@ int qname_to_fqdn( char* _source, int _sourcelen, char* _sink, int _sinklen ) break; } else if (i == next_dot) { _sink[i-1]='.'; - next_dot = _source[i] + i + 1; + next_dot = (unsigned)_source[i] + i + 1; } else { _sink[i-1] = _source[i]; } } - return i-1; + + return (signed)i-1; } int qname_check( char* _source, int _sourcelen ) @@ -1,3 +1,6 @@ +/* + * vi: ft=c + */ /* dns.h * (c) Jonas Gunz, 2019 * License: MIT @@ -63,4 +63,4 @@ int log_init_file(char* _file, unsigned int _verbosity); */ int log_init_stdout(unsigned int _verbosity); -int log_close(); +int log_close( void ); @@ -12,10 +12,6 @@ #include "log.h" #include "server.h" -#ifdef _TEST -#include "test.h" -#endif - void print_help( char *_argv0 ) { printf( "dns\n" @@ -29,15 +25,15 @@ void print_help( char *_argv0 ) { } void parse_args( server_config_t *_config, int argc, char* argv[]) { - int i, o; + unsigned int i, o; memset( _config, 0, sizeof( server_config_t ) ); _config->bind_ip = "0.0.0.0"; _config->bind_port = 53; _config->zonefile = "/nofile"; - for( i = 1; i < argc; i++ ) { - const int icpy = i; + for( i = 1; i < (unsigned int)argc; i++ ) { + const unsigned int icpy = i; if ( argv[i][0] != '-' ) { print_help( argv[0] ); exit( 1 ); @@ -52,7 +48,7 @@ void parse_args( server_config_t *_config, int argc, char* argv[]) { _config->bind_ip = argv[++i]; break; case 'p': - _config->bind_port = atoi( argv[++i] ); + _config->bind_port = (uint16_t)atoi( argv[++i] ); break; case 'z': _config->zonefile = argv[++i]; @@ -76,12 +72,8 @@ int main(int argc, char* argv[]) if ( getuid() == 0 ) LOGPRINTF(_LOG_WARNING, "Running as root is not a good idea. Use setcap or unprivileged port instead."); - -#ifdef _TEST - run_test(); -#else server_start( &config ); -#endif + return 0; } diff --git a/src/server.c b/src/server.c index 6eb54e0..3796b87 100644 --- a/src/server.c +++ b/src/server.c @@ -43,12 +43,10 @@ void server_start ( server_config_t* _config ) server_handle_connection( sock_server, &zone_db ); } } - - exit(0); } void server_handle_connection ( int _socket, database_t* _zone_db ) { - unsigned int i; + int i; char recv_buffer[ UDP_BUFFER_LEN ]; int recv_len = 0; @@ -124,7 +122,7 @@ void server_handle_connection ( int _socket, database_t* _zone_db ) { dns_construct_header( answ_buffer, answ_len, &answ_header ); - sendto( _socket, answ_buffer, answ_cnt, 0, (struct sockaddr*) &sock_client_addr, sock_client_addr_len ); + sendto( _socket, answ_buffer, (size_t)answ_cnt, 0, (struct sockaddr*) &sock_client_addr, sock_client_addr_len ); end: dns_destroy_struct ( &dns_req ); @@ -160,7 +158,7 @@ int server_get_socket ( char* _bind_ip, uint16_t _bind_port ) { return server_socket; } -void signal_term ( ) { +void signal_term ( int _sig ) { LOGPRINTF( _LOG_NOTE, "Server shutting down" ); close( sock_server ); exit(0); diff --git a/src/server.h b/src/server.h index f0bed00..d9fc5a0 100644 --- a/src/server.h +++ b/src/server.h @@ -42,4 +42,4 @@ void server_handle_connection ( int _socket, database_t* _zone_db ); int server_get_socket ( char* _bind_ip, uint16_t _bind_port ); -void signal_term ( ); +void signal_term ( int _sig ); @@ -17,10 +17,11 @@ static int string_compare ( const char* _1, const char* _2 ); * */ static int string_compare ( const char* _1, const char* _2 ) { + int i; + if ( !_1 || !_2 ) return 99; - int i; for (i = 0; _1[i] && _2[i]; i++) { char c1 = _1[i]; char c2 = _2[i]; @@ -76,8 +77,11 @@ int tree_insert ( tree_node_t** _root, char* _key, void* _data ) int tree_balanced_insert ( tree_node_t** _root, void* _data[], char* _key[], unsigned int _len) { - unsigned int i = 0, o = 0; - unsigned int n = 0; + unsigned int i, o, n, virtual_len, indices_cnt; + unsigned int* indices; + + indices = NULL; + indices_cnt = 0; /* * n is the smallest n, for which 2^(n+1) - 1 >= _len, @@ -87,10 +91,12 @@ int tree_balanced_insert ( tree_node_t** _root, void* _data[], char* _key[], un for (n = 0; pow( 2, n+1 ) - 1 < _len; n++){} /* The maximum size of a tree with depth n; */ - unsigned int virtual_len = pow( 2, n+1 ) - 1; + virtual_len = pow( 2, n+1 ) - 1; - unsigned int indices[ virtual_len ]; - unsigned int indices_cnt = 0; + indices = malloc( virtual_len * sizeof(unsigned int) ); + + if(!indices) + return -1; LOGPRINTF(_LOG_DEBUG, "Elements: %u Rounded size: %u Optimal depth: %u", _len, virtual_len, n); @@ -114,6 +120,9 @@ int tree_balanced_insert ( tree_node_t** _root, void* _data[], char* _key[], un } } + free( indices ); + indices = NULL; + return 0; } diff --git a/src/zonefile.c b/src/zonefile.c new file mode 100644 index 0000000..1dd3d2d --- /dev/null +++ b/src/zonefile.c @@ -0,0 +1,12 @@ +/* + * src/zonefile.c + * (c) 2021 Jonas Gunz <himself@jonasgunz.de> + * License: MIT + */ + +#include "zonefile.h" + +int zonefile_parse_to_list (void** _list, char* _file) { + return -1; +} + diff --git a/src/zonefile.h b/src/zonefile.h new file mode 100644 index 0000000..8c2dac3 --- /dev/null +++ b/src/zonefile.h @@ -0,0 +1,11 @@ +/* + * src/zonefile.h + * (c) 2021 Jonas Gunz <himself@jonasgunz.de> + * License: MIT + */ + +#pragma once + +#include <stdio.h> + +int zonefile_parse_to_list (void** _list, char* _file); |