summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/io/config.c41
-rw-r--r--src/io/log.h2
-rw-r--r--src/packet/question.c8
-rw-r--r--src/packet/record.c219
-rw-r--r--src/packet/record.h4
-rw-r--r--src/server/resolver.c1
-rw-r--r--src/server/server.c1
7 files changed, 206 insertions, 70 deletions
diff --git a/src/io/config.c b/src/io/config.c
index be6e5b1..36afbef 100644
--- a/src/io/config.c
+++ b/src/io/config.c
@@ -97,6 +97,15 @@ static bool config_read_qtype(const char* qstr, RecordType* qtype) {
} else if (strcmp(qstr, "CAA") == 0) {
*qtype = CAA;
return true;
+ } else if (strcmp(qstr, "CMD") == 0) {
+ *qtype = CMD;
+ return true;
+ } else if(strcmp(qstr, "AR") == 0) {
+ *qtype = AR;
+ return true;
+ } else if(strcmp(qstr, "AAAAR") == 0) {
+ *qtype = AAAAR;
+ return true;
} else {
return false;
}
@@ -350,7 +359,9 @@ static bool config_read_caa_record(char* data, CAARecord* record) {
}
static bool config_read_cmd_record(char* data, CMDRecord* record) {
- record->command = data;
+ int len = strlen(data);
+ record->command = malloc(len);
+ memcpy(record->command, data, len);
return true;
}
@@ -381,6 +392,10 @@ static bool config_read_record_data(char* data, Record* record) {
return config_read_caa_record(data, &record->data.caa);
case CMD:
return config_read_cmd_record(data, &record->data.cmd);
+ case AR:
+ case AAAAR:
+ memset(&record->data, 0, sizeof(record->data));
+ return true;
}
return false;
}
@@ -395,26 +410,38 @@ static bool config_read_record(FILE* file, Record* record, Question* question) {
return false;
}
- char* words[2];
- if (!get_words(&buf[0], &words[0], 2)) {
+ char* words[4];
+ if (!get_words(&buf[0], &words[0], 4)) {
WARN("Invalid record at line %d", line);
return false;
}
+ uint16_t class;
+ if (!config_read_class(words[0], &class)) {
+ WARN("Invalid question class at line %d", line);
+ return false;
+ }
+
+ RecordType qtype;
+ if (!config_read_qtype(words[1], &qtype)) {
+ WARN("Invalid question qtype at line %d", line);
+ return false;
+ }
+
uint32_t ttl;
- if (!get_int(words[0], &ttl)) {
+ if (!get_int(words[2], &ttl)) {
WARN("Invalid record ttl at line %d", line);
return false;
}
- record->cls = question->cls;
- record->type = question->qtype;
+ record->cls = class;
+ record->type = qtype;
record->len = 0;
record->ttl = ttl;
record->domain = malloc(question->domain[0] + 1);
memcpy(record->domain, question->domain, question->domain[0] + 1);
- if(!config_read_record_data(words[1], record)) {
+ if(!config_read_record_data(words[3], record)) {
free_record(record);
return false;
}
diff --git a/src/io/log.h b/src/io/log.h
index c2fbd90..ecb03d3 100644
--- a/src/io/log.h
+++ b/src/io/log.h
@@ -42,4 +42,4 @@ void logmsg(LogLevel level, const char* msg, ...)
#define WARN(msg, ...)
#define ERROR(msg, ...)
-#endif \ No newline at end of file
+#endif
diff --git a/src/packet/question.c b/src/packet/question.c
index b138121..1c43232 100644
--- a/src/packet/question.c
+++ b/src/packet/question.c
@@ -94,7 +94,13 @@ void print_question(Question* question, char* buffer) {
break;
case CMD:
APPEND(buffer, "CMD ");
- break;
+ break;
+ case AR:
+ APPEND(buffer, "A ");
+ break;
+ case AAAAR:
+ APPEND(buffer, "AAAAR ");
+ break;
}
APPEND(buffer, "%.*s",
question->domain[0],
diff --git a/src/packet/record.c b/src/packet/record.c
index 07a8c62..a21d852 100644
--- a/src/packet/record.c
+++ b/src/packet/record.c
@@ -2,6 +2,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
+
+#undef _POSIX_C_SOURCE
+#include <stdio.h>
#include "record.h"
#include "buffer.h"
@@ -30,7 +34,11 @@ uint16_t record_to_id(RecordType type) {
case CAA:
return 257;
case CMD:
- return 1000;
+ return 16;
+ case AR:
+ return 1;
+ case AAAAR:
+ return 28;
default:
return 0;
}
@@ -233,131 +241,201 @@ bool read_record(PacketBuffer* buffer, Record* record) {
return true;
}
-static void write_a_record(PacketBuffer* buffer, Record* record) {
- ARecord data = record->data.a;
+static void write_a_record(PacketBuffer* buffer, ARecord* data) {
buffer_write_short(buffer, 4);
- buffer_write(buffer, record->data.a.addr[0]);
- buffer_write(buffer, data.addr[1]);
- buffer_write(buffer, data.addr[2]);
- buffer_write(buffer, data.addr[3]);
+ buffer_write(buffer, data->addr[0]);
+ buffer_write(buffer, data->addr[1]);
+ buffer_write(buffer, data->addr[2]);
+ buffer_write(buffer, data->addr[3]);
}
-static void write_ns_record(PacketBuffer* buffer, Record* record) {
- NSRecord data = record->data.ns;
+static void write_ns_record(PacketBuffer* buffer, NSRecord* data) {
int pos = buffer_get_index(buffer);
buffer_write_short(buffer, 0);
- buffer_write_qname(buffer, data.host);
+ buffer_write_qname(buffer, data->host);
int size = buffer_get_index(buffer) - pos - 2;
buffer_set_uint16_t(buffer, (uint16_t)size, pos);
}
-static void write_cname_record(PacketBuffer* buffer, Record* record) {
- CNAMERecord data = record->data.cname;
+static void write_cname_record(PacketBuffer* buffer, CNAMERecord* data) {
int pos = buffer_get_index(buffer);
buffer_write_short(buffer, 0);
- buffer_write_qname(buffer, data.host);
+ buffer_write_qname(buffer, data->host);
int size = buffer_get_index(buffer) - pos - 2;
buffer_set_uint16_t(buffer, (uint16_t)size, pos);
}
-static void write_soa_record(PacketBuffer* buffer, Record* record) {
- SOARecord data = record->data.soa;
+static void write_soa_record(PacketBuffer* buffer, SOARecord* data) {
int pos = buffer_get_index(buffer);
buffer_write_short(buffer, 0);
- buffer_write_qname(buffer, data.mname);
- buffer_write_qname(buffer, data.nname);
- buffer_write_int(buffer, data.serial);
- buffer_write_int(buffer, data.refresh);
- buffer_write_int(buffer, data.retry);
- buffer_write_int(buffer, data.expire);
- buffer_write_int(buffer, data.minimum);
+ buffer_write_qname(buffer, data->mname);
+ buffer_write_qname(buffer, data->nname);
+ buffer_write_int(buffer, data->serial);
+ buffer_write_int(buffer, data->refresh);
+ buffer_write_int(buffer, data->retry);
+ buffer_write_int(buffer, data->expire);
+ buffer_write_int(buffer, data->minimum);
int size = buffer_get_index(buffer) - pos - 2;
buffer_set_uint16_t(buffer, (uint16_t)size, pos);
}
-static void write_ptr_record(PacketBuffer* buffer, Record* record) {
- PTRRecord data = record->data.ptr;
+static void write_ptr_record(PacketBuffer* buffer, PTRRecord* data) {
int pos = buffer_get_index(buffer);
buffer_write_short(buffer, 0);
- buffer_write_qname(buffer, data.pointer);
+ buffer_write_qname(buffer, data->pointer);
int size = buffer_get_index(buffer) - pos - 2;
buffer_set_uint16_t(buffer, (uint16_t)size, pos);
}
-static void write_mx_record(PacketBuffer* buffer, Record* record) {
- MXRecord data = record->data.mx;
+static void write_mx_record(PacketBuffer* buffer, MXRecord* data) {
int pos = buffer_get_index(buffer);
buffer_write_short(buffer, 0);
- buffer_write_short(buffer, data.priority);
- buffer_write_qname(buffer, data.host);
+ buffer_write_short(buffer, data->priority);
+ buffer_write_qname(buffer, data->host);
int size = buffer_get_index(buffer) - pos - 2;
buffer_set_uint16_t(buffer, (uint16_t)size, pos);
}
-static void write_txt_record(PacketBuffer* buffer, Record* record) {
- TXTRecord data = record->data.txt;
+static void write_txt_record(PacketBuffer* buffer, TXTRecord* data) {
int pos = buffer_get_index(buffer);
buffer_write_short(buffer, 0);
- if(data.len == 0) {
+ if(data->len == 0) {
return;
}
- for(uint8_t i = 0; i < data.len; i++) {
- buffer_write_string(buffer, data.text[i]);
+ for(uint8_t i = 0; i < data->len; i++) {
+ buffer_write_string(buffer, data->text[i]);
}
int size = buffer_get_index(buffer) - pos - 2;
buffer_set_uint16_t(buffer, (uint16_t)size, pos);
}
-static void write_aaaa_record(PacketBuffer* buffer, Record* record) {
- AAAARecord data = record->data.aaaa;
-
+static void write_aaaa_record(PacketBuffer* buffer, AAAARecord* data) {
buffer_write_short(buffer, 16);
for (int i = 0; i < 16; i++) {
- buffer_write(buffer, data.addr[i]);
+ buffer_write(buffer, data->addr[i]);
}
}
-static void write_srv_record(PacketBuffer* buffer, Record* record) {
- SRVRecord data = record->data.srv;
+static void write_srv_record(PacketBuffer* buffer, SRVRecord* data) {
int pos = buffer_get_index(buffer);
buffer_write_short(buffer, 0);
- buffer_write_short(buffer, data.priority);
- buffer_write_short(buffer, data.weight);
- buffer_write_short(buffer, data.port);
- buffer_write_qname(buffer, data.target);
+ buffer_write_short(buffer, data->priority);
+ buffer_write_short(buffer, data->weight);
+ buffer_write_short(buffer, data->port);
+ buffer_write_qname(buffer, data->target);
int size = buffer_get_index(buffer) - pos - 2;
buffer_set_uint16_t(buffer, (uint16_t)size, pos);
}
-static void write_caa_record(PacketBuffer* buffer, Record* record) {
- CAARecord data = record->data.caa;
+static void write_caa_record(PacketBuffer* buffer, CAARecord* data) {
int pos = buffer_get_index(buffer);
buffer_write_short(buffer, 0);
- buffer_write(buffer, data.flags);
- buffer_write(buffer, data.length);
- buffer_write_n(buffer, data.tag + 1, data.tag[0]);
- buffer_write_n(buffer, data.value + 1, data.value[0]);
+ buffer_write(buffer, data->flags);
+ buffer_write(buffer, data->length);
+ buffer_write_n(buffer, data->tag + 1, data->tag[0]);
+ buffer_write_n(buffer, data->value + 1, data->value[0]);
int size = buffer_get_index(buffer) - pos - 2;
buffer_set_uint16_t(buffer, (uint16_t)size, pos);
}
+static void write_string(TXTRecord* record, uint8_t* capacity, const char* string, uint8_t len) {
+ if (len < 1) return;
+ if (record->len == *capacity) {
+ *capacity *= 2;
+ record->text = realloc(record->text, sizeof(uint8_t*) * *capacity);
+ }
+ record->text[record->len] = malloc(len + 1);
+ record->text[record->len][0] = len;
+ memcpy(record->text[record->len] + 1, string, len);
+ record->len++;
+}
+
+static void free_text(TXTRecord* record) {
+ for (uint8_t i = 0; i < record->len; i++) {
+ free(record->text[i]);
+ }
+ free(record->text);
+}
+
+static void write_cmd_record(PacketBuffer* buffer, CMDRecord* data) {
+ FILE* output = popen(data->command, "r");
+ TXTRecord res;
+
+ uint8_t capacity = 1;
+ res.len = 0;
+ res.text = malloc(capacity * sizeof(uint8_t*));
+
+ if (output == NULL) {
+ write_string(&res, &capacity, "Failed to execute command", 25);
+ write_txt_record(buffer, &res);
+ free_text(&res);
+ return;
+ }
+
+ char in[255];
+ char c;
+ int i = 0;
+
+ while (1) {
+ if ((c = getc(output)) == EOF) {
+ write_string(&res, &capacity, in, i + 1);
+ break;
+ }
+
+ in[i] = c;
+ i++;
+
+ if (i == 255) {
+ write_string(&res, &capacity, in, i);
+ i = 0;
+ }
+ }
+
+ write_txt_record(buffer, &res);
+ free_text(&res);
+
+ pclose(output);
+}
+
+static void write_ar_record(PacketBuffer* buffer) {
+ srand(time(NULL));
+ ARecord res;
+
+ for (int i = 0; i < 4; i++) {
+ res.addr[i] = (uint8_t) (rand() * 255);
+ }
+
+ write_a_record(buffer, &res);
+}
+
+static void write_aaaar_record(PacketBuffer* buffer) {
+ srand(time(NULL));
+
+ AAAARecord res;
+ for (int i = 0; i < 16; i++) {
+ res.addr[i] = (uint8_t) (rand() * 255);
+ }
+
+ write_aaaa_record(buffer, &res);
+}
+
static void write_record_header(PacketBuffer* buffer, Record* record) {
buffer_write_qname(buffer, record->domain);
uint16_t id = record_to_id(record->type);
@@ -370,43 +448,55 @@ void write_record(PacketBuffer* buffer, Record* record) {
switch(record->type) {
case A:
write_record_header(buffer, record);
- write_a_record(buffer, record);
+ write_a_record(buffer, &record->data.a);
break;
case NS:
write_record_header(buffer, record);
- write_ns_record(buffer, record);
+ write_ns_record(buffer, &record->data.ns);
break;
case CNAME:
write_record_header(buffer, record);
- write_cname_record(buffer, record);
+ write_cname_record(buffer, &record->data.cname);
break;
case SOA:
write_record_header(buffer, record);
- write_soa_record(buffer, record);
+ write_soa_record(buffer, &record->data.soa);
break;
case PTR:
write_record_header(buffer, record);
- write_ptr_record(buffer, record);
+ write_ptr_record(buffer, &record->data.ptr);
break;
case MX:
write_record_header(buffer, record);
- write_mx_record(buffer, record);
+ write_mx_record(buffer, &record->data.mx);
break;
case TXT:
write_record_header(buffer, record);
- write_txt_record(buffer, record);
+ write_txt_record(buffer, &record->data.txt);
break;
case AAAA:
write_record_header(buffer, record);
- write_aaaa_record(buffer, record);
+ write_aaaa_record(buffer, &record->data.aaaa);
break;
case SRV:
write_record_header(buffer, record);
- write_srv_record(buffer, record);
+ write_srv_record(buffer, &record->data.srv);
break;
case CAA:
write_record_header(buffer, record);
- write_caa_record(buffer, record);
+ write_caa_record(buffer, &record->data.caa);
+ break;
+ case CMD:
+ write_record_header(buffer, record);
+ write_cmd_record(buffer, &record->data.cmd);
+ break;
+ case AR:
+ write_record_header(buffer, record);
+ write_ar_record(buffer);
+ break;
+ case AAAAR:
+ write_record_header(buffer, record);
+ write_aaaar_record(buffer);
break;
default:
break;
@@ -449,6 +539,9 @@ void free_record(Record* record) {
free(record->data.caa.value);
free(record->data.caa.tag);
break;
+ case CMD:
+ free(record->data.cmd.command);
+ break;
default:
break;
}
@@ -549,5 +642,11 @@ void print_record(Record* record, char* buffer) {
record->data.cmd.command
);
break;
+ case AR:
+ APPEND(buffer, "AR");
+ break;
+ case AAAAR:
+ APPEND(buffer, "AAAAR");
+ break;
}
}
diff --git a/src/packet/record.h b/src/packet/record.h
index 6afd078..635497d 100644
--- a/src/packet/record.h
+++ b/src/packet/record.h
@@ -17,7 +17,9 @@ typedef enum {
AAAA, // 28
SRV, // 33
CAA, // 257
- CMD // 1000
+ CMD, // 1000
+ AR, // 1001
+ AAAAR // 1002
} RecordType;
uint16_t record_to_id(RecordType type);
diff --git a/src/server/resolver.c b/src/server/resolver.c
index a1fa82a..c9e5246 100644
--- a/src/server/resolver.c
+++ b/src/server/resolver.c
@@ -54,6 +54,7 @@ static bool search(Question* question, Packet* result, BindingType type, const R
while(1) {
if (record_map_get(map, question, result)) {
+ TRACE("Found answer in user defined config");
return true;
}
diff --git a/src/server/server.c b/src/server/server.c
index f96fac0..bcb070d 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -94,6 +94,7 @@ static void* server_listen(void* arg) {
pthread_detach(thread);
}
+ pthread_detach(pthread_self());
return NULL;
}