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, see
17 <http://www.gnu.org/licenses/>. */
24 #include <netinet/in.h>
25 #include <netpacket/packet.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
36 #include "netlinkaccess.h"
39 #ifndef __libc_use_alloca
40 # define __libc_use_alloca(x) (x < __MAX_ALLOCA_CUTOFF)
44 #if __ASSUME_NETLINK_SUPPORT
45 #ifdef __UCLIBC_SUPPORT_AI_ADDRCONFIG__
46 /* struct to hold the data for one ifaddrs entry, so we can allocate
47 everything at once. */
48 struct ifaddrs_storage
53 /* Save space for the biggest of the four used sockaddr types and
54 avoid a lot of casts. */
56 struct sockaddr_ll sl;
57 struct sockaddr_in s4;
58 #ifdef __UCLIBC_HAS_IPV6__
59 struct sockaddr_in6 s6;
61 } addr, netmask, broadaddr;
62 char name[IF_NAMESIZE + 1];
64 #endif /* __UCLIBC_SUPPORT_AI_ADDRCONFIG__ */
68 __netlink_free_handle (struct netlink_handle *h)
70 struct netlink_res *ptr;
75 struct netlink_res *tmpptr;
78 free (ptr); /* doesn't affect errno */
85 __netlink_sendreq (struct netlink_handle *h, int type)
92 struct sockaddr_nl nladdr;
97 req.nlh.nlmsg_len = sizeof (req);
98 req.nlh.nlmsg_type = type;
99 req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
100 req.nlh.nlmsg_pid = 0;
101 req.nlh.nlmsg_seq = h->seq;
102 req.g.rtgen_family = AF_UNSPEC;
104 memset (&nladdr, '\0', sizeof (nladdr));
105 nladdr.nl_family = AF_NETLINK;
107 return TEMP_FAILURE_RETRY (sendto (h->fd, (void *) &req, sizeof (req), 0,
108 (struct sockaddr *) &nladdr,
114 __netlink_request (struct netlink_handle *h, int type)
116 struct netlink_res *nlm_next;
117 struct netlink_res **new_nlm_list;
118 static volatile size_t buf_size = 4096;
120 struct sockaddr_nl nladdr;
121 struct nlmsghdr *nlmh;
124 bool use_malloc = false;
126 if (__netlink_sendreq (h, type) < 0)
129 size_t this_buf_size = buf_size;
130 if (__libc_use_alloca (this_buf_size))
131 buf = alloca (this_buf_size);
134 buf = malloc (this_buf_size);
141 struct iovec iov = { buf, this_buf_size };
143 if (h->nlm_list != NULL)
144 new_nlm_list = &h->end_ptr->next;
146 new_nlm_list = &h->nlm_list;
152 (void *) &nladdr, sizeof (nladdr),
158 read_len = TEMP_FAILURE_RETRY (recvmsg (h->fd, &msg, 0));
162 if (nladdr.nl_pid != 0)
165 if (__builtin_expect (msg.msg_flags & MSG_TRUNC, 0))
167 if (this_buf_size >= SIZE_MAX / 2)
170 nlm_next = *new_nlm_list;
171 while (nlm_next != NULL)
173 struct netlink_res *tmpptr;
175 tmpptr = nlm_next->next;
179 *new_nlm_list = NULL;
181 if (__libc_use_alloca (2 * this_buf_size))
182 buf = extend_alloca (buf, this_buf_size, 2 * this_buf_size);
187 char *new_buf = realloc (use_malloc ? buf : NULL, this_buf_size);
194 buf_size = this_buf_size;
197 iov.iov_len = this_buf_size;
199 /* Increase sequence number, so that we can distinguish
200 between old and new request messages. */
203 if (__netlink_sendreq (h, type) < 0)
210 size_t remaining_len = read_len;
211 for (nlmh = (struct nlmsghdr *) buf;
212 NLMSG_OK (nlmh, remaining_len);
213 nlmh = (struct nlmsghdr *) NLMSG_NEXT (nlmh, remaining_len))
215 if ((pid_t) nlmh->nlmsg_pid != h->pid
216 || nlmh->nlmsg_seq != h->seq)
220 if (nlmh->nlmsg_type == NLMSG_DONE)
222 /* We found the end, leave the loop. */
226 if (nlmh->nlmsg_type == NLMSG_ERROR)
228 struct nlmsgerr *nlerr = (struct nlmsgerr *) NLMSG_DATA (nlmh);
229 if (nlmh->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
232 errno = -nlerr->error;
237 /* If there was nothing with the expected nlmsg_pid and nlmsg_seq,
238 there is no point to record it. */
242 nlm_next = (struct netlink_res *) malloc (sizeof (struct netlink_res)
244 if (nlm_next == NULL)
246 nlm_next->next = NULL;
247 nlm_next->nlh = memcpy (nlm_next + 1, buf, read_len);
248 nlm_next->size = read_len;
249 nlm_next->seq = h->seq;
250 if (h->nlm_list == NULL)
251 h->nlm_list = nlm_next;
253 h->end_ptr->next = nlm_next;
254 h->end_ptr = nlm_next;
269 __netlink_close (struct netlink_handle *h)
271 /* Don't modify errno. */
278 /* Open a NETLINK socket. */
280 __netlink_open (struct netlink_handle *h)
282 struct sockaddr_nl nladdr;
284 h->fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
288 memset (&nladdr, '\0', sizeof (nladdr));
289 nladdr.nl_family = AF_NETLINK;
290 if (bind (h->fd, (struct sockaddr *) &nladdr, sizeof (nladdr)) < 0)
297 /* Determine the ID the kernel assigned for this netlink connection.
298 It is not necessarily the PID if there is more than one socket
300 socklen_t addr_len = sizeof (nladdr);
301 if (getsockname (h->fd, (struct sockaddr *) &nladdr, &addr_len) < 0)
303 h->pid = nladdr.nl_pid;
308 #ifdef __UCLIBC_SUPPORT_AI_ADDRCONFIG__
309 /* We know the number of RTM_NEWLINK entries, so we reserve the first
310 # of entries for this type. All RTM_NEWADDR entries have an index
311 pointer to the RTM_NEWLINK entry. To find the entry, create
312 a table to map kernel index entries to our index numbers.
313 Since we get at first all RTM_NEWLINK entries, it can never happen
314 that a RTM_NEWADDR index is not known to this map. */
317 map_newlink (int idx, struct ifaddrs_storage *ifas, int *map, int max)
321 for (i = 0; i < max; i++)
327 ifas[i - 1].ifa.ifa_next = &ifas[i].ifa;
330 else if (map[i] == idx)
333 /* This should never be reached. If this will be reached, we have
334 a very big problem. */
339 /* Create a linked list of `struct ifaddrs' structures, one for each
340 network interface on the host machine. If successful, store the
341 list in *IFAP and return 0. On errors, return -1 and set `errno'. */
343 getifaddrs (struct ifaddrs **ifap)
345 struct netlink_handle nh = { 0, 0, 0, NULL, NULL };
346 struct netlink_res *nlp;
347 struct ifaddrs_storage *ifas;
348 unsigned int i, newlink, newaddr, newaddr_idx;
349 int *map_newlink_data;
350 size_t ifa_data_size = 0; /* Size to allocate for all ifa_data. */
351 char *ifa_data_ptr; /* Pointer to the unused part of memory for
358 if (__netlink_open (&nh) < 0)
363 /* Tell the kernel that we wish to get a list of all
364 active interfaces, collect all data for every interface. */
365 if (__netlink_request (&nh, RTM_GETLINK) < 0)
371 /* Now ask the kernel for all addresses which are assigned
372 to an interface and collect all data for every interface.
373 Since we store the addresses after the interfaces in the
374 list, we will later always find the interface before the
375 corresponding addresses. */
377 if (__netlink_request (&nh, RTM_GETADDR) < 0)
383 /* Count all RTM_NEWLINK and RTM_NEWADDR entries to allocate
385 newlink = newaddr = 0;
386 for (nlp = nh.nlm_list; nlp; nlp = nlp->next)
388 struct nlmsghdr *nlh;
389 size_t size = nlp->size;
391 if (nlp->nlh == NULL)
394 /* Walk through all entries we got from the kernel and look, which
395 message type they contain. */
396 for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
398 /* Check if the message is what we want. */
399 if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
402 if (nlh->nlmsg_type == NLMSG_DONE)
405 if (nlh->nlmsg_type == RTM_NEWLINK)
407 /* A RTM_NEWLINK message can have IFLA_STATS data. We need to
408 know the size before creating the list to allocate enough
410 struct ifinfomsg *ifim = (struct ifinfomsg *) NLMSG_DATA (nlh);
411 struct rtattr *rta = IFLA_RTA (ifim);
412 size_t rtasize = IFLA_PAYLOAD (nlh);
414 while (RTA_OK (rta, rtasize))
416 size_t rta_payload = RTA_PAYLOAD (rta);
418 if (rta->rta_type == IFLA_STATS)
420 ifa_data_size += rta_payload;
424 rta = RTA_NEXT (rta, rtasize);
428 else if (nlh->nlmsg_type == RTM_NEWADDR)
433 /* Return if no interface is up. */
434 if ((newlink + newaddr) == 0)
437 /* Allocate memory for all entries we have and initialize next
439 ifas = calloc (1, (newlink + newaddr) * sizeof (ifas[0]) + ifa_data_size);
446 /* Table for mapping kernel index to entry in our list. */
447 map_newlink_data = alloca (newlink * sizeof (int));
448 memset (map_newlink_data, '\xff', newlink * sizeof (int));
450 ifa_data_ptr = (char *) &ifas[newlink + newaddr];
451 newaddr_idx = 0; /* Counter for newaddr index. */
453 /* Walk through the list of data we got from the kernel. */
454 for (nlp = nh.nlm_list; nlp; nlp = nlp->next)
456 struct nlmsghdr *nlh;
457 size_t size = nlp->size;
459 if (nlp->nlh == NULL)
462 /* Walk through one message and look at the type: If it is our
463 message, we need RTM_NEWLINK/RTM_NEWADDR and stop if we reach
464 the end or we find the end marker (in this case we ignore the
466 for (nlh = nlp->nlh; NLMSG_OK (nlh, size); nlh = NLMSG_NEXT (nlh, size))
470 /* Check if the message is the one we want */
471 if ((pid_t) nlh->nlmsg_pid != nh.pid || nlh->nlmsg_seq != nlp->seq)
474 if (nlh->nlmsg_type == NLMSG_DONE)
477 if (nlh->nlmsg_type == RTM_NEWLINK)
479 /* We found a new interface. Now extract everything from the
480 interface data we got and need. */
481 struct ifinfomsg *ifim = (struct ifinfomsg *) NLMSG_DATA (nlh);
482 struct rtattr *rta = IFLA_RTA (ifim);
483 size_t rtasize = IFLA_PAYLOAD (nlh);
485 /* Interfaces are stored in the first "newlink" entries
486 of our list, starting in the order as we got from the
488 ifa_index = map_newlink (ifim->ifi_index - 1, ifas,
489 map_newlink_data, newlink);
490 ifas[ifa_index].ifa.ifa_flags = ifim->ifi_flags;
492 while (RTA_OK (rta, rtasize))
494 char *rta_data = RTA_DATA (rta);
495 size_t rta_payload = RTA_PAYLOAD (rta);
497 switch (rta->rta_type)
500 if (rta_payload <= sizeof (ifas[ifa_index].addr))
502 ifas[ifa_index].addr.sl.sll_family = AF_PACKET;
503 memcpy (ifas[ifa_index].addr.sl.sll_addr,
504 (char *) rta_data, rta_payload);
505 ifas[ifa_index].addr.sl.sll_halen = rta_payload;
506 ifas[ifa_index].addr.sl.sll_ifindex
508 ifas[ifa_index].addr.sl.sll_hatype = ifim->ifi_type;
510 ifas[ifa_index].ifa.ifa_addr
511 = &ifas[ifa_index].addr.sa;
516 if (rta_payload <= sizeof (ifas[ifa_index].broadaddr))
518 ifas[ifa_index].broadaddr.sl.sll_family = AF_PACKET;
519 memcpy (ifas[ifa_index].broadaddr.sl.sll_addr,
520 (char *) rta_data, rta_payload);
521 ifas[ifa_index].broadaddr.sl.sll_halen = rta_payload;
522 ifas[ifa_index].broadaddr.sl.sll_ifindex
524 ifas[ifa_index].broadaddr.sl.sll_hatype
527 ifas[ifa_index].ifa.ifa_broadaddr
528 = &ifas[ifa_index].broadaddr.sa;
532 case IFLA_IFNAME: /* Name of Interface */
533 if ((rta_payload + 1) <= sizeof (ifas[ifa_index].name))
535 ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
536 *(char *) mempcpy (ifas[ifa_index].name, rta_data,
541 case IFLA_STATS: /* Statistics of Interface */
542 ifas[ifa_index].ifa.ifa_data = ifa_data_ptr;
543 ifa_data_ptr += rta_payload;
544 memcpy (ifas[ifa_index].ifa.ifa_data, rta_data,
560 rta = RTA_NEXT (rta, rtasize);
563 else if (nlh->nlmsg_type == RTM_NEWADDR)
565 struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlh);
566 struct rtattr *rta = IFA_RTA (ifam);
567 size_t rtasize = IFA_PAYLOAD (nlh);
569 /* New Addresses are stored in the order we got them from
570 the kernel after the interfaces. Theoretically it is possible
571 that we have holes in the interface part of the list,
572 but we always have already the interface for this address. */
573 ifa_index = newlink + newaddr_idx;
574 ifas[ifa_index].ifa.ifa_flags
575 = ifas[map_newlink (ifam->ifa_index - 1, ifas,
576 map_newlink_data, newlink)].ifa.ifa_flags;
578 ifas[ifa_index - 1].ifa.ifa_next = &ifas[ifa_index].ifa;
581 while (RTA_OK (rta, rtasize))
583 char *rta_data = RTA_DATA (rta);
584 size_t rta_payload = RTA_PAYLOAD (rta);
586 switch (rta->rta_type)
592 if (ifas[ifa_index].ifa.ifa_addr != NULL)
594 /* In a point-to-poing network IFA_ADDRESS
595 contains the destination address, local
596 address is supplied in IFA_LOCAL attribute.
597 destination address and broadcast address
598 are stored in an union, so it doesn't matter
599 which name we use. */
600 ifas[ifa_index].ifa.ifa_broadaddr
601 = &ifas[ifa_index].broadaddr.sa;
602 sa = &ifas[ifa_index].broadaddr.sa;
606 ifas[ifa_index].ifa.ifa_addr
607 = &ifas[ifa_index].addr.sa;
608 sa = &ifas[ifa_index].addr.sa;
611 sa->sa_family = ifam->ifa_family;
613 switch (ifam->ifa_family)
616 /* Size must match that of an address for IPv4. */
617 if (rta_payload == 4)
618 memcpy (&((struct sockaddr_in *) sa)->sin_addr,
619 rta_data, rta_payload);
622 #ifdef __UCLIBC_HAS_IPV6__
624 /* Size must match that of an address for IPv6. */
625 if (rta_payload == 16)
627 memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr,
628 rta_data, rta_payload);
629 if (IN6_IS_ADDR_LINKLOCAL (rta_data)
630 || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
631 ((struct sockaddr_in6 *) sa)->sin6_scope_id
638 if (rta_payload <= sizeof (ifas[ifa_index].addr))
639 memcpy (sa->sa_data, rta_data, rta_payload);
646 if (ifas[ifa_index].ifa.ifa_addr != NULL)
648 /* If ifa_addr is set and we get IFA_LOCAL,
649 assume we have a point-to-point network.
650 Move address to correct field. */
651 ifas[ifa_index].broadaddr = ifas[ifa_index].addr;
652 ifas[ifa_index].ifa.ifa_broadaddr
653 = &ifas[ifa_index].broadaddr.sa;
654 memset (&ifas[ifa_index].addr, '\0',
655 sizeof (ifas[ifa_index].addr));
658 ifas[ifa_index].ifa.ifa_addr = &ifas[ifa_index].addr.sa;
659 ifas[ifa_index].ifa.ifa_addr->sa_family
662 switch (ifam->ifa_family)
665 /* Size must match that of an address for IPv4. */
666 if (rta_payload == 4)
667 memcpy (&ifas[ifa_index].addr.s4.sin_addr,
668 rta_data, rta_payload);
671 #ifdef __UCLIBC_HAS_IPV6__
673 /* Size must match that of an address for IPv6. */
674 if (rta_payload == 16)
676 memcpy (&ifas[ifa_index].addr.s6.sin6_addr,
677 rta_data, rta_payload);
678 if (IN6_IS_ADDR_LINKLOCAL (rta_data)
679 || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
680 ifas[ifa_index].addr.s6.sin6_scope_id =
687 if (rta_payload <= sizeof (ifas[ifa_index].addr))
688 memcpy (ifas[ifa_index].addr.sa.sa_data,
689 rta_data, rta_payload);
695 /* We get IFA_BROADCAST, so IFA_LOCAL was too much. */
696 if (ifas[ifa_index].ifa.ifa_broadaddr != NULL)
697 memset (&ifas[ifa_index].broadaddr, '\0',
698 sizeof (ifas[ifa_index].broadaddr));
700 ifas[ifa_index].ifa.ifa_broadaddr
701 = &ifas[ifa_index].broadaddr.sa;
702 ifas[ifa_index].ifa.ifa_broadaddr->sa_family
705 switch (ifam->ifa_family)
708 /* Size must match that of an address for IPv4. */
709 if (rta_payload == 4)
710 memcpy (&ifas[ifa_index].broadaddr.s4.sin_addr,
711 rta_data, rta_payload);
714 #ifdef __UCLIBC_HAS_IPV6__
716 /* Size must match that of an address for IPv6. */
717 if (rta_payload == 16)
719 memcpy (&ifas[ifa_index].broadaddr.s6.sin6_addr,
720 rta_data, rta_payload);
721 if (IN6_IS_ADDR_LINKLOCAL (rta_data)
722 || IN6_IS_ADDR_MC_LINKLOCAL (rta_data))
723 ifas[ifa_index].broadaddr.s6.sin6_scope_id
730 if (rta_payload <= sizeof (ifas[ifa_index].addr))
731 memcpy (&ifas[ifa_index].broadaddr.sa.sa_data,
732 rta_data, rta_payload);
738 if (rta_payload + 1 <= sizeof (ifas[ifa_index].name))
740 ifas[ifa_index].ifa.ifa_name = ifas[ifa_index].name;
741 *(char *) mempcpy (ifas[ifa_index].name, rta_data,
756 rta = RTA_NEXT (rta, rtasize);
759 /* If we didn't get the interface name with the
760 address, use the name from the interface entry. */
761 if (ifas[ifa_index].ifa.ifa_name == NULL)
762 ifas[ifa_index].ifa.ifa_name
763 = ifas[map_newlink (ifam->ifa_index - 1, ifas,
764 map_newlink_data, newlink)].ifa.ifa_name;
766 /* Calculate the netmask. */
767 if (ifas[ifa_index].ifa.ifa_addr
768 && ifas[ifa_index].ifa.ifa_addr->sa_family != AF_UNSPEC
769 && ifas[ifa_index].ifa.ifa_addr->sa_family != AF_PACKET)
771 uint32_t max_prefixlen = 0;
774 ifas[ifa_index].ifa.ifa_netmask
775 = &ifas[ifa_index].netmask.sa;
777 switch (ifas[ifa_index].ifa.ifa_addr->sa_family)
780 cp = (char *) &ifas[ifa_index].netmask.s4.sin_addr;
784 #ifdef __UCLIBC_HAS_IPV6__
786 cp = (char *) &ifas[ifa_index].netmask.s6.sin6_addr;
792 ifas[ifa_index].ifa.ifa_netmask->sa_family
793 = ifas[ifa_index].ifa.ifa_addr->sa_family;
798 unsigned int preflen;
800 if ((max_prefixlen > 0) &&
801 (ifam->ifa_prefixlen > max_prefixlen))
802 preflen = max_prefixlen;
804 preflen = ifam->ifa_prefixlen;
806 for (i = 0; i < (preflen / 8); i++)
809 c <<= (8 - (preflen % 8));
817 assert (ifa_data_ptr <= (char *) &ifas[newlink + newaddr] + ifa_data_size);
821 for (i = 0; i < newlink; ++i)
822 if (map_newlink_data[i] == -1)
824 /* We have fewer links then we anticipated. Adjust the
825 forward pointer to the first address entry. */
826 ifas[i - 1].ifa.ifa_next = &ifas[newlink].ifa;
829 if (i == 0 && newlink > 0)
830 /* No valid link, but we allocated memory. We have to
831 populate the first entry. */
832 memmove (ifas, &ifas[newlink], sizeof (struct ifaddrs_storage));
836 *ifap = &ifas[0].ifa;
839 __netlink_free_handle (&nh);
840 __netlink_close (&nh);
844 libc_hidden_def(getifaddrs)
847 freeifaddrs (struct ifaddrs *ifa)
851 libc_hidden_def(freeifaddrs)
853 #endif /* __UCLIBC_SUPPORT_AI_ADDRCONFIG__ */
855 #endif /* __ASSUME_NETLINK_SUPPORT */