OpenVAS Libraries  9.0.3
openvas_networking.h File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/types.h>
#include <ifaddrs.h>
#include <netdb.h>
#include <glib.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include "array.h"
Include dependency graph for openvas_networking.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  range
 A port range. More...
 

Typedefs

typedef struct range range_t
 

Enumerations

enum  port_protocol_t { PORT_PROTOCOL_TCP = 0, PORT_PROTOCOL_UDP = 1, PORT_PROTOCOL_OTHER = 2 }
 Possible port types. More...
 

Functions

int openvas_source_iface_init (const char *)
 Initializes the source network interface name and related information. More...
 
int openvas_source_iface_is_set (void)
 
int openvas_source_set_socket (int, int, int)
 Binds a socket to use the global source address. More...
 
void openvas_source_addr (void *)
 Gives the source IPv4 address. More...
 
void openvas_source_addr6 (void *)
 Gives the source IPv6 address. More...
 
void openvas_source_addr_as_addr6 (struct in6_addr *)
 Gives the source IPv4 mapped as an IPv6 address. eg. 192.168.20.10 would map to ::ffff:192.168.20.10. More...
 
char * openvas_source_addr_str (void)
 Gives the source IPv4 address in string format. More...
 
char * openvas_source_addr6_str (void)
 Gives the source IPv6 address in string format. More...
 
void ipv4_as_ipv6 (const struct in_addr *, struct in6_addr *)
 Maps an IPv4 address as an IPv6 address. eg. 192.168.10.20 would map to ::ffff:192.168.10.20. More...
 
char * addr6_as_str (const struct in6_addr *)
 
void sockaddr_as_str (const struct sockaddr_storage *, char *)
 Convert an IP address to string format. More...
 
int openvas_resolve (const char *, void *, int)
 Resolves a hostname to an IPv4 or IPv6 address. More...
 
int openvas_resolve_as_addr6 (const char *, struct in6_addr *)
 Resolves a hostname to an IPv4-mapped IPv6 or IPv6 address. More...
 
int validate_port_range (const char *)
 Validate a port range string. More...
 
array_tport_range_ranges (const char *)
 Create a range array from a port_range string. More...
 
int port_in_port_ranges (int, port_protocol_t, array_t *)
 Checks if a port num is in port ranges array. More...
 
int ipv6_is_enabled ()
 Checks if IPv6 support is enabled. More...
 

Typedef Documentation

◆ range_t

typedef struct range range_t

Definition at line 69 of file openvas_networking.h.

Enumeration Type Documentation

◆ port_protocol_t

Possible port types.

Used in Manager database. If any symbol changes then a migrator must be added to update existing data.

Enumerator
PORT_PROTOCOL_TCP 
PORT_PROTOCOL_UDP 
PORT_PROTOCOL_OTHER 

Definition at line 50 of file openvas_networking.h.

Function Documentation

◆ addr6_as_str()

char* addr6_as_str ( const struct in6_addr *  )

Definition at line 234 of file openvas_networking.c.

235 {
236  char *str;
237 
238  if (!addr6)
239  return NULL;
240 
241  str = g_malloc0 (INET6_ADDRSTRLEN);
242  if (IN6_IS_ADDR_V4MAPPED (addr6))
243  inet_ntop (AF_INET, &addr6->s6_addr32[3], str, INET6_ADDRSTRLEN);
244  else
245  inet_ntop (AF_INET6, addr6, str, INET6_ADDRSTRLEN);
246  return str;
247 }

Referenced by get_host_ip(), nasl_smb_connect(), nasl_this_host(), nasl_win_cmd_exec(), nasl_wmi_connect(), nasl_wmi_connect_reg(), nasl_wmi_connect_rsop(), and plug_get_host_ip_str().

Here is the caller graph for this function:

◆ ipv4_as_ipv6()

void ipv4_as_ipv6 ( const struct in_addr *  ip4,
struct in6_addr *  ip6 
)

Maps an IPv4 address as an IPv6 address. eg. 192.168.10.20 would map to ::ffff:192.168.10.20.

Parameters
[in]ip4IPv4 address to map.
[out]ip6Buffer to store the IPv6 address.

Definition at line 222 of file openvas_networking.c.

223 {
224  if (ip4 == NULL || ip6 == NULL)
225  return;
226 
227  ip6->s6_addr32[0] = 0;
228  ip6->s6_addr32[1] = 0;
229  ip6->s6_addr32[2] = htonl (0xffff);
230  memcpy (&ip6->s6_addr32[3], ip4, sizeof (struct in_addr));
231 }

Referenced by openvas_host_get_addr6(), openvas_resolve(), and openvas_source_addr_as_addr6().

Here is the caller graph for this function:

◆ ipv6_is_enabled()

int ipv6_is_enabled ( )

Checks if IPv6 support is enabled.

Returns
1 if IPv6 is enabled, 0 if disabled.

Definition at line 627 of file openvas_networking.c.

628 {
629  int sock = socket (PF_INET6, SOCK_STREAM, 0);
630 
631  if (sock == -1 && errno == EAFNOSUPPORT)
632  return 0;
633  close (sock);
634  return 1;
635 }

◆ openvas_resolve()

int openvas_resolve ( const char *  name,
void *  dst,
int  family 
)

Resolves a hostname to an IPv4 or IPv6 address.

Parameters
[in]nameHostname to resolve.
[out]dstBuffer to store resolved address. Size must be at least 4 bytes for AF_INET and 16 bytes for AF_INET6.
[in]familyEither AF_INET or AF_INET6.
Returns
-1 if error, 0 otherwise.

Definition at line 301 of file openvas_networking.c.

302 {
303  struct addrinfo hints, *info, *p;
304 
305  if (name == NULL || dst == NULL
306  || (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC))
307  return -1;
308 
309  bzero (&hints, sizeof (hints));
310  hints.ai_family = family;
311  hints.ai_socktype = SOCK_STREAM;
312  hints.ai_protocol = 0;
313  if ((getaddrinfo (name, NULL, &hints, &info)) != 0)
314  return -1;
315 
316  p = info;
317  while (p)
318  {
319  if (p->ai_family == family || family == AF_UNSPEC)
320  {
321  if (p->ai_family == AF_INET && family == AF_UNSPEC)
322  {
323  struct sockaddr_in *addrin = (struct sockaddr_in *) p->ai_addr;
324  ipv4_as_ipv6 (&(addrin->sin_addr), dst);
325  }
326  else if (p->ai_family == AF_INET)
327  {
328  struct sockaddr_in *addrin = (struct sockaddr_in *) p->ai_addr;
329  memcpy (dst, &(addrin->sin_addr), sizeof (struct in_addr));
330  }
331  else if (p->ai_family == AF_INET6)
332  {
333  struct sockaddr_in6 *addrin = (struct sockaddr_in6 *) p->ai_addr;
334  memcpy (dst, &(addrin->sin6_addr), sizeof (struct in6_addr));
335  }
336  break;
337  }
338 
339  p = p->ai_next;
340  }
341 
342  freeaddrinfo (info);
343  return 0;
344 }
const char * name
Definition: nasl_init.c:524
void ipv4_as_ipv6(const struct in_addr *ip4, struct in6_addr *ip6)
Maps an IPv4 address as an IPv6 address. eg. 192.168.10.20 would map to ::ffff:192....

References ipv4_as_ipv6(), and name.

Referenced by openvas_host_resolve(), and openvas_resolve_as_addr6().

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

◆ openvas_resolve_as_addr6()

int openvas_resolve_as_addr6 ( const char *  name,
struct in6_addr *  ip6 
)

Resolves a hostname to an IPv4-mapped IPv6 or IPv6 address.

Parameters
[in]nameHostname to resolve.
[out]ip6Buffer to store resolved address.
Returns
-1 if error, 0 otherwise.

Definition at line 355 of file openvas_networking.c.

356 {
357  return openvas_resolve (name, ip6, AF_UNSPEC);
358 }
int openvas_resolve(const char *name, void *dst, int family)
Resolves a hostname to an IPv4 or IPv6 address.
const char * name
Definition: nasl_init.c:524

References name, and openvas_resolve().

Referenced by nasl_this_host(), and open_sock_opt_hn().

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

◆ openvas_source_addr()

void openvas_source_addr ( void *  addr)

Gives the source IPv4 address.

Parameters
[out]addrBuffer of at least 4 bytes.

Definition at line 153 of file openvas_networking.c.

154 {
155  if (addr)
156  memcpy (addr, &global_source_addr.s_addr, 4);
157 }
struct in_addr global_source_addr

References global_source_addr.

Referenced by openvas_source_set_socket().

Here is the caller graph for this function:

◆ openvas_source_addr6()

void openvas_source_addr6 ( void *  addr6)

Gives the source IPv6 address.

Parameters
[out]addr6Buffer of at least 16 bytes.

Definition at line 165 of file openvas_networking.c.

166 {
167  if (addr6)
168  memcpy (addr6, &global_source_addr6.s6_addr, 16);
169 }
struct in6_addr global_source_addr6

References global_source_addr6.

Referenced by nasl_this_host(), and openvas_source_set_socket().

Here is the caller graph for this function:

◆ openvas_source_addr6_str()

char* openvas_source_addr6_str ( void  )

Gives the source IPv6 address in string format.

Returns
Source IPv6 string. Free with g_free().

Definition at line 204 of file openvas_networking.c.

205 {
206  char *str = g_malloc0 (INET6_ADDRSTRLEN);
207 
208  inet_ntop (AF_INET6, &global_source_addr6, str, INET6_ADDRSTRLEN);
209  return str;
210 }
struct in6_addr global_source_addr6

References global_source_addr6.

◆ openvas_source_addr_as_addr6()

void openvas_source_addr_as_addr6 ( struct in6_addr *  addr6)

Gives the source IPv4 mapped as an IPv6 address. eg. 192.168.20.10 would map to ::ffff:192.168.20.10.

Parameters
[out]addr6Buffer of at least 16 bytes.

Definition at line 178 of file openvas_networking.c.

179 {
180  if (addr6)
182 }
void ipv4_as_ipv6(const struct in_addr *ip4, struct in6_addr *ip6)
Maps an IPv4 address as an IPv6 address. eg. 192.168.10.20 would map to ::ffff:192....
struct in_addr global_source_addr

References global_source_addr, and ipv4_as_ipv6().

Referenced by nasl_this_host().

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

◆ openvas_source_addr_str()

char* openvas_source_addr_str ( void  )

Gives the source IPv4 address in string format.

Returns
Source IPv4 string. Free with g_free().

Definition at line 190 of file openvas_networking.c.

191 {
192  char *str = g_malloc0 (INET_ADDRSTRLEN);
193 
194  inet_ntop (AF_INET, &global_source_addr.s_addr, str, INET_ADDRSTRLEN);
195  return str;
196 }
struct in_addr global_source_addr

References global_source_addr.

◆ openvas_source_iface_init()

int openvas_source_iface_init ( const char *  iface)

Initializes the source network interface name and related information.

Parameters
[in]ifaceName of network interface to use as source interface.
Returns
0 if success. If error, return 1 and reset source values to default.

Definition at line 53 of file openvas_networking.c.

54 {
55  struct ifaddrs *ifaddr, *ifa;
56  int ret = 1;
57 
58  bzero (global_source_iface, sizeof (global_source_iface));
59  global_source_addr.s_addr = INADDR_ANY;
60  global_source_addr6 = in6addr_any;
61 
62  if (iface == NULL)
63  return ret;
64 
65  if (getifaddrs (&ifaddr) == -1)
66  return ret;
67 
68  /* Search for the adequate interface/family. */
69  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
70  {
71  if (ifa->ifa_addr && strcmp (iface, ifa->ifa_name) == 0)
72  {
73  if (ifa->ifa_addr->sa_family == AF_INET)
74  {
75  struct in_addr *addr = &((struct sockaddr_in *)
76  ifa->ifa_addr)->sin_addr;
77 
78  memcpy (&global_source_addr, addr, sizeof (global_source_addr));
79  ret = 0;
80  }
81  else if (ifa->ifa_addr->sa_family == AF_INET6)
82  {
83  struct sockaddr_in6 *addr;
84 
85  addr = (struct sockaddr_in6 *) ifa->ifa_addr;
86  memcpy (&global_source_addr6.s6_addr, &addr->sin6_addr,
87  sizeof (struct in6_addr));
88  ret = 0;
89  }
90  }
91  }
92 
93  /* At least one address for the interface was found. */
94  if (ret == 0)
95  strncpy (global_source_iface, iface, sizeof (global_source_iface) - 1);
96 
97  freeifaddrs (ifaddr);
98  return ret;
99 }
char global_source_iface[IFNAMSIZ]
struct in6_addr global_source_addr6
struct in_addr global_source_addr

References global_source_addr, global_source_addr6, and global_source_iface.

◆ openvas_source_iface_is_set()

int openvas_source_iface_is_set ( void  )

Definition at line 102 of file openvas_networking.c.

103 {
104  return *global_source_iface != '\0';
105 }
char global_source_iface[IFNAMSIZ]

References global_source_iface.

Referenced by nasl_this_host().

Here is the caller graph for this function:

◆ openvas_source_set_socket()

int openvas_source_set_socket ( int  socket,
int  port,
int  family 
)

Binds a socket to use the global source address.

Parameters
[in]socketSocket to set source address for.
[in]portNetwork port for socket.
[in]familyFamily of socket. AF_INET or AF_INET6.
Returns
0 if success, -1 if error.

Definition at line 117 of file openvas_networking.c.

118 {
119  if (family == AF_INET)
120  {
121  struct sockaddr_in addr;
122 
123  openvas_source_addr (&addr.sin_addr);
124  addr.sin_port = htons (port);
125  addr.sin_family = AF_INET;
126 
127  if (bind (socket, (struct sockaddr *) &addr, sizeof (addr)) < 0)
128  return -1;
129  }
130  else if (family == AF_INET6)
131  {
132  struct sockaddr_in6 addr6;
133 
134  openvas_source_addr6 (&addr6.sin6_addr);
135  addr6.sin6_port = htons (port);
136  addr6.sin6_family = AF_INET6;
137 
138  if (bind (socket, (struct sockaddr *) &addr6, sizeof (addr6)) < 0)
139  return -1;
140  }
141  else
142  return -1;
143 
144  return 0;
145 }
void openvas_source_addr6(void *addr6)
Gives the source IPv6 address.
void openvas_source_addr(void *addr)
Gives the source IPv4 address.

References openvas_source_addr(), and openvas_source_addr6().

Referenced by nasl_open_sock_udp().

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

◆ port_in_port_ranges()

int port_in_port_ranges ( int  pnum,
port_protocol_t  ptype,
array_t pranges 
)

Checks if a port num is in port ranges array.

Parameters
[in]pnumPort number.
[in]ptypePort type.
[in]prangesArray of port ranges.
Returns
1 if port in port ranges, 0 otherwise.

Definition at line 603 of file openvas_networking.c.

604 {
605  unsigned int i;
606 
607  if (pranges == NULL || pnum < 0 || pnum > 65536)
608  return 0;
609 
610  for (i = 0; i < pranges->len; i++)
611  {
612  range_t *range = (range_t *) g_ptr_array_index (pranges, i);
613  if (range->type != ptype)
614  continue;
615  if (range->start <= pnum && pnum <= range->end)
616  return 1;
617  }
618  return 0;
619 }
A port range.
port_protocol_t type

References range::start, and range::type.

◆ port_range_ranges()

array_t* port_range_ranges ( const char *  port_range)

Create a range array from a port_range string.

Parameters
[in]port_rangeValid port_range string.
Returns
Range array.

Definition at line 500 of file openvas_networking.c.

501 {
502  gchar **split, **point, *range_start, *current;
503  array_t *ranges;
504  int tcp;
505 
506  if (!port_range)
507  return NULL;
508 
509  ranges = make_array ();
510 
511  while (*port_range && isblank (*port_range)) port_range++;
512 
513  /* Accepts T: and U: before any of the ranges. This toggles the remaining
514  * ranges, as in nmap. Treats a leading naked range as TCP, whereas nmap
515  * treats it as TCP and UDP. */
516 
517  /* Treat newlines like commas. */
518  range_start = current = g_strdup (port_range);
519  while (*current)
520  {
521  if (*current == '\n') *current = ',';
522  current++;
523  }
524 
525  tcp = 1;
526  split = g_strsplit (range_start, ",", 0);
527  g_free (range_start);
528  point = split;
529 
530  while (*point)
531  {
532  gchar *hyphen, *element;
533  range_t *range;
534 
535  element = g_strstrip (*point);
536  if (strlen (element) >= 2)
537  {
538  if ((element[0] == 'T') && (element[1] == ':'))
539  {
540  tcp = 1;
541  element = element + 2;
542  }
543  else if ((element[0] == 'U') && (element[1] == ':'))
544  {
545  tcp = 0;
546  element = element + 2;
547  }
548  /* Else tcp stays as it is. */
549  }
550 
551  /* Skip any space that followed the type specifier. */
552  while (*element && isblank (*element)) element++;
553 
554  hyphen = strchr (element, '-');
555  if (hyphen)
556  {
557  *hyphen = '\0';
558  hyphen++;
559  while (*hyphen && isblank (*hyphen)) hyphen++;
560  assert (*hyphen); /* Validation checks this. */
561 
562  /* A range. */
563 
564  range = (range_t*) g_malloc0 (sizeof (range_t));
565 
566  range->start = atoi (element);
567  range->end = atoi (hyphen);
569  range->exclude = 0;
570 
571  array_add (ranges, range);
572  }
573  else if (*element)
574  {
575  /* A single port. */
576 
577  range = (range_t*) g_malloc0 (sizeof (range_t));
578 
579  range->start = atoi (element);
580  range->end = range->start;
582  range->exclude = 0;
583 
584  array_add (ranges, range);
585  }
586  /* Else skip over empty range. */
587  point += 1;
588  }
589  g_strfreev (split);
590  return ranges;
591 }
GPtrArray array_t
Definition: array.h:31
A port range.
void array_add(array_t *array, gpointer pointer)
Push a generic pointer onto an array.
Definition: array.c:82
GPtrArray * make_array()
Make a global array.
Definition: array.c:39
port_protocol_t type

References array_add(), range::end, range::exclude, make_array(), PORT_PROTOCOL_TCP, PORT_PROTOCOL_UDP, range::start, and range::type.

Here is the call graph for this function:

◆ sockaddr_as_str()

void sockaddr_as_str ( const struct sockaddr_storage *  addr,
char *  str 
)

Convert an IP address to string format.

Parameters
[in]addrAddress to convert.
[out]strBuffer of INET6_ADDRSTRLEN size.

Definition at line 256 of file openvas_networking.c.

257 {
258  if (!addr || !str)
259  return;
260 
261  if (addr->ss_family == AF_INET)
262  {
263  struct sockaddr_in *saddr = (struct sockaddr_in *) addr;
264  inet_ntop (AF_INET, &saddr->sin_addr, str, INET6_ADDRSTRLEN);
265  }
266  else if (addr->ss_family == AF_INET6)
267  {
268  struct sockaddr_in6 *s6addr = (struct sockaddr_in6 *) addr;
269  if (IN6_IS_ADDR_V4MAPPED (&s6addr->sin6_addr))
270  inet_ntop (AF_INET, &s6addr->sin6_addr.s6_addr[12],
271  str, INET6_ADDRSTRLEN);
272  else
273  inet_ntop (AF_INET6, &s6addr->sin6_addr, str, INET6_ADDRSTRLEN);
274  }
275  else if (addr->ss_family == AF_UNIX)
276  {
277  g_snprintf (str, INET6_ADDRSTRLEN, "unix_socket");
278  }
279  else if (addr->ss_family == AF_UNSPEC)
280  {
281  g_snprintf (str, INET6_ADDRSTRLEN, "unknown_socket");
282  }
283  else
284  {
285  g_snprintf (str, INET6_ADDRSTRLEN,
286  "type_%d_socket", addr->ss_family);
287  }
288 }

◆ validate_port_range()

int validate_port_range ( const char *  port_range)

Validate a port range string.

Accepts ranges in form of "103,U:200-1024,3000-4000,T:3-4,U:7".

Parameters
[in]port_rangeA port range.
Returns
0 success, 1 failed.

Definition at line 372 of file openvas_networking.c.

373 {
374  gchar **split, **point, *range, *range_start;
375 
376  if (!port_range)
377  return 1;
378 
379  while (*port_range && isblank (*port_range)) port_range++;
380  if (*port_range == '\0')
381  return 1;
382 
383  /* Treat newlines like commas. */
384  range = range_start = g_strdup (port_range);
385  while (*range)
386  {
387  if (*range == '\n') *range = ',';
388  range++;
389  }
390 
391  split = g_strsplit (range_start, ",", 0);
392  g_free (range_start);
393  point = split;
394 
395  while (*point)
396  {
397  gchar *hyphen, *element;
398 
399  /* Strip off any outer whitespace. */
400 
401  element = g_strstrip (*point);
402 
403  /* Strip off any leading type specifier. */
404 
405  if ((strlen (element) >= 2)
406  && ((element[0] == 'T') || (element[0] == 'U'))
407  && (element[1] == ':'))
408  element = element + 2;
409 
410  /* Look for a hyphen. */
411 
412  hyphen = strchr (element, '-');
413  if (hyphen)
414  {
415  long int number1, number2;
416  const char *first;
417  char *end;
418 
419  hyphen++;
420 
421  /* Check the first number. */
422 
423  first = element;
424  while (*first && isblank (*first)) first++;
425  if (*first == '-')
426  goto fail;
427 
428  errno = 0;
429  number1 = strtol (first, &end, 10);
430  while (*end && isblank (*end)) end++;
431  if (errno || (*end != '-'))
432  goto fail;
433  if (number1 == 0)
434  goto fail;
435  if (number1 > 65535)
436  goto fail;
437 
438  /* Check the second number. */
439 
440  while (*hyphen && isblank (*hyphen)) hyphen++;
441  if (*hyphen == '\0')
442  goto fail;
443 
444  errno = 0;
445  number2 = strtol (hyphen, &end, 10);
446  while (*end && isblank (*end)) end++;
447  if (errno || *end)
448  goto fail;
449  if (number2 == 0)
450  goto fail;
451  if (number2 > 65535)
452  goto fail;
453 
454  if (number1 > number2)
455  goto fail;
456  }
457  else
458  {
459  long int number;
460  const char *only;
461  char *end;
462 
463  /* Check the single number. */
464 
465  only = element;
466  while (*only && isblank (*only)) only++;
467  /* Empty ranges are OK. */
468  if (*only)
469  {
470  errno = 0;
471  number = strtol (only, &end, 10);
472  while (*end && isblank (*end)) end++;
473  if (errno || *end)
474  goto fail;
475  if (number == 0)
476  goto fail;
477  if (number > 65535)
478  goto fail;
479  }
480  }
481  point += 1;
482  }
483 
484  g_strfreev (split);
485  return 0;
486 
487  fail:
488  g_strfreev (split);
489  return 1;
490 }
A port range.