dcerpc-nt: add UNION_ALIGN_TO... helpers
[wireshark-sm.git] / wsutil / interface.c
blob0fc990d40295a81ada9d6297747624902b0a60d1
1 /* interface.c
2 * Utility functions to get infos from interfaces
4 * Copyright 2016, Dario Lombardo
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include "interface.h"
17 #include <string.h>
18 #include <wsutil/inet_addr.h>
20 #include <sys/types.h>
22 #ifdef HAVE_SYS_SOCKET_H
23 #include <sys/socket.h>
24 #endif
26 #ifdef HAVE_NETINET_IN_H
27 #include <netinet/in.h>
28 #endif
30 #ifdef HAVE_ARPA_INET_H
31 #include <arpa/inet.h>
32 #endif
34 #ifdef HAVE_IFADDRS_H
35 #include <ifaddrs.h>
36 #endif
38 #ifdef _WIN32
39 #include <winsock2.h>
40 #include <iphlpapi.h>
41 #include <ws2tcpip.h>
42 #endif
44 #define WORKING_BUFFER_SIZE 15000
46 #ifdef HAVE_GETIFADDRS
47 static GSList* local_interfaces_to_list_nix(void)
49 GSList *interfaces = NULL;
50 struct ifaddrs *ifap;
51 struct ifaddrs *ifa;
52 int family;
53 char ip[WS_INET6_ADDRSTRLEN];
55 if (getifaddrs(&ifap)) {
56 goto end;
59 for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
60 if (ifa->ifa_addr == NULL)
61 continue;
63 family = ifa->ifa_addr->sa_family;
65 memset(ip, 0x0, WS_INET6_ADDRSTRLEN);
67 switch (family) {
68 case AF_INET:
70 struct sockaddr_in *addr4 = (struct sockaddr_in *)ifa->ifa_addr;
71 ws_inet_ntop4(&addr4->sin_addr, ip, sizeof(ip));
72 break;
75 case AF_INET6:
77 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)ifa->ifa_addr;
78 ws_inet_ntop6(&addr6->sin6_addr, ip, sizeof(ip));
79 break;
82 default:
83 break;
86 /* skip loopback addresses */
87 if (!g_strcmp0(ip, "127.0.0.1") || !g_strcmp0(ip, "::1"))
88 continue;
90 if (*ip) {
91 interfaces = g_slist_prepend(interfaces, g_strdup(ip));
94 freeifaddrs(ifap);
95 end:
96 return interfaces;
98 #endif /* HAVE_GETIFADDRS */
100 #ifdef _WIN32
101 static GSList* local_interfaces_to_list_win(void)
103 GSList *interfaces = NULL;
104 PIP_ADAPTER_ADDRESSES pAddresses = NULL;
105 ULONG outBufLen = WORKING_BUFFER_SIZE;
106 ULONG family = AF_UNSPEC;
107 PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
108 PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
109 char ip[100];
110 unsigned iplen = 100;
112 pAddresses = (IP_ADAPTER_ADDRESSES *)g_malloc0(outBufLen);
113 if (pAddresses == NULL)
114 return NULL;
116 if (GetAdaptersAddresses(family, 0, NULL, pAddresses, &outBufLen) != NO_ERROR)
117 goto end;
119 pCurrAddresses = pAddresses;
120 while (pCurrAddresses) {
122 for (pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast != NULL; pUnicast = pUnicast->Next) {
123 if (pUnicast->Address.lpSockaddr->sa_family == AF_INET) {
124 SOCKADDR_IN* sa_in = (SOCKADDR_IN *)pUnicast->Address.lpSockaddr;
125 ws_inet_ntop4(&(sa_in->sin_addr), ip, iplen);
126 if (!g_strcmp0(ip, "127.0.0.1"))
127 continue;
128 if (*ip)
129 interfaces = g_slist_prepend(interfaces, g_strdup(ip));
131 if (pUnicast->Address.lpSockaddr->sa_family == AF_INET6) {
132 SOCKADDR_IN6* sa_in6 = (SOCKADDR_IN6 *)pUnicast->Address.lpSockaddr;
133 ws_inet_ntop6(&(sa_in6->sin6_addr), ip, iplen);
134 if (!g_strcmp0(ip, "::1"))
135 continue;
136 if (*ip)
137 interfaces = g_slist_prepend(interfaces, g_strdup(ip));
140 pCurrAddresses = pCurrAddresses->Next;
142 end:
143 g_free(pAddresses);
145 return interfaces;
147 #endif /* _WIN32 */
149 GSList* local_interfaces_to_list(void)
151 #if defined(_WIN32)
152 return local_interfaces_to_list_win();
153 #elif defined(HAVE_GETIFADDRS)
154 return local_interfaces_to_list_nix();
155 #else
156 return NULL;
157 #endif
161 * Editor modelines - https://www.wireshark.org/tools/modelines.html
163 * Local variables:
164 * c-basic-offset: 4
165 * tab-width: 8
166 * indent-tabs-mode: t
167 * End:
169 * vi: set shiftwidth=4 tabstop=8 noexpandtab:
170 * :indentSize=4:tabSize=8:noTabs=false: