Rizin
unix-like reverse engineering framework and cli tools
android-ifaddrs.c File Reference
#include "uv/android-ifaddrs.h"
#include "uv-common.h"
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <netinet/in.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/if_packet.h>

Go to the source code of this file.

Classes

struct  NetlinkList
 

Typedefs

typedef struct NetlinkList NetlinkList
 

Functions

static int netlink_socket (pid_t *p_pid)
 
static int netlink_send (int p_socket, int p_request)
 
static int netlink_recv (int p_socket, void *p_buffer, size_t p_len)
 
static struct nlmsghdr * getNetlinkResponse (int p_socket, pid_t p_pid, int *p_size, int *p_done)
 
static NetlinkListnewListItem (struct nlmsghdr *p_data, unsigned int p_size)
 
static void freeResultList (NetlinkList *p_list)
 
static NetlinkListgetResultList (int p_socket, int p_request, pid_t p_pid)
 
static size_t maxSize (size_t a, size_t b)
 
static size_t calcAddrLen (sa_family_t p_family, int p_dataSize)
 
static void makeSockaddr (sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size)
 
static void addToEnd (struct ifaddrs **p_resultList, struct ifaddrs *p_entry)
 
static int interpretLink (struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)
 
static struct ifaddrsfindInterface (int p_index, struct ifaddrs **p_links, int p_numLinks)
 
static int interpretAddr (struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, int p_numLinks)
 
static int interpretLinks (int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList)
 
static int interpretAddrs (int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks)
 
int getifaddrs (struct ifaddrs **ifap)
 
void freeifaddrs (struct ifaddrs *ifa)
 

Typedef Documentation

◆ NetlinkList

typedef struct NetlinkList NetlinkList

Function Documentation

◆ addToEnd()

static void addToEnd ( struct ifaddrs **  p_resultList,
struct ifaddrs p_entry 
)
static

Definition at line 307 of file android-ifaddrs.c.

308 {
309  if(!*p_resultList)
310  {
311  *p_resultList = p_entry;
312  }
313  else
314  {
315  struct ifaddrs *l_cur = *p_resultList;
316  while(l_cur->ifa_next)
317  {
318  l_cur = l_cur->ifa_next;
319  }
320  l_cur->ifa_next = p_entry;
321  }
322 }
struct ifaddrs * ifa_next

References ifaddrs::ifa_next.

Referenced by interpretAddr(), and interpretLink().

◆ calcAddrLen()

static size_t calcAddrLen ( sa_family_t  p_family,
int  p_dataSize 
)
static

Definition at line 271 of file android-ifaddrs.c.

272 {
273  switch(p_family)
274  {
275  case AF_INET:
276  return sizeof(struct sockaddr_in);
277  case AF_INET6:
278  return sizeof(struct sockaddr_in6);
279  case AF_PACKET:
280  return maxSize(sizeof(struct sockaddr_ll), offsetof(struct sockaddr_ll, sll_addr) + p_dataSize);
281  default:
282  return maxSize(sizeof(struct sockaddr), offsetof(struct sockaddr, sa_data) + p_dataSize);
283  }
284 }
static size_t maxSize(size_t a, size_t b)
#define offsetof(type, member)
#define AF_INET
Definition: sftypes.h:287
#define AF_INET6
Definition: sftypes.h:295
#define AF_PACKET
Definition: sftypes.h:303

References AF_INET, AF_INET6, AF_PACKET, maxSize(), and offsetof.

Referenced by interpretAddr(), and interpretLink().

◆ findInterface()

static struct ifaddrs* findInterface ( int  p_index,
struct ifaddrs **  p_links,
int  p_numLinks 
)
static

Definition at line 424 of file android-ifaddrs.c.

425 {
426  int l_num = 0;
427  struct ifaddrs *l_cur = *p_links;
428  while(l_cur && l_num < p_numLinks)
429  {
430  char *l_indexPtr = ((char *)l_cur) + sizeof(struct ifaddrs);
431  int l_index;
432  memcpy(&l_index, l_indexPtr, sizeof(int));
433  if(l_index == p_index)
434  {
435  return l_cur;
436  }
437 
438  l_cur = l_cur->ifa_next;
439  ++l_num;
440  }
441  return NULL;
442 }
#define NULL
Definition: cris-opc.c:27
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))

References ifaddrs::ifa_next, memcpy(), and NULL.

Referenced by interpretAddr().

◆ freeifaddrs()

void freeifaddrs ( struct ifaddrs ifa)

Definition at line 704 of file android-ifaddrs.c.

705 {
706  struct ifaddrs *l_cur;
707  while(ifa)
708  {
709  l_cur = ifa;
710  ifa = ifa->ifa_next;
711  uv__free(l_cur);
712  }
713 }
void uv__free(void *ptr)
Definition: uv-common.c:81

References ifaddrs::ifa_next, and uv__free().

Referenced by uv_interface_addresses().

◆ freeResultList()

static void freeResultList ( NetlinkList p_list)
static

Definition at line 207 of file android-ifaddrs.c.

208 {
209  NetlinkList *l_cur;
210  while(p_list)
211  {
212  l_cur = p_list;
213  p_list = p_list->m_next;
214  uv__free(l_cur->m_data);
215  uv__free(l_cur);
216  }
217 }

References NetlinkList::m_data, NetlinkList::m_next, and uv__free().

Referenced by getifaddrs(), and getResultList().

◆ getifaddrs()

int getifaddrs ( struct ifaddrs **  ifap)

Definition at line 655 of file android-ifaddrs.c.

656 {
657  int l_socket;
658  int l_result;
659  int l_numLinks;
660  pid_t l_pid;
661  NetlinkList *l_linkResults;
662  NetlinkList *l_addrResults;
663 
664  if(!ifap)
665  {
666  return -1;
667  }
668  *ifap = NULL;
669 
670  l_socket = netlink_socket(&l_pid);
671  if(l_socket < 0)
672  {
673  return -1;
674  }
675 
676  l_linkResults = getResultList(l_socket, RTM_GETLINK, l_pid);
677  if(!l_linkResults)
678  {
679  close(l_socket);
680  return -1;
681  }
682 
683  l_addrResults = getResultList(l_socket, RTM_GETADDR, l_pid);
684  if(!l_addrResults)
685  {
686  close(l_socket);
687  freeResultList(l_linkResults);
688  return -1;
689  }
690 
691  l_result = 0;
692  l_numLinks = interpretLinks(l_socket, l_pid, l_linkResults, ifap);
693  if(l_numLinks == -1 || interpretAddrs(l_socket, l_pid, l_addrResults, ifap, l_numLinks) == -1)
694  {
695  l_result = -1;
696  }
697 
698  freeResultList(l_linkResults);
699  freeResultList(l_addrResults);
700  close(l_socket);
701  return l_result;
702 }
static NetlinkList * getResultList(int p_socket, int p_request, pid_t p_pid)
static int netlink_socket(pid_t *p_pid)
static int interpretAddrs(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList, int p_numLinks)
static void freeResultList(NetlinkList *p_list)
static int interpretLinks(int p_socket, pid_t p_pid, NetlinkList *p_netlinkList, struct ifaddrs **p_resultList)
static static fork const void static count close
Definition: sflib.h:33
int pid_t
Definition: sftypes.h:38

References close, freeResultList(), getResultList(), interpretAddrs(), interpretLinks(), netlink_socket(), and NULL.

Referenced by uv_interface_addresses().

◆ getNetlinkResponse()

static struct nlmsghdr* getNetlinkResponse ( int  p_socket,
pid_t  p_pid,
int p_size,
int p_done 
)
static

Definition at line 141 of file android-ifaddrs.c.

142 {
143  size_t l_size = 4096;
144  void *l_buffer = NULL;
145 
146  for(;;)
147  {
148  int l_read;
149 
150  uv__free(l_buffer);
151  l_buffer = uv__malloc(l_size);
152  if (l_buffer == NULL)
153  {
154  return NULL;
155  }
156 
157  l_read = netlink_recv(p_socket, l_buffer, l_size);
158  *p_size = l_read;
159  if(l_read == -2)
160  {
161  uv__free(l_buffer);
162  return NULL;
163  }
164  if(l_read >= 0)
165  {
166  struct nlmsghdr *l_hdr;
167  for(l_hdr = (struct nlmsghdr *)l_buffer; NLMSG_OK(l_hdr, (unsigned int)l_read); l_hdr = (struct nlmsghdr *)NLMSG_NEXT(l_hdr, l_read))
168  {
169  if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket)
170  {
171  continue;
172  }
173 
174  if(l_hdr->nlmsg_type == NLMSG_DONE)
175  {
176  *p_done = 1;
177  break;
178  }
179 
180  if(l_hdr->nlmsg_type == NLMSG_ERROR)
181  {
182  uv__free(l_buffer);
183  return NULL;
184  }
185  }
186  return l_buffer;
187  }
188 
189  l_size *= 2;
190  }
191 }
static int netlink_recv(int p_socket, void *p_buffer, size_t p_len)
static int
Definition: sfsocketcall.h:114
void * uv__malloc(size_t size)
Definition: uv-common.c:75

References int, netlink_recv(), NULL, uv__free(), and uv__malloc().

Referenced by getResultList().

◆ getResultList()

static NetlinkList* getResultList ( int  p_socket,
int  p_request,
pid_t  p_pid 
)
static

Definition at line 219 of file android-ifaddrs.c.

220 {
221  int l_size;
222  int l_done;
223  NetlinkList *l_list;
224  NetlinkList *l_end;
225 
226  if(netlink_send(p_socket, p_request) < 0)
227  {
228  return NULL;
229  }
230 
231  l_list = NULL;
232  l_end = NULL;
233 
234  l_done = 0;
235  while(!l_done)
236  {
237  NetlinkList *l_item;
238 
239  struct nlmsghdr *l_hdr = getNetlinkResponse(p_socket, p_pid, &l_size, &l_done);
240  /* Error */
241  if(!l_hdr)
242  {
243  freeResultList(l_list);
244  return NULL;
245  }
246 
247  l_item = newListItem(l_hdr, l_size);
248  if (!l_item)
249  {
250  freeResultList(l_list);
251  return NULL;
252  }
253  if(!l_list)
254  {
255  l_list = l_item;
256  }
257  else
258  {
259  l_end->m_next = l_item;
260  }
261  l_end = l_item;
262  }
263  return l_list;
264 }
static int netlink_send(int p_socket, int p_request)
static NetlinkList * newListItem(struct nlmsghdr *p_data, unsigned int p_size)
static struct nlmsghdr * getNetlinkResponse(int p_socket, pid_t p_pid, int *p_size, int *p_done)

References freeResultList(), getNetlinkResponse(), NetlinkList::m_next, netlink_send(), newListItem(), and NULL.

Referenced by getifaddrs().

◆ interpretAddr()

static int interpretAddr ( struct nlmsghdr *  p_hdr,
struct ifaddrs **  p_resultList,
int  p_numLinks 
)
static

Definition at line 444 of file android-ifaddrs.c.

445 {
446  struct ifaddrmsg *l_info = (struct ifaddrmsg *)NLMSG_DATA(p_hdr);
447  struct ifaddrs *l_interface = findInterface(l_info->ifa_index, p_resultList, p_numLinks);
448 
449  size_t l_nameSize = 0;
450  size_t l_addrSize = 0;
451 
452  int l_addedNetmask = 0;
453 
454  size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
455  struct rtattr *l_rta;
456  struct ifaddrs *l_entry;
457 
458  char *l_name;
459  char *l_addr;
460 
461  for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
462  {
463  size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
464  if(l_info->ifa_family == AF_PACKET)
465  {
466  continue;
467  }
468 
469  switch(l_rta->rta_type)
470  {
471  case IFA_ADDRESS:
472  case IFA_LOCAL:
473  l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
474  if((l_info->ifa_family == AF_INET || l_info->ifa_family == AF_INET6) && !l_addedNetmask)
475  {
476  /* Make room for netmask */
477  l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
478  l_addedNetmask = 1;
479  }
480  break;
481  case IFA_BROADCAST:
482  l_addrSize += NLMSG_ALIGN(calcAddrLen(l_info->ifa_family, l_rtaDataSize));
483  break;
484  case IFA_LABEL:
485  l_nameSize += NLMSG_ALIGN(l_rtaDataSize + 1);
486  break;
487  default:
488  break;
489  }
490  }
491 
492  l_entry = uv__malloc(sizeof(struct ifaddrs) + l_nameSize + l_addrSize);
493  if (l_entry == NULL)
494  {
495  return -1;
496  }
497  memset(l_entry, 0, sizeof(struct ifaddrs));
498  l_entry->ifa_name = (l_interface ? l_interface->ifa_name : "");
499 
500  l_name = ((char *)l_entry) + sizeof(struct ifaddrs);
501  l_addr = l_name + l_nameSize;
502 
503  l_entry->ifa_flags = l_info->ifa_flags;
504  if(l_interface)
505  {
506  l_entry->ifa_flags |= l_interface->ifa_flags;
507  }
508 
509  l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifaddrmsg));
510  for(l_rta = IFA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
511  {
512  void *l_rtaData = RTA_DATA(l_rta);
513  size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
514  switch(l_rta->rta_type)
515  {
516  case IFA_ADDRESS:
517  case IFA_BROADCAST:
518  case IFA_LOCAL:
519  {
520  size_t l_addrLen = calcAddrLen(l_info->ifa_family, l_rtaDataSize);
521  makeSockaddr(l_info->ifa_family, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
522  if(l_info->ifa_family == AF_INET6)
523  {
524  if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)l_rtaData) || IN6_IS_ADDR_MC_LINKLOCAL((struct in6_addr *)l_rtaData))
525  {
526  ((struct sockaddr_in6 *)l_addr)->sin6_scope_id = l_info->ifa_index;
527  }
528  }
529 
530  /* Apparently in a point-to-point network IFA_ADDRESS contains
531  * the dest address and IFA_LOCAL contains the local address
532  */
533  if(l_rta->rta_type == IFA_ADDRESS)
534  {
535  if(l_entry->ifa_addr)
536  {
537  l_entry->ifa_dstaddr = (struct sockaddr *)l_addr;
538  }
539  else
540  {
541  l_entry->ifa_addr = (struct sockaddr *)l_addr;
542  }
543  }
544  else if(l_rta->rta_type == IFA_LOCAL)
545  {
546  if(l_entry->ifa_addr)
547  {
548  l_entry->ifa_dstaddr = l_entry->ifa_addr;
549  }
550  l_entry->ifa_addr = (struct sockaddr *)l_addr;
551  }
552  else
553  {
554  l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
555  }
556  l_addr += NLMSG_ALIGN(l_addrLen);
557  break;
558  }
559  case IFA_LABEL:
560  strncpy(l_name, l_rtaData, l_rtaDataSize);
561  l_name[l_rtaDataSize] = '\0';
562  l_entry->ifa_name = l_name;
563  break;
564  default:
565  break;
566  }
567  }
568 
569  if(l_entry->ifa_addr && (l_entry->ifa_addr->sa_family == AF_INET || l_entry->ifa_addr->sa_family == AF_INET6))
570  {
571  unsigned l_maxPrefix = (l_entry->ifa_addr->sa_family == AF_INET ? 32 : 128);
572  unsigned l_prefix = (l_info->ifa_prefixlen > l_maxPrefix ? l_maxPrefix : l_info->ifa_prefixlen);
573  unsigned char l_mask[16] = {0};
574  unsigned i;
575  for(i=0; i<(l_prefix/8); ++i)
576  {
577  l_mask[i] = 0xff;
578  }
579  if(l_prefix % 8)
580  {
581  l_mask[i] = 0xff << (8 - (l_prefix % 8));
582  }
583 
584  makeSockaddr(l_entry->ifa_addr->sa_family, (struct sockaddr *)l_addr, l_mask, l_maxPrefix / 8);
585  l_entry->ifa_netmask = (struct sockaddr *)l_addr;
586  }
587 
588  addToEnd(p_resultList, l_entry);
589  return 0;
590 }
static void addToEnd(struct ifaddrs **p_resultList, struct ifaddrs *p_entry)
static struct ifaddrs * findInterface(int p_index, struct ifaddrs **p_links, int p_numLinks)
static size_t calcAddrLen(sa_family_t p_family, int p_dataSize)
static void makeSockaddr(sa_family_t p_family, struct sockaddr *p_dest, void *p_data, size_t p_size)
lzma_index ** i
Definition: index.h:629
return memset(p, 0, total)
struct sockaddr * ifa_addr
unsigned int ifa_flags
char * ifa_name
struct sockaddr * ifa_dstaddr
struct sockaddr * ifa_netmask

References addToEnd(), AF_INET, AF_INET6, AF_PACKET, calcAddrLen(), findInterface(), i, ifaddrs::ifa_addr, ifaddrs::ifa_dstaddr, ifaddrs::ifa_flags, ifaddrs::ifa_name, ifaddrs::ifa_netmask, makeSockaddr(), memset(), NULL, and uv__malloc().

Referenced by interpretAddrs().

◆ interpretAddrs()

static int interpretAddrs ( int  p_socket,
pid_t  p_pid,
NetlinkList p_netlinkList,
struct ifaddrs **  p_resultList,
int  p_numLinks 
)
static

Definition at line 625 of file android-ifaddrs.c.

626 {
627  for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
628  {
629  unsigned int l_nlsize = p_netlinkList->m_size;
630  struct nlmsghdr *l_hdr;
631  for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
632  {
633  if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket)
634  {
635  continue;
636  }
637 
638  if(l_hdr->nlmsg_type == NLMSG_DONE)
639  {
640  break;
641  }
642 
643  if(l_hdr->nlmsg_type == RTM_NEWADDR)
644  {
645  if (interpretAddr(l_hdr, p_resultList, p_numLinks) == -1)
646  {
647  return -1;
648  }
649  }
650  }
651  }
652  return 0;
653 }
static int interpretAddr(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList, int p_numLinks)

References int, interpretAddr(), NetlinkList::m_data, NetlinkList::m_next, and NetlinkList::m_size.

Referenced by getifaddrs().

◆ interpretLink()

static int interpretLink ( struct nlmsghdr *  p_hdr,
struct ifaddrs **  p_resultList 
)
static

Definition at line 324 of file android-ifaddrs.c.

325 {
326  struct ifaddrs *l_entry;
327 
328  char *l_index;
329  char *l_name;
330  char *l_addr;
331  char *l_data;
332 
333  struct ifinfomsg *l_info = (struct ifinfomsg *)NLMSG_DATA(p_hdr);
334 
335  size_t l_nameSize = 0;
336  size_t l_addrSize = 0;
337  size_t l_dataSize = 0;
338 
339  size_t l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
340  struct rtattr *l_rta;
341  for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
342  {
343  size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
344  switch(l_rta->rta_type)
345  {
346  case IFLA_ADDRESS:
347  case IFLA_BROADCAST:
348  l_addrSize += NLMSG_ALIGN(calcAddrLen(AF_PACKET, l_rtaDataSize));
349  break;
350  case IFLA_IFNAME:
351  l_nameSize += NLMSG_ALIGN(l_rtaSize + 1);
352  break;
353  case IFLA_STATS:
354  l_dataSize += NLMSG_ALIGN(l_rtaSize);
355  break;
356  default:
357  break;
358  }
359  }
360 
361  l_entry = uv__malloc(sizeof(struct ifaddrs) + sizeof(int) + l_nameSize + l_addrSize + l_dataSize);
362  if (l_entry == NULL)
363  {
364  return -1;
365  }
366  memset(l_entry, 0, sizeof(struct ifaddrs));
367  l_entry->ifa_name = "";
368 
369  l_index = ((char *)l_entry) + sizeof(struct ifaddrs);
370  l_name = l_index + sizeof(int);
371  l_addr = l_name + l_nameSize;
372  l_data = l_addr + l_addrSize;
373 
374  /* Save the interface index so we can look it up when handling the
375  * addresses.
376  */
377  memcpy(l_index, &l_info->ifi_index, sizeof(int));
378 
379  l_entry->ifa_flags = l_info->ifi_flags;
380 
381  l_rtaSize = NLMSG_PAYLOAD(p_hdr, sizeof(struct ifinfomsg));
382  for(l_rta = IFLA_RTA(l_info); RTA_OK(l_rta, l_rtaSize); l_rta = RTA_NEXT(l_rta, l_rtaSize))
383  {
384  void *l_rtaData = RTA_DATA(l_rta);
385  size_t l_rtaDataSize = RTA_PAYLOAD(l_rta);
386  switch(l_rta->rta_type)
387  {
388  case IFLA_ADDRESS:
389  case IFLA_BROADCAST:
390  {
391  size_t l_addrLen = calcAddrLen(AF_PACKET, l_rtaDataSize);
392  makeSockaddr(AF_PACKET, (struct sockaddr *)l_addr, l_rtaData, l_rtaDataSize);
393  ((struct sockaddr_ll *)l_addr)->sll_ifindex = l_info->ifi_index;
394  ((struct sockaddr_ll *)l_addr)->sll_hatype = l_info->ifi_type;
395  if(l_rta->rta_type == IFLA_ADDRESS)
396  {
397  l_entry->ifa_addr = (struct sockaddr *)l_addr;
398  }
399  else
400  {
401  l_entry->ifa_broadaddr = (struct sockaddr *)l_addr;
402  }
403  l_addr += NLMSG_ALIGN(l_addrLen);
404  break;
405  }
406  case IFLA_IFNAME:
407  strncpy(l_name, l_rtaData, l_rtaDataSize);
408  l_name[l_rtaDataSize] = '\0';
409  l_entry->ifa_name = l_name;
410  break;
411  case IFLA_STATS:
412  memcpy(l_data, l_rtaData, l_rtaDataSize);
413  l_entry->ifa_data = l_data;
414  break;
415  default:
416  break;
417  }
418  }
419 
420  addToEnd(p_resultList, l_entry);
421  return 0;
422 }
void * ifa_data

References addToEnd(), AF_PACKET, calcAddrLen(), ifaddrs::ifa_addr, ifaddrs::ifa_data, ifaddrs::ifa_flags, ifaddrs::ifa_name, int, makeSockaddr(), memcpy(), memset(), NULL, and uv__malloc().

Referenced by interpretLinks().

◆ interpretLinks()

static int interpretLinks ( int  p_socket,
pid_t  p_pid,
NetlinkList p_netlinkList,
struct ifaddrs **  p_resultList 
)
static

Definition at line 592 of file android-ifaddrs.c.

593 {
594 
595  int l_numLinks = 0;
596  for(; p_netlinkList; p_netlinkList = p_netlinkList->m_next)
597  {
598  unsigned int l_nlsize = p_netlinkList->m_size;
599  struct nlmsghdr *l_hdr;
600  for(l_hdr = p_netlinkList->m_data; NLMSG_OK(l_hdr, l_nlsize); l_hdr = NLMSG_NEXT(l_hdr, l_nlsize))
601  {
602  if((pid_t)l_hdr->nlmsg_pid != p_pid || (int)l_hdr->nlmsg_seq != p_socket)
603  {
604  continue;
605  }
606 
607  if(l_hdr->nlmsg_type == NLMSG_DONE)
608  {
609  break;
610  }
611 
612  if(l_hdr->nlmsg_type == RTM_NEWLINK)
613  {
614  if(interpretLink(l_hdr, p_resultList) == -1)
615  {
616  return -1;
617  }
618  ++l_numLinks;
619  }
620  }
621  }
622  return l_numLinks;
623 }
static int interpretLink(struct nlmsghdr *p_hdr, struct ifaddrs **p_resultList)

References int, interpretLink(), NetlinkList::m_data, NetlinkList::m_next, and NetlinkList::m_size.

Referenced by getifaddrs().

◆ makeSockaddr()

static void makeSockaddr ( sa_family_t  p_family,
struct sockaddr p_dest,
void *  p_data,
size_t  p_size 
)
static

Definition at line 286 of file android-ifaddrs.c.

287 {
288  switch(p_family)
289  {
290  case AF_INET:
291  memcpy(&((struct sockaddr_in*)p_dest)->sin_addr, p_data, p_size);
292  break;
293  case AF_INET6:
294  memcpy(&((struct sockaddr_in6*)p_dest)->sin6_addr, p_data, p_size);
295  break;
296  case AF_PACKET:
297  memcpy(((struct sockaddr_ll*)p_dest)->sll_addr, p_data, p_size);
298  ((struct sockaddr_ll*)p_dest)->sll_halen = p_size;
299  break;
300  default:
301  memcpy(p_dest->sa_data, p_data, p_size);
302  break;
303  }
304  p_dest->sa_family = p_family;
305 }
char sa_data[14]
Definition: sftypes.h:330

References AF_INET, AF_INET6, AF_PACKET, memcpy(), and sockaddr_in6::sin6_addr.

Referenced by interpretAddr(), and interpretLink().

◆ maxSize()

static size_t maxSize ( size_t  a,
size_t  b 
)
static

Definition at line 266 of file android-ifaddrs.c.

267 {
268  return (a > b ? a : b);
269 }
#define b(i)
Definition: sha256.c:42
#define a(i)
Definition: sha256.c:41

References a, and b.

Referenced by calcAddrLen().

◆ netlink_recv()

static int netlink_recv ( int  p_socket,
void *  p_buffer,
size_t  p_len 
)
static

Definition at line 102 of file android-ifaddrs.c.

103 {
104  struct sockaddr_nl l_addr;
105  struct msghdr l_msg;
106 
107  struct iovec l_iov;
108  l_iov.iov_base = p_buffer;
109  l_iov.iov_len = p_len;
110 
111  for(;;)
112  {
113  int l_result;
114  l_msg.msg_name = (void *)&l_addr;
115  l_msg.msg_namelen = sizeof(l_addr);
116  l_msg.msg_iov = &l_iov;
117  l_msg.msg_iovlen = 1;
118  l_msg.msg_control = NULL;
119  l_msg.msg_controllen = 0;
120  l_msg.msg_flags = 0;
121  l_result = recvmsg(p_socket, &l_msg, 0);
122 
123  if(l_result < 0)
124  {
125  if(errno == EINTR)
126  {
127  continue;
128  }
129  return -2;
130  }
131 
132  /* Buffer was too small */
133  if(l_msg.msg_flags & MSG_TRUNC)
134  {
135  return -1;
136  }
137  return l_result;
138  }
139 }
#define EINTR
Definition: sftypes.h:114
Definition: sftypes.h:73

References EINTR, msghdr::msg_control, msghdr::msg_controllen, msghdr::msg_flags, msghdr::msg_iov, msghdr::msg_iovlen, msghdr::msg_name, msghdr::msg_namelen, and NULL.

Referenced by getNetlinkResponse().

◆ netlink_send()

static int netlink_send ( int  p_socket,
int  p_request 
)
static

Definition at line 77 of file android-ifaddrs.c.

78 {
79  char l_buffer[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtgenmsg))];
80 
81  struct nlmsghdr *l_hdr;
82  struct rtgenmsg *l_msg;
83  struct sockaddr_nl l_addr;
84 
85  memset(l_buffer, 0, sizeof(l_buffer));
86 
87  l_hdr = (struct nlmsghdr *)l_buffer;
88  l_msg = (struct rtgenmsg *)NLMSG_DATA(l_hdr);
89 
90  l_hdr->nlmsg_len = NLMSG_LENGTH(sizeof(*l_msg));
91  l_hdr->nlmsg_type = p_request;
92  l_hdr->nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
93  l_hdr->nlmsg_pid = 0;
94  l_hdr->nlmsg_seq = p_socket;
95  l_msg->rtgen_family = AF_UNSPEC;
96 
97  memset(&l_addr, 0, sizeof(l_addr));
98  l_addr.nl_family = AF_NETLINK;
99  return (sendto(p_socket, l_hdr, l_hdr->nlmsg_len, 0, (struct sockaddr *)&l_addr, sizeof(l_addr)));
100 }
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen sendto
Definition: sfsocketcall.h:125
#define AF_NETLINK
Definition: sftypes.h:301
#define AF_UNSPEC
Definition: sftypes.h:283

References AF_NETLINK, AF_UNSPEC, memset(), and sendto.

Referenced by getResultList().

◆ netlink_socket()

static int netlink_socket ( pid_t p_pid)
static

Definition at line 47 of file android-ifaddrs.c.

48 {
49  struct sockaddr_nl l_addr;
50  socklen_t l_len;
51 
52  int l_socket = socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
53  if(l_socket < 0)
54  {
55  return -1;
56  }
57 
58  memset(&l_addr, 0, sizeof(l_addr));
59  l_addr.nl_family = AF_NETLINK;
60  if(bind(l_socket, (struct sockaddr *)&l_addr, sizeof(l_addr)) < 0)
61  {
62  close(l_socket);
63  return -1;
64  }
65 
66  l_len = sizeof(l_addr);
67  if(getsockname(l_socket, (struct sockaddr *)&l_addr, &l_len) < 0)
68  {
69  close(l_socket);
70  return -1;
71  }
72  *p_pid = l_addr.nl_pid;
73 
74  return l_socket;
75 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd socket
Definition: sflib.h:79
static bind
Definition: sfsocketcall.h:114
unsigned int socklen_t
Definition: sftypes.h:219
@ SOCK_RAW
Definition: sftypes.h:230
#define PF_NETLINK
Definition: sftypes.h:269

References AF_NETLINK, bind, close, memset(), PF_NETLINK, SOCK_RAW, and socket.

Referenced by getifaddrs().

◆ newListItem()

static NetlinkList* newListItem ( struct nlmsghdr *  p_data,
unsigned int  p_size 
)
static

Definition at line 193 of file android-ifaddrs.c.

194 {
195  NetlinkList *l_item = uv__malloc(sizeof(NetlinkList));
196  if (l_item == NULL)
197  {
198  return NULL;
199  }
200 
201  l_item->m_next = NULL;
202  l_item->m_data = p_data;
203  l_item->m_size = p_size;
204  return l_item;
205 }

References NetlinkList::m_data, NetlinkList::m_next, NetlinkList::m_size, NULL, and uv__malloc().

Referenced by getResultList().