[filesystem.c] Add a cast to aviod a warning with VisualStudio 2017.
[metze/wireshark/wip.git] / wsutil / interface.c
1 /* interface.c
2  * Utility functions to get infos from interfaces
3  *
4  * Copyright 2016, Dario Lombardo
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 #include "config.h"
26
27 #include "interface.h"
28
29 #include <string.h>
30 #include <wsutil/inet_addr.h>
31
32 #ifdef HAVE_SYS_TYPES_H
33         #include <sys/types.h>
34 #endif
35
36 #ifdef HAVE_SYS_SOCKET_H
37         #include <sys/socket.h>
38 #endif
39
40 #ifdef HAVE_NETINET_IN_H
41         #include <netinet/in.h>
42 #endif
43
44 #ifdef HAVE_ARPA_INET_H
45         #include <arpa/inet.h>
46 #endif
47
48 #ifdef HAVE_IFADDRS_H
49         #include <ifaddrs.h>
50 #endif
51
52 #ifdef _WIN32
53         #include <winsock2.h>
54         #include <iphlpapi.h>
55         #include <Ws2tcpip.h>
56 #endif
57
58 #define WORKING_BUFFER_SIZE 15000
59
60 #ifdef HAVE_GETIFADDRS
61 static GSList* local_interfaces_to_list_nix(void)
62 {
63         GSList *interfaces = NULL;
64         struct ifaddrs *ifap;
65         struct ifaddrs *ifa;
66         int family;
67         char ip[INET6_ADDRSTRLEN];
68
69         if (getifaddrs(&ifap)) {
70                 goto end;
71         }
72
73         for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
74                 if (ifa->ifa_addr == NULL)
75                         continue;
76
77                 family = ifa->ifa_addr->sa_family;
78
79                 memset(ip, 0x0, INET6_ADDRSTRLEN);
80
81                 switch (family) {
82                         case AF_INET:
83                         {
84                                 struct sockaddr_in *addr4 = (struct sockaddr_in *)ifa->ifa_addr;
85                                 ws_inet_ntop4(&addr4->sin_addr, ip, sizeof(ip));
86                                 break;
87                         }
88
89                         case AF_INET6:
90                         {
91                                 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)ifa->ifa_addr;
92                                 ws_inet_ntop6(&addr6->sin6_addr, ip, sizeof(ip));
93                                 break;
94                         }
95
96                         default:
97                                 break;
98                 }
99
100                 /* skip loopback addresses */
101                 if (!g_strcmp0(ip, "127.0.0.1") || !g_strcmp0(ip, "::1"))
102                         continue;
103
104                 if (*ip) {
105                         interfaces = g_slist_prepend(interfaces, g_strdup(ip));
106                 }
107         }
108         freeifaddrs(ifap);
109 end:
110         return interfaces;
111 }
112 #endif /* HAVE_GETIFADDRS */
113
114 #ifdef _WIN32
115 static GSList* local_interfaces_to_list_win(void)
116 {
117         GSList *interfaces = NULL;
118         PIP_ADAPTER_ADDRESSES pAddresses = NULL;
119         ULONG outBufLen = WORKING_BUFFER_SIZE;
120         ULONG family = AF_UNSPEC;
121         PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
122         PIP_ADAPTER_UNICAST_ADDRESS pUnicast = NULL;
123         char ip[100];
124         guint iplen = 100;
125
126         pAddresses = (IP_ADAPTER_ADDRESSES *)g_malloc0(outBufLen);
127         if (pAddresses == NULL)
128                 return NULL;
129
130         if (GetAdaptersAddresses(family, 0, NULL, pAddresses, &outBufLen) != NO_ERROR)
131                 goto end;
132
133         pCurrAddresses = pAddresses;
134         while (pCurrAddresses) {
135
136                 for (pUnicast = pCurrAddresses->FirstUnicastAddress; pUnicast != NULL; pUnicast = pUnicast->Next) {
137                         if (pUnicast->Address.lpSockaddr->sa_family == AF_INET) {
138                                 SOCKADDR_IN* sa_in = (SOCKADDR_IN *)pUnicast->Address.lpSockaddr;
139                                 ws_inet_ntop4(&(sa_in->sin_addr), ip, iplen);
140                                 if (!g_strcmp0(ip, "127.0.0.1"))
141                                         continue;
142                                 if (*ip)
143                                         interfaces = g_slist_prepend(interfaces, g_strdup(ip));
144                         }
145                         if (pUnicast->Address.lpSockaddr->sa_family == AF_INET6) {
146                                 SOCKADDR_IN6* sa_in6 = (SOCKADDR_IN6 *)pUnicast->Address.lpSockaddr;
147                                 ws_inet_ntop6(&(sa_in6->sin6_addr), ip, iplen);
148                                 if (!g_strcmp0(ip, "::1"))
149                                         continue;
150                                 if (*ip)
151                                         interfaces = g_slist_prepend(interfaces, g_strdup(ip));
152                         }
153                 }
154                 pCurrAddresses = pCurrAddresses->Next;
155         }
156 end:
157         if (pAddresses)
158                 g_free(pAddresses);
159
160         return interfaces;
161 }
162 #endif /* _WIN32 */
163
164 GSList* local_interfaces_to_list(void)
165 {
166 #if defined(_WIN32)
167         return local_interfaces_to_list_win();
168 #elif defined(HAVE_GETIFADDRS)
169         return local_interfaces_to_list_nix();
170 #else
171         return NULL;
172 #endif
173 }
174
175 /*
176  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
177  *
178  * Local variables:
179  * c-basic-offset: 4
180  * tab-width: 8
181  * indent-tabs-mode: t
182  * End:
183  *
184  * vi: set shiftwidth=4 tabstop=8 noexpandtab:
185  * :indentSize=4:tabSize=8:noTabs=false:
186  */