svn commit: r222637 - in user/hrs/ipv6/usr.sbin: rtadvd rtsold

Hiroki Sato hrs at FreeBSD.org
Fri Jun 3 05:33:39 UTC 2011


Author: hrs
Date: Fri Jun  3 05:33:38 2011
New Revision: 222637
URL: http://svn.freebsd.org/changeset/base/222637

Log:
  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.

Modified:
  user/hrs/ipv6/usr.sbin/rtadvd/config.c
  user/hrs/ipv6/usr.sbin/rtadvd/dump.c
  user/hrs/ipv6/usr.sbin/rtsold/rtsol.c

Modified: user/hrs/ipv6/usr.sbin/rtadvd/config.c
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtadvd/config.c	Fri Jun  3 05:16:54 2011	(r222636)
+++ user/hrs/ipv6/usr.sbin/rtadvd/config.c	Fri Jun  3 05:33:38 2011	(r222637)
@@ -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 *sr
 	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);
 }

Modified: user/hrs/ipv6/usr.sbin/rtadvd/dump.c
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtadvd/dump.c	Fri Jun  3 05:16:54 2011	(r222636)
+++ user/hrs/ipv6/usr.sbin/rtadvd/dump.c	Fri Jun  3 05:33:38 2011	(r222637)
@@ -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);
 }

Modified: user/hrs/ipv6/usr.sbin/rtsold/rtsol.c
==============================================================================
--- user/hrs/ipv6/usr.sbin/rtsold/rtsol.c	Fri Jun  3 05:16:54 2011	(r222636)
+++ user/hrs/ipv6/usr.sbin/rtsold/rtsol.c	Fri Jun  3 05:33:38 2011	(r222637)
@@ -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, c
 {
 	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


More information about the svn-src-user mailing list