35 #pragma comment(lib, "iphlpapi.lib")
41 #elif defined(__linux__) && defined(HAVE_IFADDRS_H)
45 #if defined(_WIN32) || (defined(__linux__) && defined(HAVE_IFADDRS_H))
46 static void io_addr_set(
io_addr_t *addr,
const struct sockaddr *address);
50 static NETIO_STATUS WINAPI ConvertLengthToIpv6Mask(
51 ULONG MaskLength, u_char Mask[16]);
54 #if defined(_WIN32) || (defined(__linux__) && defined(HAVE_IFADDRS_H))
63 ULONG Flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST
64 | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_PREFIX
65 | GAA_FLAG_SKIP_FRIENDLY_NAME
66 | GAA_FLAG_INCLUDE_ALL_INTERFACES;
68 DWORD dwErrCode = GetAdaptersAddresses(
69 AF_UNSPEC, Flags, NULL, NULL, &Size);
70 if (dwErrCode != ERROR_BUFFER_OVERFLOW) {
71 SetLastError(dwErrCode);
75 PIP_ADAPTER_ADDRESSES pAdapterAddresses = malloc(Size);
76 if (!pAdapterAddresses)
79 dwErrCode = GetAdaptersAddresses(
80 AF_UNSPEC, Flags, NULL, pAdapterAddresses, &Size);
81 if (dwErrCode != ERROR_SUCCESS) {
82 free(pAdapterAddresses);
83 SetLastError(dwErrCode);
88 for (PIP_ADAPTER_ADDRESSES paa = pAdapterAddresses; paa;
92 paa->IfIndex ? paa->IfIndex : paa->Ipv6IfIndex;
98 if (paa->OperStatus == IfOperStatusUp)
100 if (paa->IfType == IF_TYPE_PPP)
102 else if (paa->IfType == IF_TYPE_SOFTWARE_LOOPBACK)
106 if (!(paa->Flags & IP_ADAPTER_NO_MULTICAST))
110 for (PIP_ADAPTER_UNICAST_ADDRESS paua =
111 paa->FirstUnicastAddress;
112 paua; paua = paua->Next) {
113 LPSOCKADDR lpSockaddr = paua->Address.lpSockaddr;
119 switch (lpSockaddr->sa_family) {
125 if (++ninfo > maxinfo)
128 memset(info, 0,
sizeof(*info));
142 io_addr_set(&info->
addr, lpSockaddr);
147 ConvertLengthToIpv4Mask(
148 paua->OnLinkPrefixLength,
151 (uint8_t *)&Mask, 0);
156 ULONG BCast = ((
struct sockaddr_in *)lpSockaddr)
161 (uint8_t *)&BCast, 0);
166 ConvertLengthToIpv6Mask(
167 paua->OnLinkPrefixLength, Mask);
178 free(pAdapterAddresses);
180 struct ifaddrs *res = NULL;
181 if (getifaddrs(&res) == -1)
185 for (
struct ifaddrs *ifa = res; ifa; ifa = ifa->ifa_next) {
189 switch (ifa->ifa_addr->sa_family) {
198 if (++ninfo > maxinfo)
201 memset(info, 0,
sizeof(*info));
207 info->
index = if_nametoindex(ifa->ifa_name);
214 if (ifa->ifa_flags & IFF_UP)
216 if (ifa->ifa_flags & IFF_BROADCAST)
218 if (ifa->ifa_flags & IFF_LOOPBACK)
220 if (ifa->ifa_flags & IFF_POINTOPOINT)
222 if (ifa->ifa_flags & IFF_MULTICAST)
227 io_addr_set(&info->
addr, ifa->ifa_addr);
230 if (ifa->ifa_netmask)
231 io_addr_set(&info->
netmask, ifa->ifa_netmask);
234 if ((ifa->ifa_flags & IFF_BROADCAST) && ifa->ifa_broadaddr)
235 io_addr_set(&info->
broadaddr, ifa->ifa_broadaddr);
236 else if ((ifa->ifa_flags & IFF_POINTOPOINT) && ifa->ifa_dstaddr)
237 io_addr_set(&info->
broadaddr, ifa->ifa_dstaddr);
249 io_addr_set(
io_addr_t *addr,
const struct sockaddr *address)
254 switch (address->sa_family) {
255 #if defined(__linux__) && defined(HAVE_LINUX_CAN_H)
256 case AF_CAN: addr->
addrlen =
sizeof(
struct sockaddr_can);
break;
258 case AF_INET: addr->
addrlen =
sizeof(
struct sockaddr_in);
break;
259 case AF_INET6: addr->
addrlen =
sizeof(
struct sockaddr_in6);
break;
260 #if _POSIX_C_SOURCE >= 200112L
261 case AF_UNIX: addr->
addrlen =
sizeof(
struct sockaddr_un);
break;
263 default: addr->
addrlen = 0;
break;
271 static NETIO_STATUS WINAPI
272 ConvertLengthToIpv6Mask(ULONG MaskLength, u_char Mask[16])
274 if (MaskLength > 128) {
275 for (
int i = 0; i < 16; i++)
277 return ERROR_INVALID_PARAMETER;
280 for (LONG i = MaskLength, j = 0; i > 0; i -= 8, j++)
281 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).