cmd, ar, aaaar records
This commit is contained in:
parent
b22811eca2
commit
6191e2df9b
8 changed files with 207 additions and 71 deletions
2
Makefile
2
Makefile
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -42,4 +42,4 @@ void logmsg(LogLevel level, const char* msg, ...)
|
|||
#define WARN(msg, ...)
|
||||
#define ERROR(msg, ...)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -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],
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ static void* server_listen(void* arg) {
|
|||
pthread_detach(thread);
|
||||
}
|
||||
|
||||
pthread_detach(pthread_self());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue