diff options
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/database.c | 18 | ||||
-rw-r--r-- | src/database.h | 2 | ||||
-rw-r--r-- | src/dns.c | 76 | ||||
-rw-r--r-- | src/dns.h | 47 | ||||
-rw-r--r-- | src/log.c | 5 | ||||
-rw-r--r-- | src/log.h | 6 | ||||
-rw-r--r-- | src/main.c | 11 | ||||
-rw-r--r-- | src/server.c | 12 | ||||
-rw-r--r-- | src/server.h | 1 | ||||
-rw-r--r-- | src/test.c | 15 | ||||
-rw-r--r-- | src/tree.c | 38 | ||||
-rw-r--r-- | src/tree.h | 2 |
13 files changed, 136 insertions, 99 deletions
@@ -1,5 +1,5 @@ CC = clang -CFLAGS = -Wall +CFLAGS = -Wall -std=c89 -D _DEFAULT_SOURCE LDFLAGS = -lm BUILDDIR = build SOURCEDIR = src diff --git a/src/database.c b/src/database.c index ba64a8e..7fcd10c 100644 --- a/src/database.c +++ b/src/database.c @@ -7,12 +7,14 @@ #include "database.h" static int database_init ( database_t* _database ) { - // Initialize 2D array of tree_node pointers, paranoia style + unsigned int i = 0; + + /* 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; - for ( unsigned int i = 0; i < DB_CLASS_LEN; i++ ) { + for ( i = 0; i < DB_CLASS_LEN; i++ ) { if ( !( _database->zone[i] = malloc( rr_size ) ) ) return 1; @@ -31,7 +33,7 @@ int database_populate ( return 1; } - // TODO parsing + /* TODO parsing */ char* qname = malloc(32); @@ -54,12 +56,14 @@ int database_populate ( } int database_destroy ( database_t* _database ) { + unsigned int i, o; + if ( !_database || !_database->zone ) return 1; - for ( unsigned int i = 0; i < DB_CLASS_LEN; i++ ) { - for ( unsigned int o = 0; o < DB_RR_LEN; o++ ) { - // TODO should we free data and key? + for ( i = 0; i < DB_CLASS_LEN; i++ ) { + for ( o = 0; o < DB_RR_LEN; o++ ) { + /* TODO should we free data and key? */ tree_destroy( &_database->zone[i][o], _TREE_FREE_DATA | _TREE_FREE_KEY ); } @@ -82,7 +86,7 @@ int database_query ( ) { uint16_t type, class; - // _qtype and _qclass start at 1, so they are invalid when 0. + /* _qtype and _qclass start at 1, so they are invalid when 0. */ if ( !_rdata || !_database || !_qname || !_qtype || !_qclass || _qname_len <= 0 ) { LOGPRINTF(_LOG_ERROR, "Invalid arguments"); diff --git a/src/database.h b/src/database.h index 3fcef80..363f29c 100644 --- a/src/database.h +++ b/src/database.h @@ -11,7 +11,7 @@ #include "tree.h" #include "log.h" -// TODO remove +/* TODO remove */ #include "dns.h" /* @@ -10,7 +10,7 @@ int dns_construct_header ( char* _buffer, int _bufflen, dns_header_t* _header ) if ( !_buffer || !_header || _bufflen < 12 ) return -1; - *((uint16_t*)_buffer) = _header->id; //Since only copied, no flipping necessary + *((uint16_t*)_buffer) = _header->id; /* Since only copied, no flipping necessary */ _buffer[2] = ((_header->QR & 0x01) << 7) | ((_header->OPCODE & 0x0F) << 3) | @@ -39,7 +39,7 @@ int dns_construct_answer ( if ( !_buffer || _bufflen <= 0 || !_answer ) return -1; - // Check buffer size + /* Check buffer size */ if ( _answer->qname_len + _answer->rdlength + 10 > _bufflen ) return -1; @@ -64,13 +64,13 @@ int dns_construct_questoin ( int _bufflen, dns_question_t* _question ) { - //TODO Test + /* TODO Test */ int ret = 0; if ( !_buffer || _bufflen <= 0 || !_question ) return -1; - // Check buffer size + /* Check buffer size */ if ( _question->qname_len + 4 > _bufflen ) return -1; @@ -85,7 +85,7 @@ int dns_construct_questoin ( } -// Question and answer count come from header +/* Question and answer count come from header */ int dns_construct_packet ( char* _buffer, int _bufflen, @@ -115,15 +115,16 @@ int dns_destroy_struct ( dns_message_t* _msg ) int dns_parse_packet ( char* _buffer, int _bufflen, dns_message_t* _msg ) { - //TODO refactor + int i = 0; + /* TODO refactor */ if ( !_buffer || !_bufflen || !_msg ) - return 1; //Invalid input + return 1; /* Invalid input */ if ( _bufflen < 12 ) - return 1; //Too short to contain a DNS header + return 1; /* Too short to contain a DNS header */ - //TODO test + /* TODO test */ _msg->header.id = *( (uint16_t*) _buffer ); _msg->header.QR = ( 0x80 & *( (uint8_t*) (_buffer + 2)) ) >> 7; _msg->header.OPCODE = (0x78 & *( (uint8_t*) (_buffer + 2))) >> 3; @@ -138,14 +139,14 @@ int dns_parse_packet ( char* _buffer, int _bufflen, dns_message_t* _msg ) _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 + /* 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); */ - //Check for sensible QD, AN, NS and ARCOUNTS before massive memory allocation + /* Check for sensible QD, AN, NS and ARCOUNTS before massive memory allocation */ if( _msg->header.question_count > 4 || _msg->header.answer_count > 32 || _msg->header.authorative_count > 32 || @@ -153,30 +154,32 @@ int dns_parse_packet ( char* _buffer, int _bufflen, dns_message_t* _msg ) return 1; } - //Allocate question array - //TODO Only implements question section. - size_t qsize = sizeof(typeof(*(_msg->question))) * _msg->question_count; + /* + * Allocate question array + * TODO Only implements question section. + */ + size_t qsize = sizeof(*(_msg->question)) * _msg->question_count; _msg->question_count = _msg->header.question_count; _msg->question = malloc ( qsize ); memset( _msg->question, 0, qsize ); - if (!_msg->question) //malloc failed + if (!_msg->question) /* malloc failed */ return 1; - int ptr = 12; //byte counter + int ptr = 12; /* byte counter */ - // TODO refactor - for (int i = 0; i < _msg->question_count; i++) { + /* TODO refactor */ + for ( i = 0; i < _msg->question_count; i++ ) { int qname_len = qname_check ( (_buffer + ptr), _bufflen - ptr); - if (qname_len <= 0) //Check for faulty QNAME + if (qname_len <= 0) /* Check for faulty QNAME */ return 1; _msg->question[i].qname = _buffer + ptr; _msg->question[i].qname_len = qname_len; ptr += qname_len; - if( ptr >= (_bufflen - 4) ) //Out of bounds check + if( ptr >= (_bufflen - 4) ) /* Out of bounds check */ return 1; _msg->question[i].qtype = ((uint8_t)*(_buffer + ptr) << 8) | ((uint8_t)*(_buffer + ptr + 1)); @@ -191,24 +194,24 @@ int dns_parse_packet ( char* _buffer, int _bufflen, dns_message_t* _msg ) int fqdn_to_qname( char* _source, int _sourcelen, char* _sink ,int _sinklen ) { - int i; + int i, o; int lastdot = 0; if (_sourcelen < 1 || _sinklen < 1) return -1; - _sink[0] = ' '; //Set to known value + _sink[0] = ' '; /* Set to known value */ - for(i = 0; ((i < _sourcelen) && (i < (_sinklen - 1))); i++) { //Copy offset 1 + for(i = 0; ((i < _sourcelen) && (i < (_sinklen - 1))); i++) { /* Copy offset 1 */ if(! _source[i]) break; _sink[i+1] = _source[i]; } - if( _source[i] ) // _source not terminated, thus no valid string + if( _source[i] ) /* _source not terminated, thus no valid string */ return -1; - for (int o = 0; o < i; o++) { + for (o = 0; o < i; o++) { if( _sink[o] == '.') { _sink[lastdot] = o - lastdot - 1; lastdot = o; @@ -223,14 +226,15 @@ 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; + if ( !_sourcelen || !_sinklen ) { return -1; } - unsigned int next_dot = _source[0] + 1; - int i = 1; for(i = 1; i < _sourcelen; i++) { - if( i > _sinklen){ //Output too small. Not >= bc sink[i-1] is used + if( i > _sinklen){ /* Output too small. Not >= bc sink[i-1] is used */ return -1; } if ( !_source[i] ) { @@ -248,21 +252,23 @@ int qname_to_fqdn( char* _source, int _sourcelen, char* _sink, int _sinklen ) int qname_check( char* _source, int _sourcelen ) { + int next_dot = 0; + int i = 0; + if (!_sourcelen) return -1; - int next_dot = 0; - //TODO questionable control flow - //TODO add ASCII prrintable check - for (int i = 0; i < _sourcelen; i++) { + /* TODO questionable control flow */ + /* TODO add ASCII prrintable check */ + for (i = 0; i < _sourcelen; i++) { if ( i == next_dot ) { - if (_source[i]) { //Not last dot + if (_source[i]) { /* Not last dot */ next_dot = _source[i] + i + 1; - } else { //last dot + } else { /* last dot */ return i+1; } - } else if (!_source[i]) { //Unexpected \0 + } else if (!_source[i]) { /* Unexpected \0 */ return -1; } } @@ -9,11 +9,10 @@ #include <stdlib.h> #include <string.h> -//TODO remove +/* TODO remove */ #include <stdio.h> -//TODO remove defines -//Resource Records +/* Resource Records */ #define RR_A 1 #define RR_NS 2 #define RR_CNAME 5 @@ -33,11 +32,11 @@ enum dns_record { SRV = 33 }; -//Record Classes -#define CL_IN 1 //Internet -#define CL_CS 2 //CSNET (Obsolete) -#define CL_CH 3 //CHAOS -#define CL_HS 4 //Hesiod +/* Record Classes */ +#define CL_IN 1 /* Internet */ +#define CL_CS 2 /* CSNET (Obsolete) */ +#define CL_CH 3 /* CHAOS */ +#define CL_HS 4 /* Hesiod */ enum dns_record_class { IN = 1, CS = 2, @@ -45,22 +44,22 @@ enum dns_record_class { HS = 4 }; -//OPCODES -#define OP_QUERY 0 //Query -#define OP_IQUERY 1 //Inverse Query -#define OP_STATUS 2 //Status request +/* OPCODES */ +#define OP_QUERY 0 /* Query */ +#define OP_IQUERY 1 /* Inverse Query */ +#define OP_STATUS 2 /* Status request */ enum dns_opcode { QUERY = 0, INVERSE = 1, STATUS = 2 }; -//Responsecode +/* Responsecode */ #define RCODE_NOERR 0 #define RCODE_FORMAT 1 #define RCODE_SERVFAIL 2 #define RCODE_NAMEERR 3 -#define RCODE_NOTIMPL 4 //Not implemented +#define RCODE_NOTIMPL 4 #define RCODE_REFUSED 5 enum dns_responsecode { NOERR = 0, @@ -102,14 +101,14 @@ typedef struct dns_message dns_message_t; struct dns_header { uint16_t id; - uint8_t QR; //Query:0 Reply:1 - uint8_t OPCODE; //Query:0 Iquery:1 Status:2 - uint8_t AA; //Authorative answer - uint8_t TC; //Truncation - uint8_t RD; //Recursion Desired - uint8_t RA; //Recursion Available - uint8_t Z; //Unused - uint8_t RCODE; //Response Code + uint8_t QR; /* Query:0 Reply:1 */ + uint8_t OPCODE; /* Query:0 Iquery:1 Status:2 */ + uint8_t AA; /* Authorative answer */ + uint8_t TC; /* Truncation */ + uint8_t RD; /* Recursion Desired */ + uint8_t RA; /* Recursion Available */ + uint8_t Z; /* Unused */ + uint8_t RCODE; /* Response Code */ uint16_t question_count; uint16_t answer_count; @@ -126,7 +125,7 @@ struct dns_question { }; struct dns_answer { - const char* qname; //in qname format + const char* qname; int qname_len; uint16_t type; @@ -164,7 +163,7 @@ int dns_construct_questoin ( dns_question_t* _question ); -// Question and answer count come from header +/* Question and answer count come from header */ int dns_construct_packet ( char* _buffer, int _bufflen, @@ -19,14 +19,17 @@ const char* log_loglevel_str[6] = { int log_init_file(char* _file, unsigned int _verbosity) { + return -1; + /* log_fd = open(_file, O_WRONLY | O_APPEND | O_CREAT | O_DSYNC); return log_init_stdout(_verbosity);; + */ } int log_init_stdout(unsigned int _verbosity) { - log_loglevel = _verbosity;// > _LOG_DEBUG ? _LOG_DEBUG : _verbosity; + log_loglevel = _verbosity; /* > _LOG_DEBUG ? _LOG_DEBUG : _verbosity; */ log_fd = STDIN_FILENO; LOGPRINTF(0, "=== RESTART ==="); @@ -41,8 +41,10 @@ extern const char* log_loglevel_str[6]; }\ } -// DEBUG Wrapper around LOGPRINTF wich is only compiled in in -// _DEBUG mode for performance +/* + * DEBUG Wrapper around LOGPRINTF wich is only compiled in in + * _DEBUG mode for performance + */ #ifdef _DEBUG #define DEBUG(...) { LOGPRINTF(_LOG_DEBUG, __VA_ARGS__); } @@ -7,6 +7,8 @@ #include <stdlib.h> #include <sys/types.h> +#include <unistd.h> + #include "log.h" #include "server.h" @@ -27,20 +29,21 @@ void print_help( char *_argv0 ) { } void parse_args( server_config_t *_config, int argc, char* argv[]) { + 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( int i = 1; i < argc; i++ ) { + for( i = 1; i < argc; i++ ) { const int icpy = i; if ( argv[i][0] != '-' ) { print_help( argv[0] ); exit( 1 ); } - for( int o = 1; o < strlen(argv[icpy]); o++ ) { + for( o = 1; o < strlen(argv[icpy]); o++ ) { switch( argv[icpy][o] ) { case 'h': print_help( argv[0] ); @@ -69,6 +72,10 @@ int main(int argc, char* argv[]) parse_args( &config, argc, argv ); log_init_stdout(_LOG_DEBUG); + + if ( getuid() == 0 ) + LOGPRINTF(_LOG_WARNING, "Running as root is not a good idea. Use setcap or unprivileged port instead."); + #ifdef _TEST run_test(); diff --git a/src/server.c b/src/server.c index 28db427..6eb54e0 100644 --- a/src/server.c +++ b/src/server.c @@ -48,13 +48,15 @@ void server_start ( server_config_t* _config ) } void server_handle_connection ( int _socket, database_t* _zone_db ) { + unsigned int i; + char recv_buffer[ UDP_BUFFER_LEN ]; int recv_len = 0; char answ_buffer[ UDP_BUFFER_LEN ]; int answ_len = UDP_BUFFER_LEN; int answ_cnt = DNS_HEADER_LEN; - // preload with header length, because it is written last. + /* preload with header length, because it is written last. */ struct sockaddr_in sock_client_addr; socklen_t sock_client_addr_len = sizeof( struct sockaddr_in ); @@ -88,11 +90,11 @@ void server_handle_connection ( int _socket, database_t* _zone_db ) { memset( &answ_header, 0, sizeof( dns_header_t ) ); answ_header.id = dns_req.header.id; - answ_header.QR = 1; // Response - answ_header.AA = 1; // Authorative answer + answ_header.QR = 1; /* Response */ + answ_header.AA = 1; /* Authorative answer */ - // TODO test with artificially large rdata to exceed buffer - for (unsigned int i = 0; i < dns_req.question_count; i++) { + /* TODO test with artificially large rdata to exceed buffer */ + for (i = 0; i < dns_req.question_count; i++) { int cnt_inc = 0; database_rdata_t db_rdata; dns_question_t *quest = &dns_req.question[i]; diff --git a/src/server.h b/src/server.h index 03156c5..f0bed00 100644 --- a/src/server.h +++ b/src/server.h @@ -14,6 +14,7 @@ #include <sys/socket.h> #include <netinet/ip.h> +#include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> @@ -29,6 +29,8 @@ void run_test () int test_tree () { + unsigned int i, j; + unsigned const int len = pow ( 'z' - 'a' + 1, 2); unsigned int len_cnt = 0; char* keys[len]; @@ -38,8 +40,8 @@ int test_tree () printf("\n-> test_tree()\n======\n\n"); - for ( char i = 'a'; i <= 'z'; i++ ) { - for ( char j = 'a'; j <= 'z'; j++ ) { + for ( i = 'a'; i <= 'z'; i++ ) { + for ( j = 'a'; j <= 'z'; j++ ) { keys[len_cnt] = malloc (3); keys[len_cnt][0] = i; keys[len_cnt][1] = j; @@ -60,7 +62,7 @@ int test_tree () printf("%s\n", (char*)tree_get(&root, "aa")); - for ( int i = 0; i < len; i++ ) { + for ( i = 0; i < len; i++ ) { if ( strcmp( tree_get(&root, keys[i]), data[i] ) ) LOGPRINTF(_LOG_WARNING, "Data does not match for %s", keys[i]); } @@ -76,6 +78,8 @@ int test_tree () int test_dns_parsing () { + int i; + printf("\n-> test_dns_parsing()\n======\n\n"); char in[128]; char out[128]; @@ -96,7 +100,7 @@ int test_dns_parsing () return 1; } - for(int i = 0; i < written; i++) + for(i = 0; i < written; i++) printf(" %x ", out[i]); written = qname_to_fqdn (out,128,in,128); @@ -185,6 +189,9 @@ int test_database(){ database_destroy( &db ); + free(qname); + qname = NULL; + return 0; } @@ -25,7 +25,7 @@ static int string_compare ( const char* _1, const char* _2 ) char c1 = _1[i]; char c2 = _2[i]; - //Convert to uppercase + /* Convert to uppercase */ if ( c1 >= 97 && c1 <= 122 ) c1 -= 32; if ( c2 >= 97 && c2 <= 122 ) @@ -44,7 +44,7 @@ static int string_compare ( const char* _1, const char* _2 ) if ( _2[i] ) return -1; - //TODO not so great + /* TODO not so great */ return 99; } @@ -58,15 +58,15 @@ int tree_insert ( tree_node_t** _root, char* _key, void* _data ) node = & (*node)->above; } else if ( ret < 0 ) { node = & (*node)->below; - } else { //Already exists + } else { /* Already exists */ return 1; } } - *node = malloc (sizeof(typeof(**node))); + *node = malloc (sizeof(**node)); if( ! *node ) return 2; - memset ( *node, 0, sizeof(typeof(**node)) ); + memset ( *node, 0, sizeof(**node) ); (*node)->key = _key; (*node)->data = _data; @@ -76,31 +76,37 @@ 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) { - // n is the smallest n, for which 2^(n+1) - 1 >= _len, - // thus describes the minimal tree depth required to store - // _len amount of elements + unsigned int i = 0, o = 0; unsigned int n = 0; - for (n = 0; pow( 2, n+1 ) - 1 < _len; n++); + /* + * n is the smallest n, for which 2^(n+1) - 1 >= _len, + * thus describes the minimal tree depth required to store + * _len amount of elements + */ + for (n = 0; pow( 2, n+1 ) - 1 < _len; n++){} - // The maximum size of a tree with depth n; + /* The maximum size of a tree with depth n; */ unsigned int virtual_len = pow( 2, n+1 ) - 1; unsigned int indices[ virtual_len ]; unsigned int indices_cnt = 0; + LOGPRINTF(_LOG_DEBUG, "Elements: %u Rounded size: %u Optimal depth: %u", _len, virtual_len, n); - // Creates the series - // 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, ... - for (unsigned int i = 0; i <= n+1; i++) { + /* + * Creates the series + * 1/2, 1/4, 3/4, 1/8, 3/8, 5/8, 7/8, ... + */ + for (i = 0; i <= n+1; i++) { unsigned int pow_2_i = pow(2,i); - for (unsigned int o = 1; o < pow(2,i); o+=2) { + for (o = 1; o < pow(2,i); o+=2) { indices[ indices_cnt++ ] = virtual_len * o / pow_2_i; } } - for ( unsigned int i = 0; i < virtual_len; i++ ) { + for ( i = 0; i < virtual_len; i++ ) { if ( indices[i] < _len ) { if (tree_insert ( _root, _key[indices[i]], _data[indices[i]] )){ LOGPRINTF(_LOG_WARNING, "tree_insert failed on \"%s\". Double?", _key[indices[i]]); @@ -113,7 +119,7 @@ int tree_balanced_insert ( tree_node_t** _root, void* _data[], char* _key[], un int tree_destroy ( tree_node_t** _root, uint8_t _options ) { - //Not efficient, but this code is for testing only. + /* Not efficient, but this code is for testing only, anyways. */ unsigned int max_depth = 0; unsigned int node_cnt = 0; while(*_root) @@ -46,7 +46,7 @@ #include <math.h> #include <string.h> -//TODO remove +/* TODO remove */ #include <stdio.h> #include "log.h" |