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); }