17#include <glib/gstdio.h>
23#include <sys/socket.h>
27#include <netinet/in.h>
28#define s6_addr32 __u6_addr.__u6_addr32
35#define G_LOG_DOMAIN "libgvm base"
37#if GLIB_CHECK_VERSION(2, 67, 3)
38#define memdup g_memdup2
40#define memdup g_memdup
66 struct ifaddrs *ifaddr, *ifa;
79 if (getifaddrs (&ifaddr) == -1)
83 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
85 if (ifa->ifa_addr && strcmp (iface, ifa->ifa_name) == 0)
87 if (ifa->ifa_addr->sa_family == AF_INET)
89 struct in_addr *addr =
90 &((
struct sockaddr_in *) ifa->ifa_addr)->sin_addr;
95 else if (ifa->ifa_addr->sa_family == AF_INET6)
97 struct sockaddr_in6 *addr;
99 addr = (
struct sockaddr_in6 *) ifa->ifa_addr;
101 sizeof (
struct in6_addr));
111 freeifaddrs (ifaddr);
138 if (family == AF_INET)
140 struct sockaddr_in addr;
142 bzero (&addr,
sizeof (addr));
144 addr.sin_port = htons (port);
145 addr.sin_family = AF_INET;
147 if (bind (socket, (
struct sockaddr *) &addr,
sizeof (addr)) < 0)
150 else if (family == AF_INET6)
152 struct sockaddr_in6 addr6;
154 bzero (&addr6,
sizeof (addr6));
156 addr6.sin6_port = htons (port);
157 addr6.sin6_family = AF_INET6;
159 if (bind (socket, (
struct sockaddr *) &addr6,
sizeof (addr6)) < 0)
213 char *str = g_malloc0 (INET_ADDRSTRLEN);
227 char *str = g_malloc0 (INET6_ADDRSTRLEN);
245 if (ip4 == NULL || ip6 == NULL)
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));
265 if (IN6_IS_ADDR_V4MAPPED (addr6))
266 inet_ntop (AF_INET, &addr6->s6_addr32[3], str, INET6_ADDRSTRLEN);
268 inet_ntop (AF_INET6, addr6, str, INET6_ADDRSTRLEN);
286 str = g_malloc0 (INET6_ADDRSTRLEN);
303 if (addr->ss_family == AF_INET)
305 struct sockaddr_in *saddr = (
struct sockaddr_in *) addr;
306 inet_ntop (AF_INET, &saddr->sin_addr, str, INET6_ADDRSTRLEN);
308 else if (addr->ss_family == AF_INET6)
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,
315 inet_ntop (AF_INET6, &s6addr->sin6_addr, str, INET6_ADDRSTRLEN);
317 else if (addr->ss_family == AF_UNIX)
319 g_snprintf (str, INET6_ADDRSTRLEN,
"unix_socket");
321 else if (addr->ss_family == AF_UNSPEC)
323 g_snprintf (str, INET6_ADDRSTRLEN,
"unknown_socket");
327 g_snprintf (str, INET6_ADDRSTRLEN,
"type_%d_socket", addr->ss_family);
341 struct addrinfo hints, *info, *p;
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)
359 if (p->ai_family == AF_INET)
361 struct sockaddr_in *addrin = (
struct sockaddr_in *) p->ai_addr;
363 list = g_slist_prepend (list,
memdup (&dst,
sizeof (dst)));
365 else if (p->ai_family == AF_INET6)
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)));
391 struct addrinfo hints, *info, *p;
393 if (name == NULL || dst == NULL
394 || (family != AF_INET && family != AF_INET6 && family != AF_UNSPEC))
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)
407 if (p->ai_family == family || family == AF_UNSPEC)
409 if (p->ai_family == AF_INET && family == AF_UNSPEC)
411 struct sockaddr_in *addrin = (
struct sockaddr_in *) p->ai_addr;
414 else if (p->ai_family == AF_INET)
416 struct sockaddr_in *addrin = (
struct sockaddr_in *) p->ai_addr;
417 memcpy (dst, &(addrin->sin_addr), sizeof (
struct in_addr));
419 else if (p->ai_family == AF_INET6)
421 struct sockaddr_in6 *addrin = (
struct sockaddr_in6 *) p->ai_addr;
422 memcpy (dst, &(addrin->sin6_addr), sizeof (
struct in6_addr));
462 gchar **split, **point, *
range, *range_start;
467 while (*port_range && isblank (*port_range))
469 if (*port_range ==
'\0')
473 range = range_start = g_strdup (port_range);
481 split = g_strsplit (range_start,
",", 0);
482 g_free (range_start);
487 gchar *hyphen, *element;
491 element = g_strstrip (*point);
495 if ((strlen (element) >= 2)
496 && ((element[0] ==
'T') || (element[0] ==
'U')))
499 while (*element && isblank (*element))
507 hyphen = strchr (element,
'-');
510 long int number1, number2;
519 while (*first && isblank (*first))
525 number1 = strtol (first, &end, 10);
526 while (*end && isblank (*end))
528 if (errno || (*end !=
'-'))
537 while (*hyphen && isblank (*hyphen))
543 number2 = strtol (hyphen, &end, 10);
544 while (*end && isblank (*end))
553 if (number1 > number2)
565 while (*only && isblank (*only))
571 number = strtol (only, &end, 10);
572 while (*end && isblank (*end))
603 gchar **split, **point, *range_start, *current;
617 while (*port_range && isblank (*port_range))
625 range_start = current = g_strdup (port_range);
628 if (*current ==
'\n')
634 split = g_strsplit (range_start,
",", 0);
635 g_free (range_start);
640 gchar *hyphen, *element;
644 element = g_strstrip (*point);
645 element_strlen = strlen (element);
647 if (element_strlen >= 2)
649 if (element[0] ==
'T')
652 while (*element && isblank (*element))
660 else if (element[0] ==
'U')
663 while (*element && isblank (*element))
675 while (*element && isblank (*element))
678 hyphen = strchr (element,
'-');
683 while (*hyphen && isblank (*hyphen))
732 if (pranges == NULL || pnum < 0 || pnum > 65536)
735 for (i = 0; i < pranges->len; i++)
740 if (
range->
start <= pnum && pnum <= range->end)
754 int sock = socket (PF_INET6, SOCK_STREAM, 0);
758 if (errno == EAFNOSUPPORT)
778 struct in_addr *addr_p;
779 struct in6_addr addr6 = IN6ADDR_ANY_INIT;
780 struct in6_addr *addr6_p;
781 struct sockaddr_in *sin_p;
782 struct sockaddr_in6 *sin6_p;
783 struct ifaddrs *ifaddr, *ifa;
786 family = storage->ss_family;
791 if (family == AF_INET)
793 sin_p = (
struct sockaddr_in *) storage;
794 addr = sin_p->sin_addr;
799 if ((addr_p)->s_addr == 0)
802 if (((addr_p)->s_addr & htonl (0xFF000000)) == htonl (0x7F000000))
805 if (family == AF_INET6)
807 sin6_p = (
struct sockaddr_in6 *) storage;
808 addr6 = sin6_p->sin6_addr;
810 if (IN6_IS_ADDR_V4MAPPED (&addr6))
813 if (addr6_p->s6_addr32[3] == 0)
817 if ((addr6_p->s6_addr32[3] & htonl (0xFF000000))
818 == htonl (0x7F000000))
821 if (IN6_IS_ADDR_LOOPBACK (addr6_p))
825 if (getifaddrs (&ifaddr) == -1)
827 g_debug (
"%s: getifaddr failed: %s", __func__, strerror (errno));
832 struct sockaddr_in *sin;
833 struct sockaddr_in6 *sin6;
835 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
837 if (ifa->ifa_addr == NULL)
839 if (ifa->ifa_addr->sa_family == AF_INET)
841 sin = (
struct sockaddr_in *) (ifa->ifa_addr);
843 if (addr_p->s_addr == sin->sin_addr.s_addr)
846 if (ifa->ifa_addr->sa_family == AF_INET6)
848 sin6 = (
struct sockaddr_in6 *) (ifa->ifa_addr);
851 if (family == AF_INET6
852 && IN6_ARE_ADDR_EQUAL (&(sin6->sin6_addr), addr6_p))
856 freeifaddrs (ifaddr);
882 GIOChannel *file_channel;
884 gchar **items_in_line;
893 file_channel = g_io_channel_new_file (
"/proc/net/route",
"r", &err);
894 if (file_channel == NULL)
896 g_warning (
"%s: %s. ", __func__,
897 err ? err->message :
"Error opening /proc/net/ipv6_route");
903 status = g_io_channel_read_line (file_channel, &line, NULL, NULL, &err);
904 if (status != G_IO_STATUS_NORMAL || !line || err)
906 g_warning (
"%s: %s", __func__,
908 :
"g_io_channel_read_line() status != G_IO_STATUS_NORMAL");
917 gchar *interface, *char_p;
918 unsigned long mask, dest;
923 status = g_io_channel_read_line (file_channel, &line, NULL, NULL, &err);
924 if ((status != G_IO_STATUS_NORMAL) || !line || err)
926 if (status == G_IO_STATUS_AGAIN)
927 g_warning (
"%s: /proc/net/route unavailable.", __func__);
928 if (err || status == G_IO_STATUS_ERROR)
932 :
"g_io_channel_read_line() status == G_IO_STATUS_ERROR");
939 items_in_line = g_strsplit (line,
"\t", -1);
941 for (count = 0; items_in_line[count]; count++)
945 g_strfreev (items_in_line);
950 interface = g_strndup (items_in_line[0], 64);
952 char_p = strchr (interface,
':');
957 dest = strtoul (items_in_line[1], NULL, 16);
958 mask = strtoul (items_in_line[7], NULL, 16);
965 routes = g_slist_append (routes, entry);
967 g_strfreev (items_in_line);
971 status = g_io_channel_shutdown (file_channel, TRUE, &err);
972 if ((G_IO_STATUS_NORMAL != status) || err)
973 g_warning (
"%s: %s", __func__,
975 :
"g_io_channel_shutdown() was not successful");
996 struct sockaddr_storage *storage_source)
998 struct ifaddrs *ifaddr, *ifa;
999 gchar *interface_out;
1001 interface_out = NULL;
1006 if (getifaddrs (&ifaddr) == -1)
1008 g_debug (
"%s: getifaddr failed: %s", __func__, strerror (errno));
1013 if (storage_dest->ss_family == AF_INET)
1027 struct sockaddr_in *sin_p = (
struct sockaddr_in *) storage_source;
1028 sin_p->sin_addr.s_addr = htonl (0x7F000001);
1031 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
1033 if (ifa->ifa_addr && (ifa->ifa_addr->sa_family == AF_INET)
1034 && (ifa->ifa_flags & (IFF_LOOPBACK)))
1036 interface_out = g_strdup (ifa->ifa_name);
1043 struct sockaddr_in *sin_dest_p, *sin_src_p;
1044 struct in_addr global_src;
1045 unsigned long best_match;
1050 sin_dest_p = (
struct sockaddr_in *) storage_dest;
1051 sin_src_p = (
struct sockaddr_in *) storage_source;
1054 for (best_match = 0, routes_p = routes; routes_p;
1055 routes_p = routes_p->next)
1057 if (((sin_dest_p->sin_addr.s_addr
1060 && (((
route_entry_t *) (routes_p->data))->mask >= best_match))
1063 g_free (interface_out);
1068 if (!storage_source)
1073 if (global_src.s_addr != INADDR_ANY)
1074 sin_src_p->sin_addr.s_addr = global_src.s_addr;
1079 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
1082 && (ifa->ifa_addr->sa_family == AF_INET)
1083 && (g_strcmp0 (interface_out, ifa->ifa_name)
1086 sin_src_p->sin_addr.s_addr =
1087 ((
struct sockaddr_in *) (ifa->ifa_addr))
1099 for (routes_p = routes; routes_p; routes_p = routes_p->next)
1104 g_slist_free (routes);
1107 else if (storage_dest->ss_family == AF_INET6)
1109 g_warning (
"%s: IPv6 not yet implemented for this function. Will be "
1110 "implemented soon. Thanks for your patience.",
1114 return interface_out != NULL ? interface_out : NULL;
1127 int family = target_addr->ss_family;
1129 if (family == AF_INET)
1131 sockfd = socket (AF_INET, SOCK_DGRAM, 0);
1134 g_warning (
"Socket error: %s", strerror (errno));
1138 ((
struct sockaddr_in *) target_addr)->sin_port = htons (9877);
1139 if (connect (sockfd, (
struct sockaddr *) target_addr,
1140 sizeof (
struct sockaddr_in))
1143 g_warning (
"Connect error: %s", strerror (errno));
1148 else if (family == AF_INET6)
1150 sockfd = socket (AF_INET6, SOCK_DGRAM, 0);
1153 g_warning (
"Socket error: %s", strerror (errno));
1156 ((
struct sockaddr_in6 *) target_addr)->sin6_port = htons (9877);
1157 if (connect (sockfd, (
struct sockaddr *) target_addr,
1158 sizeof (
struct sockaddr_in6))
1161 g_warning (
"Connect error: %s", strerror (errno));
1181 int family = sock_addr->ss_family;
1182 if (family == AF_INET)
1184 len =
sizeof (
struct sockaddr_in);
1185 if (getsockname (sockfd, (
struct sockaddr *) sock_addr, &len) < 0)
1187 g_warning (
"getsockname error: %s", strerror (errno));
1192 else if (family == AF_INET6)
1194 len =
sizeof (
struct sockaddr_in6);
1195 if (getsockname (sockfd, (
struct sockaddr *) sock_addr, &len) < 0)
1197 g_warning (
"getsockname error:%s", strerror (errno));
1216 struct ifaddrs *ifaddr, *ifa;
1217 int family = target_addr->ss_family;
1218 char *interface_out = NULL;
1220 if (getifaddrs (&ifaddr) == -1)
1222 g_warning (
"%s: getifaddr failed: %s", __func__, strerror (errno));
1225 if (family == AF_INET)
1227 struct sockaddr_in *sin;
1228 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
1230 if (!(ifa->ifa_flags & IFF_UP))
1232 if (ifa->ifa_addr == NULL)
1234 if (ifa->ifa_addr->sa_family == AF_INET)
1236 sin = (
struct sockaddr_in *) (ifa->ifa_addr);
1237 if (((
struct sockaddr_in *) target_addr)->sin_addr.s_addr
1238 == sin->sin_addr.s_addr)
1239 interface_out = g_strdup (ifa->ifa_name);
1243 else if (family == AF_INET6)
1245 struct sockaddr_in6 *sin6;
1246 for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next)
1248 if (!(ifa->ifa_flags & IFF_UP))
1250 if (ifa->ifa_addr == NULL)
1252 if (ifa->ifa_addr->sa_family == AF_INET6)
1254 sin6 = (
struct sockaddr_in6 *) (ifa->ifa_addr);
1255 if (IN6_ARE_ADDR_EQUAL (
1257 &((
struct sockaddr_in6 *) target_addr)->sin6_addr))
1258 interface_out = g_strdup (ifa->ifa_name);
1262 freeifaddrs (ifaddr);
1263 return interface_out;
1286 struct sockaddr_storage out_iface_addr;
1287 char *out_iface_str;
1289 out_iface_str = NULL;
1290 family = target_addr->ss_family;
1300 out_iface_addr.ss_family = family;
1305 return out_iface_str;
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
void addr6_to_str(const struct in6_addr *addr6, char *str)
Stringifies an IP address.
Definition networking.c:261
int ipv6_is_enabled(void)
Checks if IPv6 support is enabled.
Definition networking.c:752
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
static int get_connected_udp_sock(struct sockaddr_storage *target_addr)
Get a connected UDP socket.
Definition networking.c:1125
struct in6_addr global_source_addr6
Definition networking.c:52
char * gvm_get_outgoing_iface(struct sockaddr_storage *target_addr)
Get the outgoing interface name for a given destination addr.
Definition networking.c:1283
array_t * port_range_ranges(const char *port_range)
Create a range array from a port_range string.
Definition networking.c:601
void gvm_source_addr6(void *addr6)
Gives the source IPv6 address.
Definition networking.c:186
void gvm_source_addr(void *addr)
Gives the source IPv4 address.
Definition networking.c:174
int gvm_resolve(const char *name, void *dst, int family)
Resolves a hostname to an IPv4 or IPv6 address.
Definition networking.c:389
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....
Definition networking.c:199
#define memdup
Definition networking.c:40
static int get_sock_addr(int sockfd, struct sockaddr_storage *sock_addr)
Get address from socket.
Definition networking.c:1178
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
char global_source_iface[IFNAMSIZ]
Definition networking.c:46
static char * get_ifname_from_ifaddr(struct sockaddr_storage *target_addr)
Get iface name of iface matching the given interface address.
Definition networking.c:1214
void sockaddr_as_str(const struct sockaddr_storage *addr, char *str)
Convert an IP address to string format.
Definition networking.c:298
int validate_port_range(const char *port_range)
Validate a port range string.
Definition networking.c:460
char * addr6_as_str(const struct in6_addr *addr6)
Stringifies an IP address.
Definition networking.c:279
int gvm_resolve_as_addr6(const char *name, struct in6_addr *ip6)
Resolves a hostname to an IPv4-mapped IPv6 or IPv6 address.
Definition networking.c:443
int gvm_source_iface_init(const char *iface)
Initializes the source network interface name and related information.
Definition networking.c:64
gchar * gvm_routethrough(struct sockaddr_storage *storage_dest, struct sockaddr_storage *storage_source)
Get Interface which should be used for routing to destination addr.
Definition networking.c:995
char * gvm_source_addr6_str(void)
Gives the source IPv6 address in string format.
Definition networking.c:225
int gvm_source_set_socket(int socket, int port, int family)
Binds a socket to use the global source address.
Definition networking.c:136
int port_in_port_ranges(int pnum, port_protocol_t ptype, array_t *pranges)
Checks if a port num is in port ranges array.
Definition networking.c:728
struct in_addr global_source_addr
Definition networking.c:49
GSList * gvm_resolve_list(const char *name)
Returns a list of addresses that a hostname resolves to.
Definition networking.c:339
int gvm_source_iface_is_set(void)
Check if global_source global_source_iface is set.
Definition networking.c:121
char * gvm_source_addr_str(void)
Gives the source IPv4 address in string format.
Definition networking.c:211
static GSList * get_routes(void)
Get the entries of /proc/net/route as list of route_entry structs.
Definition networking.c:878
GVM Networking related API.
port_protocol_t
Possible port types.
Definition networking.h:25
@ PORT_PROTOCOL_TCP
Definition networking.h:26
@ PORT_PROTOCOL_UDP
Definition networking.h:27
struct range range_t
Definition networking.h:43
A port range.
Definition networking.h:35
int start
Definition networking.h:40
int exclude
Definition networking.h:39
port_protocol_t type
Definition networking.h:41
int end
Definition networking.h:38
Definition networking.c:866
unsigned long dest
Definition networking.c:869
unsigned long mask
Definition networking.c:868
gchar * interface
Definition networking.c:867