Date: Tue, 31 May 2011 12:03:34 +0000 (UTC) From: Hiroki Sato <hrs@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r222521 - user/hrs/ipv6/usr.sbin/rtsold Message-ID: <201105311203.p4VC3Y3x022940@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: hrs Date: Tue May 31 12:03:34 2011 New Revision: 222521 URL: http://svn.freebsd.org/changeset/base/222521 Log: - Implement RA option expiration based on the lifetime field. - Add option length check described in RFC 6106 Section 5.3.1. Modified: user/hrs/ipv6/usr.sbin/rtsold/rtsol.c user/hrs/ipv6/usr.sbin/rtsold/rtsold.c user/hrs/ipv6/usr.sbin/rtsold/rtsold.h Modified: user/hrs/ipv6/usr.sbin/rtsold/rtsol.c ============================================================================== --- user/hrs/ipv6/usr.sbin/rtsold/rtsol.c Tue May 31 09:22:52 2011 (r222520) +++ user/hrs/ipv6/usr.sbin/rtsold/rtsol.c Tue May 31 12:03:34 2011 (r222521) @@ -83,7 +83,6 @@ static const struct sockaddr_in6 sin6_al static void call_script(const int, const char *const *, void *); static size_t dname_labeldec(char *, const char *); static int safefile(const char *); -static int ra_opt_handler(struct ifinfo *); #define _ARGS_OTHER otherconf_script, ifi->ifname #define _ARGS_RESADD resolvconf_script, "-a", ifi->ifname @@ -244,10 +243,7 @@ rtsol_input(int s) struct nd_opt_rdnss *rdnss; struct nd_opt_dnssl *dnssl; size_t len; - char nsbuf[11 + INET6_ADDRSTRLEN + 1 + IFNAMSIZ + 1 + 1]; - /* 11 = sizeof("nameserver "), 1+1 = \n\0 termination */ - char slbuf[7 + NI_MAXHOST + 1 + 1]; - /* 7 = sizeof("search "), 1+1 = \n\0 termination */ + char nsbuf[INET6_ADDRSTRLEN + 1 + IFNAMSIZ + 1 + 1]; char dname[NI_MAXHOST + 1]; struct timeval now; struct timeval lifetime; @@ -400,6 +396,16 @@ rtsol_input(int s) case ND_OPT_RDNSS: rdnss = (struct nd_opt_rdnss *)raoptp; + /* Optlen sanity check (Section 5.3.1 in RFC 6106) */ + if (rdnss->nd_opt_rdnss_len < 3) { + warnmsg(LOG_INFO, __func__, + "too short RDNSS option" + "in RA from %s was ignored.", + inet_ntop(AF_INET6, &from.sin6_addr, + ntopbuf, INET6_ADDRSTRLEN)); + break; + } + addr = (struct in6_addr *)(raoptp + sizeof(*rdnss)); while ((char *)addr < (char *)RA_OPT_NEXT_HDR(raoptp)) { if (inet_ntop(AF_INET6, addr, ntopbuf, @@ -447,16 +453,25 @@ rtsol_input(int s) case ND_OPT_DNSSL: dnssl = (struct nd_opt_dnssl *)raoptp; + /* Optlen sanity check (Section 5.3.1 in RFC 6106) */ + if (dnssl->nd_opt_dnssl_len < 2) { + warnmsg(LOG_INFO, __func__, + "too short DNSSL option" + "in RA from %s was ignored.", + inet_ntop(AF_INET6, &from.sin6_addr, + ntopbuf, INET6_ADDRSTRLEN)); + break; + } + p = raoptp + sizeof(*dnssl); while (0 < (len = dname_labeldec(dname, p))) { - sprintf(slbuf, "%s ", dname); - warnmsg(LOG_DEBUG, __func__, "slbuf = %s", - slbuf); + warnmsg(LOG_DEBUG, __func__, "dname = %s", + dname); ELM_MALLOC(rao, break); rao->rao_type = ndo->nd_opt_type; - rao->rao_len = strlen(nsbuf); - rao->rao_msg = strdup(slbuf); + rao->rao_len = strlen(dname); + rao->rao_msg = strdup(dname); if (rao->rao_msg == NULL) { warnmsg(LOG_ERR, __func__, "strdup failed: %s", @@ -498,8 +513,9 @@ rtsol_input(int s) static char resstr_ns_prefix[] = "nameserver "; static char resstr_sh_prefix[] = "search "; static char resstr_nl[] = "\n"; +static char resstr_sp[] = " "; -static int +int ra_opt_handler(struct ifinfo *ifi) { struct ra_opt *rao; @@ -548,6 +564,10 @@ ra_opt_handler(struct ifinfo *ifi) ELM_MALLOC(smp, continue); smp->sm_msg = rao->rao_msg; TAILQ_INSERT_TAIL(&sm_dnssl_head, smp, sm_next); + + ELM_MALLOC(smp, continue); + smp->sm_msg = resstr_sp; + TAILQ_INSERT_TAIL(&sm_dnssl_head, smp, sm_next); break; default: break; Modified: user/hrs/ipv6/usr.sbin/rtsold/rtsold.c ============================================================================== --- user/hrs/ipv6/usr.sbin/rtsold/rtsold.c Tue May 31 09:22:52 2011 (r222520) +++ user/hrs/ipv6/usr.sbin/rtsold/rtsold.c Tue May 31 12:03:34 2011 (r222521) @@ -570,6 +570,19 @@ rtsol_check_timer(void) "state = %d", ifi->ifname, ifi->state); + /* Remove all RA options. */ + if (!TAILQ_EMPTY(&ifi->ifi_ra_opt)) { + struct ra_opt *rao; + struct ra_opt *rao_tmp; + + rao = TAILQ_FIRST(&ifi->ifi_ra_opt); + while (rao != NULL) { + rao_tmp = TAILQ_NEXT(rao, rao_next); + free(rao_tmp->rao_msg); + free(rao_tmp); + rao = rao_tmp; + } + } switch (ifi->state) { case IFS_DOWN: case IFS_TENTATIVE: @@ -635,8 +648,29 @@ rtsol_check_timer(void) break; } rtsol_timer_update(ifi); + } else { + /* Expiration check for RA options. */ + struct ra_opt *rao; + struct ra_opt *rao_tmp; + int expire = 0; + + TAILQ_FOREACH_SAFE(rao, &ifi->ifi_ra_opt, rao_next, rao_tmp) { + warnmsg(LOG_DEBUG, __func__, + "RA expiration timer: " + "type=%d, msg=%s, timer=%ld:%08ld", + rao->rao_type, (char *)rao->rao_msg, + (long)rao->rao_expire.tv_sec, + (long)rao->rao_expire.tv_usec); + if (timercmp(&now, &rao->rao_expire, >=)) { + warnmsg(LOG_DEBUG, __func__, + "RA expiration timer: expired."); + TAILQ_REMOVE(&ifi->ifi_ra_opt, rao, rao_next); + expire = 1; + } + } + if (expire) + ra_opt_handler(ifi); } - if (timercmp(&ifi->expire, &rtsol_timer, <)) rtsol_timer = ifi->expire; } Modified: user/hrs/ipv6/usr.sbin/rtsold/rtsold.h ============================================================================== --- user/hrs/ipv6/usr.sbin/rtsold/rtsold.h Tue May 31 09:22:52 2011 (r222520) +++ user/hrs/ipv6/usr.sbin/rtsold/rtsold.h Tue May 31 12:03:34 2011 (r222521) @@ -118,6 +118,7 @@ void rtsol_timer_update(struct ifinfo *) extern void warnmsg(int, const char *, const char *, ...) __attribute__((__format__(__printf__, 3, 4))); extern char **autoifprobe(void); +extern int ra_opt_handler(struct ifinfo *); /* if.c */ extern int ifinit(void);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201105311203.p4VC3Y3x022940>