diff options
author | Jonas Gunz <himself@jonasgunz.de> | 2019-12-20 13:50:42 +0100 |
---|---|---|
committer | Jonas Gunz <himself@jonasgunz.de> | 2019-12-20 13:50:42 +0100 |
commit | 9dc2a544f88ddedea24d16f05170cb90858c3e9a (patch) | |
tree | 08b296c874aaa9780527a27ef9985f15ecc2e2ac /src | |
parent | 5124da870f85b23ea8e46d48a9cccc38df6323fb (diff) | |
download | dns-9dc2a544f88ddedea24d16f05170cb90858c3e9a.tar.gz |
started rousource record storeage and query
Diffstat (limited to 'src')
-rw-r--r-- | src/dns.c | 4 | ||||
-rw-r--r-- | src/dns.h | 31 | ||||
-rw-r--r-- | src/main.c | 11 | ||||
-rw-r--r-- | src/zonefile.c | 100 | ||||
-rw-r--r-- | src/zonefile.h | 47 |
5 files changed, 189 insertions, 4 deletions
@@ -183,6 +183,8 @@ int qname_check( char* _source, int _sourcelen ) int next_dot = 0; + //TODO questionable control flow + //TODO add ASCII prrintable check for (int i = 0; i < _sourcelen; i++) { if ( i == next_dot ) { if (_source[i]) { //Not last dot @@ -190,7 +192,7 @@ int qname_check( char* _source, int _sourcelen ) } else { //last dot return i+1; } - } else if (!_source[i]) { //Invalid qname + } else if (!_source[i]) { //Unexpected \0 return -1; } } @@ -12,6 +12,7 @@ //TODO remove #include <stdio.h> +//TODO remove defines //Resource Records #define RR_A 1 #define RR_NS 2 @@ -21,17 +22,38 @@ #define RR_TXT 16 #define RR_AAAA 28 #define RR_SRV 33 +enum dns_record { + A = 1, + NS = 2, + CNAME = 5, + SOA = 6, + MX = 15, + TXT = 16, + AAAA = 28, + SRV = 33 +}; //Record Classes #define CL_IN 1 //Internet #define CL_CS 2 //CSNET (Onsolete) #define CL_CH 3 //CHAOS #define CL_HS 4 //Hesiod +enum dns_record_class { + IN = 1, + CS = 2, + CH = 3, + HS = 4 +}; //OPCODES #define OP_Q 0 //Query #define OP_IQ 1 //Inverse Query #define OP_STAT 2 //Status request +enum dns_opcode { + QUERY = 0, + INVERSE = 1, + STATUS = 2 +}; //Responsecode #define RCODE_NOERR 0 @@ -40,6 +62,14 @@ #define RCODE_NAMEERR 3 #define RCODE_NI 4 //Not implemented #define RCODE_REFUSED 5 +enum dns_responsecode { + NOERR = 0, + FORMAT = 1, + SERVFAIL= 2, + NAMEERR = 3, + NOTIMPL = 4, + REFUSED = 5 +}; #define FLIP_BYTES(u) (((0x00FF & u) << 8) | ((0xFF00 & u) >> 8)) @@ -148,6 +178,7 @@ int qname_to_fqdn( char* _source, int _sourcelen, char* _sink, int _sinklen ); /** * Check a QNAME and get length + * accepts only ASCII alphanumeric characters * returns: length of QNAME including NULL-byte at the end, < 0 on error * */ int qname_check( char* _source, int _sourcelen ); @@ -20,6 +20,8 @@ #include "dns.h" #include "log.h" +#include "zonefile.h" + #define PRINT_ERRNO() {printf("%s:%i %i:%s\n", __FILE__, __LINE__, errno, strerror(errno));} #define UDP_BUFFER_LEN 512 @@ -43,7 +45,10 @@ int main1( int argc, char* argv[] ) { printf("TEST MODE. NOT FUNCTIONAL\n"); - + + printf ("%i\n", string_compare (argv[1], argv[2])); + + return 0; /* //Fuzztest the QNAME checker FILE* urand = fopen ("/dev/urandom", "r"); @@ -185,14 +190,14 @@ int handle_connection ( int _socket, if(msg.question_count > 0) { char out[128]; - qname_to_fqdn( msg.question[0].qname, 100, out, 128); + qname_to_fqdn( (char*) msg.question[0].qname, 100, out, 128); printf("%s %i\n", out, msg.question[0].qtype); } dns_destroy_struct ( &msg ); //Always return NXDOMAIN - struct dns_header head = {msg.header.id,1,OP_Q,0,0,0,0,0,RCODE_NAMEERR,0,0,0,0}; + struct dns_header head = {msg.header.id,1,OP_Q,0,0,0,0,0,NAMEERR,0,0,0,0}; char ret[20]; int retlen = dns_construct_header ( &head, ret, 20 ); sendto (_socket, ret, retlen, 0, (struct sockaddr*) sockaddr_client, sockaddr_client_len); diff --git a/src/zonefile.c b/src/zonefile.c new file mode 100644 index 0000000..3ed47c8 --- /dev/null +++ b/src/zonefile.c @@ -0,0 +1,100 @@ +/* + * zonefile.c + * (c) 2019 Jonas Gunz + * License: MIT + * */ + +#include "zonefile.h" + +int zonefile_parse ( char* _filename, struct record_node* _dns_zone ) +{ + return 1; +} + +int zonefile_query ( char* _hostname, struct record_entry* _entry ) +{ + return 1; +} + +static int tree_insert ( struct record_node* _root, struct record_entry* _node ) +{ + struct record_node* node = _root; + + while(node) { + int ret = string_compare ( node->rr->name, _node->name ); + if ( ret > 0 ) { + node = node->above; + } else if ( ret < 0 ) { + node = node->below; + } else { //Already exists + return 1; + } + } + + node = malloc (sizeof(*node)); + if(!node) + return 1; + + node->rr = _node; + + return 0; +} + +static int tree_balance ( struct record_node* _root ) +{ + return 1; +} + +static struct record_entry* tree_get ( struct record_node* _root, char* _query ) +{ + struct record_node* node = _root; + + while(node) { + int ret = string_compare ( node->rr->name, _query ); + if ( ret > 0 ) { + node = node->above; + } else if ( ret < 0 ) { + node = node->below; + } else { + break; + } + } + + return node ? node->rr : NULL; + + return 0; +} + +static int tree_destroy ( struct record_node* _root ) +{ + return 1; +} + +int string_compare ( char* _1, char* _2 ) +{ + if ( !_1 || !_2 ) + return 99; + int i; + for (i = 0; _1[i] && _2[i]; i++) { + char c1 = _1[i]; + char c2 = _2[i]; + + //Convert to uppercase + if ( c1 >= 97 && c1 <= 122 ) + c1 -= 32; + if ( c2 >= 97 && c2 <= 122 ) + c2 -= 32; + + if (c1 > c2) + return 1; + if (c1 < c2) + return -1; + } + + if ( _1[i] == _2[i] ) + return 0; + if ( _1[i] ) + return 1; + if ( _2[i] ) + return -1; +} diff --git a/src/zonefile.h b/src/zonefile.h new file mode 100644 index 0000000..94a0de7 --- /dev/null +++ b/src/zonefile.h @@ -0,0 +1,47 @@ +/* + * zonefile.h + * (c) 2019 Jonas Gunz + * License: MIT + * */ + +#pragma once + +#include <stdint.h> +#include <stdlib.h> + +struct record_entry { + char* name; + uint32_t ttl; + uint16_t class; + uint16_t type; + uint16_t rdlength; + char* rd; +}; + +struct record_node { + struct record_entry* rr; + struct record_node* below; + struct record_node* above; +}; + +/** + * */ +int zonefile_parse ( char* _filename, struct record_node* _dns_zone ); + +int zonefile_query ( char* _hostname, struct record_entry* _entry ); + +static int tree_insert ( struct record_node* _root, struct record_entry* _node ); + +static int tree_balance ( struct record_node* _root ); + +static struct record_entry* tree_get ( struct record_node* _root, char* _query ); + +static int tree_destroy ( struct record_node* _root ); + +/** + * returns: + * 0 :: _1 == _2 + * -1 :: _1 < _2 + * +1 :: _1 > _2 + * */ +int string_compare ( char* _1, char* _2 ); |