aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Jonas Gunz <himself@jonasgunz.de> 2021-02-28 23:23:54 +0100
committerGravatar Jonas Gunz <himself@jonasgunz.de> 2021-02-28 23:23:54 +0100
commit233f169f507e31472b23a64269878557d6f0f9fe (patch)
tree666e3a2920a4936097f970c89819909e69ad5db6 /src
parent3cac8f89459317626d521904d85fcb8267671c78 (diff)
downloaddns-233f169f507e31472b23a64269878557d6f0f9fe.tar.gz
construct answer/question
Diffstat (limited to 'src')
-rw-r--r--src/dns.c74
-rw-r--r--src/dns.h34
-rw-r--r--src/main.c6
-rw-r--r--src/server.c24
-rw-r--r--src/server.h8
5 files changed, 130 insertions, 16 deletions
diff --git a/src/dns.c b/src/dns.c
index 2bf6add..01fe7fa 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -5,7 +5,7 @@
#include "dns.h"
-int dns_construct_header ( struct dns_header* _header, char* _buffer, int _bufflen )
+int dns_construct_header ( char* _buffer, int _bufflen, struct dns_header* _header )
{
if ( !_buffer || !_header || _bufflen < 12 )
return -1;
@@ -29,6 +29,72 @@ int dns_construct_header ( struct dns_header* _header, char* _buffer, int _buffl
return 12;
}
+int dns_construct_answer (
+ char* _buffer,
+ int _bufflen,
+ struct dns_answer* _answer
+ ) {
+ int ret = 0;
+
+ if ( !_buffer || _bufflen <= 0 || !_answer )
+ return -1;
+
+ // Check buffer size
+ if ( _answer->qname_len + _answer->rdlength + 10 > _bufflen )
+ return -1;
+
+ memcpy( _buffer, _answer->qname, _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);
+ ret += 10;
+
+ memcpy( _buffer + ret, _answer->rdata, _answer->rdlength );
+ ret += _answer->rdlength;
+
+ return ret;
+}
+
+int dns_construct_questoin (
+ char* _buffer,
+ int _bufflen,
+ struct dns_question* _question
+ ) {
+ //TODO Test
+ int ret = 0;
+
+ if ( !_buffer || _bufflen <= 0 || !_question )
+ return -1;
+
+ // Check buffer size
+ if ( _question->qname_len + 4 > _bufflen )
+ return -1;
+
+ memcpy( _buffer, _question->qname, _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);
+ ret += 4;
+
+ return ret;
+}
+
+
+// Question and answer count come from header
+int dns_construct_packet (
+ char* _buffer,
+ int _bufflen,
+ struct dns_message* _message
+ ) {
+ return -1;
+}
+
+
int dns_destroy_struct ( struct dns_message* _msg )
{
if ( !_msg )
@@ -77,7 +143,8 @@ int dns_parse_packet ( char* _buffer, int _bufflen, struct dns_message* _msg )
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
if( _msg->header.question_count > 4 ||
_msg->header.answer_count > 32 ||
@@ -97,6 +164,8 @@ int dns_parse_packet ( char* _buffer, int _bufflen, struct dns_message* _msg )
return 1;
int ptr = 12; //byte counter
+
+ // TODO refactor
for (int i = 0; i < _msg->question_count; i++) {
int qname_len = qname_check ( (_buffer + ptr), _bufflen - ptr);
@@ -104,6 +173,7 @@ int dns_parse_packet ( char* _buffer, int _bufflen, struct dns_message* _msg )
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
diff --git a/src/dns.h b/src/dns.h
index 73cf9c3..c44fb29 100644
--- a/src/dns.h
+++ b/src/dns.h
@@ -91,8 +91,9 @@ struct dns_answer;
/**
* DNS Message struct
*
- * A initialized instance is only valid as long as
- * the buffer used to create it remains unchanged
+ * An initialized instance is only valid as long as
+ * the buffer used to create it remains unchanged as
+ * some values are referenced, not copied.
* */
struct dns_message;
@@ -116,12 +117,16 @@ struct dns_header {
struct dns_question {
const char* qname;
+ int qname_len;
+
uint16_t qtype;
uint16_t qclass;
};
struct dns_answer {
- char* name; //in qname format
+ char* qname; //in qname format
+ int qname_len;
+
uint16_t type;
uint16_t class;
uint32_t ttl;
@@ -140,9 +145,28 @@ struct dns_message {
};
int dns_construct_header (
- struct dns_header* _header,
char* _buffer,
- int _bufflen
+ int _bufflen,
+ struct dns_header* _header
+ );
+
+int dns_construct_answer (
+ char* _buffer,
+ int _bufflen,
+ struct dns_answer* _answer
+ );
+
+int dns_construct_questoin (
+ char* _buffer,
+ int _bufflen,
+ struct dns_question* _question
+ );
+
+// Question and answer count come from header
+int dns_construct_packet (
+ char* _buffer,
+ int _bufflen,
+ struct dns_message* _message
);
/**
diff --git a/src/main.c b/src/main.c
index 848f04e..36a37c6 100644
--- a/src/main.c
+++ b/src/main.c
@@ -20,7 +20,11 @@ int main(int argc, char* argv[])
#ifdef _TEST
run_test();
#else
- run_dns_server();
+ server_config_t config;
+ config.bind_ip = "0.0.0.0";
+ config.bind_port = 53;
+
+ run_dns_server( &config );
#endif
}
diff --git a/src/server.c b/src/server.c
index 1b28b14..3ec6603 100644
--- a/src/server.c
+++ b/src/server.c
@@ -5,7 +5,7 @@
#include "server.h"
-void run_dns_server ( void )
+void run_dns_server ( server_config_t* _config )
{
int ret;
struct sockaddr_in sock_server_addr;
@@ -21,6 +21,8 @@ void run_dns_server ( void )
log_init_stdout ( _LOG_DEBUG );
+ LOGPRINTF(_LOG_NOTE, "Initializing DNS Server on %s:%i", _config->bind_ip, _config->bind_port);
+
sock_server = socket ( AF_INET, SOCK_DGRAM, 0 );
if ( sock_server == -1 ) {
LOGPRINTF(_LOG_ERROR, "socket() failed");
@@ -29,8 +31,8 @@ void run_dns_server ( void )
memset( &sock_server_addr, '\0', sizeof(struct sockaddr_in) );
sock_server_addr.sin_family = AF_INET;
- sock_server_addr.sin_port = htons( 53 );
- ret = inet_aton ( "0.0.0.0", & sock_server_addr.sin_addr );
+ sock_server_addr.sin_port = htons( _config->bind_port );
+ ret = inet_aton ( _config->bind_ip, & sock_server_addr.sin_addr );
if( ret == 0 ) { //Error on 0, no errno!
LOGPRINTF(_LOG_NOTE, "inet_aton(): Invalid bind IP\n" );
exit ( 1 );
@@ -44,6 +46,8 @@ void run_dns_server ( void )
exit ( errno );
}
+ LOGPRINTF(_LOG_NOTE, "Done!");
+
while( 1 )
{
struct sockaddr_in sock_client_addr;
@@ -95,10 +99,16 @@ int handle_connection ( int _socket,
}
//Always return NXDOMAIN
- 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);
+
+ struct dns_question quest = & msg.question[0];
+
+ struct dns_header head = {msg.header.id,1,OP_Q,0,0,0,0,0,dns_responsecode.NOERR,0,0,0,0};
+ struct dns_answer answ = {quest->qname, quest->qname_len, }
+
+ char ret[512];
+ int hlen = dns_construct_header ( ret, 512, &head );
+ int alen = dns_construct_answer ( ret + hlen, 512-hlen, &answer );
+ sendto (_socket, ret, hlen + alen, 0, (struct sockaddr*) sockaddr_client, sockaddr_client_len);
dns_destroy_struct ( &msg );
diff --git a/src/server.h b/src/server.h
index 388dbae..d59eba6 100644
--- a/src/server.h
+++ b/src/server.h
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -24,9 +25,14 @@
#define UDP_BUFFER_LEN 512
+typedef struct server_config {
+ char* bind_ip;
+ uint16_t bind_port;
+} server_config_t;
+
static int sock_server;
-void run_dns_server ( void );
+void run_dns_server ( server_config_t* _config );
int handle_connection ( int _socket,
struct sockaddr_in *sockaddr_client,