From 67e53c2fff6f1a25b3929b998b1fc6ee3cb116a4 Mon Sep 17 00:00:00 2001 From: Erik Ekman Date: Sun, 5 Nov 2006 11:44:43 +0000 Subject: [PATCH] Fixed hostname encoding, cleanup --- dns.c | 16 +++++++++++----- dns.h | 1 + test.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/dns.c b/dns.c index 96bd5e8..460932f 100644 --- a/dns.c +++ b/dns.c @@ -43,7 +43,6 @@ #endif -static int host2dns(const char *, char *, int); static int dns_write(int, int, char *, int, char); static void dns_query(int, int, char *, int); @@ -207,7 +206,7 @@ dns_query(int fd, int id, char *host, int type) header->arcount = htons(1); p = buf + sizeof(HEADER); - p += host2dns(host, p, strlen(host)); + p += dns_encode_hostname(host, p, strlen(host)); putshort(&p, type); putshort(&p, C_IN); @@ -325,6 +324,7 @@ dns_parse_reply(char *outbuf, int buflen, char *packet, int packetlen) } if(type == T_NULL && rv > 2) { + rv = MIN(rv, buflen); memcpy(outbuf, rdata, rv); } } @@ -332,19 +332,25 @@ dns_parse_reply(char *outbuf, int buflen, char *packet, int packetlen) return rv; } -static int -host2dns(const char *host, char *buffer, int size) +int +dns_encode_hostname(const char *host, char *buffer, int size) { char *h; char *p; char *word; + int left; h = strdup(host); memset(buffer, 0, size); p = buffer; + left = size; word = strtok(h, "."); while(word) { + if (strlen(word) > 63 || strlen(word) > left) { + return -1; + } + left -= (strlen(word) + 1); *p++ = (char)strlen(word); memcpy(p, word, strlen(word)); p += strlen(word); @@ -387,7 +393,7 @@ dnsd_send(int fd, struct query *q, char *data, int datalen) p = buf + sizeof(HEADER); name = 0xc000 | ((p - buf) & 0x3fff); - p += host2dns(q->name, p, strlen(q->name)); + p += dns_encode_hostname(q->name, p, strlen(q->name)); putshort(&p, q->type); putshort(&p, C_IN); diff --git a/dns.h b/dns.h index f3807a1..f8da628 100644 --- a/dns.h +++ b/dns.h @@ -26,6 +26,7 @@ void dns_handle_tun(int, char *, int); void dns_ping(int); void dns_handshake(int); int dns_read(int, char *, int); +int dns_encode_hostname(const char *, char *, int); extern struct sockaddr_in peer; diff --git a/test.c b/test.c index 4125ebe..19050df 100644 --- a/test.c +++ b/test.c @@ -162,6 +162,33 @@ test_readname() printf("OK\n"); } +static void +test_encode_hostname() { + char buf[256]; + int len; + int ret; + + len = 256; + printf(" * Testing hostname encoding... "); + + memset(buf, 0, 256); + ret = dns_encode_hostname( // More than 63 chars between dots + "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" + , buf, len); + assert(ret == -1); + + memset(buf, 0, 256); + ret = dns_encode_hostname( // More chars than fits into array + "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ." + "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ." + "ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ." + , buf, len); + assert(ret == -1); + assert(strlen(buf) < len); + + printf("OK\n"); +} + int main() { @@ -170,6 +197,7 @@ main() test_readputshort(); test_readputlong(); test_readname(); + test_encode_hostname(); printf("** All went well :)\n"); return 0;