aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jonas Gunz <himself@jonasgunz.de> 2019-12-20 13:50:42 +0100
committerGravatar Jonas Gunz <himself@jonasgunz.de> 2019-12-20 13:50:42 +0100
commit9dc2a544f88ddedea24d16f05170cb90858c3e9a (patch)
tree08b296c874aaa9780527a27ef9985f15ecc2e2ac
parent5124da870f85b23ea8e46d48a9cccc38df6323fb (diff)
downloaddns-9dc2a544f88ddedea24d16f05170cb90858c3e9a.tar.gz
started rousource record storeage and query
-rw-r--r--src/dns.c4
-rw-r--r--src/dns.h31
-rw-r--r--src/main.c11
-rw-r--r--src/zonefile.c100
-rw-r--r--src/zonefile.h47
5 files changed, 189 insertions, 4 deletions
diff --git a/src/dns.c b/src/dns.c
index b8e4d22..1716b45 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -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;
}
}
diff --git a/src/dns.h b/src/dns.h
index fe871e0..fa9d81f 100644
--- a/src/dns.h
+++ b/src/dns.h
@@ -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 );
diff --git a/src/main.c b/src/main.c
index 75574a0..ff07c48 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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 );