summaryrefslogtreecommitdiff
path: root/src/rtnl.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-05-14 13:33:47 +0300
committerPatrik Flykt <patrik.flykt@linux.intel.com>2012-05-15 15:51:53 +0300
commit941e94a18d9e8c0af1124b36f8c0682b608604c4 (patch)
tree4ca4d326b900271a436b2909dc7d89201d43cc3d /src/rtnl.c
parenta7a79a2e795146c750dcb9e3c29c4bf92f0832a6 (diff)
downloadconnman-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.c57
1 files changed, 27 insertions, 30 deletions
diff --git a/src/rtnl.c b/src/rtnl.c
index 1aaef29c..4f502195 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -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);
}