GNUnet  0.10.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)   GNUNET_log_from_strerror_file(kind, "util-os-network", 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 
)    GNUNET_log_from_strerror_file(kind, "util-os-network", syscall, 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 47 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().

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

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