GNUnet  0.19.3
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:56
@ 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 IFCONFIG
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: