This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 884a6803d659b93b9e7291009c0d9645284a9059 Author: meijian <[email protected]> AuthorDate: Fri Oct 18 14:11:47 2024 +0800 net/getifaddrs: Support multiple IPv6 addresses for getifaddrs Signed-off-by: meijian <[email protected]> --- libs/libc/net/lib_getifaddrs.c | 78 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/libs/libc/net/lib_getifaddrs.c b/libs/libc/net/lib_getifaddrs.c index 7a722e9a0d..2bb67dc806 100644 --- a/libs/libc/net/lib_getifaddrs.c +++ b/libs/libc/net/lib_getifaddrs.c @@ -24,6 +24,7 @@ * Included Files ****************************************************************************/ +#include <debug.h> #include <errno.h> #include <ifaddrs.h> #include <net/if.h> @@ -57,6 +58,76 @@ struct myifaddrs struct sockaddr hwaddr; }; +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: getmutil_ipv6addr + * + * Input Parameters: + * fd - socket fd of ioctl. + * req - lifreq struct for ioctl request. + * ifaddr - the ifaddrs struct to be filled. + * + * Returned Value: + * On success, getmutil_ipv6addr() returns newest pointer of the linked + * list; on error, NULL is returned. + * + ****************************************************************************/ + +#ifdef CONFIG_NETDEV_MAX_IPv6_ADDR +static FAR struct myifaddrs *getmutil_ipv6addr(int fd, struct lifreq *req, + FAR struct myifaddrs *ifaddr) +{ + FAR struct sockaddr_in6 *ipv6addr; + int index; + + /* eth0:0 is the second ipaddr */ + + for (index = 0; index < CONFIG_NETDEV_MAX_IPv6_ADDR - 1; index++) + { + int len = snprintf(req->lifr_name, sizeof(req->lifr_name), + "%s:%d", ifaddr->name, index); + + if (len < 0 || len >= sizeof(req->lifr_name)) + { + nwarn("ifname %s:%2d error or too long\n", ifaddr->name, index); + return ifaddr; + } + + if (ioctl(fd, SIOCGLIFADDR, (unsigned long)req) < 0) + { + continue; + } + + ipv6addr = (FAR struct sockaddr_in6 *)&(req->lifr_addr); + if (IN6_IS_ADDR_UNSPECIFIED(&ipv6addr->sin6_addr)) + { + continue; + } + + ifaddr->addrs.ifa_next = lib_zalloc(sizeof(*ifaddr)); + if (ifaddr == NULL) + { + return NULL; + } + + memcpy(ifaddr->addrs.ifa_next, ifaddr, sizeof(struct myifaddrs)); + ifaddr = (FAR struct myifaddrs *)ifaddr->addrs.ifa_next; + memcpy(&ifaddr->addr, &(req->lifr_addr), sizeof(req->lifr_addr)); + ifaddr->addrs.ifa_addr = (FAR struct sockaddr *)&ifaddr->addr; + ifaddr->addrs.ifa_netmask = (FAR struct sockaddr *)&ifaddr->netmask; + ifaddr->addrs.ifa_dstaddr = (FAR struct sockaddr *)&ifaddr->dstaddr; + ifaddr->addrs.ifa_broadaddr = + (FAR struct sockaddr *)&ifaddr->broadaddr; + ifaddr->addrs.ifa_data = (FAR struct sockaddr *)&ifaddr->hwaddr; + } + + return ifaddr; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -267,6 +338,13 @@ int getifaddrs(FAR struct ifaddrs **addrs) memcpy(&myaddrs->hwaddr, &req.lifr_hwaddr, sizeof(req.lifr_hwaddr)); } + +# ifdef CONFIG_NETDEV_MAX_IPv6_ADDR + if (getmutil_ipv6addr(sockfd, &req, myaddrs) == NULL) + { + goto err; + } +# endif } #endif }
