summaryrefslogtreecommitdiff
path: root/src/inet.c
diff options
context:
space:
mode:
authorJukka Rissanen <jukka.rissanen@linux.intel.com>2012-01-05 13:38:07 +0200
committerDaniel Wagner <daniel.wagner@bmw-carit.de>2012-01-05 13:17:26 +0100
commit6ea547962997517629240c4c9d8e5a2592a6a95a (patch)
tree0693bccff7815bc96168c91f7ce61ef174196e5b /src/inet.c
parent931367f3c9574b7fc473fdce23627f4108cfb90d (diff)
downloadconnman-6ea547962997517629240c4c9d8e5a2592a6a95a.tar.gz
connman-6ea547962997517629240c4c9d8e5a2592a6a95a.tar.bz2
connman-6ea547962997517629240c4c9d8e5a2592a6a95a.zip
inet: Get router advertisement prefix option information.
Diffstat (limited to 'src/inet.c')
-rw-r--r--src/inet.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/src/inet.c b/src/inet.c
index a659ab0d..d9e12a9b 100644
--- a/src/inet.c
+++ b/src/inet.c
@@ -1722,3 +1722,53 @@ int __connman_inet_ipv6_send_rs(int index, int timeout,
return 0;
}
+
+GSList *__connman_inet_ipv6_get_prefixes(struct nd_router_advert *hdr,
+ unsigned int length)
+{
+ GSList *prefixes = NULL;
+ uint8_t *pos;
+ int len;
+
+ if (length <= sizeof(struct nd_router_advert))
+ return NULL;
+
+ len = length - sizeof(struct nd_router_advert);
+ pos = (uint8_t *)hdr + sizeof(struct nd_router_advert);
+
+ while (len > 0) {
+ struct nd_opt_prefix_info *pinfo;
+ char prefix_str[INET6_ADDRSTRLEN+1], *str;
+ const char *prefix;
+ int optlen;
+
+ if (len < 2)
+ break;
+
+ optlen = pos[1] << 3;
+ if (optlen == 0 || optlen > len)
+ break;
+
+ switch (pos[0]) {
+ case ND_OPT_PREFIX_INFORMATION:
+ pinfo = (struct nd_opt_prefix_info *)pos;
+ prefix = inet_ntop(AF_INET6, &pinfo->nd_opt_pi_prefix,
+ prefix_str, INET6_ADDRSTRLEN);
+ if (prefix == NULL)
+ break;
+
+ str = g_strdup_printf("%s/%d", prefix,
+ pinfo->nd_opt_pi_prefix_len);
+ prefixes = g_slist_append(prefixes, str);
+
+ DBG("prefix %s", str);
+
+ break;
+ }
+
+ len -= optlen;
+ pos += optlen;
+ }
+
+ return prefixes;
+}