Greenbone Vulnerability Management Libraries 22.32.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.
int gvm_source_iface_is_set (void)
 Check if global_source global_source_iface is set.
int gvm_source_set_socket (int, int, int)
 Binds a socket to use the global source address.
void gvm_source_addr (void *)
 Gives the source IPv4 address.
void gvm_source_addr6 (void *)
 Gives the source IPv6 address.
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.
char * gvm_source_addr_str (void)
 Gives the source IPv4 address in string format.
char * gvm_source_addr6_str (void)
 Gives the source IPv6 address in string format.
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.
void addr6_to_str (const struct in6_addr *, char *)
 Stringifies an IP address.
char * addr6_as_str (const struct in6_addr *)
 Stringifies an IP address.
void sockaddr_as_str (const struct sockaddr_storage *, char *)
 Convert an IP address to string format.
int gvm_resolve (const char *, void *, int)
 Resolves a hostname to an IPv4 or IPv6 address.
GSList * gvm_resolve_list (const char *)
 Returns a list of addresses that a hostname resolves to.
int gvm_resolve_as_addr6 (const char *, struct in6_addr *)
 Resolves a hostname to an IPv4-mapped IPv6 or IPv6 address.
int validate_port_range (const char *)
 Validate a port range string.
array_tport_range_ranges (const char *)
 Create a range array from a port_range string.
int port_in_port_ranges (int, port_protocol_t, array_t *)
 Checks if a port num is in port ranges array.
int ipv6_is_enabled (void)
 Checks if IPv6 support is enabled.
gchar * gvm_routethrough (struct sockaddr_storage *, struct sockaddr_storage *)
 Get Interface which should be used for routing to destination addr.
char * gvm_get_outgoing_iface (struct sockaddr_storage *)
 Get the outgoing interface name for a given destination addr.

Detailed Description

GVM Networking related API.

Definition in file networking.h.

Typedef Documentation

◆ range_t

typedef struct range range_t

Definition at line 43 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{
port_protocol_t
Possible port types.
Definition networking.h:25
@ PORT_PROTOCOL_TCP
Definition networking.h:26
@ PORT_PROTOCOL_OTHER
Definition networking.h:28
@ PORT_PROTOCOL_UDP
Definition networking.h:27

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}
void addr6_to_str(const struct in6_addr *addr6, char *str)
Stringifies an IP address.
Definition networking.c:261

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

1299{
1300 int family, sockfd;
1301 struct sockaddr_storage out_iface_addr;
1302 char *out_iface_str;
1303
1304 out_iface_str = NULL;
1305 family = target_addr->ss_family;
1306
1307 if (!target_addr)
1308 return NULL;
1309
1310 // get a connected udp socket
1311 sockfd = get_connected_udp_sock (target_addr);
1312 if (sockfd < 0)
1313 return NULL;
1314 // get socked address which is the addr of the interface we want to get
1315 out_iface_addr.ss_family = family;
1316 if (get_sock_addr (sockfd, &out_iface_addr) < 0)
1317 return NULL;
1318 // get interface name form interface address
1319 out_iface_str = get_ifname_from_ifaddr (&out_iface_addr);
1320 return out_iface_str;
1321}
static int get_connected_udp_sock(struct sockaddr_storage *target_addr)
Get a connected UDP socket.
static int get_sock_addr(int sockfd, struct sockaddr_storage *sock_addr)
Get address from socket.
static char * get_ifname_from_ifaddr(struct sockaddr_storage *target_addr)
Get iface name of iface matching the given interface address.

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}
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

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}
int gvm_resolve(const char *name, void *dst, int family)
Resolves a hostname to an IPv4 or IPv6 address.
Definition networking.c:389

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}
#define memdup
Definition networking.c:40

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

1020{
1021 struct ifaddrs *ifaddr, *ifa;
1022 gchar *interface_out;
1023
1024 interface_out = NULL;
1025
1026 if (!storage_dest)
1027 return NULL;
1028
1029 if (getifaddrs (&ifaddr) == -1)
1030 {
1031 g_debug ("%s: getifaddr failed: %s", __func__, strerror (errno));
1032 return NULL;
1033 }
1034
1035 /* IPv4. */
1036 if (storage_dest->ss_family == AF_INET)
1037 {
1038 GSList *routes;
1039
1040 routes = get_routes ();
1041
1042 /* Set storage_source to localhost if storage_source was supplied and
1043 * return name of loopback interface. */
1044 if (ip_islocalhost (storage_dest))
1045 {
1046 // TODO: check for (storage_source->ss_family == AF_INET)
1047 if (storage_source)
1048 {
1049 struct sockaddr_in *sin_p = (struct sockaddr_in *) storage_source;
1050 sin_p->sin_addr.s_addr = htonl (0x7F000001);
1051 }
1052
1053 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
1054 {
1055 if (ifa->ifa_addr && (ifa->ifa_addr->sa_family == AF_INET)
1056 && (ifa->ifa_flags & (IFF_LOOPBACK)))
1057 {
1058 interface_out = g_strdup (ifa->ifa_name);
1059 break;
1060 }
1061 }
1062 }
1063 else
1064 {
1065 struct sockaddr_in *sin_dest_p, *sin_src_p;
1066 struct in_addr global_src;
1067 unsigned long best_match;
1068 GSList *routes_p;
1069
1070 /* Check if global_source_addr in use. */
1071 gvm_source_addr (&global_src);
1072
1073 sin_dest_p = (struct sockaddr_in *) storage_dest;
1074 sin_src_p = (struct sockaddr_in *) storage_source;
1075 /* Check routes for matching address. Get interface name and set
1076 * storage_source*/
1077 for (best_match = 0, routes_p = routes; routes_p;
1078 routes_p = routes_p->next)
1079 {
1080 if (((sin_dest_p->sin_addr.s_addr
1081 & ((route_entry_t *) (routes_p->data))->mask)
1082 == ((route_entry_t *) (routes_p->data))->dest)
1083 && (((route_entry_t *) (routes_p->data))->mask >= best_match))
1084 {
1085 /* Interface of matching route.*/
1086 g_free (interface_out);
1087 interface_out =
1088 g_strdup (((route_entry_t *) (routes_p->data))->interface);
1089 best_match = ((route_entry_t *) (routes_p->data))->mask;
1090
1091 if (!storage_source)
1092 continue;
1093
1094 /* Set storage_source to global source if global source
1095 * present.*/
1096 if (global_src.s_addr != INADDR_ANY)
1097 sin_src_p->sin_addr.s_addr = global_src.s_addr;
1098 /* Set storage_source to addr of matching interface if no
1099 * global source present.*/
1100 else
1101 {
1102 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
1103 {
1104 if (ifa->ifa_addr
1105 && (ifa->ifa_addr->sa_family == AF_INET)
1106 && (g_strcmp0 (interface_out, ifa->ifa_name)
1107 == 0))
1108 {
1109 sin_src_p->sin_addr.s_addr =
1110 ((struct sockaddr_in *) (ifa->ifa_addr))
1111 ->sin_addr.s_addr;
1112 break;
1113 }
1114 }
1115 }
1116 }
1117 }
1118 }
1119 free_routes (routes);
1120 }
1121 else if (storage_dest->ss_family == AF_INET6)
1122 {
1123 g_warning ("%s: IPv6 not yet implemented for this function. Will be "
1124 "implemented soon. Thanks for your patience.",
1125 __func__);
1126 }
1127
1128 freeifaddrs (ifaddr);
1129 return interface_out != NULL ? interface_out : NULL;
1130}
static void free_routes(GSList *routes)
Free the list of routes.
Definition networking.c:987
void gvm_source_addr(void *addr)
Gives the source IPv4 address.
Definition networking.c:174
static gboolean ip_islocalhost(struct sockaddr_storage *storage)
Determine if IP is localhost.
Definition networking.c:775
struct route_entry route_entry_t
Definition networking.c:862
static GSList * get_routes(void)
Get the entries of /proc/net/route as list of route_entry structs.
Definition networking.c:878

References free_routes(), 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}
struct in_addr global_source_addr
Definition networking.c:49

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}
struct in6_addr global_source_addr6
Definition networking.c:52

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
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}
char global_source_iface[IFNAMSIZ]
Definition networking.c:46

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}
void gvm_source_addr6(void *addr6)
Gives the source IPv6 address.
Definition networking.c:186

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}
struct range range_t
Definition networking.h:43
A port range.
Definition networking.h:35
int start
Definition networking.h:40
port_protocol_t type
Definition networking.h:41

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}
GPtrArray * make_array(void)
Make a global array.
Definition array.c:25
void array_add(array_t *array, gpointer pointer)
Push a generic pointer onto an array.
Definition array.c:68
GPtrArray array_t
Definition array.h:16
int validate_port_range(const char *port_range)
Validate a port range string.
Definition networking.c:460
int exclude
Definition networking.h:39
int end
Definition networking.h:38

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(), 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
588fail:
589 g_strfreev (split);
590 return 1;
591}

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

Here is the caller graph for this function: