GNUnet  0.11.x
Macros | Functions
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 34 of file os_network.c.

Referenced by GNUNET_OS_network_interfaces_list().

◆ LOG_STRERROR_FILE

#define LOG_STRERROR_FILE (   kind,
  syscall,
  filename 
)
Value:
"util-os-network", \
syscall, \
#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...
static char * filename

Definition at line 35 of file os_network.c.

Referenced by try_ifconfig(), and try_ip().

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 51 of file os_network.c.

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, and start.

Referenced by GNUNET_OS_network_interfaces_list().

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

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

Referenced by GNUNET_OS_network_interfaces_list().

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