Skip to content

Commit

Permalink
Merge pull request #18161 from maribu/sys/net/netif
Browse files Browse the repository at this point in the history
sys/net/netif: add convenience functions for getting/printing IPv6 addresses
  • Loading branch information
benpicco authored Jun 6, 2022
2 parents a6ac93d + 6b2a1f7 commit bdf1c97
Show file tree
Hide file tree
Showing 10 changed files with 180 additions and 68 deletions.
22 changes: 5 additions & 17 deletions examples/gnrc_minimal/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,29 +24,17 @@
#include "net/ipv6/addr.h"
#include "net/gnrc.h"
#include "net/gnrc/netif.h"
#include "net/netif.h"

int main(void)
{

puts("RIOT network stack example application");

/* get interfaces and print their addresses */
gnrc_netif_t *netif = NULL;
while ((netif = gnrc_netif_iter(netif))) {
ipv6_addr_t ipv6_addrs[CONFIG_GNRC_NETIF_IPV6_ADDRS_NUMOF];
int res = gnrc_netapi_get(netif->pid, NETOPT_IPV6_ADDR, 0, ipv6_addrs,
sizeof(ipv6_addrs));

if (res < 0) {
continue;
}
for (unsigned i = 0; i < (unsigned)(res / sizeof(ipv6_addr_t)); i++) {
char ipv6_addr[IPV6_ADDR_MAX_STR_LEN];

ipv6_addr_to_str(ipv6_addr, &ipv6_addrs[i], IPV6_ADDR_MAX_STR_LEN);
printf("My address is %s\n", ipv6_addr);
}
}
/* print all IPv6 addresses */
printf("{\"IPv6 addresses\": [\"");
netifs_print_ipv6("\", \"");
puts("\"]}");

/* main thread exits */
return 0;
Expand Down
3 changes: 0 additions & 3 deletions examples/nanocoap_server/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ USEMODULE += fmt
# include sha256 (used by example blockwise handler)
USEMODULE += hashes

# include this for printing IP addresses
USEMODULE += shell_commands

# Comment this out to enable code in RIOT that does safety checking
# which is not needed in a production environment but helps in the
# development process:
Expand Down
8 changes: 3 additions & 5 deletions examples/nanocoap_server/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
#define MAIN_QUEUE_SIZE (8)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];

/* import "ifconfig" shell command, used for printing addresses */
extern int _gnrc_netif_config(int argc, char **argv);

int main(void)
{
puts("RIOT nanocoap example application");
Expand All @@ -41,8 +38,9 @@ int main(void)
xtimer_sleep(3);

/* print network addresses */
puts("Configured network interfaces:");
_gnrc_netif_config(0, NULL);
printf("{\"IPv6 addresses\": [\"");
netifs_print_ipv6("\", \"");
puts("\"]}");

/* initialize nanocoap server instance */
uint8_t buf[COAP_INBUF_SIZE];
Expand Down
26 changes: 4 additions & 22 deletions examples/telnet_server/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,6 @@
#define MAIN_QUEUE_SIZE (8)
static msg_t _main_msg_queue[MAIN_QUEUE_SIZE];

static void _print_addr(void)
{
gnrc_netif_t *netif = NULL;
while ((netif = gnrc_netif_iter(netif))) {
ipv6_addr_t ipv6_addrs[CONFIG_GNRC_NETIF_IPV6_ADDRS_NUMOF];
int res = gnrc_netapi_get(netif->pid, NETOPT_IPV6_ADDR, 0, ipv6_addrs,
sizeof(ipv6_addrs));

if (res < 0) {
continue;
}
for (unsigned i = 0; i < (unsigned)(res / sizeof(ipv6_addr_t)); i++) {
char ipv6_addr[IPV6_ADDR_MAX_STR_LEN];

ipv6_addr_to_str(ipv6_addr, &ipv6_addrs[i], IPV6_ADDR_MAX_STR_LEN);
printf("My address is %s\n", ipv6_addr);
}
}
}

static void _print_motd(void)
{
puts("RIOT telnet example application");
Expand Down Expand Up @@ -90,8 +70,10 @@ int main(void)

_print_motd();

/* print address so we can connect to it */
_print_addr();
/* print address(es) so we can connect to it */
printf("{\"IPv6 addresses\": [\"");
netifs_print_ipv6("\", \"");
puts("\"]}");

/* start shell */
printf("All up, awaiting connection on port %u\n", CONFIG_TELNET_PORT);
Expand Down
12 changes: 11 additions & 1 deletion sys/include/net/ipv6/addr.h
Original file line number Diff line number Diff line change
Expand Up @@ -816,10 +816,20 @@ static inline char *ipv6_addr_split_iface(char *addr_str)
/**
* @brief Print IPv6 address to stdout
*
* @param[in] addr Pointer to ipv6_addr_t to print
* @param[in] addr Pointer to ipv6_addr_t to print
*/
void ipv6_addr_print(const ipv6_addr_t *addr);

/**
* @brief Print IPv6 addresses to stdout
*
* @param[in] addrs Array of addresses to print
* @param[in] num Number of elements in @p addrs
* @param[in] separator Separator to print between addresses
*/
void ipv6_addrs_print(const ipv6_addr_t *addrs, size_t num,
const char *separator);

#ifdef __cplusplus
}
#endif
Expand Down
61 changes: 61 additions & 0 deletions sys/include/net/netif.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@

#include <stdint.h>
#include <string.h>
#include <unistd.h>

#include "list.h"
#include "net/netopt.h"
#include "net/ipv6.h"

#ifdef MODULE_NETSTATS_NEIGHBOR
#include "cib.h"
Expand Down Expand Up @@ -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
Expand Down
52 changes: 51 additions & 1 deletion sys/net/netif/netif.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@
*/

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>

#include "errno.h"
#include "irq.h"
#include "kernel_defines.h"
#include "net/netif.h"
#include "utlist.h"

Expand Down Expand Up @@ -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);
}
}
}
/** @} */
51 changes: 40 additions & 11 deletions sys/net/network_layer/ipv6/addr/ipv6_addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,11 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include "net/ipv6/addr.h"

#ifdef MODULE_FMT
#include "fmt.h"
#else
#include <stdio.h>
#endif
#include "kernel_defines.h"
#include "net/ipv6/addr.h"

const ipv6_addr_t ipv6_addr_unspecified = IPV6_ADDR_UNSPECIFIED;
const ipv6_addr_t ipv6_addr_loopback = IPV6_ADDR_LOOPBACK;
Expand Down Expand Up @@ -147,11 +144,43 @@ void ipv6_addr_print(const ipv6_addr_t *addr)
assert(addr);
char addr_str[IPV6_ADDR_MAX_STR_LEN];
ipv6_addr_to_str(addr_str, addr, sizeof(addr_str));
#ifdef MODULE_FMT
print_str(addr_str);
#else
printf("%s", addr_str);
#endif

if (IS_USED(MODULE_FMT)) {
print_str(addr_str);
}
else {
printf("%s", addr_str);
}
}

void ipv6_addrs_print(const ipv6_addr_t *addrs, size_t num,
const char *separator)
{
if (num == 0) {
return;
}

num--;
char buf[IPV6_ADDR_MAX_STR_LEN];
for (size_t idx = 0; idx < (size_t)num; idx++) {
ipv6_addr_to_str(buf, &addrs[idx], sizeof(buf));
if (IS_USED(MODULE_FMT)) {
print_str(buf);
print_str(separator);
}
else {
printf("%s%s", buf, separator);
}
}

ipv6_addr_to_str(buf, &addrs[num], sizeof(buf));
if (IS_USED(MODULE_FMT)) {
print_str(buf);
print_str(separator);
}
else {
printf("%s%s", buf, separator);
}
}

/**
Expand Down
3 changes: 0 additions & 3 deletions tests/pkg_microcoap/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ USEMODULE += xtimer

USEPKG += microcoap

# include this for printing IP addresses
USEMODULE += shell_commands

# Use different settings when compiling for one of the following (low-memory)
# boards
LOW_MEMORY_BOARDS := nucleo-f334r8
Expand Down
10 changes: 5 additions & 5 deletions tests/pkg_microcoap/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,13 @@
*/

#include <stdio.h>

#include "msg.h"
#include "net/netif.h"
#include "xtimer.h"

void microcoap_server_loop(void);

/* import "ifconfig" shell command, used for printing addresses */
extern int _gnrc_netif_config(int argc, char **argv);

int main(void)
{
puts("RIOT microcoap test application");
Expand All @@ -34,8 +33,9 @@ int main(void)
xtimer_sleep(3);

/* print network addresses */
puts("Configured network interfaces:");
_gnrc_netif_config(0, NULL);
printf("{\"IPv6 addresses\": [\"");
netifs_print_ipv6("\", \"");
puts("\"]}");

/* start coap server loop */
microcoap_server_loop();
Expand Down

0 comments on commit bdf1c97

Please sign in to comment.