cmd, ar, aaaar records

This commit is contained in:
Murphy 2023-04-11 13:44:16 -04:00
parent b22811eca2
commit 6191e2df9b
8 changed files with 207 additions and 71 deletions

View file

@ -2,7 +2,7 @@ CC = gcc
INCFLAGS = -Isrc
CCFLAGS = -std=c17 -Wall -Wextra -O2
CCFLAGS = -std=gnu99 -Wall -Wextra -pedantic -O2
CCFLAGS += $(INCFLAGS)
LDFLAGS += $(INCFLAGS)

View file

@ -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;
}

View file

@ -42,4 +42,4 @@ void logmsg(LogLevel level, const char* msg, ...)
#define WARN(msg, ...)
#define ERROR(msg, ...)
#endif
#endif

View file

@ -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],

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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;
}

View file

@ -94,6 +94,7 @@ static void* server_listen(void* arg) {
pthread_detach(thread);
}
pthread_detach(pthread_self());
return NULL;
}