diff options
author | hrs <hrs@FreeBSD.org> | 2011-06-03 05:33:38 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2011-06-03 05:33:38 +0000 |
commit | 7e254a82b1514ddec8ea068d512fa233afcc4ec7 (patch) | |
tree | de00df5fc1ec290496bd08e46813faca12d4944b | |
parent | 3de0851e497b4e51b595a4ffb3481cdc801d85a7 (diff) | |
download | FreeBSD-src-7e254a82b1514ddec8ea068d512fa233afcc4ec7.zip FreeBSD-src-7e254a82b1514ddec8ea068d512fa233afcc4ec7.tar.gz |
Fix label encoding/decoding function for RFC 1035 Section 3.1 encoding.
Each label can have 63 octets at most, and the length of whole domain name
is limited to NI_MAXHOST.
-rw-r--r-- | usr.sbin/rtadvd/config.c | 17 | ||||
-rw-r--r-- | usr.sbin/rtadvd/dump.c | 16 | ||||
-rw-r--r-- | usr.sbin/rtsold/rtsol.c | 12 |
3 files changed, 32 insertions, 13 deletions
diff --git a/usr.sbin/rtadvd/config.c b/usr.sbin/rtadvd/config.c index 011e8d3..fdbddb0 100644 --- a/usr.sbin/rtadvd/config.c +++ b/usr.sbin/rtadvd/config.c @@ -85,6 +85,7 @@ static size_t dname_labelenc(char *dst, const char *src) { char *dst_origin; + char *p; size_t len; dst_origin = dst; @@ -94,13 +95,23 @@ dname_labelenc(char *dst, const char *src) memset(dst, 0, len + len / 64 + 1 + 1); syslog(LOG_DEBUG, "<%s> labelenc = %s", __func__, src); - while ((len = strlen(src)) != 0) { + while (src && (len = strlen(src)) != 0) { /* Put a length field with 63 octet limitation first. */ - *dst++ = len = MIN(63, len + 1); + p = index(src, '.'); + if (p == NULL) + *dst++ = len = MIN(63, len); + else + *dst++ = len = MIN(63, p - src); + /* Copy only 63 octets at most. */ memcpy(dst, src, len); dst += len; - src += len; + if (p == NULL) /* the last label */ + break; + src = p + 1; } + /* Always need a 0-length label at the tail. */ + *dst++ = '\0'; + syslog(LOG_DEBUG, "<%s> labellen = %d", __func__, dst - dst_origin); return (dst - dst_origin); } diff --git a/usr.sbin/rtadvd/dump.c b/usr.sbin/rtadvd/dump.c index 8f3b0d2..97dc122 100644 --- a/usr.sbin/rtadvd/dump.c +++ b/usr.sbin/rtadvd/dump.c @@ -64,7 +64,7 @@ extern struct rainfo *ralist; static char *ether_str(struct sockaddr_dl *); static void if_dump(void); -static size_t dname_labeldec(char *, const char *); +static size_t dname_labeldec(char *, size_t, const char *); static char *rtpref_str[] = { "medium", /* 00 */ @@ -262,7 +262,7 @@ if_dump(void) fprintf(fp, " % 8u\t", dns->dn_ltime); TAILQ_FOREACH(dnsa, &dns->dn_list, da_next) { - dname_labeldec(buf, dnsa->da_dom); + dname_labeldec(buf, sizeof(buf), dnsa->da_dom); if (dnsa != TAILQ_FIRST(&dns->dn_list)) fprintf(fp, " \t"); fprintf(fp, "%s(%d)\n", buf, dnsa->da_len); @@ -291,20 +291,24 @@ rtadvd_dump_file(char *dumpfile) /* Decode domain name label encoding in RFC 1035 Section 3.1 */ static size_t -dname_labeldec(char *dst, const char *src) +dname_labeldec(char *dst, size_t dlen, const char *src) { size_t len; const char *src_origin; + const char *dst_origin; src_origin = src; - while (*src && (len = (uint8_t)(*src++) & 0x3f) != 0) { + dst_origin = dst; + memset(dst, '\0', dlen); + while (src && (len = (uint8_t)(*src++) & 0x3f)) { + if (dst != dst_origin) + *dst++ = '.'; syslog(LOG_DEBUG, "<%s> labellen = %d", __func__, len); memcpy(dst, src, len); src += len; dst += len; - if (*(dst - 1) == '\0') - break; } + *dst = '\0'; return (src - src_origin); } diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c index 6447515..e5184f1 100644 --- a/usr.sbin/rtsold/rtsol.c +++ b/usr.sbin/rtsold/rtsol.c @@ -475,8 +475,9 @@ rtsol_input(int s) } p = raoptp + sizeof(*dnssl); - while (0 < (len = dname_labeldec(dname, sizeof(dname), + while (1 < (len = dname_labeldec(dname, sizeof(dname), p))) { + /* length == 1 means empty string */ warnmsg(LOG_DEBUG, __func__, "dname = %s", dname); @@ -789,17 +790,20 @@ dname_labeldec(char *dst, size_t dlen, const char *src) { size_t len; const char *src_origin; + const char *dst_origin; src_origin = src; + dst_origin = dst; memset(dst, '\0', dlen); - while (*src && (len = (uint8_t)(*src++) & 0x3f) != 0) { + while (src && (len = (uint8_t)(*src++) & 0x3f)) { + if (dst != dst_origin) + *dst++ = '.'; warnmsg(LOG_DEBUG, __func__, "labellen = %zd", len); memcpy(dst, src, len); src += len; dst += len; - if (*(dst - 1) == '\0') - break; } + *dst = '\0'; /* * XXX validate that domain name only contains valid characters |