From a00eeb638a89aa775076efdf1e26a271b0c15982 Mon Sep 17 00:00:00 2001 From: Chris Friedt Date: Fri, 22 Mar 2024 21:03:13 -0400 Subject: [PATCH] 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 --- include/zephyr/posix/net/if.h | 16 +++++- lib/posix/options/net.c | 98 +++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 1 deletion(-) diff --git a/include/zephyr/posix/net/if.h b/include/zephyr/posix/net/if.h index a8d6183cf8..80360a6960 100644 --- a/include/zephyr/posix/net/if.h +++ b/include/zephyr/posix/net/if.h @@ -6,12 +6,26 @@ #ifndef ZEPHYR_INCLUDE_POSIX_NET_IF_H_ #define ZEPHYR_INCLUDE_POSIX_NET_IF_H_ -#include +#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 diff --git a/lib/posix/options/net.c b/lib/posix/options/net.c index 76e1cef3f6..f489910eae 100644 --- a/lib/posix/options/net.c +++ b/lib/posix/options/net.c @@ -6,9 +6,12 @@ #include #include +#include +#include #include #include +#include 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; +}