1 /* getifaddrs -- get names and addresses of all network interfaces
2 Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
27 #include <netinet/in.h>
28 #include <netpacket/packet.h>
34 #include <sys/ioctl.h>
35 #include <sys/socket.h>
36 #include <libc-internal.h>
40 #include "netlinkaccess.h"
43 #ifndef __libc_use_alloca
44 # define __libc_use_alloca(x) (x < __MAX_ALLOCA_CUTOFF)
48 #if __ASSUME_NETLINK_SUPPORT
49 #ifdef __UCLIBC_SUPPORT_AI_ADDRCONFIG__
50 /* struct to hold the data for one ifaddrs entry, so we can allocate
51 everything at once. */
52 struct ifaddrs_storage
57 /* Save space for the biggest of the four used sockaddr types and
58 avoid a lot of casts. */
60 struct sockaddr_ll sl;
61 struct sockaddr_in s4;
62 #ifdef __UCLIBC_HAS_IPV6__
63 struct sockaddr_in6 s6;
65 } addr, netmask, broadaddr;
66 char name[IF_NAMESIZE + 1];
68 #endif /* __UCLIBC_SUPPORT_AI_ADDRCONFIG__ */
72 __netlink_free_handle (struct netlink_handle *h)
74 struct netlink_res *ptr;
79 struct netlink_res *tmpptr;
82 free (ptr); /* doesn't affect errno */
89 __netlink_sendreq (struct netlink_handle *h, int type)
96 struct sockaddr_nl nladdr;
101 req.nlh.nlmsg_len = sizeof (req);
102 req.nlh.nlmsg_type = type;
103 req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
104 req.nlh.nlmsg_pid = 0;
105 req.nlh.nlmsg_seq = h->seq;
106 req.g.rtgen_family = AF_UNSPEC;
108 memset (&nladdr, '\0', sizeof (nladdr));
109 nladdr.nl_family = AF_NETLINK;
111 return TEMP_FAILURE_RETRY (sendto (h->fd, (void *) &req, sizeof (req), 0,
112 (struct sockaddr *) &nladdr,
118 __netlink_request (struct netlink_handle *h, int type)
120 struct netlink_res *nlm_next;
121 struct netlink_res **new_nlm_list;
122 static volatile size_t buf_size = 4096;
124 struct sockaddr_nl nladdr;
125 struct nlmsghdr *nlmh;
128 bool use_malloc = false;
130 if (__netlink_sendreq (h, type) < 0)
133 size_t this_buf_size = buf_size;
134 if (__libc_use_alloca (this_buf_size))
135 buf = alloca (this_buf_size);
138 buf = malloc (this_buf_size);
145 struct iovec iov = { buf, this_buf_size };
147 if (h->nlm_list != NULL)
148 new_nlm_list = &h->end_ptr->next;
150 new_nlm_list = &h->nlm_list;
156 (void *) &nladdr, sizeof (nladdr),
162 read_len = TEMP_FAILURE_RETRY (recvmsg (h->fd, &msg, 0));
166 if (nladdr.nl_pid != 0)
169 if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0))
171 if (this_buf_size >= SIZE_MAX / 2)
174 nlm_next = *new_nlm_list;
175 while (nlm_next != NULL)
177 struct netlink_res *tmpptr;
179 tmpptr = nlm_next->next;
183 *new_nlm_list = NULL;
185 if (__libc_use_alloca (2 * this_buf_size))
186 buf = extend_alloca (buf, this_buf_size, 2 * this_buf_size);
191 char *new_buf = realloc (use_malloc ? buf : NULL, this_buf_size);
198 buf_size = this_buf_size;
201 iov.iov_len = this_buf_size;
203 /* Increase sequence number, so that we can distinguish
204 between old and new request messages. */
207 if (__netlink_sendreq (h, type) < 0)
214 size_t remaining_len = read_len;
215 for (nlmh = (struct nlmsghdr *) buf;
216 NLMSG_OK (nlmh, remaining_len);
217 nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, remaining_len))
219 if ((pid_t) nlmh->nlmsg_pid != h->pid
220 || nlmh->nlmsg_seq != h->seq)
224 if (nlmh->nlmsg_type == NLMSG_DONE)
226 /* We found the end, leave the loop. */
230 if (nlmh->nlmsg_type == NLMSG_ERROR)
232 struct nlmsgerr *nlerr = (struct nlmsgerr *) NLMSG_DATA (nlmh);
233 if (nlmh->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
236 errno = -nlerr->error;
241 /* If there was nothing with the expected nlmsg_pid and nlmsg_seq,
242 there is no point to record it. */
246 nlm_next = (struct netlink_res *) malloc (sizeof (struct netlink_res)
248 if (nlm_next == NULL)
250 nlm_next->next = NULL;
251 nlm_next->nlh = memcpy (nlm_next + 1, buf, read_len);
252 nlm_next->size = read_len;
253 nlm_next->seq = h->seq;
254 if (h->nlm_list == NULL)
255 h->nlm_list = nlm_next;
257 h->end_ptr->next = nlm_next;
258 h->end_ptr = nlm_next;
273 __netlink_close (struct netlink_handle *h)
275 /* Don't modify errno. */
282 /* Open a NETLINK socket. */
284 __netlink_open (struct netlink_handle *h)
286 struct sockaddr_nl nladdr;
288 h->fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
292 memset (&nladdr, '\0', sizeof (nladdr));
293 nladdr.nl_family = AF_NETLINK;
294 if (bind (h->fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) < 0)
301 /* Determine the ID the kernel assigned for this netlink connection.
302 It is not necessarily the PID if there is more than one socket
304 socklen_t addr_len = sizeof (nladdr);
305 if (getsockname (h->fd, (struct sockaddr *) &nladdr, &addr_len) < 0)
307 h->pid = nladdr.nl_pid;
312 #ifdef __UCLIBC_SUPPORT_AI_ADDRCONFIG__
313 /* We know the number of RTM_NEWLINK entries, so we reserve the first
314 # of entries for this type. All RTM_NEWADDR entries have an index
315 pointer to the RTM_NEWLINK entry. To find the entry, create
316 a table to map kernel index entries to our index numbers.
317 Since we get at first all RTM_NEWLINK entries, it can never happen
318 that a RTM_NEWADDR index is not known to this map. */
321 map_newlink (int idx, struct ifaddrs_storage *ifas, int *map, int max)
325 for (i = 0; i < max; i++)
331 ifas[i - 1].ifa.ifa_next = &ifas[i].ifa;
334 else if (map[i] == idx)
337 /* This should never be reached. If this will be reached, we have
338 a very big problem. */
343 /* Create a linked list of `struct ifaddrs' structures, one for each
344 network interface on the host machine. If successful, store the
345 list in *IFAP and return 0. On errors, return -1 and set `errno'. */
347 getifaddrs (struct ifaddrs **ifap)
349 struct netlink_handle nh = { 0, 0, 0, NULL, NULL };
350 struct netlink_res *nlp;
351 struct ifaddrs_storage *ifas;
352 unsigned int i, newlink, newaddr, newaddr_idx;
353 int *map_newlink_data;
354 size_t ifa_data_size = 0; /* Size to allocate for all ifa_data. */
355 char *ifa_data_ptr; /* Pointer to the unused part of memory for
362 if (__netlink_open (&nh) < 0)
367 /* Tell the kernel that we wish to get a list of all
368 active interfaces, collect all data for every interface. */
369 if (__netlink_request (&nh, RTM_GETLINK) < 0)
375 /* Now ask the kernel for all addresses which are assigned
376 to an interface and collect all data for every interface.
377 Since we store the addresses after the interfaces in the
378 list, we will later always find the interface before the
379 corresponding addresses. */
381 if (__netlink_request (&nh, RTM_GETADDR) < 0)
387 /* Count all RTM_NEWLINK and RTM_NEWADDR entries to allocate
389 newlink = newaddr = 0;
390 for (nlp = nh.nlm_list; nlp; nlp = nlp->next)
392 struct nlmsghdr *nlh;
393 size_t size = nlp->size;
395 if (nlp->nlh == NULL)
398 /* Walk through all entries we got from the kernel and look, which
399 message type they contain. */
400 for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
402 /* Check if the message is what we want. */
403 if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
406 if (nlh->nlmsg_type == NLMSG_DONE)
409 if (nlh->nlmsg_type == RTM_NEWLINK)
411 /* A RTM_NEWLINK message can have IFLA_STATS data. We need to
412 know the size before creating the list to allocate enough
414 struct ifinfomsg *ifim = (struct ifinfomsg *) NLMSG_DATA (nlh);
415 struct rtattr *rta = IFLA_RTA (ifim);
416 size_t rtasize = IFLA_PAYLOAD (nlh);
418 while (RTA_OK (rta, rtasize))
420 size_t rta_payload = RTA_PAYLOAD (rta);
422 if (rta->rta_type == IFLA_STATS)
424 ifa_data_size += rta_payload;
428 rta = RTA_NEXT (rta, rtasize);
432 else if (nlh->nlmsg_type == RTM_NEWADDR)
437 /* Return if no interface is up. */
438 if ((newlink + newaddr) == 0)
441 /* Allocate memory for all entries we have and initialize next
443 ifas = calloc (1, (newlink + newaddr) * sizeof (ifas[0]) + ifa_data_size);
450 /* Table for mapping kernel index to entry in our list. */
451 map_newlink_data = alloca (newlink * sizeof (int));
452 memset (map_newlink_data, '\xff', newlink * sizeof (int));
454 ifa_data_ptr = (char *) &ifas[newlink + newaddr];
455 newaddr_idx = 0; /* Counter for newaddr index. */
457 /* Walk through the list of data we got from the kernel. */
458 for (nlp = nh.nlm_list; nlp; nlp = nlp->next)
460 struct nlmsghdr *nlh;
461 size_t size = nlp->size;
463 if (nlp->nlh == NULL)
466 /* Walk through one message and look at the type: If it is our
467 message, we need RTM_NEWLINK/RTM_NEWADDR and stop if we reach
468 the end or we find the end marker (in this case we ignore the
470 for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
474 /* Check if the message is the one we want */
475 if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
478 if (nlh->nlmsg_type == NLMSG_DONE)
481 if (nlh->nlmsg_type == RTM_NEWLINK)
483 /* We found a new interface. Now extract everything from the
484 interface data we got and need. */
485 struct ifinfomsg *ifim = (struct ifinfomsg *) NLMSG_DATA (nlh);
486 struct rtattr *rta = IFLA_RTA (ifim);
487 size_t rtasize = IFLA_PAYLOAD (nlh);
489 /* Interfaces are stored in the first "newlink" entries
490 of our list, starting in the order as we got from the
492 ifa_index = map_newlink (ifim->ifi_index - 1, ifas,
493 map_newlink_data, newlink);
494 ifas[ifa_index].ifa.ifa_flags = ifim->ifi_flags;
496 while (RTA_OK (rta, rtasize))
498 char *rta_data = RTA_DATA (rta);
499 size_t rta_payload = RTA_PAYLOAD (rta);
501 switch (rta->rta_type)
504 if (rta_payload <= sizeof (ifas[ifa_index].addr))
506 ifas[ifa_index].addr.sl.sll_family = AF_PACKET;
507 memcpy (ifas[ifa_index].addr.sl.sll_addr,
508 (char *) rta_data, rta_payload);
509 ifas[ifa_index].addr.sl.sll_halen = rta_payload;
510 ifas[ifa_index].addr.sl.sll_ifindex
512 ifas[ifa_index].addr.sl.sll_hatype = ifim->ifi_type;
514 ifas[ifa_index].ifa.ifa_addr
515 = &ifas[ifa_index].addr.sa;
520 if (rta_payload <= sizeof (ifas[ifa_index].broadaddr))
522 ifas[ifa_index].broadaddr.sl.sll_family = AF_PACKET;
523 memcpy (ifas[ifa_index].broadaddr.sl.sll_addr,
524 (char *) rta_data, rta_payload);
525 ifas[ifa_index].broadaddr.sl.sll_halen = rta_payload;
526 ifas[ifa_index].broadaddr.sl.sll_ifindex
528 ifas[ifa_index].broadaddr.sl.sll_hatype
531 ifas[ifa_index].ifa.ifa_broadaddr
532 = &ifas[ifa_index].broadaddr.sa;
536 case IFLA_IFNAME: /* Name of Interface */
537 if ((rta_payload + 1) <= sizeof (ifas[ifa_index].name))
539 ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
540 *(char *) mempcpy (ifas[ifa_index].name, rta_data,
545 case IFLA_STATS: /* Statistics of Interface */
546 ifas[ifa_index].ifa.ifa_data = ifa_data_ptr;
547 ifa_data_ptr += rta_payload;
548 memcpy (ifas[ifa_index].ifa.ifa_data, rta_data,
564 rta = RTA_NEXT (rta, rtasize);
567 else if (nlh->nlmsg_type == RTM_NEWADDR)
569 struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlh);
570 struct rtattr *rta = IFA_RTA (ifam);
571 size_t rtasize = IFA_PAYLOAD (nlh);
573 /* New Addresses are stored in the order we got them from
574 the kernel after the interfaces. Theoretically it is possible
575 that we have holes in the interface part of the list,
576 but we always have already the interface for this address. */
577 ifa_index = newlink + newaddr_idx;
578 ifas[ifa_index].ifa.ifa_flags
579 = ifas[map_newlink (ifam->ifa_index - 1, ifas,
580 map_newlink_data, newlink)].ifa.ifa_flags;
582 ifas[ifa_index - 1].ifa.ifa_next = &ifas[ifa_index].ifa;
585 while (RTA_OK (rta, rtasize))
587 char *rta_data = RTA_DATA (rta);
588 size_t rta_payload = RTA_PAYLOAD (rta);
590 switch (rta->rta_type)
596 if (ifas[ifa_index].ifa.ifa_addr != NULL)
598 /* In a point-to-poing network IFA_ADDRESS
599 contains the destination address, local
600 address is supplied in IFA_LOCAL attribute.
601 destination address and broadcast address
602 are stored in an union, so it doesn't matter
603 which name we use. */
604 ifas[ifa_index].ifa.ifa_broadaddr
605 = &ifas[ifa_index].broadaddr.sa;
606 sa = &ifas[ifa_index].broadaddr.sa;
610 ifas[ifa_index].ifa.ifa_addr
611 = &ifas[ifa_index].addr.sa;
612 sa = &ifas[ifa_index].addr.sa;
615 sa->sa_family = ifam->ifa_family;
617 switch (ifam->ifa_family)
620 /* Size must match that of an address for IPv4. */
621 if (rta_payload == 4)
622 memcpy (&((struct sockaddr_in *) sa)->sin_addr,
623 rta_data, rta_payload);
626 #ifdef __UCLIBC_HAS_IPV6__
628 /* Size must match that of an address for IPv6. */
629 if (rta_payload == 16)
631 memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr,
632 rta_data, rta_payload);
633 if (IN6_IS_ADDR_LINKLOCAL (rta_data)
634 || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
635 ((struct sockaddr_in6 *) sa)->sin6_scope_id
642 if (rta_payload <= sizeof (ifas[ifa_index].addr))
643 memcpy (sa->sa_data, rta_data, rta_payload);
650 if (ifas[ifa_index].ifa.ifa_addr != NULL)
652 /* If ifa_addr is set and we get IFA_LOCAL,
653 assume we have a point-to-point network.
654 Move address to correct field. */
655 ifas[ifa_index].broadaddr = ifas[ifa_index].addr;
656 ifas[ifa_index].ifa.ifa_broadaddr
657 = &ifas[ifa_index].broadaddr.sa;
658 memset (&ifas[ifa_index].addr, '\0',
659 sizeof (ifas[ifa_index].addr));
662 ifas[ifa_index].ifa.ifa_addr = &ifas[ifa_index].addr.sa;
663 ifas[ifa_index].ifa.ifa_addr->sa_family
666 switch (ifam->ifa_family)
669 /* Size must match that of an address for IPv4. */
670 if (rta_payload == 4)
671 memcpy (&ifas[ifa_index].addr.s4.sin_addr,
672 rta_data, rta_payload);
675 #ifdef __UCLIBC_HAS_IPV6__
677 /* Size must match that of an address for IPv6. */
678 if (rta_payload == 16)
680 memcpy (&ifas[ifa_index].addr.s6.sin6_addr,
681 rta_data, rta_payload);
682 if (IN6_IS_ADDR_LINKLOCAL (rta_data)
683 || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
684 ifas[ifa_index].addr.s6.sin6_scope_id =
691 if (rta_payload <= sizeof (ifas[ifa_index].addr))
692 memcpy (ifas[ifa_index].addr.sa.sa_data,
693 rta_data, rta_payload);
699 /* We get IFA_BROADCAST, so IFA_LOCAL was too much. */
700 if (ifas[ifa_index].ifa.ifa_broadaddr != NULL)
701 memset (&ifas[ifa_index].broadaddr, '\0',
702 sizeof (ifas[ifa_index].broadaddr));
704 ifas[ifa_index].ifa.ifa_broadaddr
705 = &ifas[ifa_index].broadaddr.sa;
706 ifas[ifa_index].ifa.ifa_broadaddr->sa_family
709 switch (ifam->ifa_family)
712 /* Size must match that of an address for IPv4. */
713 if (rta_payload == 4)
714 memcpy (&ifas[ifa_index].broadaddr.s4.sin_addr,
715 rta_data, rta_payload);
718 #ifdef __UCLIBC_HAS_IPV6__
720 /* Size must match that of an address for IPv6. */
721 if (rta_payload == 16)
723 memcpy (&ifas[ifa_index].broadaddr.s6.sin6_addr,
724 rta_data, rta_payload);
725 if (IN6_IS_ADDR_LINKLOCAL (rta_data)
726 || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
727 ifas[ifa_index].broadaddr.s6.sin6_scope_id
734 if (rta_payload <= sizeof (ifas[ifa_index].addr))
735 memcpy (&ifas[ifa_index].broadaddr.sa.sa_data,
736 rta_data, rta_payload);
742 if (rta_payload + 1 <= sizeof (ifas[ifa_index].name))
744 ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
745 *(char *) mempcpy (ifas[ifa_index].name, rta_data,
760 rta = RTA_NEXT (rta, rtasize);
763 /* If we didn't get the interface name with the
764 address, use the name from the interface entry. */
765 if (ifas[ifa_index].ifa.ifa_name == NULL)
766 ifas[ifa_index].ifa.ifa_name
767 = ifas[map_newlink (ifam->ifa_index - 1, ifas,
768 map_newlink_data, newlink)].ifa.ifa_name;
770 /* Calculate the netmask. */
771 if (ifas[ifa_index].ifa.ifa_addr
772 && ifas[ifa_index].ifa.ifa_addr->sa_family != AF_UNSPEC
773 && ifas[ifa_index].ifa.ifa_addr->sa_family != AF_PACKET)
775 uint32_t max_prefixlen = 0;
778 ifas[ifa_index].ifa.ifa_netmask
779 = &ifas[ifa_index].netmask.sa;
781 switch (ifas[ifa_index].ifa.ifa_addr->sa_family)
784 cp = (char *) &ifas[ifa_index].netmask.s4.sin_addr;
788 #ifdef __UCLIBC_HAS_IPV6__
790 cp = (char *) &ifas[ifa_index].netmask.s6.sin6_addr;
796 ifas[ifa_index].ifa.ifa_netmask->sa_family
797 = ifas[ifa_index].ifa.ifa_addr->sa_family;
802 unsigned int preflen;
804 if ((max_prefixlen > 0) &&
805 (ifam->ifa_prefixlen > max_prefixlen))
806 preflen = max_prefixlen;
808 preflen = ifam->ifa_prefixlen;
810 for (i = 0; i < (preflen / 8); i++)
813 c <<= (8 - (preflen % 8));
821 assert (ifa_data_ptr <= (char *) &ifas[newlink + newaddr] + ifa_data_size);
825 for (i = 0; i < newlink; ++i)
826 if (map_newlink_data[i] == -1)
828 /* We have fewer links then we anticipated. Adjust the
829 forward pointer to the first address entry. */
830 ifas[i - 1].ifa.ifa_next = &ifas[newlink].ifa;
833 if (i == 0 && newlink > 0)
834 /* No valid link, but we allocated memory. We have to
835 populate the first entry. */
836 memmove (ifas, &ifas[newlink], sizeof (struct ifaddrs_storage));
840 *ifap = &ifas[0].ifa;
843 __netlink_free_handle (&nh);
844 __netlink_close (&nh);
848 libc_hidden_def(getifaddrs)
851 freeifaddrs (struct ifaddrs *ifa)
855 libc_hidden_def(freeifaddrs)
857 #endif /* __UCLIBC_SUPPORT_AI_ADDRCONFIG__ */
859 #endif /* __ASSUME_NETLINK_SUPPORT */