summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rtadvd
diff options
context:
space:
mode:
authorhrs <hrs@FreeBSD.org>2011-06-03 05:33:38 +0000
committerhrs <hrs@FreeBSD.org>2011-06-03 05:33:38 +0000
commit7e254a82b1514ddec8ea068d512fa233afcc4ec7 (patch)
treede00df5fc1ec290496bd08e46813faca12d4944b /usr.sbin/rtadvd
parent3de0851e497b4e51b595a4ffb3481cdc801d85a7 (diff)
downloadFreeBSD-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.
Diffstat (limited to 'usr.sbin/rtadvd')
-rw-r--r--usr.sbin/rtadvd/config.c17
-rw-r--r--usr.sbin/rtadvd/dump.c16
2 files changed, 24 insertions, 9 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);
}
OpenPOWER on IntegriCloud