tags 567096 + patch
thanks
I created a patch for this issue and verified that it does answer NS
request in a manner dig can understand. Unfortunately I was not able to
test it in a real use case yet.
Helmut
diff --git a/common/includes/dns.h b/common/includes/dns.h
index 435c57f..eebc4f4 100644
--- a/common/includes/dns.h
+++ b/common/includes/dns.h
@@ -128,6 +128,7 @@ struct req_hdr {
struct rr_hdr {
uint16_t type;
+#define TYPE_NS 2
#define TYPE_TXT 16
#define TYPE_KEY 25
uint16_t klass;
diff --git a/server/requests.c b/server/requests.c
index 45570d5..86a3ecf 100644
--- a/server/requests.c
+++ b/server/requests.c
@@ -167,6 +167,72 @@ static int get_ressources(t_conf *conf,void *req,
return (0);
}
+static int answer_ns(t_conf *conf,void *req,
+ int in_len, struct sockaddr_in *sa)
+{
+ int out_len = -1;
+ struct dns_hdr *hdr;
+ struct rr_hdr *rr;
+ char *data;
+ int token_length;
+ const char *mydata;
+
+ hdr = req;
+ hdr->ra = 1; /* ???? */
+ hdr->qr = 1; /* response */
+ PUT_16(&hdr->ancount, 1); /* one answer */
+ data = JUMP_DNS_HDR(req);
+ mydata = conf->my_domain;
+ /* data should point to our name */
+ while(*data)
+ {
+ token_length = *(unsigned char*)data;
+ ++data;
+ if(strlen(mydata) < token_length)
+ return (-1);
+ if(memcmp(data, mydata, token_length))
+ return (-1);
+ data += token_length;
+ mydata += token_length;
+ if(*mydata == '.')
+ ++mydata;
+ }
+ if(*mydata)
+ return (-1);
+ ++data;
+ /* followed by query type TYPE_NS */
+ if(GET_16(data) != TYPE_NS)
+ return (-1);
+ data += 2;
+ /* followed by class IN */
+ if(GET_16(data) != CLASS_IN)
+ return (-1);
+ data += 2;
+ if(((void*)data - req) + 12 + strlen(conf->my_ip) + 2 >= MAX_REQ_LEN)
+ return (-1);
+ /* name: compressed, point to JUMP_DNS_HDR(req) */
+ PUT_16(data, COMPRESS_FLAG | DNS_HDR_SIZE);
+ data += 2;
+ rr = (void*)data;
+ PUT_16(&rr->type, TYPE_NS);
+ PUT_16(&rr->klass, CLASS_IN);
+ rr->ttl = htonl(24*60*60);
+ data += 10;
+ strcpy(data, conf->my_ip);
+ dns_encode(data);
+ PUT_16(&rr->rdlength, strlen(data)+1);
+ data += strlen(data)+1;
+ out_len = (void*)data - req;
+
+ if (sendto(conf->sd_udp, req, out_len, 0, (struct sockaddr *)sa,
+ sizeof(struct sockaddr)) == -1)
+ {
+ MYERROR("send error\n");
+ return (-1);
+ }
+ return 0;
+}
+
int get_incoming_request(t_conf *conf)
{
struct sockaddr_in sa_other;
@@ -185,6 +251,8 @@ static int get_ressources(t_conf *conf,void *req,
return (get_ressources(conf,buffer, len, &sa_other));
if (type == TYPE_TXT)
return (queue_put_data(conf,buffer, len, &sa_other));
+ if (type == TYPE_NS)
+ return (answer_ns(conf,buffer, len, &sa_other));
return (0);
}