bsd-ifaddrs.c
Go to the documentation of this file.
1 /* Copyright libuv project contributors. All rights reserved.
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining a copy
4  * of this software and associated documentation files (the "Software"), to
5  * deal in the Software without restriction, including without limitation the
6  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7  * sell copies of the Software, and to permit persons to whom the Software is
8  * furnished to do so, subject to the following conditions:
9  *
10  * The above copyright notice and this permission notice shall be included in
11  * all copies or substantial portions of the Software.
12  *
13  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19  * IN THE SOFTWARE.
20  */
21 
22 #include "uv.h"
23 #include "internal.h"
24 
25 #include <errno.h>
26 #include <stddef.h>
27 
28 #include <ifaddrs.h>
29 #include <net/if.h>
30 #if !defined(__CYGWIN__) && !defined(__MSYS__)
31 #include <net/if_dl.h>
32 #endif
33 
34 #if defined(__HAIKU__)
35 #define IFF_RUNNING IFF_LINK
36 #endif
37 
38 static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type) {
39  if (!((ent->ifa_flags & IFF_UP) && (ent->ifa_flags & IFF_RUNNING)))
40  return 1;
41  if (ent->ifa_addr == NULL)
42  return 1;
43 #if !defined(__CYGWIN__) && !defined(__MSYS__)
44  /*
45  * If `exclude_type` is `UV__EXCLUDE_IFPHYS`, just see whether `sa_family`
46  * equals to `AF_LINK` or not. Otherwise, the result depends on the operation
47  * system with `AF_LINK` or `PF_INET`.
48  */
49  if (exclude_type == UV__EXCLUDE_IFPHYS)
50  return (ent->ifa_addr->sa_family != AF_LINK);
51 #endif
52 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__DragonFly__) || \
53  defined(__HAIKU__)
54  /*
55  * On BSD getifaddrs returns information related to the raw underlying
56  * devices. We're not interested in this information.
57  */
58  if (ent->ifa_addr->sa_family == AF_LINK)
59  return 1;
60 #elif defined(__NetBSD__) || defined(__OpenBSD__)
61  if (ent->ifa_addr->sa_family != PF_INET &&
62  ent->ifa_addr->sa_family != PF_INET6)
63  return 1;
64 #endif
65  return 0;
66 }
67 
69  struct ifaddrs* addrs;
70  struct ifaddrs* ent;
71  uv_interface_address_t* address;
72 #if !(defined(__CYGWIN__) || defined(__MSYS__))
73  int i;
74 #endif
75 
76  *count = 0;
77  *addresses = NULL;
78 
79  if (getifaddrs(&addrs) != 0)
80  return UV__ERR(errno);
81 
82  /* Count the number of interfaces */
83  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
85  continue;
86  (*count)++;
87  }
88 
89  if (*count == 0) {
90  freeifaddrs(addrs);
91  return 0;
92  }
93 
94  /* Make sure the memory is initiallized to zero using calloc() */
95  *addresses = uv__calloc(*count, sizeof(**addresses));
96 
97  if (*addresses == NULL) {
98  freeifaddrs(addrs);
99  return UV_ENOMEM;
100  }
101 
102  address = *addresses;
103 
104  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
106  continue;
107 
108  address->name = uv__strdup(ent->ifa_name);
109 
110  if (ent->ifa_addr->sa_family == AF_INET6) {
111  address->address.address6 = *((struct sockaddr_in6*) ent->ifa_addr);
112  } else {
113  address->address.address4 = *((struct sockaddr_in*) ent->ifa_addr);
114  }
115 
116  if (ent->ifa_netmask->sa_family == AF_INET6) {
117  address->netmask.netmask6 = *((struct sockaddr_in6*) ent->ifa_netmask);
118  } else {
119  address->netmask.netmask4 = *((struct sockaddr_in*) ent->ifa_netmask);
120  }
121 
122  address->is_internal = !!(ent->ifa_flags & IFF_LOOPBACK);
123 
124  address++;
125  }
126 
127 #if !(defined(__CYGWIN__) || defined(__MSYS__))
128  /* Fill in physical addresses for each interface */
129  for (ent = addrs; ent != NULL; ent = ent->ifa_next) {
131  continue;
132 
133  address = *addresses;
134 
135  for (i = 0; i < *count; i++) {
136  if (strcmp(address->name, ent->ifa_name) == 0) {
137  struct sockaddr_dl* sa_addr;
138  sa_addr = (struct sockaddr_dl*)(ent->ifa_addr);
139  memcpy(address->phys_addr, LLADDR(sa_addr), sizeof(address->phys_addr));
140  }
141  address++;
142  }
143  }
144 #endif
145 
146  freeifaddrs(addrs);
147 
148  return 0;
149 }
150 
151 
153  int count) {
154  int i;
155 
156  for (i = 0; i < count; i++) {
157  uv__free(addresses[i].name);
158  }
159 
160  uv__free(addresses);
161 }
AF_INET6
#define AF_INET6
Definition: ares_setup.h:208
UV__EXCLUDE_IFPHYS
@ UV__EXCLUDE_IFPHYS
Definition: third_party/libuv/src/unix/internal.h:146
setup.name
name
Definition: setup.py:542
uv__ifaddr_exclude
static int uv__ifaddr_exclude(struct ifaddrs *ent, int exclude_type)
Definition: bsd-ifaddrs.c:38
uv_interface_address_s::netmask
union uv_interface_address_s::@401 netmask
uv_interface_address_s::name
char * name
Definition: uv.h:1086
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
sockaddr_in6
Definition: ares_ipv6.h:25
ifaddrs::ifa_netmask
struct sockaddr * ifa_netmask
Definition: android-ifaddrs.h:34
ifaddrs::ifa_addr
struct sockaddr * ifa_addr
Definition: android-ifaddrs.h:33
uv__strdup
char * uv__strdup(const char *s)
Definition: uv-common.c:55
ifaddrs::ifa_name
char * ifa_name
Definition: android-ifaddrs.h:31
uv_interface_addresses
int uv_interface_addresses(uv_interface_address_t **addresses, int *count)
Definition: bsd-ifaddrs.c:68
uv__calloc
void * uv__calloc(size_t count, size_t size)
Definition: uv-common.c:92
uv__free
void uv__free(void *ptr)
Definition: uv-common.c:81
UV__ERR
#define UV__ERR(x)
Definition: errno.h:29
UV__EXCLUDE_IFADDR
@ UV__EXCLUDE_IFADDR
Definition: third_party/libuv/src/unix/internal.h:147
uv_interface_address_s
Definition: uv.h:1085
uv.h
PF_INET6
#define PF_INET6
Definition: ares_ipv6.h:21
internal.h
count
int * count
Definition: bloaty/third_party/googletest/googlemock/test/gmock_stress_test.cc:96
uv_interface_address_s::address4
struct sockaddr_in address4
Definition: uv.h:1090
uv_interface_address_s::netmask6
struct sockaddr_in6 netmask6
Definition: uv.h:1095
ifaddrs::ifa_flags
unsigned int ifa_flags
Definition: android-ifaddrs.h:32
uv_interface_address_s::is_internal
int is_internal
Definition: uv.h:1088
ifaddrs
Definition: android-ifaddrs.h:29
uv_interface_address_s::address
union uv_interface_address_s::@400 address
uv_interface_address_s::phys_addr
char phys_addr[6]
Definition: uv.h:1087
ifaddrs::ifa_next
struct ifaddrs * ifa_next
Definition: android-ifaddrs.h:30
uv_interface_address_s::netmask4
struct sockaddr_in netmask4
Definition: uv.h:1094
freeifaddrs
void freeifaddrs(struct ifaddrs *ifa)
Definition: android-ifaddrs.c:704
getifaddrs
__BEGIN_DECLS int getifaddrs(struct ifaddrs **ifap)
Definition: android-ifaddrs.c:655
uv_free_interface_addresses
void uv_free_interface_addresses(uv_interface_address_t *addresses, int count)
Definition: bsd-ifaddrs.c:152
errno.h
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
uv_interface_address_s::address6
struct sockaddr_in6 address6
Definition: uv.h:1091


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:58:40