posix: net: implement if_nameindex() et al

Implement if_indextoname(), if_freenameindex(), if_nameindex(),
and if_nametoindex() by wrapping around networking subystem
calls.

Signed-off-by: Chris Friedt <chrisfriedt@gmail.com>
This commit is contained in:
Chris Friedt 2024-03-22 21:03:13 -04:00
parent bfb91da5ec
commit a00eeb638a
2 changed files with 113 additions and 1 deletions

View file

@ -6,12 +6,26 @@
#ifndef ZEPHYR_INCLUDE_POSIX_NET_IF_H_
#define ZEPHYR_INCLUDE_POSIX_NET_IF_H_
#include <zephyr/net/socket.h>
#ifdef CONFIG_NET_INTERFACE_NAME_LEN
#define IF_NAMESIZE CONFIG_NET_INTERFACE_NAME_LEN
#else
#define IF_NAMESIZE 1
#endif
#ifdef __cplusplus
extern "C" {
#endif
struct if_nameindex {
unsigned int if_index;
char *if_name;
};
char *if_indextoname(unsigned int ifindex, char *ifname);
void if_freenameindex(struct if_nameindex *ptr);
struct if_nameindex *if_nameindex(void);
unsigned int if_nametoindex(const char *ifname);
#ifdef __cplusplus
}
#endif

View file

@ -6,9 +6,12 @@
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <zephyr/net/net_if.h>
#include <zephyr/posix/arpa/inet.h>
#include <zephyr/posix/netinet/in.h>
#include <zephyr/posix/net/if.h>
in_addr_t inet_addr(const char *cp)
{
@ -76,3 +79,98 @@ char *inet_ntoa(struct in_addr in)
return buf;
}
char *if_indextoname(unsigned int ifindex, char *ifname)
{
int ret;
if (!IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) {
errno = ENOTSUP;
return NULL;
}
ret = net_if_get_name(net_if_get_by_index(ifindex), ifname, IF_NAMESIZE);
if (ret < 0) {
errno = ENXIO;
return NULL;
}
return ifname;
}
void if_freenameindex(struct if_nameindex *ptr)
{
size_t n;
if (ptr == NULL || !IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) {
return;
}
NET_IFACE_COUNT(&n);
for (size_t i = 0; i < n; ++i) {
if (IS_ENABLED(CONFIG_NET_INTERFACE_NAME) && ptr[i].if_name != NULL) {
free(ptr[i].if_name);
}
}
free(ptr);
}
struct if_nameindex *if_nameindex(void)
{
size_t n;
char *name;
struct if_nameindex *ni;
if (!IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) {
errno = ENOTSUP;
return NULL;
}
/* FIXME: would be nice to use this without malloc */
NET_IFACE_COUNT(&n);
ni = malloc((n + 1) * sizeof(*ni));
if (ni == NULL) {
goto return_err;
}
for (size_t i = 0; i < n; ++i) {
ni[i].if_index = i + 1;
ni[i].if_name = malloc(IF_NAMESIZE);
if (ni[i].if_name == NULL) {
goto return_err;
}
name = if_indextoname(i + 1, ni[i].if_name);
__ASSERT_NO_MSG(name != NULL);
}
ni[n].if_index = 0;
ni[n].if_name = NULL;
return ni;
return_err:
if_freenameindex(ni);
errno = ENOBUFS;
return NULL;
}
unsigned int if_nametoindex(const char *ifname)
{
int ret;
if (!IS_ENABLED(CONFIG_NET_INTERFACE_NAME)) {
return 0;
}
ret = net_if_get_by_name(ifname);
if (ret < 0) {
return 0;
}
return ret;
}