aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jonas Gunz <himself@jonasgunz.de> 2019-11-30 16:05:41 +0100
committerGravatar Jonas Gunz <himself@jonasgunz.de> 2019-11-30 16:05:41 +0100
commitd2c641eb5b516783adfe2a236bc18412cd89af71 (patch)
tree17b9ebf08a749991bab83abd4771d05188b33049
parent3efdb35480dd6fa656d0728cab5c8dc76eaba24c (diff)
downloaddns-d2c641eb5b516783adfe2a236bc18412cd89af71.tar.gz
asdf
-rw-r--r--Makefile6
-rw-r--r--src/dns.c31
-rw-r--r--src/dns.h63
-rw-r--r--src/main.c92
4 files changed, 150 insertions, 42 deletions
diff --git a/Makefile b/Makefile
index 13462bc..8b56258 100644
--- a/Makefile
+++ b/Makefile
@@ -30,8 +30,12 @@ $(OBJECTDIR)/%.o: $(SOURCEDIR)/%.c
@echo [CC] $<
@$(CC) $(CFLAGS) -c $< -o $@
-.PHONY: clean
+#sudo setcap 'cap_net_bind_service=+ep' /path/to/prog
+#to allow port access
+run: build
+ $(BUILDDIR)/$(OUTPUT)
+.PHONY: clean
clean:
@echo [RM] $(OBJ)
@echo [RM] $(BUILDDIR)/$(OUTPUT)
diff --git a/src/dns.c b/src/dns.c
index 7c94c8a..2d3ac75 100644
--- a/src/dns.c
+++ b/src/dns.c
@@ -1,5 +1,36 @@
#include "dns.h"
+int dns_parse_packet ( char* _buffer, int _bufflen, struct dns_message* _msg )
+{
+ if ( !_buffer || !_bufflen || !_msg )
+ return 1; //Invalid input
+
+ if ( _bufflen < 12 )
+ return 1; //Too short to contain a DNS header
+
+ //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;
+ _msg->header.AA = (0x04 & *( (uint8_t*) (_buffer + 2))) >> 2;
+ _msg->header.TC = (0x02 & *( (uint8_t*) (_buffer + 2))) >> 1;
+ _msg->header.RD = (0x01 & *( (uint8_t*) (_buffer + 2)));
+ _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->header.question_count = (*((uint8_t*) (_buffer + 4)) << 8) | *((uint8_t*) (_buffer + 5));
+ _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));
+
+ 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);
+
+ return 1;
+}
+
int fqdn_to_qname( char* _source, int _sourcelen, char* _sink ,int _sinklen )
{
int i;
diff --git a/src/dns.h b/src/dns.h
index 5d8096e..8cba804 100644
--- a/src/dns.h
+++ b/src/dns.h
@@ -2,6 +2,69 @@
#include <stdint.h>
+//TODO remove
+#include <stdio.h>
+
+struct dns_header;
+
+struct dns_question;
+
+struct dns_answer;
+
+/**
+ * DNS Message struct
+ * */
+struct dns_message;
+
+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
+
+ uint16_t question_count;
+ uint16_t answer_count;
+ uint16_t authorative_count;
+ uint16_t additional_count;
+};
+
+struct dns_question {
+ char* qname;
+ uint16_t qtype;
+ uint16_t qclass;
+};
+
+struct dns_answer {
+ char* name; //in qname format
+ uint16_t type;
+ uint16_t class;
+ uint32_t ttl;
+ uint16_t rdlength;
+ char* rdata;
+};
+
+struct dns_message {
+ struct dns_header header;
+
+ int qcount;
+ struct dns_question* question;
+
+ int acount;
+ struct dns_answer* answer;
+};
+
+/**
+ * Parse the packet in _buffer and populate the dns_message struct
+ * returns: 0 on success, !=0 on failure
+ * */
+int dns_parse_packet ( char* _buffer, int _bufflen, struct dns_message* _msg );
+
/**
* Convert a null terminated string containing a
* fqdn (eg server.example.com) to the binary format used by DNS records
diff --git a/src/main.c b/src/main.c
index 9d3e214..92ca391 100644
--- a/src/main.c
+++ b/src/main.c
@@ -19,39 +19,21 @@
#define UDP_BUFFER_LEN 512
-struct dns_message {
- //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 RCODE; //Response Code
-
- uint16_t question_count;
- uint16_t answer_count;
- uint16_t authorative_count;
- uint16_t additional_count;
-
- //Question
- //Answer
- };
-
+//main server socket
int sock_server;
-int dns_parse_packet ( int _socket,
+int handle_connection ( int _socket,
struct sockaddr_in *sockaddr_client,
socklen_t sockaddr_client_len,
- char* buffer,
- int bufflen );
+ char* _buffer,
+ int _bufflen );
void signal_term ( );
void signal_term_child ( );
+void signal_child ( );
+
int test_main( int argc,
char* argv[] )
{
@@ -60,7 +42,7 @@ int test_main( int argc,
char in[128];
char out[128];
- strncpy ( in, "aaa.aaaaa.aa\0", 127);
+ strncpy ( in, "sub.domain.example.com\0", 127);
printf("%s\n", in);
@@ -74,6 +56,15 @@ int test_main( int argc,
for(int i = 0; i < written; i++)
printf(" %x ", out[i]);
+ written = qname_to_fqdn (out,128,in,128);
+
+ if (written < 0) {
+ printf("invalid qname\n");
+ return 1;
+ }
+
+ printf("%s\n", in);
+
printf("\n\n");
return 0;
}
@@ -89,11 +80,14 @@ int main( int argc,
signal ( SIGTERM, signal_term );
signal ( SIGINT, signal_term );
+ //Avoid zombie processes
+ signal (SIGCHLD, SIG_IGN);
+
log_init_stdout ( _LOG_DEBUG );
sock_server = socket ( AF_INET, SOCK_DGRAM, 0 );
if ( sock_server == -1 ) {
- PRINT_ERRNO();
+ LOGPRINTF(_LOG_ERROR, "socket() failed");
return errno;
}
@@ -102,7 +96,7 @@ int main( int argc,
sock_server_addr.sin_port = htons( 53 );
ret = inet_aton ( "0.0.0.0", & sock_server_addr.sin_addr );
if( ret == 0 ) { //Error on 0, no errno!
- LOGPRINTF(_LOG_NOTE, "inet_aton(): Invalid IP\n" );
+ LOGPRINTF(_LOG_NOTE, "inet_aton(): Invalid bind IP\n" );
return 1;
}
@@ -110,7 +104,7 @@ int main( int argc,
(struct sockaddr*) &sock_server_addr,
sizeof(struct sockaddr_in) );
if ( ret == -1 ) {
- PRINT_ERRNO();
+ LOGPRINTF(_LOG_ERROR, "bind() failed");
return errno;
}
@@ -118,6 +112,7 @@ int main( int argc,
{
struct sockaddr_in sock_client_addr;
socklen_t sock_client_addr_len;
+ pid_t pid;
sock_client_addr_len = sizeof ( struct sockaddr_in );
memset ( &sock_client_addr, '\0', sock_client_addr_len );
@@ -133,18 +128,18 @@ int main( int argc,
return errno;
}
- LOGPRINTF(_LOG_NOTE, "Connection");
+ LOGPRINTF(_LOG_DEBUG, "UDP Packet size %i", ret);
- if ( dns_parse_packet ( sock_server,
+ if ( (pid = handle_connection (sock_server,
&sock_client_addr,
sock_client_addr_len,
recv_buffer,
- ret ) ) {
- LOGPRINTF(_LOG_ERROR, "dns_parse_packet()");
+ ret ) ) ) {
+ LOGPRINTF(_LOG_ERROR, "handle_connection() failed");
return errno;
}
else {
- LOGPRINTF ( _LOG_DEBUG, "forked\n" );
+ LOGPRINTF ( _LOG_DEBUG, "forked " );
}
}
@@ -153,11 +148,11 @@ int main( int argc,
return 0;
}
-int dns_parse_packet ( int _socket,
+int handle_connection ( int _socket,
struct sockaddr_in *sockaddr_client,
socklen_t sockaddr_client_len,
- char* buffer,
- int bufflen )
+ char* _buffer,
+ int _bufflen )
{
pid_t pid = fork();
@@ -165,13 +160,27 @@ int dns_parse_packet ( int _socket,
return 0;
else if ( pid < 0 )
return errno;
+
+ //Change signal handler. signal_term shuts down entire socket on TERM
+ signal ( SIGTERM, signal_term_child );
- signal ( SIGTERM, signal_term_child);
+ //echo request
+ sendto (_socket, _buffer, _bufflen, 0, (struct sockaddr*) sockaddr_client, sockaddr_client_len);
- struct dns_message msg;
+ //Testing recieved question
+ //TODO remove
+ char out[128];
+ qname_to_fqdn((_buffer+12), _bufflen-12, out, 128);
+ printf("%s\n", out);
- msg.id = *( (uint16_t*) buffer );
- msg.QR = 0x80 & *( (uint8_t*) (buffer + 2));
+
+ struct dns_message msg;
+
+ if (dns_parse_packet (_buffer, _bufflen, &msg) ) {
+ LOGPRINTF (_LOG_DEBUG, "Malformed packet recieved. parsing failed");
+ close ( _socket );
+ exit( 1 );
+ }
exit ( 0 );
}
@@ -179,7 +188,8 @@ int dns_parse_packet ( int _socket,
void signal_term ( ) {
printf( "Recieved Signal. Terminating active connections and closing socket\n" );
- kill ( 0, SIGTERM ); //terminate all child processes
+ //terminate all children >:)
+ kill ( 0, SIGTERM );
shutdown ( sock_server, SHUT_RDWR );
close ( sock_server );