From 13e485d648e02876be8ab5cf78b1c87430b04d4d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Philipp=20T=C3=B6lke?= Date: Tue, 18 Oct 2011 18:41:19 +0000 Subject: [PATCH] allow "unparsing" of dns-packets --- src/vpn/gnunet-dns-parser.c | 112 ++++++++++++++++++++++++++++++++++++ src/vpn/gnunet-dns-parser.h | 3 + 2 files changed, 115 insertions(+) diff --git a/src/vpn/gnunet-dns-parser.c b/src/vpn/gnunet-dns-parser.c index df0e63ed7..31b0af1a7 100644 --- a/src/vpn/gnunet-dns-parser.c +++ b/src/vpn/gnunet-dns-parser.c @@ -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) { diff --git a/src/vpn/gnunet-dns-parser.h b/src/vpn/gnunet-dns-parser.h index 70a1e4b9e..b5cc7e1e8 100644 --- a/src/vpn/gnunet-dns-parser.h +++ b/src/vpn/gnunet-dns-parser.h @@ -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); -- 2.25.1