diff --git a/sys/include/net/netif.h b/sys/include/net/netif.h index 2316695fa3..0540c2db99 100644 --- a/sys/include/net/netif.h +++ b/sys/include/net/netif.h @@ -35,9 +35,11 @@ #include #include +#include #include "list.h" #include "net/netopt.h" +#include "net/ipv6.h" #ifdef MODULE_NETSTATS_NEIGHBOR #include "cib.h" @@ -200,6 +202,65 @@ int netif_set_opt(netif_t *netif, netopt_t opt, uint16_t context, */ int netif_register(netif_t *netif); +/** + * @brief Get IPv6 address(es) of the given interface + * @param[in] netif Interface to get the IPv6 address(es) from + * @param[out] dest Array of IPv6 addresses to write to + * @param[in] numof Size of @p dest in array elements (not in bytes!) + * @retval -1 Failed + * @return Number of addresses written to @p dest + */ +static inline ssize_t netif_get_ipv6(netif_t *netif, ipv6_addr_t *dest, + size_t numof) +{ + int res = netif_get_opt(netif, NETOPT_IPV6_ADDR, 0, dest, sizeof(*dest) * numof); + if (res < 0) { + /* standard says at ssize_t's value range is [-1, SSIZE_MAX], so do + * not rely on smaller numbers that -1 being passed through correctly */ + return -1; + } + + return res / sizeof(*dest); +} + +/** + * @brief Get IPv6 address(es) of **all** interfaces + * @param[out] dest Array of IPv6 addresses to write to + * @param[in] numof Size of @p dest in array elements (not in bytes!) + * @retval -1 Failed + * @return Number of addresses written to @p dest + */ +ssize_t netifs_get_ipv6(ipv6_addr_t *dest, size_t numof); + +/** + * @brief Print the IPv6 address(es) of the given interface + * @param[in] netif Interface to print the IPv6 address(es) of + * @param[in] separator Separator to print between the IPv6 addresses + * + * Usage: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c} + * // print IPv6 addrs of netif as JSON + * printf("{\"IPv6 addresses\": [\""); + * netif_print_ipv6(netif, "\", \""); + * puts("\"]}"); + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +void netif_print_ipv6(netif_t *netif, const char *separator); + +/** + * @brief Print the IPv6 address(es) of **all** interface + * @param[in] separator Separator to print between the IPv6 addresses + * + * Usage: + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.c} + * // print all IPv6 addrs as JSON + * printf("{\"IPv6 addresses\": [\""); + * netifs_print_ipv6("\", \""); + * puts("\"]}"); + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +void netifs_print_ipv6(const char *separator); + #ifdef __cplusplus } #endif diff --git a/sys/net/netif/netif.c b/sys/net/netif/netif.c index 57064d05d7..79f2ce24c8 100644 --- a/sys/net/netif/netif.c +++ b/sys/net/netif/netif.c @@ -14,10 +14,12 @@ */ #include +#include +#include #include -#include "errno.h" #include "irq.h" +#include "kernel_defines.h" #include "net/netif.h" #include "utlist.h" @@ -91,4 +93,52 @@ __attribute__((weak)) netif_t *netif_get_by_id(int16_t id) return NULL; } +ssize_t netifs_get_ipv6(ipv6_addr_t *dest, size_t numof) +{ + ssize_t result = 0; + netif_t *netif = NULL; + while (((netif = netif_iter(netif)) != NULL) && (numof > 0)) { + ssize_t addrs_numof = netif_get_ipv6(netif, dest, numof); + if (addrs_numof <= 0) { + continue; + } + result += addrs_numof; + dest += addrs_numof; + numof -= addrs_numof; + } + + return result; +} + +#ifndef NETIF_PRINT_IPV6_NUMOF +#define NETIF_PRINT_IPV6_NUMOF 4 +#endif + +void netif_print_ipv6(netif_t *netif, const char *separator) +{ + ipv6_addr_t addrs[NETIF_PRINT_IPV6_NUMOF]; + ssize_t num = netif_get_ipv6(netif, addrs, ARRAY_SIZE(addrs)); + if (num > 0) { + ipv6_addrs_print(addrs, num, separator); + } +} + +void netifs_print_ipv6(const char *separator) +{ + netif_t *netif = 0; + bool first = true; + while ((netif = netif_iter(netif)) != NULL) { + ipv6_addr_t addrs[NETIF_PRINT_IPV6_NUMOF]; + ssize_t num = netif_get_ipv6(netif, addrs, ARRAY_SIZE(addrs)); + if (num > 0) { + if (first) { + first = false; + } + else { + printf("%s", separator); + } + ipv6_addrs_print(addrs, num, separator); + } + } +} /** @} */