Skip to content
This repository was archived by the owner on Dec 20, 2023. It is now read-only.

Commit 1898571

Browse files
authored
Merge pull request #506 from robszewczyk/bug/android-ndk-21-support
Provide implementation of if_nameindex
2 parents 460c826 + 407ab73 commit 1898571

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

src/inet/InetInterface.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,133 @@ void CloseIOCTLSocket(void)
226226

227227
#if WEAVE_SYSTEM_CONFIG_USE_SOCKETS
228228

229+
#if __ANDROID__ && __ANDROID_API__ < 24
230+
231+
static struct if_nameindex * backport_if_nameindex(void);
232+
static void backport_if_freenameindex(struct if_nameindex *);
233+
234+
static void backport_if_freenameindex(struct if_nameindex * inArray)
235+
{
236+
if (inArray == NULL)
237+
return;
238+
239+
for (size_t i = 0; inArray[i].if_index != 0; i++)
240+
{
241+
if (inArray[i].if_name != NULL)
242+
free(inArray[i].if_name);
243+
}
244+
245+
free(inArray);
246+
}
247+
248+
static struct if_nameindex * backport_if_nameindex(void)
249+
{
250+
int err;
251+
unsigned index;
252+
size_t intfIter = 0;
253+
size_t maxIntfNum = 0;
254+
size_t numIntf = 0;
255+
size_t numAddrs = 0;
256+
struct if_nameindex * retval = NULL;
257+
struct if_nameindex * tmpval = NULL;
258+
struct ifaddrs * addrList = NULL;
259+
struct ifaddrs * addrIter = NULL;
260+
const char * lastIntfName = "";
261+
262+
err = getifaddrs(&addrList);
263+
VerifyOrExit(err >= 0, );
264+
265+
// coalesce on consecutive interface names
266+
for (addrIter = addrList; addrIter != NULL; addrIter = addrIter->ifa_next)
267+
{
268+
numAddrs++;
269+
if (strcmp(addrIter->ifa_name, lastIntfName) == 0)
270+
continue;
271+
numIntf++;
272+
lastIntfName = addrIter->ifa_name;
273+
}
274+
275+
tmpval = (struct if_nameindex *) malloc((numIntf + 1) * sizeof(struct if_nameindex));
276+
VerifyOrExit(tmpval != NULL, );
277+
memset(tmpval, 0, (numIntf + 1) * sizeof(struct if_nameindex));
278+
279+
lastIntfName = "";
280+
for (addrIter = addrList; addrIter != NULL; addrIter = addrIter->ifa_next)
281+
{
282+
if (strcmp(addrIter->ifa_name, lastIntfName) == 0)
283+
continue;
284+
285+
index = if_nametoindex(addrIter->ifa_name);
286+
if (index != 0)
287+
{
288+
tmpval[intfIter].if_index = index;
289+
tmpval[intfIter].if_name = strdup(addrIter->ifa_name);
290+
intfIter++;
291+
}
292+
lastIntfName = addrIter->ifa_name;
293+
}
294+
295+
// coalesce on interface index
296+
maxIntfNum = 0;
297+
for (size_t i = 0; tmpval[i].if_index != 0; i++)
298+
{
299+
if (maxIntfNum < tmpval[i].if_index)
300+
maxIntfNum = tmpval[i].if_index;
301+
}
302+
303+
retval = (struct if_nameindex *) malloc((maxIntfNum + 1) * sizeof(struct if_nameindex));
304+
VerifyOrExit(retval != NULL, );
305+
memset(retval, 0, (maxIntfNum + 1) * sizeof(struct if_nameindex));
306+
307+
for (size_t i = 0; tmpval[i].if_index != 0; i++)
308+
{
309+
struct if_nameindex * intf = &tmpval[i];
310+
if (retval[intf->if_index - 1].if_index == 0)
311+
{
312+
retval[intf->if_index - 1] = *intf;
313+
}
314+
else
315+
{
316+
free(intf->if_name);
317+
intf->if_index = 0;
318+
intf->if_name = 0;
319+
}
320+
}
321+
322+
intfIter = 0;
323+
324+
// coalesce potential gaps between indeces
325+
for (size_t i = 0; i < maxIntfNum; i++)
326+
{
327+
if (retval[i].if_index != 0)
328+
{
329+
retval[intfIter] = retval[i];
330+
intfIter++;
331+
}
332+
}
333+
334+
for (size_t i = intfIter; i < maxIntfNum; i++)
335+
{
336+
retval[i].if_index = 0;
337+
retval[i].if_name = NULL;
338+
}
339+
340+
exit:
341+
if (tmpval != NULL)
342+
{
343+
free(tmpval);
344+
}
345+
346+
if (addrList != NULL)
347+
{
348+
freeifaddrs(addrList);
349+
}
350+
351+
return retval;
352+
}
353+
354+
#endif // __ANDROID__ && __ANDROID_API__ < 24
355+
229356
InterfaceIterator::InterfaceIterator(void)
230357
{
231358
mIntfArray = NULL;
@@ -251,7 +378,11 @@ InterfaceIterator::~InterfaceIterator(void)
251378
{
252379
if (mIntfArray != NULL)
253380
{
381+
#if __ANDROID__ && __ANDROID_API__ < 24
382+
backport_if_freenameindex(mIntfArray);
383+
#else
254384
if_freenameindex(mIntfArray);
385+
#endif
255386
mIntfArray = NULL;
256387
}
257388
}
@@ -304,7 +435,11 @@ bool InterfaceIterator::Next(void)
304435

305436
if (mIntfArray == NULL)
306437
{
438+
#if __ANDROID__ && __ANDROID_API__ < 24
439+
mIntfArray = backport_if_nameindex();
440+
#else
307441
mIntfArray = if_nameindex();
442+
#endif
308443
}
309444
else if (mIntfArray[mCurIntf].if_index != 0)
310445
{

0 commit comments

Comments
 (0)