From 852b4f4ff636f3005b03be5e2195a00dd0d1b7e9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Philipp=20T=C3=B6lke?= Date: Tue, 5 Oct 2010 18:20:20 +0000 Subject: [PATCH] parse a complete dns-packet-struct to another struct so as to completly have it in memory --- src/vpn/gnunet-dns-parser.c | 68 ++++++++++++++++++++++++ src/vpn/gnunet-dns-parser.h | 9 ++-- src/vpn/gnunet-vpn-packet.h | 10 ++-- src/vpn/gnunet-vpn-pretty-print.c | 87 +++---------------------------- 4 files changed, 86 insertions(+), 88 deletions(-) diff --git a/src/vpn/gnunet-dns-parser.c b/src/vpn/gnunet-dns-parser.c index 3425e78f6..be4770e24 100644 --- a/src/vpn/gnunet-dns-parser.c +++ b/src/vpn/gnunet-dns-parser.c @@ -1,5 +1,6 @@ #include "platform.h" #include "gnunet-dns-parser.h" +#include "gnunet-vpn-packet.h" unsigned int parse_dns_name(unsigned char* d, const unsigned char* src, unsigned short idx) {/*{{{*/ unsigned char* dest = d; @@ -23,3 +24,70 @@ unsigned int parse_dns_name(unsigned char* d, const unsigned char* src, unsigned return idx; } /*}}}*/ + +unsigned short parse_dns_record(unsigned char* data, struct dns_record** dst, unsigned short count, unsigned short idx) {/*{{{*/ + int i; + unsigned short _idx; + for (i = 0; i < count; i++) { + dst[i] = GNUNET_malloc(sizeof(struct dns_record)); + dst[i]->name = alloca(255); // see RFC1035 + unsigned char* name = dst[i]->name; + + _idx = parse_dns_name(name, data, idx); + dst[i]->namelen = _idx - idx; + idx = _idx; + + dst[i]->type = *((unsigned short*)(data+idx)); + idx += 2; + dst[i]->class = *((unsigned short*)(data+idx)); + idx += 2; + dst[i]->ttl = *((unsigned int*)(data+idx)); + idx += 4; + dst[i]->data_len = *((unsigned short*)(data+idx)); + idx += 2; + dst[i]->data = GNUNET_malloc(ntohs(dst[i]->data_len)); + memcpy(dst[i]->data, data+idx, ntohs(dst[i]->data_len)); + idx += ntohs(dst[i]->data_len); + } + return idx; +}/*}}}*/ + +struct dns_pkt_parsed* parse_dns_packet(struct dns_pkt* pkt) { + struct dns_pkt_parsed* ppkt = GNUNET_malloc(sizeof(struct dns_pkt_parsed)); + memcpy(&ppkt->s, &pkt->s, sizeof pkt->s); + + unsigned short qdcount = ntohs(ppkt->s.qdcount); + unsigned short ancount = ntohs(ppkt->s.ancount); + unsigned short nscount = ntohs(ppkt->s.nscount); + unsigned short arcount = ntohs(ppkt->s.arcount); + + ppkt->queries = GNUNET_malloc(qdcount*sizeof(struct dns_query*)); + ppkt->answers = GNUNET_malloc(ancount*sizeof(struct dns_record*)); + ppkt->nameservers = GNUNET_malloc(nscount*sizeof(struct dns_record*)); + ppkt->additional = GNUNET_malloc(arcount*sizeof(struct dns_record*)); + + unsigned short idx = 0, _idx; /* This keeps track how far we have parsed the data */ + + int i; + for (i = 0; i < qdcount; i++) { /*{{{*/ + ppkt->queries[i] = GNUNET_malloc(sizeof(struct dns_query)); + unsigned char* name = alloca(255); /* see RFC1035, it can't be more than this. */ + + _idx = parse_dns_name(name, pkt->data, idx); + ppkt->queries[i]->namelen = _idx - idx; + idx = _idx; + + ppkt->queries[i]->name = GNUNET_malloc(ppkt->queries[i]->namelen + 1); + memcpy(ppkt->queries[i]->name, name, ppkt->queries[i]->namelen + 1); + + ppkt->queries[i]->qtype = *((unsigned short*)(pkt->data+idx)); + idx += 2; + ppkt->queries[i]->qclass = *((unsigned short*)(pkt->data+idx)); + idx += 2; + } + /*}}}*/ + idx = parse_dns_record(pkt->data, ppkt->answers, ancount, idx); + idx = parse_dns_record(pkt->data, ppkt->nameservers, nscount, idx); + idx = parse_dns_record(pkt->data, ppkt->additional, arcount, idx); + return ppkt; +} diff --git a/src/vpn/gnunet-dns-parser.h b/src/vpn/gnunet-dns-parser.h index 77dcd6d4e..1ee82e7a3 100644 --- a/src/vpn/gnunet-dns-parser.h +++ b/src/vpn/gnunet-dns-parser.h @@ -1,10 +1,9 @@ #ifndef _GNVPN_DNSP_H_ #define _GNVPN_DNSP_H_ -/** - * Parses the dns-name pointed to by src+idx returning idx so, that src+idx points - * to the first unused char. - */ -unsigned int parse_dns_name(unsigned char* dest, const unsigned char* src, unsigned short idx); +#include "platform.h" +#include "gnunet-vpn-packet.h" + +struct dns_pkt_parsed* parse_dns_packet(struct dns_pkt* pkt); #endif diff --git a/src/vpn/gnunet-vpn-packet.h b/src/vpn/gnunet-vpn-packet.h index 0659215cb..61f274e95 100644 --- a/src/vpn/gnunet-vpn-packet.h +++ b/src/vpn/gnunet-vpn-packet.h @@ -92,20 +92,22 @@ struct dns_pkt { struct dns_pkt_parsed { struct dns_static s; - struct dns_query* queries; - struct dns_record* answers; - struct dns_record* nameservers; - struct dns_record* additional; + struct dns_query** queries; + struct dns_record** answers; + struct dns_record** nameservers; + struct dns_record** additional; }; struct dns_query { unsigned char* name; + unsigned char namelen; unsigned short qtype; unsigned short qclass; }; struct dns_record { unsigned char* name; + unsigned char namelen; unsigned short type; unsigned short class; unsigned int ttl; diff --git a/src/vpn/gnunet-vpn-pretty-print.c b/src/vpn/gnunet-vpn-pretty-print.c index e8fe4c722..0d165a650 100644 --- a/src/vpn/gnunet-vpn-pretty-print.c +++ b/src/vpn/gnunet-vpn-pretty-print.c @@ -260,7 +260,9 @@ static char* dns_classes(short class) { /* {{{ */ } /*}}}*/ -void pkt_printf_dns(struct dns_pkt* pkt) {{{ +void pkt_printf_dns(struct dns_pkt* upkt) {{{ + struct dns_pkt_parsed* pkt = parse_dns_packet(upkt); + printf("DNS-Packet:\n"); printf("\tid: %d\n", ntohs(pkt->s.id)); printf("\t%d: %s\n", pkt->s.qr, pkt->s.qr == 0 ? "query" : "response"); @@ -275,97 +277,24 @@ void pkt_printf_dns(struct dns_pkt* pkt) {{{ printf("\t#ns: %d\n", nscount); printf("\t#ar: %d\n", arcount); - struct dns_query** queries = alloca(qdcount*sizeof(struct dns_query*)); - struct dns_record** answers = alloca(ancount*sizeof(struct dns_record*)); - struct dns_record** nameserver = alloca(nscount*sizeof(struct dns_record*)); - struct dns_record** additional = alloca(arcount*sizeof(struct dns_record*)); - unsigned short idx = 0; - int i; for (i = 0; i < qdcount; i++) { /*{{{*/ - queries[i] = alloca(sizeof(struct dns_query)); - queries[i]->name = alloca(255); // see RFC1035 - unsigned char* name = queries[i]->name; - - idx = parse_dns_name(name, pkt->data, idx); - - printf("%d\n", idx); - queries[i]->qtype = *((unsigned short*)(pkt->data+idx)); - idx += 2; - queries[i]->qclass = *((unsigned short*)(pkt->data+idx)); - idx += 2; - printf("query for %s type=%d (%s) class=%d (%s)\n", queries[i]->name, ntohs(queries[i]->qtype), dns_types(ntohs(queries[i]->qtype)), ntohs(queries[i]->qclass), dns_classes(ntohs(queries[i]->qclass))); + printf("query for %s type=%d (%s) class=%d (%s)\n", pkt->queries[i]->name, ntohs(pkt->queries[i]->qtype), dns_types(ntohs(pkt->queries[i]->qtype)), ntohs(pkt->queries[i]->qclass), dns_classes(ntohs(pkt->queries[i]->qclass))); } /*}}}*/ for (i = 0; i < ancount; i++) { /*{{{*/ - answers[i] = alloca(sizeof(struct dns_record)); - answers[i]->name = alloca(255); // see RFC1035 - unsigned char* name = answers[i]->name; - - idx = parse_dns_name(name, pkt->data, idx); - - printf("%d\n", idx); - answers[i]->type = *((unsigned short*)(pkt->data+idx)); - idx += 2; - answers[i]->class = *((unsigned short*)(pkt->data+idx)); - idx += 2; - answers[i]->ttl = *((unsigned int*)(pkt->data+idx)); - idx += 4; - answers[i]->data_len = *((unsigned short*)(pkt->data+idx)); - idx += 2; - answers[i]->data = alloca(ntohs(answers[i]->data_len)); - memcpy(answers[i]->data, pkt->data+idx, ntohs(answers[i]->data_len)); - idx += ntohs(answers[i]->data_len); - - printf("answer for %s type=%d (%s) class=%d (%s) ttl=%d data_len=%d\n", answers[i]->name, ntohs(answers[i]->type), dns_types(ntohs(answers[i]->type)), ntohs(answers[i]->class), dns_classes(ntohs(answers[i]->class)), ntohl(answers[i]->ttl), ntohs(answers[i]->data_len)); + printf("answer for %s type=%d (%s) class=%d (%s) ttl=%d data_len=%d\n", pkt->answers[i]->name, ntohs(pkt->answers[i]->type), dns_types(ntohs(pkt->answers[i]->type)), ntohs(pkt->answers[i]->class), dns_classes(ntohs(pkt->answers[i]->class)), ntohl(pkt->answers[i]->ttl), ntohs(pkt->answers[i]->data_len)); } /*}}}*/ for (i = 0; i < nscount; i++) { /*{{{*/ - nameserver[i] = alloca(sizeof(struct dns_record)); - nameserver[i]->name = alloca(255); // see RFC1035 - unsigned char* name = nameserver[i]->name; - - idx = parse_dns_name(name, pkt->data, idx); - - printf("%d\n", idx); - nameserver[i]->type = *((unsigned short*)(pkt->data+idx)); - idx += 2; - nameserver[i]->class = *((unsigned short*)(pkt->data+idx)); - idx += 2; - nameserver[i]->ttl = *((unsigned int*)(pkt->data+idx)); - idx += 4; - nameserver[i]->data_len = *((unsigned short*)(pkt->data+idx)); - idx += 2; - nameserver[i]->data = alloca(ntohs(nameserver[i]->data_len)); - memcpy(nameserver[i]->data, pkt->data+idx, ntohs(nameserver[i]->data_len)); - idx += ntohs(nameserver[i]->data_len); - - printf("nameserver for %s type=%d (%s) class=%d (%s) ttl=%d data_len=%d\n", nameserver[i]->name, ntohs(nameserver[i]->type), dns_types(ntohs(nameserver[i]->type)), ntohs(nameserver[i]->class), dns_classes(ntohs(nameserver[i]->class)), ntohl(nameserver[i]->ttl), ntohs(nameserver[i]->data_len)); + printf("nameservers for %s type=%d (%s) class=%d (%s) ttl=%d data_len=%d\n", pkt->nameservers[i]->name, ntohs(pkt->nameservers[i]->type), dns_types(ntohs(pkt->nameservers[i]->type)), ntohs(pkt->nameservers[i]->class), dns_classes(ntohs(pkt->nameservers[i]->class)), ntohl(pkt->nameservers[i]->ttl), ntohs(pkt->nameservers[i]->data_len)); } /*}}}*/ for (i = 0; i < arcount; i++) { /*{{{*/ - additional[i] = alloca(sizeof(struct dns_query)); - additional[i]->name = alloca(255); // see RFC1035 - unsigned char* name = additional[i]->name; - - idx = parse_dns_name(name, pkt->data, idx); - - printf("%d\n", idx); - additional[i]->type = *((unsigned short*)(pkt->data+idx)); - idx += 2; - additional[i]->class = *((unsigned short*)(pkt->data+idx)); - idx += 2; - additional[i]->ttl = *((unsigned int*)(pkt->data+idx)); - idx += 4; - additional[i]->data_len = *((unsigned short*)(pkt->data+idx)); - idx += 2; - additional[i]->data = alloca(ntohs(additional[i]->data_len)); - memcpy(additional[i]->data, pkt->data+idx, ntohs(additional[i]->data_len)); - idx += ntohs(additional[i]->data_len); - - printf("additional record for %s type=%d (%s) class=%d (%s) ttl=%d data_len=%d\n", additional[i]->name, ntohs(additional[i]->type), dns_types(ntohs(additional[i]->type)), ntohs(additional[i]->class), dns_classes(ntohs(additional[i]->class)), ntohl(additional[i]->ttl), ntohs(additional[i]->data_len)); + printf("additional record for %s type=%d (%s) class=%d (%s) ttl=%d data_len=%d\n", pkt->additional[i]->name, ntohs(pkt->additional[i]->type), dns_types(ntohs(pkt->additional[i]->type)), ntohs(pkt->additional[i]->class), dns_classes(ntohs(pkt->additional[i]->class)), ntohl(pkt->additional[i]->ttl), ntohs(pkt->additional[i]->data_len)); } /*}}}*/ + GNUNET_free(pkt); }}} void pkt_printf_udp_dns(struct udp_dns* pkt) {{{ -- 2.25.1