allow "unparsing" of dns-packets
authorPhilipp Tölke <toelke@in.tum.de>
Tue, 18 Oct 2011 18:41:19 +0000 (18:41 +0000)
committerPhilipp Tölke <toelke@in.tum.de>
Tue, 18 Oct 2011 18:41:19 +0000 (18:41 +0000)
src/vpn/gnunet-dns-parser.c
src/vpn/gnunet-dns-parser.h

index df0e63ed7ba94cdaceec0c83b3ee0f02a37d918b..31b0af1a7070e9f87a237c789389610a98dda978 100644 (file)
@@ -135,6 +135,118 @@ parse_dns_packet (struct dns_pkt *pkt)
   return ppkt;
 }                               /*}}} */
 
+static void
+unparse_dns_name(char* dest, char* src, size_t len)
+{
+  char *b = dest;
+  char cnt = 0;
+  dest++;
+  while (*src != 0)
+    {
+      while (*src != '.' && *src != 0)
+        {
+          *dest = *src;
+          src++;
+          dest++;
+          cnt++;
+        }
+      *b = cnt;
+      cnt = 0;
+      b = dest;
+      dest++;
+    }
+  *b = 0;
+}
+
+struct dns_pkt *
+unparse_dns_packet (struct dns_pkt_parsed* ppkt)
+{
+  size_t size = sizeof(struct dns_pkt) - 1;
+  int i;
+  for (i = 0; i < ppkt->s.qdcount; i++)
+    size += ppkt->queries[i]->namelen + 1;
+
+  for (i = 0; i < ppkt->s.ancount; i++)
+    {
+      size += ppkt->answers[i]->namelen + 1;
+      size += ppkt->answers[i]->data_len;
+    }
+  for (i = 0; i < ppkt->s.nscount; i++)
+    {
+      size += ppkt->nameservers[i]->namelen + 1;
+      size += ppkt->nameservers[i]->data_len;
+    }
+  for (i = 0; i < ppkt->s.arcount; i++)
+    {
+      size += ppkt->additional[i]->namelen + 1;
+      size += ppkt->additional[i]->data_len;
+    }
+
+  size += 4*ppkt->s.qdcount + 10*(
+                                  ppkt->s.ancount+
+                                  ppkt->s.arcount+
+                                  ppkt->s.nscount);
+
+  struct dns_pkt *pkt = GNUNET_malloc(size);
+  char *pkt_c = (char*)pkt;
+  memcpy(&pkt->s, &ppkt->s, sizeof ppkt->s);
+  size_t idx = sizeof ppkt->s;
+
+  for (i = 0; i < ppkt->s.qdcount; i++)
+    {
+      unparse_dns_name(&pkt_c[idx], ppkt->queries[i]->name, ppkt->queries[i]->namelen);
+      idx += ppkt->queries[i]->namelen;
+      struct dns_query_line *d = (struct dns_query_line*)&pkt_c[idx];
+      d->class = ppkt->queries[i]->qclass;
+      d->type = ppkt->queries[i]->qtype;
+      idx += sizeof(struct dns_query_line);
+    }
+
+  for (i = 0; i < ppkt->s.ancount; i++)
+    {
+      unparse_dns_name(&pkt_c[idx], ppkt->answers[i]->name, ppkt->answers[i]->namelen);
+      idx += ppkt->answers[i]->namelen;
+      struct dns_record_line *r = (struct dns_record_line*)&pkt_c[idx];
+      r->type = ppkt->answers[i]->type;
+      r->class = ppkt->answers[i]->class;
+      r->ttl = ppkt->answers[i]->ttl;
+      r->data_len = ppkt->answers[i]->data_len;
+      idx += sizeof(struct dns_record_line);
+      memcpy(&r->data, ppkt->answers[i]->data, ppkt->answers[i]->data_len);
+      idx += ppkt->answers[i]->data_len;
+    }
+
+  for (i = 0; i < ppkt->s.nscount; i++)
+    {
+      unparse_dns_name(&pkt_c[idx], ppkt->nameservers[i]->name, ppkt->nameservers[i]->namelen);
+      idx += ppkt->nameservers[i]->namelen;
+      struct dns_record_line *r = (struct dns_record_line*)&pkt_c[idx];
+      r->type = ppkt->nameservers[i]->type;
+      r->class = ppkt->nameservers[i]->class;
+      r->ttl = ppkt->nameservers[i]->ttl;
+      r->data_len = ppkt->nameservers[i]->data_len;
+      idx += sizeof(struct dns_record_line);
+      memcpy(&r->data, ppkt->nameservers[i]->data, ppkt->nameservers[i]->data_len);
+      idx += ppkt->nameservers[i]->data_len;
+    }
+
+  for (i = 0; i < ppkt->s.arcount; i++)
+    {
+      unparse_dns_name(&pkt_c[idx], ppkt->additional[i]->name, ppkt->additional[i]->namelen);
+      idx += ppkt->additional[i]->namelen;
+      struct dns_record_line *r = (struct dns_record_line*)&pkt_c[idx];
+      r->type = ppkt->additional[i]->type;
+      r->class = ppkt->additional[i]->class;
+      r->ttl = ppkt->additional[i]->ttl;
+      r->data_len = ppkt->additional[i]->data_len;
+      idx += sizeof(struct dns_record_line);
+      memcpy(&r->data, ppkt->additional[i]->data, ppkt->additional[i]->data_len);
+      idx += ppkt->additional[i]->data_len;
+    }
+
+  return pkt;
+}
+
 void
 free_parsed_dns_packet (struct dns_pkt_parsed *ppkt)
 {
index 70a1e4b9e9f70381c09f2758ab9c05c1ff3cc17f..b5cc7e1e87b6c839aca57350420683c31b14e86c 100644 (file)
@@ -7,6 +7,9 @@
 struct dns_pkt_parsed *
 parse_dns_packet (struct dns_pkt *pkt);
 
+struct dns_pkt *
+unparse_dns_packet (struct dns_pkt_parsed *pkt);
+
 void
 free_parsed_dns_packet (struct dns_pkt_parsed *ppkt);