diff options
author | Jukka Rissanen <jukka.rissanen@linux.intel.com> | 2012-01-05 13:38:07 +0200 |
---|---|---|
committer | Daniel Wagner <daniel.wagner@bmw-carit.de> | 2012-01-05 13:17:26 +0100 |
commit | 6ea547962997517629240c4c9d8e5a2592a6a95a (patch) | |
tree | 0693bccff7815bc96168c91f7ce61ef174196e5b /src/inet.c | |
parent | 931367f3c9574b7fc473fdce23627f4108cfb90d (diff) | |
download | connman-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.c | 50 |
1 files changed, 50 insertions, 0 deletions
@@ -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; +} |