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,6 +313,7 @@ int main(int argc, char **argv)
return 1; return 1;
} }
for (;;) {
/* fetch a request */ /* fetch a request */
udp_receive(&sock, &client_sock_addr, (char *) &buffer, &length); udp_receive(&sock, &client_sock_addr, (char *) &buffer, &length);
@ -367,6 +377,96 @@ int main(int argc, char **argv)
/* memory clean-up */ /* memory clean-up */
free(answers); free(answers);
/* 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 the request */
udp_send(&resolver_sock, &resolver_sock_addr, (char *) &buffer, length);
/* fetch the answer */
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);
} }
} }