1
0
mirror of https://code.semirocket.science/wrapsix synced 2024-09-19 23:11:04 +03:00

Synthesing AAAA records from A ones

Leaving all other types of records to be 'just processed'
Running in an infinite loop
This commit is contained in:
Michal Zima 2010-02-04 20:58:01 +01:00
parent 8968ffedb3
commit e7046c4ea3

View File

@ -1,6 +1,6 @@
/* /*
* WrapSix * WrapSix
* Copyright (C) 2008-2009 Michal Zima <xhire@mujmalysvet.cz> * Copyright (C) 2008-2010 Michal Zima <xhire@mujmalysvet.cz>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
@ -46,6 +46,7 @@ struct s_dns_answer {
#define IP "::2" #define IP "::2"
#define RESOLVER "::1" #define RESOLVER "::1"
#define PORT 53 #define PORT 53
#define PREFIX "::"
unsigned short id = 0; unsigned short id = 0;
@ -283,10 +284,18 @@ int main(int argc, char **argv)
struct sockaddr_in6 sock_addr, struct sockaddr_in6 sock_addr,
client_sock_addr; client_sock_addr;
int resolver_sock;
struct sockaddr_in6 resolver_sock_addr;
struct s_dns_header *dns, *dns_answer; struct s_dns_header *dns, *dns_answer;
unsigned short qtype, qclass; unsigned short qtype, qclass;
struct s_dns_answer *answers; struct s_dns_answer *answers;
struct in6_addr ipv6_prefix;
/* initialization */
inet_pton(AF_INET6, PREFIX, &ipv6_prefix);
/* create the socket */ /* create the socket */
if ((sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1) { if ((sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
fprintf(stderr, "[Error] Unable to create UDP socket\n"); fprintf(stderr, "[Error] Unable to create UDP socket\n");
@ -304,69 +313,160 @@ int main(int argc, char **argv)
return 1; return 1;
} }
/* fetch a request */ for (;;) {
udp_receive(&sock, &client_sock_addr, (char *) &buffer, &length); /* fetch a request */
udp_receive(&sock, &client_sock_addr, (char *) &buffer, &length);
/* process the request */ /* process the request */
dns = (struct s_dns_header *) &buffer; dns = (struct s_dns_header *) &buffer;
/* TODO: there could be more than one question */ /* TODO: there could be more than one question */
offset = sizeof(struct s_dns_header); offset = sizeof(struct s_dns_header);
while (buffer[offset] != 0x0) { while (buffer[offset] != 0x0) {
offset += buffer[offset] + 1; offset += buffer[offset] + 1;
} }
memcpy(&qtype, &buffer[offset + 1], 2); memcpy(&qtype, &buffer[offset + 1], 2);
memcpy(&qclass, &buffer[offset + 3], 2); memcpy(&qclass, &buffer[offset + 3], 2);
qtype = htons(qtype); qtype = htons(qtype);
qclass = htons(qclass); qclass = htons(qclass);
/* this is AAAA request */ /* this is AAAA request */
if (qclass == 0x1 && qtype == 0x1c) { if (qclass == 0x1 && qtype == 0x1c) {
answers = NULL; answers = NULL;
/* first look up if some AAAA exists */ /* first look up if some AAAA exists */
if (lookup(0x1c, &buffer[sizeof(struct s_dns_header)], &answers, &answer_count) == 0) { if (lookup(0x1c, &buffer[sizeof(struct s_dns_header)], &answers, &answer_count) == 0) {
/* send back an answer */ /* send back an answer */
dns_answer = (struct s_dns_header *) &buffer_answer; dns_answer = (struct s_dns_header *) &buffer_answer;
dns_answer->id = dns->id; dns_answer->id = dns->id;
dns_answer->flags = htons(0x8180); dns_answer->flags = htons(0x8180);
dns_answer->question = htons(1); dns_answer->question = htons(1);
dns_answer->answer = htons(answer_count); dns_answer->answer = htons(answer_count);
dns_answer->auth = 0; dns_answer->auth = 0;
dns_answer->add = 0; dns_answer->add = 0;
/* copy question section */ /* copy question section */
i = offset - sizeof(struct s_dns_header) + 5; i = offset - sizeof(struct s_dns_header) + 5;
memcpy(&buffer_answer[sizeof(struct s_dns_header)], &buffer[sizeof(struct s_dns_header)], i); memcpy(&buffer_answer[sizeof(struct s_dns_header)], &buffer[sizeof(struct s_dns_header)], i);
/* construct answer section */ /* construct answer section */
i = offset + 5; i = offset + 5;
for (j = 0; j < answer_count; j++) { for (j = 0; j < answer_count; j++) {
/* copy fqdn */ /* copy fqdn */
memcpy(&buffer_answer[i], answers[j].fqdn, answers[j].dnlength); memcpy(&buffer_answer[i], answers[j].fqdn, answers[j].dnlength);
i += answers[j].dnlength; i += answers[j].dnlength;
/* copy type, class and ttl */ /* copy type, class and ttl */
memcpy(&buffer_answer[i], &(answers[j].type), 2 * sizeof(unsigned short) + sizeof(unsigned int)); memcpy(&buffer_answer[i], &(answers[j].type), 2 * sizeof(unsigned short) + sizeof(unsigned int));
i += 2 * sizeof(unsigned short) + sizeof(unsigned int); i += 2 * sizeof(unsigned short) + sizeof(unsigned int);
/* copy rdlength */ /* copy rdlength */
k = htons(answers[j].rdlength); k = htons(answers[j].rdlength);
memcpy(&buffer_answer[i], &k, sizeof(unsigned short)); memcpy(&buffer_answer[i], &k, sizeof(unsigned short));
i += sizeof(unsigned short); i += sizeof(unsigned short);
/* copy rdata */ /* copy rdata */
memcpy(&buffer_answer[i], answers[j].rdata, answers[j].rdlength); memcpy(&buffer_answer[i], answers[j].rdata, answers[j].rdlength);
i += answers[j].rdlength; i += answers[j].rdlength;
/* memory clean-up */
free(answers[j].fqdn);
free(answers[j].rdata);
}
/* send it */
udp_send(&sock, &client_sock_addr, (char *) &buffer_answer, i);
/* memory clean-up */ /* memory clean-up */
free(answers[j].fqdn); free(answers);
free(answers[j].rdata); /* second look up if some A exists & transform it */
} else if (lookup(0x1, &buffer[sizeof(struct s_dns_header)], &answers, &answer_count) == 0) {
/* send back an answer */
dns_answer = (struct s_dns_header *) &buffer_answer;
dns_answer->id = dns->id;
dns_answer->flags = htons(0x8180);
dns_answer->question = htons(1);
dns_answer->answer = htons(answer_count);
dns_answer->auth = 0;
dns_answer->add = 0;
/* copy question section */
i = offset - sizeof(struct s_dns_header) + 5;
memcpy(&buffer_answer[sizeof(struct s_dns_header)], &buffer[sizeof(struct s_dns_header)], i);
/* construct answer section */
i = offset + 5;
for (j = 0; j < answer_count; j++) {
/* copy fqdn */
memcpy(&buffer_answer[i], answers[j].fqdn, answers[j].dnlength);
i += answers[j].dnlength;
/* set type */
k = htons(0x1c);
memcpy(&buffer_answer[i], &k, sizeof(unsigned short));
i += sizeof(unsigned short);
/* copy class and ttl */
memcpy(&buffer_answer[i], &(answers[j].class), sizeof(unsigned short) + sizeof(unsigned int));
i += sizeof(unsigned short) + sizeof(unsigned int);
/* set rdlength */
k = htons(sizeof(ipv6_prefix));
memcpy(&buffer_answer[i], &k, sizeof(unsigned short));
i += sizeof(unsigned short);
/* copy IPv6 prefix */
memcpy(&buffer_answer[i], &ipv6_prefix, sizeof(ipv6_prefix) - answers[j].rdlength);
i += sizeof(ipv6_prefix) - answers[j].rdlength;
/* copy IPv4 address */
memcpy(&buffer_answer[i], answers[j].rdata, answers[j].rdlength);
i += answers[j].rdlength;
/* memory clean-up */
free(answers[j].fqdn);
free(answers[j].rdata);
}
/* send it */
udp_send(&sock, &client_sock_addr, (char *) &buffer_answer, i);
/* memory clean-up */
free(answers);
/* third say we have no clue about the fqdn */
} else {
/* send back an answer */
dns_answer = (struct s_dns_header *) &buffer_answer;
dns_answer->id = dns->id;
dns_answer->flags = htons(0x8183);
dns_answer->question = htons(1);
dns_answer->answer = 0;
dns_answer->auth = 0;
dns_answer->add = 0;
/* copy question section */
i = offset - sizeof(struct s_dns_header) + 5;
memcpy(&buffer_answer[sizeof(struct s_dns_header)], &buffer[sizeof(struct s_dns_header)], i);
i += sizeof(struct s_dns_header);
/* send it */
udp_send(&sock, &client_sock_addr, (char *) &buffer_answer, i);
} }
/* this is other than AAAA request -> just proxy it */
} else {
/* create a connection socket */
resolver_connect(&resolver_sock, &resolver_sock_addr);
/* send it */ /* send the request */
udp_send(&sock, &client_sock_addr, (char *) &buffer_answer, i); udp_send(&resolver_sock, &resolver_sock_addr, (char *) &buffer, length);
/* memory clean-up */ /* fetch the answer */
free(answers); udp_receive(&resolver_sock, &resolver_sock_addr, (char *) &buffer, (int *) &length);
/* close the socket */
close(resolver_sock);
/* forward the answer to the client */
udp_send(&sock, &client_sock_addr, (char *) &buffer, length);
} }
} }