2023-04-11 13:27:16 +00:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2023-04-06 03:08:09 +00:00
|
|
|
#include "packet.h"
|
|
|
|
#include "buffer.h"
|
|
|
|
#include "header.h"
|
|
|
|
#include "question.h"
|
|
|
|
#include "record.h"
|
2023-04-12 18:24:39 +00:00
|
|
|
#include "../io/log.h"
|
2023-04-06 03:08:09 +00:00
|
|
|
|
|
|
|
void read_packet(PacketBuffer* buffer, Packet* packet) {
|
|
|
|
read_header(buffer, &packet->header);
|
|
|
|
|
|
|
|
packet->questions = malloc(sizeof(Question) * packet->header.questions);
|
|
|
|
for(uint16_t i = 0; i < packet->header.questions; i++) {
|
2023-04-11 13:27:16 +00:00
|
|
|
if (!read_question(buffer, &packet->questions[i])) {
|
|
|
|
i--;
|
|
|
|
packet->header.questions--;
|
|
|
|
}
|
2023-04-06 03:08:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
packet->answers = malloc(sizeof(Record) * packet->header.answers);
|
|
|
|
for(uint16_t i = 0; i < packet->header.answers; i++) {
|
2023-04-11 13:27:16 +00:00
|
|
|
if (!read_record(buffer, &packet->answers[i])) {
|
|
|
|
i--;
|
|
|
|
packet->header.answers--;
|
|
|
|
}
|
2023-04-06 03:08:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
packet->authorities = malloc(sizeof(Record) * packet->header.authoritative_entries);
|
|
|
|
for(uint16_t i = 0; i < packet->header.authoritative_entries; i++) {
|
2023-04-11 13:27:16 +00:00
|
|
|
if (!read_record(buffer, &packet->authorities[i])) {
|
|
|
|
i--;
|
|
|
|
packet->header.authoritative_entries--;
|
|
|
|
}
|
2023-04-06 03:08:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
packet->resources = malloc(sizeof(Record) * packet->header.resource_entries);
|
|
|
|
for(uint16_t i = 0; i < packet->header.resource_entries; i++) {
|
2023-04-11 13:27:16 +00:00
|
|
|
if (!read_record(buffer, &packet->resources[i])) {
|
|
|
|
i--;
|
|
|
|
packet->header.resource_entries--;
|
|
|
|
}
|
2023-04-06 03:08:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void write_packet(PacketBuffer* buffer, Packet* packet) {
|
|
|
|
write_header(buffer, &packet->header);
|
|
|
|
|
|
|
|
for(uint16_t i = 0; i < packet->header.questions; i++) {
|
|
|
|
write_question(buffer, &packet->questions[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(uint16_t i = 0; i < packet->header.answers; i++) {
|
|
|
|
write_record(buffer, &packet->answers[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(uint16_t i = 0; i < packet->header.authoritative_entries; i++) {
|
|
|
|
write_record(buffer, &packet->authorities[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(uint16_t i = 0; i < packet->header.resource_entries; i++) {
|
|
|
|
write_record(buffer, &packet->resources[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void free_packet(Packet* packet) {
|
|
|
|
|
|
|
|
for(uint16_t i = 0; i < packet->header.questions; i++) {
|
|
|
|
free_question(&packet->questions[i]);
|
|
|
|
}
|
|
|
|
free(packet->questions);
|
|
|
|
|
|
|
|
for(uint16_t i = 0; i < packet->header.answers; i++) {
|
|
|
|
free_record(&packet->answers[i]);
|
|
|
|
}
|
|
|
|
free(packet->answers);
|
|
|
|
|
|
|
|
for(uint16_t i = 0; i < packet->header.authoritative_entries; i++) {
|
|
|
|
free_record(&packet->authorities[i]);
|
|
|
|
}
|
|
|
|
free(packet->authorities);
|
|
|
|
|
|
|
|
for(uint16_t i = 0; i < packet->header.resource_entries; i++) {
|
|
|
|
free_record(&packet->resources[i]);
|
|
|
|
}
|
|
|
|
free(packet->resources);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool get_random_a(Packet* packet, IpAddr* addr) {
|
|
|
|
for (uint16_t i = 0; i < packet->header.answers; i++) {
|
|
|
|
Record record = packet->answers[i];
|
|
|
|
if (record.type == A) {
|
2023-04-08 19:58:03 +00:00
|
|
|
create_ip_addr(record.data.a.addr, addr);
|
2023-04-06 03:08:09 +00:00
|
|
|
return true;
|
|
|
|
} else if (record.type == AAAA) {
|
2023-04-08 19:58:03 +00:00
|
|
|
create_ip_addr6(record.data.aaaa.addr, addr);
|
2023-04-06 03:08:09 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool ends_with(uint8_t* full, uint8_t* end) {
|
|
|
|
uint8_t check = end[0];
|
|
|
|
uint8_t len = full[0];
|
|
|
|
|
|
|
|
if (check > len) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(uint8_t i = 0; i < check; i++) {
|
|
|
|
if (end[check - 1 - i] != full[len - 1 - i]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool equals(uint8_t* a, uint8_t* b) {
|
|
|
|
if (a[0] != b[0]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(uint8_t i = 1; i < a[0] + 1; i++) {
|
|
|
|
if(a[i] != b[i]) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool get_resolved_ns(Packet* packet, uint8_t* qname, IpAddr* addr) {
|
|
|
|
for (uint16_t i = 0; i < packet->header.authoritative_entries; i++) {
|
|
|
|
Record record = packet->authorities[i];
|
|
|
|
if (record.type != NS) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!ends_with(qname, record.domain)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (uint16_t i = 0; i < packet->header.resource_entries; i++) {
|
|
|
|
Record resource = packet->resources[i];
|
|
|
|
if (!equals(record.data.ns.host, resource.domain)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (resource.type == A) {
|
2023-04-08 19:58:03 +00:00
|
|
|
create_ip_addr(record.data.a.addr, addr);
|
2023-04-06 03:08:09 +00:00
|
|
|
return true;
|
|
|
|
} else if (resource.type == AAAA) {
|
2023-04-08 19:58:03 +00:00
|
|
|
create_ip_addr6(record.data.aaaa.addr, addr);
|
2023-04-06 03:08:09 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool get_unresoled_ns(Packet* packet, uint8_t* qname, Question* question) {
|
|
|
|
for (uint16_t i = 0; i < packet->header.authoritative_entries; i++) {
|
|
|
|
Record record = packet->authorities[i];
|
|
|
|
if (record.type != NS) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!ends_with(qname, record.domain)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t* host = record.data.ns.host;
|
|
|
|
|
|
|
|
question->qtype = NS;
|
|
|
|
question->domain = malloc(host[0] + 1);
|
|
|
|
memcpy(question->domain, host, host[0] + 1);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
2023-04-08 19:58:03 +00:00
|
|
|
}
|