Greenbone Vulnerability Management Libraries  22.8.0
networking.h File Reference

GVM Networking related API. More...

#include "array.h"
#include <netdb.h>
Include dependency graph for 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 gvm_source_iface_init (const char *)
 Initializes the source network interface name and related information. More...
 
int gvm_source_iface_is_set (void)
 Check if global_source global_source_iface is set. More...
 
int gvm_source_set_socket (int, int, int)
 Binds a socket to use the global source address. More...
 
void gvm_source_addr (void *)
 Gives the source IPv4 address. More...
 
void gvm_source_addr6 (void *)
 Gives the source IPv6 address. More...
 
void gvm_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 * gvm_source_addr_str (void)
 Gives the source IPv4 address in string format. More...
 
char * gvm_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...
 
void addr6_to_str (const struct in6_addr *, char *)
 Stringifies an IP address. More...
 
char * addr6_as_str (const struct in6_addr *)
 Stringifies an IP address. More...
 
void sockaddr_as_str (const struct sockaddr_storage *, char *)
 Convert an IP address to string format. More...
 
int gvm_resolve (const char *, void *, int)
 Resolves a hostname to an IPv4 or IPv6 address. More...
 
GSList * gvm_resolve_list (const char *)
 Returns a list of addresses that a hostname resolves to. More...
 
int gvm_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 (void)
 Checks if IPv6 support is enabled. More...
 
gchar * gvm_routethrough (struct sockaddr_storage *, struct sockaddr_storage *)
 Get Interface which should be used for routing to destination addr. More...
 
char * gvm_get_outgoing_iface (struct sockaddr_storage *)
 Get the outgoing interface name for a given destination addr. More...
 

Detailed Description

GVM Networking related API.

Definition in file networking.h.

Typedef Documentation

◆ range_t

typedef struct range range_t

Definition at line 1 of file 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 24 of file networking.h.

25 {

Function Documentation

◆ addr6_as_str()

char* addr6_as_str ( const struct in6_addr *  addr6)

Stringifies an IP address.

Parameters
[in]addr6IP address.
Returns
IP as string. NULL otherwise.

Definition at line 279 of file networking.c.

280 {
281  char *str;
282 
283  if (!addr6)
284  return NULL;
285 
286  str = g_malloc0 (INET6_ADDRSTRLEN);
287  addr6_to_str (addr6, str);
288  return str;
289 }

References addr6_to_str().

Here is the call graph for this function:

◆ addr6_to_str()

void addr6_to_str ( const struct in6_addr *  addr6,
char *  str 
)

Stringifies an IP address.

Parameters
[in]addr6IP address.
[out]strBuffer to output IP.

Definition at line 261 of file networking.c.

262 {
263  if (!addr6)
264  return;
265  if (IN6_IS_ADDR_V4MAPPED (addr6))
266  inet_ntop (AF_INET, &addr6->s6_addr32[3], str, INET6_ADDRSTRLEN);
267  else
268  inet_ntop (AF_INET6, addr6, str, INET6_ADDRSTRLEN);
269 }

Referenced by addr6_as_str(), and host_name_verify().

Here is the caller graph for this function:

◆ gvm_get_outgoing_iface()

char* gvm_get_outgoing_iface ( struct sockaddr_storage *  target_addr)

Get the outgoing interface name for a given destination addr.

A UDP socket is connected and its address retrieved. The address is the address of the interface of the outgoing interface. Its is determined by the kernel. We then search the list of interfaces for this address to determine the interface name. This method has the downside that if two interfaces with same addr are UP, a wrong interface might be returned because we can only retrieve the interface addr which was chosen by the kernel and nothing else (like e.g. interface number).

Parameters
[in]target_addrDestination address.
Returns
Name of outgoing interface which has to be freed by caller. NULL if no interface found or Error.

Definition at line 1282 of file networking.c.

1283 {
1284  int family, sockfd;
1285  struct sockaddr_storage out_iface_addr;
1286  char *out_iface_str;
1287 
1288  out_iface_str = NULL;
1289  family = target_addr->ss_family;
1290 
1291  if (!target_addr)
1292  return NULL;
1293 
1294  // get a connected udp socket
1295  if ((sockfd = get_connected_udp_sock (target_addr)) < 0)
1296  return NULL;
1297  // get socked address which is the addr of the interface we want to get
1298  out_iface_addr.ss_family = family;
1299  if (get_sock_addr (sockfd, &out_iface_addr) < 0)
1300  return NULL;
1301  // get interface name form interface address
1302  out_iface_str = get_ifname_from_ifaddr (&out_iface_addr);
1303  return out_iface_str;
1304 }

References get_connected_udp_sock(), get_ifname_from_ifaddr(), and get_sock_addr().

Here is the call graph for this function:

◆ gvm_resolve()

int gvm_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 389 of file networking.c.

390 {
391  struct addrinfo hints, *info, *p;
392 
393  if (name == NULL || dst == NULL
394  || (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC))
395  return -1;
396 
397  bzero (&hints, sizeof (hints));
398  hints.ai_family = family;
399  hints.ai_socktype = SOCK_STREAM;
400  hints.ai_protocol = 0;
401  if ((getaddrinfo (name, NULL, &hints, &info)) != 0)
402  return -1;
403 
404  p = info;
405  while (p)
406  {
407  if (p->ai_family == family || family == AF_UNSPEC)
408  {
409  if (p->ai_family == AF_INET && family == AF_UNSPEC)
410  {
411  struct sockaddr_in *addrin = (struct sockaddr_in *) p->ai_addr;
412  ipv4_as_ipv6 (&(addrin->sin_addr), dst);
413  }
414  else if (p->ai_family == AF_INET)
415  {
416  struct sockaddr_in *addrin = (struct sockaddr_in *) p->ai_addr;
417  memcpy (dst, &(addrin->sin_addr), sizeof (struct in_addr));
418  }
419  else if (p->ai_family == AF_INET6)
420  {
421  struct sockaddr_in6 *addrin = (struct sockaddr_in6 *) p->ai_addr;
422  memcpy (dst, &(addrin->sin6_addr), sizeof (struct in6_addr));
423  }
424  break;
425  }
426 
427  p = p->ai_next;
428  }
429 
430  freeaddrinfo (info);
431  return 0;
432 }

References ipv4_as_ipv6().

Referenced by gvm_host_resolve(), and gvm_resolve_as_addr6().

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

◆ gvm_resolve_as_addr6()

int gvm_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 443 of file networking.c.

444 {
445  return gvm_resolve (name, ip6, AF_UNSPEC);
446 }

References gvm_resolve().

Here is the call graph for this function:

◆ gvm_resolve_list()

GSList* gvm_resolve_list ( const char *  name)

Returns a list of addresses that a hostname resolves to.

Parameters
[in]nameHostname to resolve.
Returns
List of addresses, NULL otherwise.

Definition at line 339 of file networking.c.

340 {
341  struct addrinfo hints, *info, *p;
342  GSList *list = NULL;
343 
344  if (name == NULL)
345  return NULL;
346 
347  bzero (&hints, sizeof (hints));
348  hints.ai_family = AF_UNSPEC;
349  hints.ai_socktype = SOCK_STREAM;
350  hints.ai_protocol = 0;
351  if ((getaddrinfo (name, NULL, &hints, &info)) != 0)
352  return NULL;
353 
354  p = info;
355  while (p)
356  {
357  struct in6_addr dst;
358 
359  if (p->ai_family == AF_INET)
360  {
361  struct sockaddr_in *addrin = (struct sockaddr_in *) p->ai_addr;
362  ipv4_as_ipv6 (&(addrin->sin_addr), &dst);
363  list = g_slist_prepend (list, memdup (&dst, sizeof (dst)));
364  }
365  else if (p->ai_family == AF_INET6)
366  {
367  struct sockaddr_in6 *addrin = (struct sockaddr_in6 *) p->ai_addr;
368  memcpy (&dst, &(addrin->sin6_addr), sizeof (struct in6_addr));
369  list = g_slist_prepend (list, memdup (&dst, sizeof (dst)));
370  }
371  p = p->ai_next;
372  }
373 
374  freeaddrinfo (info);
375  return list;
376 }

References ipv4_as_ipv6(), and memdup.

Referenced by gvm_hosts_resolve(), and host_name_verify().

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

◆ gvm_routethrough()

gchar* gvm_routethrough ( struct sockaddr_storage *  storage_dest,
struct sockaddr_storage *  storage_source 
)

Get Interface which should be used for routing to destination addr.

This function should be used sparingly as it parses /proc/net/route for every call.

Parameters
[in]storage_destDestination address.
[out]storage_sourceSource address. Is set to either address of the interface we use or global source address if set. Only gets filled if storage_source != NULL.
Returns
Interface name of interface used for routing to destination address. NULL if no interface found or Error.

Definition at line 994 of file networking.c.

996 {
997  struct ifaddrs *ifaddr, *ifa;
998  gchar *interface_out;
999 
1000  interface_out = NULL;
1001 
1002  if (!storage_dest)
1003  return NULL;
1004 
1005  if (getifaddrs (&ifaddr) == -1)
1006  {
1007  g_debug ("%s: getifaddr failed: %s", __func__, strerror (errno));
1008  return NULL;
1009  }
1010 
1011  /* IPv4. */
1012  if (storage_dest->ss_family == AF_INET)
1013  {
1014  GSList *routes;
1015  GSList *routes_p;
1016 
1017  routes = get_routes ();
1018 
1019  /* Set storage_source to localhost if storage_source was supplied and
1020  * return name of loopback interface. */
1021  if (ip_islocalhost (storage_dest))
1022  {
1023  // TODO: check for (storage_source->ss_family == AF_INET)
1024  if (storage_source)
1025  {
1026  struct sockaddr_in *sin_p = (struct sockaddr_in *) storage_source;
1027  sin_p->sin_addr.s_addr = htonl (0x7F000001);
1028  }
1029 
1030  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
1031  {
1032  if (ifa->ifa_addr && (ifa->ifa_addr->sa_family == AF_INET)
1033  && (ifa->ifa_flags & (IFF_LOOPBACK)))
1034  {
1035  interface_out = g_strdup (ifa->ifa_name);
1036  break;
1037  }
1038  }
1039  }
1040  else
1041  {
1042  struct sockaddr_in *sin_dest_p, *sin_src_p;
1043  struct in_addr global_src;
1044  unsigned long best_match;
1045 
1046  /* Check if global_source_addr in use. */
1047  gvm_source_addr (&global_src);
1048 
1049  sin_dest_p = (struct sockaddr_in *) storage_dest;
1050  sin_src_p = (struct sockaddr_in *) storage_source;
1051  /* Check routes for matching address. Get interface name and set
1052  * storage_source*/
1053  for (best_match = 0, routes_p = routes; routes_p;
1054  routes_p = routes_p->next)
1055  {
1056  if (((sin_dest_p->sin_addr.s_addr
1057  & ((route_entry_t *) (routes_p->data))->mask)
1058  == ((route_entry_t *) (routes_p->data))->dest)
1059  && (((route_entry_t *) (routes_p->data))->mask >= best_match))
1060  {
1061  /* Interface of matching route.*/
1062  g_free (interface_out);
1063  interface_out =
1064  g_strdup (((route_entry_t *) (routes_p->data))->interface);
1065  best_match = ((route_entry_t *) (routes_p->data))->mask;
1066 
1067  if (!storage_source)
1068  continue;
1069 
1070  /* Set storage_source to global source if global source
1071  * present.*/
1072  if (global_src.s_addr != INADDR_ANY)
1073  sin_src_p->sin_addr.s_addr = global_src.s_addr;
1074  /* Set storage_source to addr of matching interface if no
1075  * global source present.*/
1076  else
1077  {
1078  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
1079  {
1080  if (ifa->ifa_addr
1081  && (ifa->ifa_addr->sa_family == AF_INET)
1082  && (g_strcmp0 (interface_out, ifa->ifa_name)
1083  == 0))
1084  {
1085  sin_src_p->sin_addr.s_addr =
1086  ((struct sockaddr_in *) (ifa->ifa_addr))
1087  ->sin_addr.s_addr;
1088  break;
1089  }
1090  }
1091  }
1092  }
1093  }
1094  }
1095  /* Free GSList. */
1096  if (routes)
1097  {
1098  for (routes_p = routes; routes_p; routes_p = routes_p->next)
1099  {
1100  if (((route_entry_t *) (routes_p->data))->interface)
1101  g_free (((route_entry_t *) (routes_p->data))->interface);
1102  }
1103  g_slist_free (routes);
1104  }
1105  }
1106  else if (storage_dest->ss_family == AF_INET6)
1107  {
1108  g_warning ("%s: IPv6 not yet implemented for this function. Will be "
1109  "implemented soon. Thanks for your patience.",
1110  __func__);
1111  }
1112 
1113  return interface_out != NULL ? interface_out : NULL;
1114 }

References get_routes(), gvm_source_addr(), and ip_islocalhost().

Referenced by Ensure().

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

◆ gvm_source_addr()

void gvm_source_addr ( void *  addr)

Gives the source IPv4 address.

Parameters
[out]addrBuffer of at least 4 bytes.

Definition at line 174 of file networking.c.

175 {
176  if (addr)
177  memcpy (addr, &global_source_addr.s_addr, 4);
178 }

References global_source_addr.

Referenced by Ensure(), gvm_routethrough(), gvm_source_set_socket(), and main().

Here is the caller graph for this function:

◆ gvm_source_addr6()

void gvm_source_addr6 ( void *  addr6)

Gives the source IPv6 address.

Parameters
[out]addr6Buffer of at least 16 bytes.

Definition at line 186 of file networking.c.

187 {
188  if (addr6)
189  memcpy (addr6, &global_source_addr6.s6_addr, 16);
190 }

References global_source_addr6.

Referenced by gvm_source_set_socket().

Here is the caller graph for this function:

◆ gvm_source_addr6_str()

char* gvm_source_addr6_str ( void  )

Gives the source IPv6 address in string format.

Returns
Source IPv6 string. Free with g_free().

Definition at line 225 of file networking.c.

226 {
227  char *str = g_malloc0 (INET6_ADDRSTRLEN);
228 
229  inet_ntop (AF_INET6, &global_source_addr6, str, INET6_ADDRSTRLEN);
230  return str;
231 }

References global_source_addr6.

◆ gvm_source_addr_as_addr6()

void gvm_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 199 of file networking.c.

200 {
201  if (addr6)
203 }

References global_source_addr, and ipv4_as_ipv6().

Here is the call graph for this function:

◆ gvm_source_addr_str()

char* gvm_source_addr_str ( void  )

Gives the source IPv4 address in string format.

Returns
Source IPv4 string. Free with g_free().

Definition at line 211 of file networking.c.

212 {
213  char *str = g_malloc0 (INET_ADDRSTRLEN);
214 
215  inet_ntop (AF_INET, &global_source_addr.s_addr, str, INET_ADDRSTRLEN);
216  return str;
217 }

References global_source_addr.

◆ gvm_source_iface_init()

int gvm_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 64 of file networking.c.

65 {
66  struct ifaddrs *ifaddr, *ifa;
67  int ret = 1;
68 
69  bzero (global_source_iface, sizeof (global_source_iface));
70  global_source_addr.s_addr = INADDR_ANY;
71  global_source_addr6 = in6addr_any;
72 
73  if (iface == NULL)
74  return ret;
75 
76  if (strlen (iface) >= sizeof (global_source_iface))
77  return ret;
78 
79  if (getifaddrs (&ifaddr) == -1)
80  return ret;
81 
82  /* Search for the adequate interface/family. */
83  for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
84  {
85  if (ifa->ifa_addr && strcmp (iface, ifa->ifa_name) == 0)
86  {
87  if (ifa->ifa_addr->sa_family == AF_INET)
88  {
89  struct in_addr *addr =
90  &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr;
91 
92  memcpy (&global_source_addr, addr, sizeof (global_source_addr));
93  ret = 0;
94  }
95  else if (ifa->ifa_addr->sa_family == AF_INET6)
96  {
97  struct sockaddr_in6 *addr;
98 
99  addr = (struct sockaddr_in6 *) ifa->ifa_addr;
100  memcpy (&global_source_addr6.s6_addr, &addr->sin6_addr,
101  sizeof (struct in6_addr));
102  ret = 0;
103  }
104  }
105  }
106 
107  /* At least one address for the interface was found. */
108  if (ret == 0)
109  memcpy (global_source_iface, iface, strlen (iface));
110 
111  freeifaddrs (ifaddr);
112  return ret;
113 }

References global_source_addr, global_source_addr6, and global_source_iface.

Referenced by Ensure().

Here is the caller graph for this function:

◆ gvm_source_iface_is_set()

int gvm_source_iface_is_set ( void  )

Check if global_source global_source_iface is set.

Returns
1 if set, 0 otherwise.

Definition at line 121 of file networking.c.

122 {
123  return *global_source_iface != '\0';
124 }

References global_source_iface.

◆ gvm_source_set_socket()

int gvm_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 136 of file networking.c.

137 {
138  if (family == AF_INET)
139  {
140  struct sockaddr_in addr;
141 
142  bzero (&addr, sizeof (addr));
143  gvm_source_addr (&addr.sin_addr);
144  addr.sin_port = htons (port);
145  addr.sin_family = AF_INET;
146 
147  if (bind (socket, (struct sockaddr *) &addr, sizeof (addr)) < 0)
148  return -1;
149  }
150  else if (family == AF_INET6)
151  {
152  struct sockaddr_in6 addr6;
153 
154  bzero (&addr6, sizeof (addr6));
155  gvm_source_addr6 (&addr6.sin6_addr);
156  addr6.sin6_port = htons (port);
157  addr6.sin6_family = AF_INET6;
158 
159  if (bind (socket, (struct sockaddr *) &addr6, sizeof (addr6)) < 0)
160  return -1;
161  }
162  else
163  return -1;
164 
165  return 0;
166 }

References gvm_source_addr(), and gvm_source_addr6().

Here is the call 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 243 of file networking.c.

244 {
245  if (ip4 == NULL || ip6 == NULL)
246  return;
247 
248  ip6->s6_addr32[0] = 0;
249  ip6->s6_addr32[1] = 0;
250  ip6->s6_addr32[2] = htonl (0xffff);
251  memcpy (&ip6->s6_addr32[3], ip4, sizeof (struct in_addr));
252 }

Referenced by gvm_host_get_addr6(), gvm_resolve(), gvm_resolve_list(), and gvm_source_addr_as_addr6().

Here is the caller graph for this function:

◆ ipv6_is_enabled()

int ipv6_is_enabled ( void  )

Checks if IPv6 support is enabled.

Returns
1 if IPv6 is enabled, 0 if disabled.

Definition at line 752 of file networking.c.

753 {
754  int sock = socket (PF_INET6, SOCK_STREAM, 0);
755 
756  if (sock < 0)
757  {
758  if (errno == EAFNOSUPPORT)
759  return 0;
760  }
761  else
762  close (sock);
763 
764  return 1;
765 }

◆ 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 728 of file networking.c.

729 {
730  unsigned int i;
731 
732  if (pranges == NULL || pnum < 0 || pnum > 65536)
733  return 0;
734 
735  for (i = 0; i < pranges->len; i++)
736  {
737  range_t *range = (range_t *) g_ptr_array_index (pranges, i);
738  if (range->type != ptype)
739  continue;
740  if (range->start <= pnum && pnum <= range->end)
741  return 1;
742  }
743  return 0;
744 }

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

Referenced by Ensure(), and main().

Here is the caller graph for this function:

◆ 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 or NULL if port_range invalid or NULL.

Definition at line 601 of file networking.c.

602 {
603  gchar **split, **point, *range_start, *current;
604  array_t *ranges;
605  int tcp, err;
606 
607  if (!port_range)
608  return NULL;
609 
610  /* port_range needs to be a valid port_range string. */
611  err = validate_port_range (port_range);
612  if (err)
613  return NULL;
614 
615  ranges = make_array ();
616 
617  while (*port_range && isblank (*port_range))
618  port_range++;
619 
620  /* Accepts T: and U: before any of the ranges. This toggles the remaining
621  * ranges, as in nmap. Treats a leading naked range as TCP, whereas nmap
622  * treats it as TCP and UDP. */
623 
624  /* Treat newlines like commas. */
625  range_start = current = g_strdup (port_range);
626  while (*current)
627  {
628  if (*current == '\n')
629  *current = ',';
630  current++;
631  }
632 
633  tcp = 1;
634  split = g_strsplit (range_start, ",", 0);
635  g_free (range_start);
636  point = split;
637 
638  while (*point)
639  {
640  gchar *hyphen, *element;
641  range_t *range;
642  int element_strlen;
643 
644  element = g_strstrip (*point);
645  element_strlen = strlen (element);
646 
647  if (element_strlen >= 2)
648  {
649  if (element[0] == 'T')
650  {
651  element++;
652  while (*element && isblank (*element))
653  element++;
654  if (*element == ':')
655  {
656  element++;
657  tcp = 1;
658  }
659  }
660  else if (element[0] == 'U')
661  {
662  element++;
663  while (*element && isblank (*element))
664  element++;
665  if (*element == ':')
666  {
667  element++;
668  tcp = 0;
669  }
670  }
671  /* Else tcp stays as it is. */
672  }
673 
674  /* Skip any space that followed the type specifier. */
675  while (*element && isblank (*element))
676  element++;
677 
678  hyphen = strchr (element, '-');
679  if (hyphen)
680  {
681  *hyphen = '\0';
682  hyphen++;
683  while (*hyphen && isblank (*hyphen))
684  hyphen++;
685  assert (*hyphen); /* Validation checks this. */
686 
687  /* A range. */
688 
689  range = (range_t *) g_malloc0 (sizeof (range_t));
690 
691  range->start = atoi (element);
692  range->end = atoi (hyphen);
694  range->exclude = 0;
695 
696  array_add (ranges, range);
697  }
698  else if (*element)
699  {
700  /* A single port. */
701 
702  range = (range_t *) g_malloc0 (sizeof (range_t));
703 
704  range->start = atoi (element);
705  range->end = range->start;
707  range->exclude = 0;
708 
709  array_add (ranges, range);
710  }
711  /* Else skip over empty range. */
712  point += 1;
713  }
714  g_strfreev (split);
715  return ranges;
716 }

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

Referenced by Ensure(), and main().

Here is the call graph for this function:
Here is the caller 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 298 of file networking.c.

299 {
300  if (!addr || !str)
301  return;
302 
303  if (addr->ss_family == AF_INET)
304  {
305  struct sockaddr_in *saddr = (struct sockaddr_in *) addr;
306  inet_ntop (AF_INET, &saddr->sin_addr, str, INET6_ADDRSTRLEN);
307  }
308  else if (addr->ss_family == AF_INET6)
309  {
310  struct sockaddr_in6 *s6addr = (struct sockaddr_in6 *) addr;
311  if (IN6_IS_ADDR_V4MAPPED (&s6addr->sin6_addr))
312  inet_ntop (AF_INET, &s6addr->sin6_addr.s6_addr[12], str,
313  INET6_ADDRSTRLEN);
314  else
315  inet_ntop (AF_INET6, &s6addr->sin6_addr, str, INET6_ADDRSTRLEN);
316  }
317  else if (addr->ss_family == AF_UNIX)
318  {
319  g_snprintf (str, INET6_ADDRSTRLEN, "unix_socket");
320  }
321  else if (addr->ss_family == AF_UNSPEC)
322  {
323  g_snprintf (str, INET6_ADDRSTRLEN, "unknown_socket");
324  }
325  else
326  {
327  g_snprintf (str, INET6_ADDRSTRLEN, "type_%d_socket", addr->ss_family);
328  }
329 }

◆ 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 460 of file networking.c.

461 {
462  gchar **split, **point, *range, *range_start;
463 
464  if (!port_range)
465  return 1;
466 
467  while (*port_range && isblank (*port_range))
468  port_range++;
469  if (*port_range == '\0')
470  return 1;
471 
472  /* Treat newlines like commas. */
473  range = range_start = g_strdup (port_range);
474  while (*range)
475  {
476  if (*range == '\n')
477  *range = ',';
478  range++;
479  }
480 
481  split = g_strsplit (range_start, ",", 0);
482  g_free (range_start);
483  point = split;
484 
485  while (*point)
486  {
487  gchar *hyphen, *element;
488 
489  /* Strip off any outer whitespace. */
490 
491  element = g_strstrip (*point);
492 
493  /* Strip off any leading type specifier and following whitespace. */
494 
495  if ((strlen (element) >= 2)
496  && ((element[0] == 'T') || (element[0] == 'U')))
497  {
498  element++;
499  while (*element && isblank (*element))
500  element++;
501  if (*element == ':')
502  element++;
503  }
504 
505  /* Look for a hyphen. */
506 
507  hyphen = strchr (element, '-');
508  if (hyphen)
509  {
510  long int number1, number2;
511  const char *first;
512  char *end;
513 
514  hyphen++;
515 
516  /* Check the first number. */
517 
518  first = element;
519  while (*first && isblank (*first))
520  first++;
521  if (*first == '-')
522  goto fail;
523 
524  errno = 0;
525  number1 = strtol (first, &end, 10);
526  while (*end && isblank (*end))
527  end++;
528  if (errno || (*end != '-'))
529  goto fail;
530  if (number1 == 0)
531  goto fail;
532  if (number1 > 65535)
533  goto fail;
534 
535  /* Check the second number. */
536 
537  while (*hyphen && isblank (*hyphen))
538  hyphen++;
539  if (*hyphen == '\0')
540  goto fail;
541 
542  errno = 0;
543  number2 = strtol (hyphen, &end, 10);
544  while (*end && isblank (*end))
545  end++;
546  if (errno || *end)
547  goto fail;
548  if (number2 == 0)
549  goto fail;
550  if (number2 > 65535)
551  goto fail;
552 
553  if (number1 > number2)
554  goto fail;
555  }
556  else
557  {
558  long int number;
559  const char *only;
560  char *end;
561 
562  /* Check the single number. */
563 
564  only = element;
565  while (*only && isblank (*only))
566  only++;
567  /* Empty ranges are OK. */
568  if (*only)
569  {
570  errno = 0;
571  number = strtol (only, &end, 10);
572  while (*end && isblank (*end))
573  end++;
574  if (errno || *end)
575  goto fail;
576  if (number == 0)
577  goto fail;
578  if (number > 65535)
579  goto fail;
580  }
581  }
582  point += 1;
583  }
584 
585  g_strfreev (split);
586  return 0;
587 
588 fail:
589  g_strfreev (split);
590  return 1;
591 }

Referenced by Ensure(), main(), and port_range_ranges().

Here is the caller graph for this function:
global_source_iface
char global_source_iface[IFNAMSIZ]
Definition: networking.c:46
addr6_to_str
void addr6_to_str(const struct in6_addr *addr6, char *str)
Stringifies an IP address.
Definition: networking.c:261
memdup
#define memdup
Definition: networking.c:40
get_sock_addr
static int get_sock_addr(int sockfd, struct sockaddr_storage *sock_addr)
Get address from socket.
Definition: networking.c:1177
get_connected_udp_sock
static int get_connected_udp_sock(struct sockaddr_storage *target_addr)
Get a connected UDP socket.
Definition: networking.c:1124
array_t
GPtrArray array_t
Definition: array.h:16
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....
Definition: networking.c:243
range::type
port_protocol_t type
Definition: networking.h:41
port_protocol_t
port_protocol_t
Possible port types.
Definition: networking.h:25
route_entry
Definition: networking.c:866
gvm_resolve
int gvm_resolve(const char *name, void *dst, int family)
Resolves a hostname to an IPv4 or IPv6 address.
Definition: networking.c:389
make_array
GPtrArray * make_array(void)
Make a global array.
Definition: array.c:25
ip_islocalhost
static gboolean ip_islocalhost(struct sockaddr_storage *storage)
Determine if IP is localhost.
Definition: networking.c:775
PORT_PROTOCOL_UDP
@ PORT_PROTOCOL_UDP
Definition: networking.h:27
array_add
void array_add(array_t *array, gpointer pointer)
Push a generic pointer onto an array.
Definition: array.c:68
global_source_addr
struct in_addr global_source_addr
Definition: networking.c:49
range::exclude
int exclude
Definition: networking.h:39
get_routes
static GSList * get_routes(void)
Get the entries of /proc/net/route as list of route_entry structs.
Definition: networking.c:878
get_ifname_from_ifaddr
static char * get_ifname_from_ifaddr(struct sockaddr_storage *target_addr)
Get iface name of iface matching the given interface address.
Definition: networking.c:1213
gvm_source_addr
void gvm_source_addr(void *addr)
Gives the source IPv4 address.
Definition: networking.c:174
validate_port_range
int validate_port_range(const char *port_range)
Validate a port range string.
Definition: networking.c:460
PORT_PROTOCOL_TCP
@ PORT_PROTOCOL_TCP
Definition: networking.h:26
range::end
int end
Definition: networking.h:38
global_source_addr6
struct in6_addr global_source_addr6
Definition: networking.c:52
range
A port range.
Definition: networking.h:35
gvm_source_addr6
void gvm_source_addr6(void *addr6)
Gives the source IPv6 address.
Definition: networking.c:186
range::start
int start
Definition: networking.h:40
PORT_PROTOCOL_OTHER
@ PORT_PROTOCOL_OTHER
Definition: networking.h:28