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