netlib_ipv[4|6]adaptor: Add a check to handle the case where the network device configuration changed asynchronously and the second IOCTL returns more data than the allocated buffer.
This commit is contained in:
parent
2cd27e17a1
commit
fb804e3498
@ -160,11 +160,11 @@ int netlib_get_ipv6addr(FAR const char *ifname, FAR struct in6_addr *addr);
|
||||
int netlib_set_ipv6addr(FAR const char *ifname, FAR const struct in6_addr *addr);
|
||||
int netlib_set_dripv6addr(FAR const char *ifname, FAR const struct in6_addr *addr);
|
||||
int netlib_set_ipv6netmask(FAR const char *ifname, FAR const struct in6_addr *addr);
|
||||
int netlib_ipv6adaptor(FAR const struct in6_addr *destipaddr,
|
||||
FAR struct in6_addr *srcipaddr);
|
||||
|
||||
uint8_t netlib_ipv6netmask2prefix(FAR const uint16_t *mask);
|
||||
void netlib_prefix2ipv6netmask(uint8_t preflen, FAR struct in6_addr *netmask);
|
||||
int netlib_ipv6adaptor(FAR const struct in6_addr *destipaddr,
|
||||
FAR struct in6_addr *srcipaddr);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NETDEV_WIRELESS_IOCTL
|
||||
|
@ -91,6 +91,8 @@ int netlib_ipv4adaptor(in_addr_t destipaddr, FAR in_addr_t *srcipaddr)
|
||||
{
|
||||
FAR struct ifreq *ifr;
|
||||
struct ifconf ifc;
|
||||
size_t allocsize;
|
||||
size_t buflen;
|
||||
int nintf;
|
||||
int ret;
|
||||
int sd;
|
||||
@ -123,7 +125,8 @@ int netlib_ipv4adaptor(in_addr_t destipaddr, FAR in_addr_t *srcipaddr)
|
||||
|
||||
/* Allocate the buffer to hold the interface descriptions */
|
||||
|
||||
ifr = (FAR struct ifreq *)malloc(ifc.ifc_len);
|
||||
allocsize = ifc.ifc_len;
|
||||
ifr = (FAR struct ifreq *)malloc(allocsize);
|
||||
if (ifr == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to allocate IFC buffer\n");
|
||||
@ -144,10 +147,22 @@ int netlib_ipv4adaptor(in_addr_t destipaddr, FAR in_addr_t *srcipaddr)
|
||||
}
|
||||
|
||||
/* Find an interface that supports the subnet needed by the provided
|
||||
* IPv4 address.
|
||||
* IPv4 address. Be careful! The size of the returned buffer could
|
||||
* be different if the network device configuration changed in between
|
||||
* the two calls!
|
||||
*/
|
||||
|
||||
nintf = ifc.ifc_len / sizeof(struct ifreq);
|
||||
buflen = ifc.ifc_len;
|
||||
if (buflen > allocsize)
|
||||
{
|
||||
/* Something has changed. Limit to the original size (OR do the
|
||||
* allocation and IOCTL again).
|
||||
*/
|
||||
|
||||
buflen = allocsize;
|
||||
}
|
||||
|
||||
nintf = buflen / sizeof(struct ifreq);
|
||||
ret = -EHOSTUNREACH;
|
||||
|
||||
for (i = 0; i < nintf; i++)
|
||||
|
@ -92,6 +92,8 @@ int netlib_ipv6adaptor(FAR const struct in6_addr *destipaddr,
|
||||
{
|
||||
FAR struct lifreq *lifr;
|
||||
struct lifconf lifc;
|
||||
size_t allocsize;
|
||||
size_t buflen;
|
||||
int nintf;
|
||||
int ret;
|
||||
int sd;
|
||||
@ -124,7 +126,8 @@ int netlib_ipv6adaptor(FAR const struct in6_addr *destipaddr,
|
||||
|
||||
/* Allocate the buffer to hold the interface descriptions */
|
||||
|
||||
lifr = (FAR struct lifreq *)malloc(lifc.lifc_len);
|
||||
allocsize = lifc.lifc_len;
|
||||
lifr = (FAR struct lifreq *)malloc(allocsize);
|
||||
if (lifr == NULL)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to allocate LIFC buffer\n");
|
||||
@ -145,10 +148,22 @@ int netlib_ipv6adaptor(FAR const struct in6_addr *destipaddr,
|
||||
}
|
||||
|
||||
/* Find an interface that supports the subnet needed by the provided
|
||||
* IPv6 address.
|
||||
* IPv6 address. Be careful! The size of the returned buffer could
|
||||
* be different if the network device configuration changed in between
|
||||
* the two calls!
|
||||
*/
|
||||
|
||||
nintf = lifc.lifc_len / sizeof(struct lifreq);
|
||||
buflen = lifc.lifc_len;
|
||||
if (buflen > allocsize)
|
||||
{
|
||||
/* Something has changed. Limit to the original size (OR do the
|
||||
* allocation and IOCTL again).
|
||||
*/
|
||||
|
||||
buflen = allocsize;
|
||||
}
|
||||
|
||||
nintf = buflen / sizeof(struct lifreq);
|
||||
ret = -EHOSTUNREACH;
|
||||
|
||||
for (i = 0; i < nintf; i++)
|
||||
|
Loading…
x
Reference in New Issue
Block a user