wrapper/src/packet/packet.c

172 lines
4.6 KiB
C
Raw Normal View History

2023-04-06 03:08:09 +00:00
#include "packet.h"
#include "buffer.h"
#include "header.h"
#include "question.h"
#include "record.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
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++) {
read_question(buffer, &packet->questions[i]);
}
packet->answers = malloc(sizeof(Record) * packet->header.answers);
for(uint16_t i = 0; i < packet->header.answers; i++) {
read_record(buffer, &packet->answers[i]);
}
packet->authorities = malloc(sizeof(Record) * packet->header.authoritative_entries);
for(uint16_t i = 0; i < packet->header.authoritative_entries; i++) {
read_record(buffer, &packet->authorities[i]);
}
packet->resources = malloc(sizeof(Record) * packet->header.resource_entries);
for(uint16_t i = 0; i < packet->header.resource_entries; i++) {
read_record(buffer, &packet->resources[i]);
}
}
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
}