GNUnet 0.21.1
os_network.c File Reference

function to determine available network interfaces More...

#include "platform.h"
#include "gnunet_util_lib.h"
Include dependency graph for os_network.c:

Go to the source code of this file.

Macros

#define LOG(kind, ...)   GNUNET_log_from (kind, "util-os-network", __VA_ARGS__)
 
#define LOG_STRERROR_FILE(kind, syscall, filename)
 

Functions

static int try_ifconfig (GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
 Try to enumerate all network interfaces using 'ifconfig'. More...
 
static int try_ip (GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
 Try to enumerate all network interfaces using 'ip'. More...
 
void GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, void *proc_cls)
 Enumerate all network interfaces. More...
 

Detailed Description

function to determine available network interfaces

Author
Nils Durner
Heikki Lindholm
Jake Dust
LRN
Christian Grothoff

Definition in file os_network.c.

Macro Definition Documentation

◆ LOG

#define LOG (   kind,
  ... 
)    GNUNET_log_from (kind, "util-os-network", __VA_ARGS__)

Definition at line 35 of file os_network.c.

◆ LOG_STRERROR_FILE

#define LOG_STRERROR_FILE (   kind,
  syscall,
  filename 
)
Value:
"util-os-network", \
syscall, \
static char * filename
#define GNUNET_log_from_strerror_file(level, component, cmd, filename)
Log an error message at log-level 'level' that indicates a failure of the command 'cmd' with the mess...

Definition at line 36 of file os_network.c.

Function Documentation

◆ try_ifconfig()

static int try_ifconfig ( GNUNET_OS_NetworkInterfaceProcessor  proc,
void *  proc_cls 
)
static

Try to enumerate all network interfaces using 'ifconfig'.

Parameters
procthe callback function
proc_clsclosure for proc
Returns
GNUNET_OK if it worked

Definition at line 52 of file os_network.c.

54{
55 int i;
56 char line[1024];
57 char *replace;
58 const char *start;
59 char ifc[12];
60 char addrstr[128];
61 char bcstr[128];
62 char netmaskstr[128];
63 FILE *f;
64 int have_ifc;
65 struct sockaddr_in a4;
66 struct sockaddr_in6 a6;
67 struct in_addr v4;
68 struct in6_addr v6;
69 struct sockaddr_in bcaddr;
70 struct sockaddr_in netmask;
71 struct sockaddr_in6 netmask6;
72 struct sockaddr *pass_bcaddr;
73 struct sockaddr *pass_netmask;
74 int prefixlen;
75 static char *pcall;
76
77 if (NULL == pcall)
78 {
79 const char *sbin_ifconfig;
80
81#ifdef IFCONFIG
82 if (0 == access (IFCONFIG, X_OK))
83 sbin_ifconfig = IFCONFIG;
84 else
85#endif
86 if (0 == access ("/sbin/ifconfig", X_OK))
87 sbin_ifconfig = "/sbin/ifconfig";
88 else if (0 == access ("/usr/sbin/ifconfig", X_OK))
89 sbin_ifconfig = "/usr/sbin/ifconfig";
90 else
91 sbin_ifconfig = "ifconfig";
92 GNUNET_asprintf (&pcall,
93 "%s -a 2> /dev/null",
94 sbin_ifconfig);
95 }
96 f = popen (pcall, "r");
97 if (NULL == f)
98 {
100 "popen",
101 "ifconfig");
102
103 return GNUNET_SYSERR;
104 }
105
106 have_ifc = GNUNET_NO;
107 ifc[11] = '\0';
108 while (NULL != fgets (line, sizeof(line), f))
109 {
110 if (strlen (line) == 0)
111 {
112 have_ifc = GNUNET_NO;
113 continue;
114 }
115 if (! isspace (line[0]))
116 {
117 have_ifc = (1 == sscanf (line, "%11s", ifc)) ? GNUNET_YES : GNUNET_NO;
118 /* would end with ':' on OSX, fix it! */
119 if (ifc[strlen (ifc) - 1] == ':')
120 ifc[strlen (ifc) - 1] = '\0';
121 continue;
122 }
123 if (! have_ifc)
124 continue; /* strange input, hope for the best */
125
126 /* make parsing of ipv6 addresses easier */
127 for (replace = line; *replace != '\0'; replace++)
128 {
129 if (*replace == '/')
130 *replace = ' ';
131 }
132 prefixlen = -1;
133
134 start = line;
135 while (('\0' != *start) && (isspace (*start)))
136 start++;
137
138 /* Zero-out stack allocated values */
139 memset (addrstr, 0, 128);
140 memset (netmaskstr, 0, 128);
141 memset (bcstr, 0, 128);
142 prefixlen = 0;
143
144 if ( /* Linux */
145 (3 == sscanf (start, "inet addr:%127s Bcast:%127s Mask:%127s", addrstr,
146 bcstr, netmaskstr)) ||
147 (2 == sscanf (start, "inet addr:%127s Mask:%127s", addrstr,
148 netmaskstr)) ||
149 (2 == sscanf (start, "inet6 addr:%127s %d", addrstr, &prefixlen)) ||
150 /* Solaris, OS X */
151 (1 == sscanf (start, "inet %127s", addrstr)) ||
152 (1 == sscanf (start, "inet6 %127s", addrstr)))
153 {
154 /* IPv4 */
155 if (1 == inet_pton (AF_INET, addrstr, &v4))
156 {
157 memset (&a4, 0, sizeof(a4));
158 a4.sin_family = AF_INET;
159#if HAVE_SOCKADDR_IN_SIN_LEN
160 a4.sin_len = (u_char) sizeof(struct sockaddr_in);
161#endif
162 a4.sin_addr = v4;
163
164 pass_bcaddr = NULL;
165 pass_netmask = NULL;
166 if (1 == inet_pton (AF_INET, bcstr, &v4))
167 {
168 memset (&bcaddr, 0, sizeof(bcaddr));
169 bcaddr.sin_family = AF_INET;
170#if HAVE_SOCKADDR_IN_SIN_LEN
171 bcaddr.sin_len = (u_char) sizeof(struct sockaddr_in);
172#endif
173 bcaddr.sin_addr = v4;
174 pass_bcaddr = (struct sockaddr *) &bcaddr;
175 }
176 if (1 == inet_pton (AF_INET, netmaskstr, &v4))
177 {
178 memset (&netmask, 0, sizeof(netmask));
179 netmask.sin_family = AF_INET;
180#if HAVE_SOCKADDR_IN_SIN_LEN
181 netmask.sin_len = (u_char) sizeof(struct sockaddr_in);
182#endif
183 netmask.sin_addr = v4;
184 pass_netmask = (struct sockaddr *) &netmask;
185 }
186
187
188 if (GNUNET_OK !=
189 proc (proc_cls, ifc,(0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE)),
190 (const struct sockaddr *) &a4,
191 pass_bcaddr, pass_netmask, sizeof(a4)))
192 break;
193 continue;
194 }
195 /* IPv6 */
196 if (1 == inet_pton (AF_INET6, addrstr, &v6))
197 {
198 memset (&a6, 0, sizeof(a6));
199 a6.sin6_family = AF_INET6;
200#if HAVE_SOCKADDR_IN_SIN_LEN
201 a6.sin6_len = (u_char) sizeof(struct sockaddr_in6);
202#endif
203 a6.sin6_addr = v6;
204
205 pass_netmask = NULL;
206 if (prefixlen != -1)
207 {
208 memset (v6.s6_addr, 0, sizeof(v6.s6_addr));
209 for (i = 0; i < prefixlen; i++)
210 {
211 v6.s6_addr[i >> 3] |= 1 << (i & 7);
212 }
213 memset (&netmask6, 0, sizeof(netmask6));
214 netmask6.sin6_family = AF_INET6;
215#if HAVE_SOCKADDR_IN_SIN_LEN
216 netmask6.sin6_len = (u_char) sizeof(struct sockaddr_in6);
217#endif
218 netmask6.sin6_addr = v6;
219
220 pass_netmask = (struct sockaddr *) &netmask6;
221 }
222
223 if (GNUNET_OK !=
224 proc (proc_cls, ifc,(0 == strcmp (ifc, GNUNET_DEFAULT_INTERFACE)),
225 (const struct sockaddr *) &a6,
226 NULL, pass_netmask, sizeof(a6)))
227 break;
228 continue;
229 }
230 }
231 }
232 pclose (f);
233 return GNUNET_OK;
234}
static int start
Set if we are to start default services (including ARM).
Definition: gnunet-arm.c:39
static char * line
Desired phone line (string to be converted to a hash).
static int replace
Replace DID Document Flag.
Definition: gnunet-did.c:53
@ GNUNET_OK
@ GNUNET_YES
@ GNUNET_NO
@ GNUNET_SYSERR
@ GNUNET_ERROR_TYPE_WARNING
@ GNUNET_ERROR_TYPE_BULK
int int GNUNET_asprintf(char **buf, const char *format,...) __attribute__((format(printf
Like asprintf, just portable.
#define LOG_STRERROR_FILE(kind, syscall, filename)
Definition: os_network.c:36

References removetrailingwhitespace::f, GNUNET_asprintf(), GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_WARNING, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, line, LOG_STRERROR_FILE, replace, and start.

Referenced by GNUNET_OS_network_interfaces_list().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ try_ip()

static int try_ip ( GNUNET_OS_NetworkInterfaceProcessor  proc,
void *  proc_cls 
)
static

Try to enumerate all network interfaces using 'ip'.

Parameters
procthe callback function
proc_clsclosure for proc
Returns
GNUNET_OK if it worked

Definition at line 245 of file os_network.c.

247{
248 char line[1024];
249 char *replace;
250 char ifname[64];
251 char afstr[6];
252 char addrstr[128];
253 FILE *f;
254 struct sockaddr_in a4;
255 struct sockaddr_in6 a6;
256 struct in_addr v4;
257 struct in6_addr v6;
258 struct sockaddr_in netmask;
259 struct sockaddr_in6 netmask6;
260 unsigned int i;
261 unsigned int prefixlen;
262 static char *pcall;
263
264 if (NULL == pcall)
265 {
266 const char *sbin_ip;
267
268#ifdef PATH_TO_IP
269 if (0 == access (PATH_TO_IP, X_OK))
270 sbin_ip = PATH_TO_IP;
271 else
272#endif
273 if (0 == access ("/sbin/ip", X_OK))
274 sbin_ip = "/sbin/ip";
275 else if (0 == access ("/usr/sbin/ip", X_OK))
276 sbin_ip = "/usr/sbin/ip";
277 else
278 sbin_ip = "if";
279 GNUNET_asprintf (&pcall,
280 "%s -o add 2> /dev/null",
281 sbin_ip);
282 }
283 f = popen (pcall, "r");
284 if (! f)
285 {
287 "popen",
288 "ip");
289 return GNUNET_SYSERR;
290 }
291
292 while (NULL != fgets (line, sizeof(line), f))
293 {
294 /* make parsing easier */
295 for (replace = line; *replace != '\0'; replace++)
296 {
297 if (*replace == '/')
298 *replace = ' ';
299 }
300 /* Zero-out stack allocated values */
301 memset (ifname, 0, 64);
302 memset (afstr, 0, 6);
303 memset (addrstr, 0, 128);
304 if (4 != sscanf (line,
305 "%*u: %63s %5s %127s %6u",
306 ifname,
307 afstr,
308 addrstr,
309 &prefixlen))
310 continue;
311 /* IPv4 */
312 if ((0 == strcasecmp ("inet",
313 afstr)) &&
314 (1 == inet_pton (AF_INET,
315 addrstr,
316 &v4)))
317 {
318 memset (&a4, 0, sizeof(a4));
319 a4.sin_family = AF_INET;
320#if HAVE_SOCKADDR_IN_SIN_LEN
321 a4.sin_len = (u_char) sizeof(struct sockaddr_in);
322#endif
323 a4.sin_addr = v4;
324
325 memset (&v4.s_addr, 0, sizeof(v4.s_addr));
326 for (i = 0; i < prefixlen; i++)
327 v4.s_addr |= 1 << (i & 7);
328 memset (&netmask, 0, sizeof(netmask));
329 netmask.sin_family = AF_INET;
330#if HAVE_SOCKADDR_IN_SIN_LEN
331 netmask.sin_len = (u_char) sizeof(struct sockaddr_in);
332#endif
333 netmask.sin_addr = v4;
334
335 if (GNUNET_OK !=
336 proc (proc_cls,
337 ifname,
338 (0 == strcmp (ifname,
339 GNUNET_DEFAULT_INTERFACE)),
340 (const struct sockaddr *) &a4,
341 NULL,
342 (const struct sockaddr *) &netmask,
343 sizeof(a4)))
344 break;
345 }
346 /* IPv6 */
347 if ((0 == strcasecmp ("inet6",
348 afstr)) &&
349 (1 == inet_pton (AF_INET6,
350 addrstr,
351 &v6)))
352 {
353 memset (&a6, 0, sizeof(a6));
354 a6.sin6_family = AF_INET6;
355#if HAVE_SOCKADDR_IN_SIN_LEN
356 a6.sin6_len = (u_char) sizeof(struct sockaddr_in6);
357#endif
358 a6.sin6_addr = v6;
359
360 memset (v6.s6_addr, 0, sizeof(v6.s6_addr));
361 for (i = 0; i < prefixlen; i++)
362 v6.s6_addr[i >> 3] |= 1 << (i & 7);
363 memset (&netmask6, 0, sizeof(netmask6));
364 netmask6.sin6_family = AF_INET6;
365#if HAVE_SOCKADDR_IN_SIN_LEN
366 netmask6.sin6_len = (u_char) sizeof(struct sockaddr_in6);
367#endif
368 netmask6.sin6_addr = v6;
369
370 if (GNUNET_OK !=
371 proc (proc_cls,
372 ifname,
373 (0 == strcmp (ifname,
374 GNUNET_DEFAULT_INTERFACE)),
375 (const struct sockaddr *) &a6,
376 NULL,
377 (const struct sockaddr *) &netmask6,
378 sizeof(a6)))
379 break;
380 }
381 }
382 pclose (f);
383 return GNUNET_OK;
384}
static const char * sbin_ip
Name and full path of IPTABLES binary.

References removetrailingwhitespace::f, GNUNET_asprintf(), GNUNET_ERROR_TYPE_BULK, GNUNET_ERROR_TYPE_WARNING, GNUNET_OK, GNUNET_SYSERR, line, LOG_STRERROR_FILE, replace, and sbin_ip.

Referenced by GNUNET_OS_network_interfaces_list().

Here is the call graph for this function:
Here is the caller graph for this function: