(root)/
glibc-2.38/
sysdeps/
unix/
sysv/
linux/
ifaddrs.c
       1  /* getifaddrs -- get names and addresses of all network interfaces
       2     Copyright (C) 2003-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <assert.h>
      20  #include <errno.h>
      21  #include <ifaddrs.h>
      22  #include <net/if.h>
      23  #include <netinet/in.h>
      24  #include <netpacket/packet.h>
      25  #include <scratch_buffer.h>
      26  #include <stdbool.h>
      27  #include <stdint.h>
      28  #include <stdlib.h>
      29  #include <string.h>
      30  #include <sys/ioctl.h>
      31  #include <sys/socket.h>
      32  #include <sysdep.h>
      33  #include <time.h>
      34  #include <unistd.h>
      35  
      36  #include "netlinkaccess.h"
      37  
      38  
      39  /* There is a problem with this type.  The address length for
      40     Infiniband sockets is much longer than the 8 bytes allocated in the
      41     sockaddr_ll definition.  Hence we use here a special
      42     definition.  */
      43  struct sockaddr_ll_max
      44    {
      45      unsigned short int sll_family;
      46      unsigned short int sll_protocol;
      47      int sll_ifindex;
      48      unsigned short int sll_hatype;
      49      unsigned char sll_pkttype;
      50      unsigned char sll_halen;
      51      unsigned char sll_addr[24];
      52    };
      53  
      54  
      55  /* struct to hold the data for one ifaddrs entry, so we can allocate
      56     everything at once.  */
      57  struct ifaddrs_storage
      58  {
      59    struct ifaddrs ifa;
      60    union
      61    {
      62      /* Save space for the biggest of the four used sockaddr types and
      63         avoid a lot of casts.  */
      64      struct sockaddr sa;
      65      struct sockaddr_ll_max sl;
      66      struct sockaddr_in s4;
      67      struct sockaddr_in6 s6;
      68    } addr, netmask, broadaddr;
      69    char name[IF_NAMESIZE + 1];
      70  };
      71  
      72  
      73  void
      74  __netlink_free_handle (struct netlink_handle *h)
      75  {
      76    struct netlink_res *ptr;
      77    int saved_errno = errno;
      78  
      79    ptr = h->nlm_list;
      80    while (ptr != NULL)
      81      {
      82        struct netlink_res *tmpptr;
      83  
      84        tmpptr = ptr->next;
      85        free (ptr);
      86        ptr = tmpptr;
      87      }
      88  
      89    __set_errno (saved_errno);
      90  }
      91  
      92  
      93  static int
      94  __netlink_sendreq (struct netlink_handle *h, int type)
      95  {
      96    struct req
      97    {
      98      struct nlmsghdr nlh;
      99      struct rtgenmsg g;
     100      char pad[0];
     101    } req;
     102    struct sockaddr_nl nladdr;
     103  
     104    if (h->seq == 0)
     105      h->seq = time_now ();
     106  
     107    req.nlh.nlmsg_len = sizeof (req);
     108    req.nlh.nlmsg_type = type;
     109    req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
     110    req.nlh.nlmsg_pid = 0;
     111    req.nlh.nlmsg_seq = h->seq;
     112    req.g.rtgen_family = AF_UNSPEC;
     113    if (sizeof (req) != offsetof (struct req, pad))
     114      memset (req.pad, '\0', sizeof (req) - offsetof (struct req, pad));
     115  
     116    memset (&nladdr, '\0', sizeof (nladdr));
     117    nladdr.nl_family = AF_NETLINK;
     118  
     119    return TEMP_FAILURE_RETRY (__sendto (h->fd, (void *) &req, sizeof (req), 0,
     120  				       (struct sockaddr *) &nladdr,
     121  				       sizeof (nladdr)));
     122  }
     123  
     124  
     125  int
     126  __netlink_request (struct netlink_handle *h, int type)
     127  {
     128    struct netlink_res *nlm_next;
     129    struct sockaddr_nl nladdr;
     130    struct nlmsghdr *nlmh;
     131    ssize_t read_len;
     132    bool done = false;
     133  
     134    /* Netlink requires that user buffer needs to be either 8kb or page size
     135       (whichever is bigger), however this has been changed over time and now
     136       8Kb is sufficient (check NLMSG_DEFAULT_SIZE on Linux
     137       linux/include/linux/netlink.h).  */
     138    const size_t buf_size = 8192;
     139    char *buf = malloc (buf_size);
     140    if (buf == NULL)
     141      goto out_fail;
     142  
     143    struct iovec iov = { buf, buf_size };
     144  
     145    if (__netlink_sendreq (h, type) < 0)
     146      goto out_fail;
     147  
     148    while (! done)
     149      {
     150        struct msghdr msg =
     151  	{
     152  	  .msg_name = (void *) &nladdr,
     153  	  .msg_namelen =  sizeof (nladdr),
     154  	  .msg_iov = &iov,
     155  	  .msg_iovlen = 1,
     156  	  .msg_control = NULL,
     157  	  .msg_controllen = 0,
     158  	  .msg_flags = 0
     159  	};
     160  
     161        read_len = TEMP_FAILURE_RETRY (__recvmsg (h->fd, &msg, 0));
     162        __netlink_assert_response (h->fd, read_len);
     163        if (read_len < 0)
     164  	goto out_fail;
     165  
     166        if (nladdr.nl_pid != 0)
     167  	continue;
     168  
     169        if (__glibc_unlikely (msg.msg_flags & MSG_TRUNC))
     170  	goto out_fail;
     171  
     172        size_t count = 0;
     173        size_t remaining_len = read_len;
     174        for (nlmh = (struct nlmsghdr *) buf;
     175  	   NLMSG_OK (nlmh, remaining_len);
     176  	   nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, remaining_len))
     177  	{
     178  	  if ((pid_t) nlmh->nlmsg_pid != h->pid
     179  	      || nlmh->nlmsg_seq != h->seq)
     180  	    continue;
     181  
     182  	  ++count;
     183  	  if (nlmh->nlmsg_type == NLMSG_DONE)
     184  	    {
     185  	      /* We found the end, leave the loop.  */
     186  	      done = true;
     187  	      break;
     188  	    }
     189  	  if (nlmh->nlmsg_type == NLMSG_ERROR)
     190  	    {
     191  	      struct nlmsgerr *nlerr = (struct nlmsgerr *) NLMSG_DATA (nlmh);
     192  	      if (nlmh->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
     193  		errno = EIO;
     194  	      else
     195  		errno = -nlerr->error;
     196  	      goto out_fail;
     197  	    }
     198  	}
     199  
     200        /* If there was nothing with the expected nlmsg_pid and nlmsg_seq,
     201  	 there is no point to record it.  */
     202        if (count == 0)
     203  	continue;
     204  
     205        nlm_next = (struct netlink_res *) malloc (sizeof (struct netlink_res)
     206  						+ read_len);
     207        if (nlm_next == NULL)
     208  	goto out_fail;
     209        nlm_next->next = NULL;
     210        nlm_next->nlh = memcpy (nlm_next + 1, buf, read_len);
     211        nlm_next->size = read_len;
     212        nlm_next->seq = h->seq;
     213        if (h->nlm_list == NULL)
     214  	h->nlm_list = nlm_next;
     215        else
     216  	h->end_ptr->next = nlm_next;
     217        h->end_ptr = nlm_next;
     218      }
     219  
     220    free(buf);
     221    return 0;
     222  
     223  out_fail:
     224    free(buf);
     225    return -1;
     226  }
     227  
     228  
     229  void
     230  __netlink_close (struct netlink_handle *h)
     231  {
     232    /* Don't modify errno.  */
     233    INTERNAL_SYSCALL_CALL (close, h->fd);
     234  }
     235  
     236  
     237  /* Open a NETLINK socket.  */
     238  int
     239  __netlink_open (struct netlink_handle *h)
     240  {
     241    struct sockaddr_nl nladdr;
     242  
     243    h->fd = __socket (PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
     244    if (h->fd < 0)
     245      goto out;
     246  
     247    memset (&nladdr, '\0', sizeof (nladdr));
     248    nladdr.nl_family = AF_NETLINK;
     249    if (__bind (h->fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) < 0)
     250      {
     251      close_and_out:
     252        __netlink_close (h);
     253      out:
     254        return -1;
     255      }
     256    /* Determine the ID the kernel assigned for this netlink connection.
     257       It is not necessarily the PID if there is more than one socket
     258       open.  */
     259    socklen_t addr_len = sizeof (nladdr);
     260    if (__getsockname (h->fd, (struct sockaddr *) &nladdr, &addr_len) < 0)
     261      goto close_and_out;
     262    h->pid = nladdr.nl_pid;
     263    return 0;
     264  }
     265  
     266  
     267  /* We know the number of RTM_NEWLINK entries, so we reserve the first
     268     # of entries for this type. All RTM_NEWADDR entries have an index
     269     pointer to the RTM_NEWLINK entry.  To find the entry, create
     270     a table to map kernel index entries to our index numbers.
     271     Since we get at first all RTM_NEWLINK entries, it can never happen
     272     that a RTM_NEWADDR index is not known to this map.  */
     273  static int
     274  map_newlink (int index, struct ifaddrs_storage *ifas, int *map, int max)
     275  {
     276    int i;
     277  
     278    for (i = 0; i < max; i++)
     279      {
     280        if (map[i] == -1)
     281  	{
     282  	  map[i] = index;
     283  	  if (i > 0)
     284  	    ifas[i - 1].ifa.ifa_next = &ifas[i].ifa;
     285  	  return i;
     286  	}
     287        else if (map[i] == index)
     288  	return i;
     289      }
     290  
     291    /* This means interfaces changed between the reading of the
     292       RTM_GETLINK and RTM_GETADDR information.  We have to repeat
     293       everything.  */
     294    return -1;
     295  }
     296  
     297  
     298  /* Create a linked list of `struct ifaddrs' structures, one for each
     299     network interface on the host machine.  If successful, store the
     300     list in *IFAP and return 0.  On errors, return -1 and set `errno'.  */
     301  static int
     302  getifaddrs_internal (struct ifaddrs **ifap)
     303  {
     304    struct netlink_handle nh = { 0, 0, 0, NULL, NULL };
     305    struct netlink_res *nlp;
     306    struct ifaddrs_storage *ifas;
     307    unsigned int i, newlink, newaddr, newaddr_idx;
     308    int *map_newlink_data;
     309    size_t ifa_data_size = 0;  /* Size to allocate for all ifa_data.  */
     310    char *ifa_data_ptr;	/* Pointer to the unused part of memory for
     311  				ifa_data.  */
     312    int result = 0;
     313    struct scratch_buffer buf;
     314    scratch_buffer_init (&buf);
     315  
     316    *ifap = NULL;
     317  
     318    if (__netlink_open (&nh) < 0)
     319      return -1;
     320  
     321    /* Tell the kernel that we wish to get a list of all
     322       active interfaces, collect all data for every interface.  */
     323    if (__netlink_request (&nh, RTM_GETLINK) < 0)
     324      {
     325        result = -1;
     326        goto exit_free;
     327      }
     328  
     329    /* Now ask the kernel for all addresses which are assigned
     330       to an interface and collect all data for every interface.
     331       Since we store the addresses after the interfaces in the
     332       list, we will later always find the interface before the
     333       corresponding addresses.  */
     334    ++nh.seq;
     335    if (__netlink_request (&nh, RTM_GETADDR) < 0)
     336      {
     337        result = -1;
     338        goto exit_free;
     339      }
     340  
     341    /* Count all RTM_NEWLINK and RTM_NEWADDR entries to allocate
     342       enough memory.  */
     343    newlink = newaddr = 0;
     344    for (nlp = nh.nlm_list; nlp; nlp = nlp->next)
     345      {
     346        struct nlmsghdr *nlh;
     347        size_t size = nlp->size;
     348  
     349        if (nlp->nlh == NULL)
     350  	continue;
     351  
     352        /* Walk through all entries we got from the kernel and look, which
     353  	 message type they contain.  */
     354        for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
     355  	{
     356  	  /* Check if the message is what we want.  */
     357  	  if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
     358  	    continue;
     359  
     360  	  /* If the dump got interrupted, we can't rely on the results
     361  	     so try again. */
     362  	  if (nlh->nlmsg_flags & NLM_F_DUMP_INTR)
     363  	    {
     364  	      result = -EAGAIN;
     365  	      goto exit_free;
     366  	    }
     367  
     368  	  if (nlh->nlmsg_type == NLMSG_DONE)
     369  	    break;		/* ok */
     370  
     371  	  if (nlh->nlmsg_type == RTM_NEWLINK)
     372  	    {
     373  	      /* A RTM_NEWLINK message can have IFLA_STATS data. We need to
     374  		 know the size before creating the list to allocate enough
     375  		 memory.  */
     376  	      struct ifinfomsg *ifim = (struct ifinfomsg *) NLMSG_DATA (nlh);
     377  	      struct rtattr *rta = IFLA_RTA (ifim);
     378  	      size_t rtasize = IFLA_PAYLOAD (nlh);
     379  
     380  	      while (RTA_OK (rta, rtasize))
     381  		{
     382  		  size_t rta_payload = RTA_PAYLOAD (rta);
     383  
     384  		  if (rta->rta_type == IFLA_STATS)
     385  		    {
     386  		      ifa_data_size += rta_payload;
     387  		      break;
     388  		    }
     389  		  else
     390  		    rta = RTA_NEXT (rta, rtasize);
     391  		}
     392  	      ++newlink;
     393  	    }
     394  	  else if (nlh->nlmsg_type == RTM_NEWADDR)
     395  	    ++newaddr;
     396  	}
     397      }
     398  
     399    /* Return if no interface is up.  */
     400    if ((newlink + newaddr) == 0)
     401      goto exit_free;
     402  
     403    /* Allocate memory for all entries we have and initialize next
     404       pointer.  */
     405    ifas = (struct ifaddrs_storage *) calloc (1,
     406  					    (newlink + newaddr)
     407  					    * sizeof (struct ifaddrs_storage)
     408  					    + ifa_data_size);
     409    if (ifas == NULL)
     410      {
     411        result = -1;
     412        goto exit_free;
     413      }
     414  
     415    /* Table for mapping kernel index to entry in our list.  */
     416    if (!scratch_buffer_set_array_size (&buf, newlink, sizeof (int)))
     417      {
     418        result = -1;
     419        goto exit_free;
     420      }
     421    map_newlink_data = buf.data;
     422    memset (map_newlink_data, '\xff', newlink * sizeof (int));
     423  
     424    ifa_data_ptr = (char *) &ifas[newlink + newaddr];
     425    newaddr_idx = 0;		/* Counter for newaddr index.  */
     426  
     427    /* Walk through the list of data we got from the kernel.  */
     428    for (nlp = nh.nlm_list; nlp; nlp = nlp->next)
     429      {
     430        struct nlmsghdr *nlh;
     431        size_t size = nlp->size;
     432  
     433        if (nlp->nlh == NULL)
     434  	continue;
     435  
     436        /* Walk through one message and look at the type: If it is our
     437  	 message, we need RTM_NEWLINK/RTM_NEWADDR and stop if we reach
     438  	 the end or we find the end marker (in this case we ignore the
     439  	 following data.  */
     440        for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
     441  	{
     442  	  int ifa_index = 0;
     443  
     444  	  /* Check if the message is the one we want */
     445  	  if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
     446  	    continue;
     447  
     448  	  if (nlh->nlmsg_type == NLMSG_DONE)
     449  	    break;		/* ok */
     450  
     451  	  if (nlh->nlmsg_type == RTM_NEWLINK)
     452  	    {
     453  	      /* We found a new interface. Now extract everything from the
     454  		 interface data we got and need.  */
     455  	      struct ifinfomsg *ifim = (struct ifinfomsg *) NLMSG_DATA (nlh);
     456  	      struct rtattr *rta = IFLA_RTA (ifim);
     457  	      size_t rtasize = IFLA_PAYLOAD (nlh);
     458  
     459  	      /* Interfaces are stored in the first "newlink" entries
     460  		 of our list, starting in the order as we got from the
     461  		 kernel.  */
     462  	      ifa_index = map_newlink (ifim->ifi_index - 1, ifas,
     463  				       map_newlink_data, newlink);
     464  	      if (__glibc_unlikely (ifa_index == -1))
     465  		{
     466  		try_again:
     467  		  result = -EAGAIN;
     468  		  free (ifas);
     469  		  goto exit_free;
     470  		}
     471  	      ifas[ifa_index].ifa.ifa_flags = ifim->ifi_flags;
     472  
     473  	      while (RTA_OK (rta, rtasize))
     474  		{
     475  		  char *rta_data = RTA_DATA (rta);
     476  		  size_t rta_payload = RTA_PAYLOAD (rta);
     477  
     478  		  switch (rta->rta_type)
     479  		    {
     480  		    case IFLA_ADDRESS:
     481  		      if (rta_payload <= sizeof (ifas[ifa_index].addr))
     482  			{
     483  			  ifas[ifa_index].addr.sl.sll_family = AF_PACKET;
     484  			  memcpy (ifas[ifa_index].addr.sl.sll_addr,
     485  				  (char *) rta_data, rta_payload);
     486  			  ifas[ifa_index].addr.sl.sll_halen = rta_payload;
     487  			  ifas[ifa_index].addr.sl.sll_ifindex
     488  			    = ifim->ifi_index;
     489  			  ifas[ifa_index].addr.sl.sll_hatype = ifim->ifi_type;
     490  
     491  			  ifas[ifa_index].ifa.ifa_addr
     492  			    = &ifas[ifa_index].addr.sa;
     493  			}
     494  		      break;
     495  
     496  		    case IFLA_BROADCAST:
     497  		      if (rta_payload <= sizeof (ifas[ifa_index].broadaddr))
     498  			{
     499  			  ifas[ifa_index].broadaddr.sl.sll_family = AF_PACKET;
     500  			  memcpy (ifas[ifa_index].broadaddr.sl.sll_addr,
     501  				  (char *) rta_data, rta_payload);
     502  			  ifas[ifa_index].broadaddr.sl.sll_halen = rta_payload;
     503  			  ifas[ifa_index].broadaddr.sl.sll_ifindex
     504  			    = ifim->ifi_index;
     505  			  ifas[ifa_index].broadaddr.sl.sll_hatype
     506  			    = ifim->ifi_type;
     507  
     508  			  ifas[ifa_index].ifa.ifa_broadaddr
     509  			    = &ifas[ifa_index].broadaddr.sa;
     510  			}
     511  		      break;
     512  
     513  		    case IFLA_IFNAME:	/* Name of Interface */
     514  		      if ((rta_payload + 1) <= sizeof (ifas[ifa_index].name))
     515  			{
     516  			  ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
     517  			  *(char *) __mempcpy (ifas[ifa_index].name, rta_data,
     518  					       rta_payload) = '\0';
     519  			}
     520  		      break;
     521  
     522  		    case IFLA_STATS:	/* Statistics of Interface */
     523  		      ifas[ifa_index].ifa.ifa_data = ifa_data_ptr;
     524  		      ifa_data_ptr += rta_payload;
     525  		      memcpy (ifas[ifa_index].ifa.ifa_data, rta_data,
     526  			      rta_payload);
     527  		      break;
     528  
     529  		    case IFLA_UNSPEC:
     530  		      break;
     531  		    case IFLA_MTU:
     532  		      break;
     533  		    case IFLA_LINK:
     534  		      break;
     535  		    case IFLA_QDISC:
     536  		      break;
     537  		    default:
     538  		      break;
     539  		    }
     540  
     541  		  rta = RTA_NEXT (rta, rtasize);
     542  		}
     543  	    }
     544  	  else if (nlh->nlmsg_type == RTM_NEWADDR)
     545  	    {
     546  	      struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlh);
     547  	      struct rtattr *rta = IFA_RTA (ifam);
     548  	      size_t rtasize = IFA_PAYLOAD (nlh);
     549  
     550  	      /* New Addresses are stored in the order we got them from
     551  		 the kernel after the interfaces. Theoretically it is possible
     552  		 that we have holes in the interface part of the list,
     553  		 but we always have already the interface for this address.  */
     554  	      ifa_index = newlink + newaddr_idx;
     555  	      int idx = map_newlink (ifam->ifa_index - 1, ifas,
     556  				     map_newlink_data, newlink);
     557  	      if (__glibc_unlikely (idx == -1))
     558  		goto try_again;
     559  	      ifas[ifa_index].ifa.ifa_flags = ifas[idx].ifa.ifa_flags;
     560  	      if (ifa_index > 0)
     561  		ifas[ifa_index - 1].ifa.ifa_next = &ifas[ifa_index].ifa;
     562  	      ++newaddr_idx;
     563  
     564  	      while (RTA_OK (rta, rtasize))
     565  		{
     566  		  char *rta_data = RTA_DATA (rta);
     567  		  size_t rta_payload = RTA_PAYLOAD (rta);
     568  
     569  		  switch (rta->rta_type)
     570  		    {
     571  		    case IFA_ADDRESS:
     572  		      {
     573  			struct sockaddr *sa;
     574  
     575  			if (ifas[ifa_index].ifa.ifa_addr != NULL)
     576  			  {
     577  			    /* In a point-to-poing network IFA_ADDRESS
     578  			       contains the destination address, local
     579  			       address is supplied in IFA_LOCAL attribute.
     580  			       destination address and broadcast address
     581  			       are stored in an union, so it doesn't matter
     582  			       which name we use.  */
     583  			    ifas[ifa_index].ifa.ifa_broadaddr
     584  			      = &ifas[ifa_index].broadaddr.sa;
     585  			    sa = &ifas[ifa_index].broadaddr.sa;
     586  			  }
     587  			else
     588  			  {
     589  			    ifas[ifa_index].ifa.ifa_addr
     590  			      = &ifas[ifa_index].addr.sa;
     591  			    sa = &ifas[ifa_index].addr.sa;
     592  			  }
     593  
     594  			sa->sa_family = ifam->ifa_family;
     595  
     596  			switch (ifam->ifa_family)
     597  			  {
     598  			  case AF_INET:
     599  			    /* Size must match that of an address for IPv4.  */
     600  			    if (rta_payload == 4)
     601  			      memcpy (&((struct sockaddr_in *) sa)->sin_addr,
     602  				      rta_data, rta_payload);
     603  			    break;
     604  
     605  			  case AF_INET6:
     606  			    /* Size must match that of an address for IPv6.  */
     607  			    if (rta_payload == 16)
     608  			      {
     609  				memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr,
     610  					rta_data, rta_payload);
     611  				if (IN6_IS_ADDR_LINKLOCAL (rta_data)
     612  				    || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
     613  				  ((struct sockaddr_in6 *) sa)->sin6_scope_id
     614  				    = ifam->ifa_index;
     615  			      }
     616  			    break;
     617  
     618  			  default:
     619  			    if (rta_payload <= sizeof (ifas[ifa_index].addr))
     620  			      memcpy (sa->sa_data, rta_data, rta_payload);
     621  			    break;
     622  			  }
     623  		      }
     624  		      break;
     625  
     626  		    case IFA_LOCAL:
     627  		      if (ifas[ifa_index].ifa.ifa_addr != NULL)
     628  			{
     629  			  /* If ifa_addr is set and we get IFA_LOCAL,
     630  			     assume we have a point-to-point network.
     631  			     Move address to correct field.  */
     632  			  ifas[ifa_index].broadaddr = ifas[ifa_index].addr;
     633  			  ifas[ifa_index].ifa.ifa_broadaddr
     634  			    = &ifas[ifa_index].broadaddr.sa;
     635  			  memset (&ifas[ifa_index].addr, '\0',
     636  				  sizeof (ifas[ifa_index].addr));
     637  			}
     638  
     639  		      ifas[ifa_index].ifa.ifa_addr = &ifas[ifa_index].addr.sa;
     640  		      ifas[ifa_index].ifa.ifa_addr->sa_family
     641  			= ifam->ifa_family;
     642  
     643  		      switch (ifam->ifa_family)
     644  			{
     645  			case AF_INET:
     646  			  /* Size must match that of an address for IPv4.  */
     647  			  if (rta_payload == 4)
     648  			    memcpy (&ifas[ifa_index].addr.s4.sin_addr,
     649  				  rta_data, rta_payload);
     650  			  break;
     651  
     652  			case AF_INET6:
     653  			  /* Size must match that of an address for IPv6.  */
     654  			  if (rta_payload == 16)
     655  			    {
     656  			      memcpy (&ifas[ifa_index].addr.s6.sin6_addr,
     657  				      rta_data, rta_payload);
     658  			      if (IN6_IS_ADDR_LINKLOCAL (rta_data)
     659  				  || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
     660  				ifas[ifa_index].addr.s6.sin6_scope_id =
     661  				  ifam->ifa_index;
     662  			    }
     663  			  break;
     664  
     665  			default:
     666  			  if (rta_payload <= sizeof (ifas[ifa_index].addr))
     667  			    memcpy (ifas[ifa_index].addr.sa.sa_data,
     668  				    rta_data, rta_payload);
     669  			  break;
     670  			}
     671  		      break;
     672  
     673  		    case IFA_BROADCAST:
     674  		      /* We get IFA_BROADCAST, so IFA_LOCAL was too much.  */
     675  		      if (ifas[ifa_index].ifa.ifa_broadaddr != NULL)
     676  			memset (&ifas[ifa_index].broadaddr, '\0',
     677  				sizeof (ifas[ifa_index].broadaddr));
     678  
     679  		      ifas[ifa_index].ifa.ifa_broadaddr
     680  			= &ifas[ifa_index].broadaddr.sa;
     681  		      ifas[ifa_index].ifa.ifa_broadaddr->sa_family
     682  			= ifam->ifa_family;
     683  
     684  		      switch (ifam->ifa_family)
     685  			{
     686  			case AF_INET:
     687  			  /* Size must match that of an address for IPv4.  */
     688  			  if (rta_payload == 4)
     689  			    memcpy (&ifas[ifa_index].broadaddr.s4.sin_addr,
     690  				    rta_data, rta_payload);
     691  			  break;
     692  
     693  			case AF_INET6:
     694  			  /* Size must match that of an address for IPv6.  */
     695  			  if (rta_payload == 16)
     696  			    {
     697  			      memcpy (&ifas[ifa_index].broadaddr.s6.sin6_addr,
     698  				      rta_data, rta_payload);
     699  			      if (IN6_IS_ADDR_LINKLOCAL (rta_data)
     700  				  || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
     701  				ifas[ifa_index].broadaddr.s6.sin6_scope_id
     702  				  = ifam->ifa_index;
     703  			    }
     704  			  break;
     705  
     706  			default:
     707  			  if (rta_payload <= sizeof (ifas[ifa_index].addr))
     708  			    memcpy (&ifas[ifa_index].broadaddr.sa.sa_data,
     709  				    rta_data, rta_payload);
     710  			  break;
     711  			}
     712  		      break;
     713  
     714  		    case IFA_LABEL:
     715  		      if (rta_payload + 1 <= sizeof (ifas[ifa_index].name))
     716  			{
     717  			  ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
     718  			  *(char *) __mempcpy (ifas[ifa_index].name, rta_data,
     719  					       rta_payload) = '\0';
     720  			}
     721  		      else
     722  			abort ();
     723  		      break;
     724  
     725  		    case IFA_UNSPEC:
     726  		      break;
     727  		    case IFA_CACHEINFO:
     728  		      break;
     729  		    default:
     730  		      break;
     731  		    }
     732  
     733  		  rta = RTA_NEXT (rta, rtasize);
     734  		}
     735  
     736  	      /* If we didn't get the interface name with the
     737  		 address, use the name from the interface entry.  */
     738  	      if (ifas[ifa_index].ifa.ifa_name == NULL)
     739  		{
     740  		  int idx = map_newlink (ifam->ifa_index - 1, ifas,
     741  					 map_newlink_data, newlink);
     742  		  if (__glibc_unlikely (idx == -1))
     743  		    goto try_again;
     744  		  ifas[ifa_index].ifa.ifa_name = ifas[idx].ifa.ifa_name;
     745  		}
     746  
     747  	      /* Calculate the netmask.  */
     748  	      if (ifas[ifa_index].ifa.ifa_addr
     749  		  && ifas[ifa_index].ifa.ifa_addr->sa_family != AF_UNSPEC
     750  		  && ifas[ifa_index].ifa.ifa_addr->sa_family != AF_PACKET)
     751  		{
     752  		  uint32_t max_prefixlen = 0;
     753  		  char *cp = NULL;
     754  
     755  		  ifas[ifa_index].ifa.ifa_netmask
     756  		    = &ifas[ifa_index].netmask.sa;
     757  
     758  		  switch (ifas[ifa_index].ifa.ifa_addr->sa_family)
     759  		    {
     760  		    case AF_INET:
     761  		      cp = (char *) &ifas[ifa_index].netmask.s4.sin_addr;
     762  		      max_prefixlen = 32;
     763  		      break;
     764  
     765  		    case AF_INET6:
     766  		      cp = (char *) &ifas[ifa_index].netmask.s6.sin6_addr;
     767  		      max_prefixlen = 128;
     768  		      break;
     769  		    }
     770  
     771  		  ifas[ifa_index].ifa.ifa_netmask->sa_family
     772  		    = ifas[ifa_index].ifa.ifa_addr->sa_family;
     773  
     774  		  if (cp != NULL)
     775  		    {
     776  		      unsigned int preflen;
     777  
     778  		      if (ifam->ifa_prefixlen > max_prefixlen)
     779  			preflen = max_prefixlen;
     780  		      else
     781  			preflen = ifam->ifa_prefixlen;
     782  
     783  		      for (i = 0; i < preflen / 8; i++)
     784  			*cp++ = 0xff;
     785  		      if (preflen % 8)
     786  			*cp = 0xff << (8 - preflen % 8);
     787  		    }
     788  		}
     789  	    }
     790  	}
     791      }
     792  
     793    assert (ifa_data_ptr <= (char *) &ifas[newlink + newaddr] + ifa_data_size);
     794  
     795    if (newaddr_idx > 0)
     796      {
     797        for (i = 0; i < newlink; ++i)
     798  	if (map_newlink_data[i] == -1)
     799  	  {
     800  	    /* We have fewer links then we anticipated.  Adjust the
     801  	       forward pointer to the first address entry.  */
     802  	    ifas[i - 1].ifa.ifa_next = &ifas[newlink].ifa;
     803  	  }
     804  
     805        if (i == 0 && newlink > 0)
     806  	/* No valid link, but we allocated memory.  We have to
     807  	   populate the first entry.  */
     808  	memmove (ifas, &ifas[newlink], sizeof (struct ifaddrs_storage));
     809      }
     810  
     811    *ifap = &ifas[0].ifa;
     812  
     813   exit_free:
     814    __netlink_free_handle (&nh);
     815    __netlink_close (&nh);
     816    scratch_buffer_free (&buf);
     817  
     818    return result;
     819  }
     820  
     821  
     822  /* Create a linked list of `struct ifaddrs' structures, one for each
     823     network interface on the host machine.  If successful, store the
     824     list in *IFAP and return 0.  On errors, return -1 and set `errno'.  */
     825  int
     826  __getifaddrs (struct ifaddrs **ifap)
     827  {
     828    int res;
     829  
     830    do
     831      res = getifaddrs_internal (ifap);
     832    while (res == -EAGAIN);
     833  
     834    return res;
     835  }
     836  weak_alias (__getifaddrs, getifaddrs)
     837  libc_hidden_def (__getifaddrs)
     838  libc_hidden_weak (getifaddrs)
     839  
     840  
     841  void
     842  __freeifaddrs (struct ifaddrs *ifa)
     843  {
     844    free (ifa);
     845  }
     846  weak_alias (__freeifaddrs, freeifaddrs)
     847  libc_hidden_def (__freeifaddrs)
     848  libc_hidden_weak (freeifaddrs)