38 #pragma comment(lib, "iphlpapi.lib")
44 #elif defined(__linux__) && defined(HAVE_IFADDRS_H)
48 #if _WIN32 || (defined(__linux__) && defined(HAVE_IFADDRS_H))
49 static void io_addr_set(
io_addr_t *addr,
const struct sockaddr *address);
53 static NETIO_STATUS WINAPI ConvertLengthToIpv6Mask(
54 ULONG MaskLength, u_char Mask[16]);
57 #if _WIN32 || (defined(__linux__) && defined(HAVE_IFADDRS_H))
66 ULONG Flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST
67 | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_PREFIX
68 | GAA_FLAG_SKIP_FRIENDLY_NAME
69 | GAA_FLAG_INCLUDE_ALL_INTERFACES;
71 DWORD dwErrCode = GetAdaptersAddresses(
72 AF_UNSPEC, Flags, NULL, NULL, &Size);
73 if (dwErrCode != ERROR_BUFFER_OVERFLOW) {
74 SetLastError(dwErrCode);
78 PIP_ADAPTER_ADDRESSES pAdapterAddresses = malloc(Size);
79 if (!pAdapterAddresses)
82 dwErrCode = GetAdaptersAddresses(
83 AF_UNSPEC, Flags, NULL, pAdapterAddresses, &Size);
84 if (dwErrCode != ERROR_SUCCESS) {
85 free(pAdapterAddresses);
86 SetLastError(dwErrCode);
91 for (PIP_ADAPTER_ADDRESSES paa = pAdapterAddresses; paa;
95 paa->IfIndex ? paa->IfIndex : paa->Ipv6IfIndex;
101 if (paa->OperStatus == IfOperStatusUp)
103 if (paa->IfType == IF_TYPE_PPP)
105 else if (paa->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
109 if (!(paa->Flags & IP_ADAPTER_NO_MULTICAST))
113 for (PIP_ADAPTER_UNICAST_ADDRESS paua =
114 paa->FirstUnicastAddress;
115 paua; paua = paua->Next) {
116 LPSOCKADDR lpSockaddr = paua->Address.lpSockaddr;
122 switch (lpSockaddr->sa_family) {
128 if (++ninfo > maxinfo)
131 memset(info, 0,
sizeof(*info));
145 io_addr_set(&info->
addr, lpSockaddr);
150 ConvertLengthToIpv4Mask(
151 paua->OnLinkPrefixLength,
154 (uint8_t *)&Mask, 0);
159 ULONG BCast = ((
struct sockaddr_in *)lpSockaddr)
164 (uint8_t *)&BCast, 0);
169 ConvertLengthToIpv6Mask(
170 paua->OnLinkPrefixLength, Mask);
181 free(pAdapterAddresses);
183 struct ifaddrs *res = NULL;
184 if (getifaddrs(&res) == -1)
188 for (
struct ifaddrs *ifa = res; ifa; ifa = ifa->ifa_next) {
192 switch (ifa->ifa_addr->sa_family) {
201 if (++ninfo > maxinfo)
204 memset(info, 0,
sizeof(*info));
210 info->
index = if_nametoindex(ifa->ifa_name);
217 if (ifa->ifa_flags & IFF_UP)
219 if (ifa->ifa_flags & IFF_BROADCAST)
221 if (ifa->ifa_flags & IFF_LOOPBACK)
223 if (ifa->ifa_flags & IFF_POINTOPOINT)
225 if (ifa->ifa_flags & IFF_MULTICAST)
230 io_addr_set(&info->
addr, ifa->ifa_addr);
233 if (ifa->ifa_netmask)
234 io_addr_set(&info->
netmask, ifa->ifa_netmask);
237 if ((ifa->ifa_flags & IFF_BROADCAST) && ifa->ifa_broadaddr)
238 io_addr_set(&info->
broadaddr, ifa->ifa_broadaddr);
239 else if ((ifa->ifa_flags & IFF_POINTOPOINT) && ifa->ifa_dstaddr)
240 io_addr_set(&info->
broadaddr, ifa->ifa_dstaddr);
252 io_addr_set(
io_addr_t *addr,
const struct sockaddr *address)
257 switch (address->sa_family) {
258 #if defined(__linux__) && defined(HAVE_LINUX_CAN_H)
259 case AF_CAN: addr->
addrlen =
sizeof(
struct sockaddr_can);
break;
261 case AF_INET: addr->
addrlen =
sizeof(
struct sockaddr_in);
break;
262 case AF_INET6: addr->
addrlen =
sizeof(
struct sockaddr_in6);
break;
263 #if _POSIX_C_SOURCE >= 200112L
264 case AF_UNIX: addr->
addrlen =
sizeof(
struct sockaddr_un);
break;
266 default: addr->
addrlen = 0;
break;
274 static NETIO_STATUS WINAPI
275 ConvertLengthToIpv6Mask(ULONG MaskLength, u_char Mask[16])
277 if (MaskLength > 128) {
278 for (
int i = 0; i < 16; i++)
280 return ERROR_INVALID_PARAMETER;
283 for (LONG i = MaskLength, j = 0; i > 0; i -= 8, j++)
284 Mask[j] = i >= 8 ? 0xff : ((0xff << (8 - i)) & 0xff);
void io_addr_set_ipv4_n(io_addr_t *addr, const uint8_t ip[4], int port)
Initializes a network address from an IPv4 address and port number.
void io_addr_set_ipv6_n(io_addr_t *addr, const uint8_t ip[16], int port)
Initializes a network address from an IPv6 address and port number.
This header file is part of the utilities library; it contains the native and platform-independent er...
int io_get_ifinfo(int maxinfo, struct io_ifinfo *info)
Obtains a list of network interfaces.
This header file is part of the I/O library; it contains network interface declarations.
#define IO_IF_NAME_STRLEN
The maximum number of bytes required to hold the name of a network interface, including the terminati...
@ IO_IF_UP
The interface is running.
@ IO_IF_POINTTOPOINT
The interface is a point-to-point link.
@ IO_IF_LOOPBACK
The interface is a loopback interface.
@ IO_IF_BROADCAST
A valid broadcast address is set.
@ IO_IF_MULTICAST
The interface supports multicast.
This header file is part of the I/O library; it contains the network socket declarations.
@ IO_SOCK_IPV4
An IPv4 socket.
@ IO_SOCK_IPV6
An IPv6 socket.
This is the internal header file of the Windows-specific I/O declarations.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
This header file is part of the C11 and POSIX compatibility library; it includes <string....
An opaque network address type.
union __io_addr::@5 addr
The network address.
int addrlen
The size (in bytes) of addr.
A structure describing a network interface.
io_addr_t addr
The address of the interface.
char name[IO_IF_NAME_STRLEN]
The interface name.
unsigned int index
The interface index.
io_addr_t netmask
The netmask used by the interface.
int flags
The status of the interface (any combination of IO_IF_UP, IO_IF_BROADCAST, IO_IF_LOOPBACK,...
io_addr_t broadaddr
The broadcast address of the interface.
int domain
The domain of the interface (one of IO_SOCK_BTH, IO_SOCK_IPV4, IO_SOCK_IPV6 or IO_SOCK_UNIX).