diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/io/config.c | 41 | ||||
-rw-r--r-- | src/io/log.h | 2 | ||||
-rw-r--r-- | src/packet/question.c | 8 | ||||
-rw-r--r-- | src/packet/record.c | 219 | ||||
-rw-r--r-- | src/packet/record.h | 4 | ||||
-rw-r--r-- | src/server/resolver.c | 1 | ||||
-rw-r--r-- | src/server/server.c | 1 |
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; } |