aboutsummaryrefslogtreecommitdiff
path: root/src/util/os_network.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/os_network.c')
-rw-r--r--src/util/os_network.c286
1 files changed, 286 insertions, 0 deletions
diff --git a/src/util/os_network.c b/src/util/os_network.c
new file mode 100644
index 000000000..cb5ccb12a
--- /dev/null
+++ b/src/util/os_network.c
@@ -0,0 +1,286 @@
1/*
2 This file is part of GNUnet.
3 (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 2, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19
20*/
21
22/**
23 * @file util/os_network.c
24 * @brief function to determine available network interfaces
25 * @author Nils Durner
26 * @author Heikki Lindholm
27 * @author Jake Dust
28 */
29
30#include "platform.h"
31#include "gnunet_common.h"
32#include "gnunet_os_lib.h"
33
34/**
35 * @brief Enumerate all network interfaces
36 * @param callback the callback function
37 */
38void
39GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc,
40 void *cls)
41{
42#ifdef MINGW
43 PMIB_IFTABLE pTable;
44 PMIB_IPADDRTABLE pAddrTable;
45 DWORD dwIfIdx, dwExternalNIC;
46 IPAddr theIP;
47
48 /* Determine our external NIC */
49 theIP = inet_addr ("192.0.34.166"); /* www.example.com */
50 if ((!GNGetBestInterface) ||
51 (GNGetBestInterface (theIP, &dwExternalNIC) != NO_ERROR))
52 {
53 dwExternalNIC = 0;
54 }
55
56 /* Enumerate NICs */
57 EnumNICs (&pTable, &pAddrTable);
58
59 if (pTable)
60 {
61 for (dwIfIdx = 0; dwIfIdx <= pTable->dwNumEntries; dwIfIdx++)
62 {
63 char szEntry[1001];
64 DWORD dwIP = 0;
65 int iItm;
66 PIP_ADAPTER_INFO pAdapterInfo;
67 PIP_ADAPTER_INFO pAdapter = NULL;
68 DWORD dwRetVal = 0;
69
70 /* Get IP-Address */
71 int i;
72 for (i = 0; i < pAddrTable->dwNumEntries; i++)
73 {
74 if (pAddrTable->table[i].dwIndex ==
75 pTable->table[dwIfIdx].dwIndex)
76 {
77 dwIP = pAddrTable->table[i].dwAddr;
78 break;
79 }
80 }
81
82 if (dwIP)
83 {
84 BYTE bPhysAddr[MAXLEN_PHYSADDR];
85 char *pszIfName = NULL;
86 char dst[INET_ADDRSTRLEN];
87
88 /* Get friendly interface name */
89 pAdapterInfo =
90 (IP_ADAPTER_INFO *) malloc (sizeof (IP_ADAPTER_INFO));
91 ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
92
93 /* Make an initial call to GetAdaptersInfo to get
94 the necessary size into the ulOutBufLen variable */
95 if (GGetAdaptersInfo (pAdapterInfo, &ulOutBufLen) ==
96 ERROR_BUFFER_OVERFLOW)
97 {
98 free (pAdapterInfo);
99 pAdapterInfo = (IP_ADAPTER_INFO *) malloc (ulOutBufLen);
100 }
101
102 if ((dwRetVal =
103 GGetAdaptersInfo (pAdapterInfo, &ulOutBufLen)) == NO_ERROR)
104 {
105 pAdapter = pAdapterInfo;
106 while (pAdapter)
107 {
108 if (pTable->table[dwIfIdx].dwIndex == pAdapter->Index)
109 {
110 char szKey[251];
111 long lLen = 250;
112
113 sprintf (szKey,
114 "SYSTEM\\CurrentControlSet\\Control\\Network\\"
115 "{4D36E972-E325-11CE-BFC1-08002BE10318}\\%s\\Connection",
116 pAdapter->AdapterName);
117 pszIfName = (char *) malloc (251);
118 if (QueryRegistry
119 (HKEY_LOCAL_MACHINE, szKey, "Name", pszIfName,
120 &lLen) != ERROR_SUCCESS)
121 {
122 free (pszIfName);
123 pszIfName = NULL;
124 }
125 }
126 pAdapter = pAdapter->Next;
127 }
128 }
129 free (pAdapterInfo);
130
131 /* Set entry */
132 memset (bPhysAddr, 0, MAXLEN_PHYSADDR);
133 memcpy (bPhysAddr,
134 pTable->table[dwIfIdx].bPhysAddr,
135 pTable->table[dwIfIdx].dwPhysAddrLen);
136
137 snprintf (szEntry, 1000, "%s (%s - %I64u)",
138 pszIfName ? pszIfName : (char *) pTable->
139 table[dwIfIdx].bDescr, inet_ntop (AF_INET, &dwIP, dst,
140 INET_ADDRSTRLEN),
141 *((unsigned long long *) bPhysAddr));
142 szEntry[1000] = 0;
143
144 if (pszIfName)
145 free (pszIfName);
146
147 if (GNUNET_OK !=
148 proc (cls,
149 szEntry,
150 pAddrTable->table[dwIfIdx].dwIndex == dwExternalNIC,
151 NULL /* FIXME: pass actual IP address! */ ,
152 0))
153 break;
154 }
155 }
156 GlobalFree (pAddrTable);
157 GlobalFree (pTable);
158 }
159
160 return GNUNET_YES;
161
162#elif HAVE_GETIFADDRS && HAVE_FREEIFADDRS
163
164 struct ifaddrs *ifa_first;
165 socklen_t alen;
166
167 if (getifaddrs (&ifa_first) == 0)
168 {
169 struct ifaddrs *ifa_ptr;
170
171 ifa_ptr = ifa_first;
172 for (ifa_ptr = ifa_first; ifa_ptr != NULL; ifa_ptr = ifa_ptr->ifa_next)
173 {
174 if (ifa_ptr->ifa_name != NULL &&
175 ifa_ptr->ifa_addr != NULL && (ifa_ptr->ifa_flags & IFF_UP) != 0)
176 {
177 if ((ifa_ptr->ifa_addr->sa_family != AF_INET) &&
178 (ifa_ptr->ifa_addr->sa_family != AF_INET6))
179 continue;
180 if (ifa_ptr->ifa_addr->sa_family == AF_INET)
181 alen = sizeof (struct sockaddr_in);
182 else
183 alen = sizeof (struct sockaddr_in6);
184 if (GNUNET_OK != proc (cls,
185 ifa_ptr->ifa_name,
186 0 == strcmp (ifa_ptr->ifa_name,
187 GNUNET_DEFAULT_INTERFACE),
188 ifa_ptr->ifa_addr, alen))
189 break;
190 }
191 }
192 freeifaddrs (ifa_first);
193 }
194#else
195 char line[1024];
196 const char *start;
197 char ifc[12];
198 char addrstr[128];
199 FILE *f;
200 int have_ifc;
201 struct sockaddr_in a4;
202 struct sockaddr_in6 a6;
203 struct in_addr v4;
204 struct in6_addr v6;
205
206 if (system ("ifconfig -a > /dev/null 2> /dev/null"))
207 if (system ("/sbin/ifconfig -a > /dev/null 2> /dev/null") == 0)
208 f = popen ("/sbin/ifconfig -a 2> /dev/null", "r");
209 else
210 f = NULL;
211 else
212 f = popen ("ifconfig -a 2> /dev/null", "r");
213 if (!f)
214 {
215 GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_WARNING |
216 GNUNET_ERROR_TYPE_BULK, "popen", "ifconfig");
217 return;
218 }
219
220 have_ifc = GNUNET_NO;
221 ifc[11] = '\0';
222 while (NULL != fgets (line, sizeof (line), f))
223 {
224 if (strlen (line) == 0)
225 {
226 have_ifc = GNUNET_NO;
227 continue;
228 }
229 if (!isspace (line[0]))
230 {
231 have_ifc =
232 (1 == SSCANF (line, "%11s", ifc)) ? GNUNET_YES : GNUNET_NO;
233 /* would end with ':' on OSX, fix it! */
234 if (ifc[strlen (ifc) - 1] == ':')
235 ifc[strlen (ifc) - 1] = '\0';
236 continue;
237 }
238 if (!have_ifc)
239 continue; /* strange input, hope for the best */
240 start = line;
241 while (('\0' != *start) && (isspace (*start)))
242 start++;
243 if ( /* Linux */
244 (1 == SSCANF (start, "inet addr:%127s", addrstr)) ||
245 (1 == SSCANF (start, "inet6 addr:%127s", addrstr)) ||
246 /* Solaris, OS X */
247 (1 == SSCANF (start, "inet %127s", addrstr)) ||
248 (1 == SSCANF (start, "inet6 %127s", addrstr)))
249 {
250 /* IPv4 */
251 if (1 == inet_pton (AF_INET, addrstr, &v4))
252 {
253 memset (&a4, 0, sizeof (a4));
254 a4.sin_family = AF_INET;
255 a4.sin_addr = v4;
256 if (GNUNET_OK !=
257 proc (cls,
258 ifc,
259 0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE),
260 (const struct sockaddr *) &a4, sizeof (a4)))
261 break;
262 continue;
263 }
264 /* IPv6 */
265 if (1 == inet_pton (AF_INET6, addrstr, &v6))
266 {
267 memset (&a6, 0, sizeof (a6));
268 a6.sin6_family = AF_INET6;
269 a6.sin6_addr = v6;
270 fprintf (stderr, "procing %s\n", addrstr);
271 if (GNUNET_OK !=
272 proc (cls,
273 ifc,
274 0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE),
275 (const struct sockaddr *) &a6, sizeof (a6)))
276 break;
277 continue;
278 }
279 }
280 }
281 pclose (f);
282#endif
283}
284
285
286/* end of os_network.c */