diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-05-14 13:33:47 +0300 |
---|---|---|
committer | Patrik Flykt <patrik.flykt@linux.intel.com> | 2012-05-15 15:51:53 +0300 |
commit | 941e94a18d9e8c0af1124b36f8c0682b608604c4 (patch) | |
tree | 4ca4d326b900271a436b2909dc7d89201d43cc3d /src/rtnl.c | |
parent | a7a79a2e795146c750dcb9e3c29c4bf92f0832a6 (diff) | |
download | connman-941e94a18d9e8c0af1124b36f8c0682b608604c4.tar.gz connman-941e94a18d9e8c0af1124b36f8c0682b608604c4.tar.bz2 connman-941e94a18d9e8c0af1124b36f8c0682b608604c4.zip |
rtnl: Domain search list was not handled according to RFC 6106
Domain search list option can exist in options without RDNSS option.
Note that the DNSSL netlink support is not yet in linux kernel
3.4-rc7, thus we will not yet get a DNSSL option in netlink RA
options.
Diffstat (limited to 'src/rtnl.c')
-rw-r--r-- | src/rtnl.c | 57 |
1 files changed, 27 insertions, 30 deletions
@@ -1193,18 +1193,18 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) guint32 lifetime = -1; const char **domains = NULL; struct in6_addr *servers = NULL; - int nr_servers = 0; + int i, nr_servers = 0; int msglen = msg->nduseropt_opts_len; char *interface; - DBG("family %02x index %x len %04x type %02x code %02x", - msg->nduseropt_family, msg->nduseropt_ifindex, - msg->nduseropt_opts_len, msg->nduseropt_icmp_type, - msg->nduseropt_icmp_code); + DBG("family %d index %d len %d type %d code %d", + msg->nduseropt_family, msg->nduseropt_ifindex, + msg->nduseropt_opts_len, msg->nduseropt_icmp_type, + msg->nduseropt_icmp_code); if (msg->nduseropt_family != AF_INET6 || - msg->nduseropt_icmp_type != ND_ROUTER_ADVERT || - msg->nduseropt_icmp_code != 0) + msg->nduseropt_icmp_type != ND_ROUTER_ADVERT || + msg->nduseropt_icmp_code != 0) return; interface = connman_inet_ifname(msg->nduseropt_ifindex); @@ -1212,40 +1212,37 @@ static void rtnl_newnduseropt(struct nlmsghdr *hdr) return; for (opt = (void *)&msg[1]; - msglen >= 2 && msglen >= opt->nd_opt_len && opt->nd_opt_len; - msglen -= opt->nd_opt_len, - opt = ((void *)opt) + opt->nd_opt_len*8) { + msglen > 0; + msglen -= opt->nd_opt_len * 8, + opt = ((void *)opt) + opt->nd_opt_len*8) { - DBG("nd opt type %d len %d\n", - opt->nd_opt_type, opt->nd_opt_len); + DBG("remaining %d nd opt type %d len %d\n", + msglen, opt->nd_opt_type, opt->nd_opt_len); - if (opt->nd_opt_type == 25) - servers = rtnl_nd_opt_rdnss(opt, &lifetime, - &nr_servers); - else if (opt->nd_opt_type == 31) - domains = rtnl_nd_opt_dnssl(opt, &lifetime); - } - - if (nr_servers) { - int i, j; - char buf[40]; + if (opt->nd_opt_type == 25) { /* ND_OPT_RDNSS */ + char buf[40]; - for (i = 0; i < nr_servers; i++) { - if (!inet_ntop(AF_INET6, servers + i, buf, sizeof(buf))) - continue; + servers = rtnl_nd_opt_rdnss(opt, &lifetime, + &nr_servers); + for (i = 0; i < nr_servers; i++) { + if (!inet_ntop(AF_INET6, servers + i, buf, + sizeof(buf))) + continue; - if (domains == NULL || domains[0] == NULL) { connman_resolver_append_lifetime(interface, NULL, buf, lifetime); - continue; } - for (j = 0; domains[j]; j++) + } else if (opt->nd_opt_type == 31) { /* ND_OPT_DNSSL */ + g_free(domains); + + domains = rtnl_nd_opt_dnssl(opt, &lifetime); + for (i = 0; domains != NULL && domains[i] != NULL; i++) connman_resolver_append_lifetime(interface, - domains[j], - buf, lifetime); + domains[i], NULL, lifetime); } } + g_free(domains); g_free(interface); } |