svn commit: r222521 - user/hrs/ipv6/usr.sbin/rtsold
Hiroki Sato
hrs at FreeBSD.org
Tue May 31 12:03:35 UTC 2011
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);
More information about the svn-src-user
mailing list