@@ -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+
229356InterfaceIterator::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