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

Reply via email to