net/getifaddrs: Support multiple IPv6 addresses for getifaddrs
Signed-off-by: meijian <meijian@xiaomi.com>
This commit is contained in:
parent
f6cfcfa39f
commit
884a6803d6
1 changed files with 78 additions and 0 deletions
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue