34 #include <arpa/inet.h> 43 #include <sys/socket.h> 49 #define G_LOG_DOMAIN "base hosts" 74 struct sockaddr_in sa;
76 return inet_pton (AF_INET, str, &(sa.sin_addr)) == 1;
90 struct sockaddr_in6 sa6;
92 return inet_pton (AF_INET6, str, &(sa6.sin6_addr)) == 1;
107 char *addr_str, *block_str, *p;
109 addr_str = g_strdup (str);
110 block_str = strchr (addr_str,
'/');
111 if (block_str == NULL)
128 block = strtol (block_str, &p, 10);
131 if (*p || block <= 0 || block > 30)
149 if (str == NULL || block == NULL)
152 if (sscanf (str,
"%*[0-9.]/%2u", block) != 1)
170 gchar *addr_str, *tmp;
172 if (str == NULL || addr == NULL)
175 addr_str = g_strdup (str);
176 tmp = strchr (addr_str,
'/');
184 if (inet_pton (AF_INET, addr_str, addr) != 1)
212 if (str == NULL || first == NULL || last == NULL)
222 first->s_addr &= htonl (0xffffffff ^ ((1 << (32 - block)) - 1));
223 first->s_addr = htonl (ntohl (first->s_addr) + 1);
226 last->s_addr = htonl (ntohl (first->s_addr) + (1 << (32 - block)) - 3);
241 char *first_str, *second_str;
244 first_str = g_strdup (str);
245 second_str = strchr (first_str,
'-');
246 if (second_str == NULL)
275 struct in_addr *last)
277 char *first_str, *last_str;
279 if (str == NULL || first == NULL || last == NULL)
282 first_str = g_strdup (str);
283 last_str = strchr (first_str,
'-');
284 if (last_str == NULL)
294 if (inet_pton (AF_INET, first_str, first) != 1
295 || inet_pton (AF_INET, last_str, last) != 1)
317 char *ip_str, *end_str, *p;
319 ip_str = g_strdup (str);
320 end_str = strchr (ip_str,
'-');
338 end = strtol (end_str, &p, 10);
341 if (*p || end < 0 || end > 255)
360 struct in_addr *last)
362 char *first_str, *last_str;
365 if (str == NULL || first == NULL || last == NULL)
368 first_str = g_strdup (str);
369 last_str = strchr (first_str,
'-');
370 if (last_str == NULL)
379 end = atoi (last_str);
382 if (inet_pton (AF_INET, first_str, first) != 1)
389 last->s_addr = htonl ((ntohl (first->s_addr) & 0xffffff00) + end);
409 while (*h && (isalnum (*h) || strchr (
"-_.", *h)))
413 if (*h ==
'\0' && h - str < 256)
431 char *addr6_str, *block_str, *p;
433 addr6_str = g_strdup (str);
434 block_str = strchr (addr6_str,
'/');
435 if (block_str == NULL)
452 block = strtol (block_str, &p, 10);
455 if (*p || block <= 0 || block > 128)
473 if (str == NULL || block == NULL)
476 if (sscanf (str,
"%*[0-9a-fA-F.:]/%3u", block) != 1)
494 gchar *addr6_str, *tmp;
496 if (str == NULL || addr6 == NULL)
499 addr6_str = g_strdup (str);
500 tmp = strchr (addr6_str,
'/');
508 if (inet_pton (AF_INET6, addr6_str, addr6) != 1)
532 if (str == NULL || first == NULL || last == NULL)
540 memcpy (&last->s6_addr, &first->s6_addr, 16);
548 for (i = (128 - block) / 8; i > 0; i--)
550 first->s6_addr[j] = 0;
553 first->s6_addr[j] &= 0xff ^ ((1 << ((128 - block) % 8)) - 1);
557 for (i = (128 - block) / 8; i > 0; i--)
559 last->s6_addr[j] = 0xff;
562 last->s6_addr[j] |= (1 << ((128 - block) % 8)) - 1;
569 for (i = 15; i >= 0; --i)
570 if (first->s6_addr[i] < 255)
576 first->s6_addr[i] = 0;
578 for (i = 15; i >= 0; --i)
579 if (last->s6_addr[i] > 0)
585 last->s6_addr[i] = 0xff;
601 char *first_str, *second_str;
604 first_str = g_strdup (str);
605 second_str = strchr (first_str,
'-');
606 if (second_str == NULL)
635 struct in6_addr *last)
637 char *first_str, *last_str;
639 if (str == NULL || first == NULL || last == NULL)
642 first_str = g_strdup (str);
643 last_str = strchr (first_str,
'-');
644 if (last_str == NULL)
654 if (inet_pton (AF_INET6, first_str, first) != 1
655 || inet_pton (AF_INET6, last_str, last) != 1)
676 char *ip_str, *end_str, *p;
678 ip_str = g_strdup (str);
679 end_str = strchr (ip_str,
'-');
698 while (isxdigit (*p) && p++)
700 if (*p || p - end_str > 4)
723 struct in6_addr *last)
725 char *first_str, *last_str;
728 if (str == NULL || first == NULL || last == NULL)
731 first_str = g_strdup (str);
732 last_str = strchr (first_str,
'-');
733 if (last_str == NULL)
743 if (inet_pton (AF_INET6, first_str, first) != 1)
750 memcpy (last, first,
sizeof (*last));
751 end = strtol (last_str, NULL, 16);
752 memcpy (&last->s6_addr[15], &end, 1);
753 memcpy (&last->s6_addr[14], ((
char *) &end) + 1, 1);
778 if (str_stripped == NULL || *str_stripped ==
'\0')
834 vhost->
value = value;
925 hosts->
orig_str = g_strdup (hosts_str);
942 for (i = 0; i < hosts->
max_size; i++)
944 if (!hosts->
hosts[i])
950 for (j = i + 1; j < hosts->
max_size; j++)
955 hosts->
hosts[j] = NULL;
961 if (!hosts->
hosts[i])
979 GHashTable *name_table;
980 size_t i, duplicates = 0;
984 name_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
986 for (i = 0; i < hosts->
count; i++)
994 host = g_hash_table_lookup (name_table, name);
1001 hosts->
hosts[i] = NULL;
1006 g_hash_table_insert (name_table, name, hosts->
hosts[i]);
1012 g_hash_table_destroy (name_table);
1013 hosts->
count -= duplicates;
1034 gchar **host_element, **split;
1037 if (hosts_str == NULL)
1051 split = g_strsplit (hosts->
orig_str,
",", 0);
1054 host_element = split;
1055 while (*host_element)
1058 gchar *stripped = g_strstrip (*host_element);
1060 if (stripped == NULL || *stripped ==
'\0')
1081 host->
name = g_strdup (stripped);
1084 if (inet_pton (AF_INET, stripped, &host->
addr) != 1)
1089 if (inet_pton (AF_INET6, stripped, &host->
addr6) != 1)
1099 struct in_addr first, last;
1101 int (*ips_func) (
const char *,
struct in_addr *,
struct in_addr *);
1110 if (ips_func (stripped, &first, &last) == -1)
1114 if (ntohl (first.s_addr) > ntohl (last.s_addr))
1118 current = first.s_addr;
1119 while (ntohl (current) <= ntohl (last.s_addr))
1122 if (max_hosts > 0 && hosts->
count > max_hosts)
1130 host->
addr.s_addr = current;
1133 current = htonl (ntohl (current) + 1);
1141 struct in6_addr first, last;
1142 unsigned char current[16];
1143 int (*ips_func) (
const char *,
struct in6_addr *,
1153 if (ips_func (stripped, &first, &last) == -1)
1157 if (memcmp (&first.s6_addr, &last.s6_addr, 16) > 0)
1161 memcpy (current, &first.s6_addr, 16);
1162 while (memcmp (current, &last.s6_addr, 16) <= 0)
1167 if (max_hosts > 0 && hosts->
count > max_hosts)
1175 memcpy (host->
addr6.s6_addr, current, 16);
1178 for (i = 15; i >= 0; --i)
1179 if (current[i] < 255)
1197 if (max_hosts > 0 && hosts->
count > max_hosts)
1207 if (g_strv_length (split) > 1)
1264 for (i = 0; i < hosts->
count; i++)
1266 g_free (hosts->
hosts);
1287 rand = g_rand_new ();
1288 for (i = 0; i < hosts->
count; i++)
1291 int j = g_rand_int_range (rand, 0, hosts->
count);
1293 tmp = hosts->
hosts[i];
1295 hosts->
hosts[j] = tmp;
1316 for (i = 0, j = hosts->
count - 1; i < j; i++, j--)
1320 hosts->
hosts[j] = tmp;
1336 size_t i, new_entries = 0;
1338 for (i = 0; i < hosts->
count; i++)
1351 struct in6_addr *ip6 = tmp->data;
1355 if (ip6->s6_addr32[0] != 0 || ip6->s6_addr32[1] != 0
1356 || ip6->s6_addr32[2] != htonl (0xffff))
1359 memcpy (&new->addr6, ip6, sizeof (new->addr6));
1364 memcpy (&new->addr6, &ip6->s6_addr32[3], sizeof (new->addr));
1368 new->vhosts = g_slist_prepend (new->vhosts, vhost);
1376 hosts->
hosts[i] = NULL;
1380 g_warning (
"Couldn't resolve hostname %s", host->
name);
1383 g_slist_free_full (list, g_free);
1405 if (!host || !excluded_str)
1409 excluded = g_strsplit (excluded_str,
",", 0);
1410 if (!excluded || !*excluded)
1412 g_strfreev (excluded);
1417 char **tmp = excluded;
1418 char *value = ((
gvm_vhost_t *) vhost->data)->value;
1422 if (!strcmp (value, g_strstrip (*tmp)))
1425 host->
vhosts = vhost = g_slist_delete_link (host->
vhosts, vhost);
1432 vhost = vhost->next;
1437 g_strfreev (excluded);
1455 unsigned int max_hosts)
1461 GHashTable *name_table;
1462 size_t excluded = 0, i;
1464 if (hosts == NULL || excluded_str == NULL)
1468 if (excluded_hosts == NULL)
1478 name_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
1479 for (i = 0; i < excluded_hosts->
count; i++)
1484 g_hash_table_insert (name_table, name, hosts);
1488 for (i = 0; i < hosts->
count; i++)
1494 if (g_hash_table_lookup (name_table, name))
1497 hosts->
hosts[i] = NULL;
1509 hosts->
count -= excluded;
1512 g_hash_table_destroy (name_table);
1550 struct sockaddr_in sa;
1552 gchar hostname[1000];
1554 bzero (&sa,
sizeof (
struct sockaddr));
1555 sa.sin_addr = host->
addr;
1556 sa.sin_family = AF_INET;
1559 int ret = getnameinfo ((
struct sockaddr *) &sa,
sizeof (sa), hostname,
1560 sizeof (hostname), NULL, 0, NI_NAMEREQD);
1562 return g_strdup (hostname);
1563 if (ret != EAI_AGAIN)
1570 struct sockaddr_in6 sa;
1571 char hostname[1000];
1573 bzero (&sa,
sizeof (
struct sockaddr));
1574 memcpy (&sa.sin6_addr, &host->
addr6, 16);
1575 sa.sin6_family = AF_INET6;
1577 if (getnameinfo ((
struct sockaddr *) &sa,
sizeof (sa), hostname,
1578 sizeof (hostname), NULL, 0, NI_NAMEREQD))
1581 return g_strdup (hostname);
1608 char buffer[INET6_ADDRSTRLEN];
1610 if (!strcmp (host_str, buffer))
1618 g_slist_free_full (list, g_free);
1649 if (!strcmp (((
gvm_vhost_t *) vhosts->data)->value, value))
1654 vhosts = vhosts->next;
1672 size_t i, count = 0;
1677 for (i = 0; i < hosts->
count; i++)
1684 hosts->
hosts[i] = NULL;
1693 hosts->
count -= count;
1714 size_t i, count = 0;
1715 GHashTable *name_table;
1720 name_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
1721 for (i = 0; i < hosts->
count; i++)
1727 if (g_hash_table_lookup (name_table, name))
1730 hosts->
hosts[i] = NULL;
1737 g_hash_table_insert (name_table, name, hosts);
1744 g_hash_table_destroy (name_table);
1746 hosts->
count -= count;
1761 return hosts ? hosts->
count : 0;
1775 return hosts ? hosts->
removed : 0;
1797 if (host == NULL || hosts == NULL)
1802 for (i = 0; i < hosts->
count; i++)
1807 if (strcasecmp (host_str, tmp) == 0)
1818 struct in6_addr tmpaddr;
1821 if (memcmp (addr->s6_addr, &tmpaddr.s6_addr, 16) == 0)
1880 return g_strdup (host->
name);
1888 const void *srcaddr;
1893 size = INET_ADDRSTRLEN;
1894 srcaddr = &host->
addr;
1899 size = INET6_ADDRSTRLEN;
1900 srcaddr = &host->
addr6;
1903 str = g_malloc0 (size);
1904 if (inet_ntop (family, srcaddr, str, size) == NULL)
1906 perror (
"inet_ntop");
1913 return g_strdup (
"Erroneous host type: Should be Hostname/IPv4/IPv6.");
1952 if (host == NULL || ip6 == NULL)
1958 memcpy (ip6, &host->
addr6, sizeof (
struct in6_addr));
int gvm_hosts_exclude_with_max(gvm_hosts_t *hosts, const char *excluded_str, unsigned int max_hosts)
Excludes a set of hosts provided as a string from a hosts collection. Not to be used while iterating ...
unsigned int gvm_hosts_count(const gvm_hosts_t *hosts)
Gets the count of single hosts objects in a hosts collection.
static int host_name_verify(gvm_host_t *host, const char *value)
Verifies that hostname value resolves to a host's IP.
static int is_short_range_network(const char *str)
Checks if a buffer points to a valid short range-expressed network. "192.168.11.1-50" is valid,...
static int is_cidr_block(const char *str)
Checks if a buffer points to an IPv4 CIDR-expressed block. "192.168.12.3/24" is valid,...
int gvm_host_get_addr6(const gvm_host_t *host, struct in6_addr *ip6)
Gives a host object's value as an IPv6 address. If the host type is hostname, it resolves the IPv4 ad...
static gvm_hosts_t * gvm_hosts_init(const char *hosts_str)
Creates a hosts collection from a hosts string.
static int is_long_range6_network(const char *str)
Checks if a buffer points to a valid long IPv6 range-expressed network. "::fee5-::1:530" is valid.
int gvm_host_in_hosts(const gvm_host_t *host, const struct in6_addr *addr, const gvm_hosts_t *hosts)
Returns whether a host has an equal host in a hosts collection. eg. 192.168.10.1 has an equal in list...
void addr6_to_str(const struct in6_addr *addr6, char *str)
Stringifies an IP address.
static void gvm_hosts_fill_gaps(gvm_hosts_t *hosts)
Fill the gaps in the array of a hosts collection, which are caused by the removal of host entries.
static int is_short_range6_network(const char *str)
Checks if a buffer points to a valid short IPv6 range-expressed network. "::200:ff:1-fee5" is valid.
The structure for a single host object.
static void gvm_hosts_deduplicate(gvm_hosts_t *hosts)
Removes duplicate hosts values from an gvm_hosts_t structure. Also resets the iterator current positi...
static int is_ipv4_address(const char *str)
Checks if a buffer points to a valid IPv4 address. "192.168.11.1" is valid, "192.168....
void gvm_host_add_reverse_lookup(gvm_host_t *host)
Add a host's reverse-lookup name to the vhosts list.
int gvm_host_resolve(const gvm_host_t *host, void *dst, int family)
Resolves a host object's name to an IPv4 or IPv6 address. Host object should be of type HOST_TYPE_NAM...
gvm_hosts_t * gvm_hosts_new_with_max(const gchar *hosts_str, unsigned int max_hosts)
Creates a new gvm_hosts_t structure and the associated hosts objects from the provided hosts_str.
enum host_type gvm_host_type(const gvm_host_t *host)
Gets a host object's type.
static int cidr_get_block(const char *str, unsigned int *block)
Gets the network block value from a CIDR-expressed block string. For "192.168.1.1/24" it is 24.
static int is_hostname(const char *str)
Checks if a buffer points to a valid hostname. Valid characters include: Alphanumerics,...
int gvm_get_host_type(const gchar *str_stripped)
Determines the host type in a buffer.
gchar * host_type_str[HOST_TYPE_MAX]
static int is_ipv6_address(const char *str)
Checks if a buffer points to a valid IPv6 address. "0:0:0:0:0:0:0:1", "::1" and "::FFFF:192....
int gvm_hosts_reverse_lookup_only(gvm_hosts_t *hosts)
Removes hosts that don't reverse-lookup from the hosts collection. Not to be used while iterating ove...
The structure for a single vhost object.
void gvm_hosts_free(gvm_hosts_t *hosts)
Frees memory occupied by an gvm_hosts_t structure.
gvm_vhost_t * gvm_vhost_new(char *value, char *source)
Creates a new gvm_vhost_t object.
GSList * gvm_resolve_list(const char *name)
Returns a list of addresses that a hostname resolves to.
static int short_range6_network_ips(const char *str, struct in6_addr *first, struct in6_addr *last)
Gets the first and last IPv6 addresses from a short range-expressed network. eg. "\::ffee:1:1001-1005...
char * gvm_host_reverse_lookup(gvm_host_t *host)
Checks for a host object reverse dns lookup existence.
static int cidr6_get_block(const char *str, unsigned int *block)
Gets the network block value from a CIDR-expressed block string. For "192.168.1.1/24" it is 24.
gvm_host_t * gvm_hosts_next(gvm_hosts_t *hosts)
Gets the next gvm_host_t from a gvm_hosts_t structure. The state of iteration is kept internally with...
int gvm_hosts_reverse_lookup_unify(gvm_hosts_t *hosts)
Removes hosts duplicates that reverse-lookup to the same value. Not to be used while iterating over t...
static int cidr6_get_ip(const char *str, struct in6_addr *addr6)
Gets the IPv4 value from a CIDR-expressed block. eg. For "192.168.1.10/24" it is "192....
gchar * gvm_host_value_str(const gvm_host_t *host)
Gets a host's value in printable format.
GVM Networking related API.
void gvm_hosts_shuffle(gvm_hosts_t *hosts)
Randomizes the order of the hosts objects in the collection. Not to be used while iterating over the ...
gchar * gvm_host_type_str(const gvm_host_t *host)
Gets a host's type in printable format.
static int long_range_network_ips(const char *str, struct in_addr *first, struct in_addr *last)
Gets the first and last IPv4 addresses from a long range-expressed network. eg. "192....
The structure for Hosts collection.
void gvm_hosts_resolve(gvm_hosts_t *hosts)
Resolves host objects of type name in a hosts collection, replacing hostnames with IPv4 values....
int gvm_resolve(const char *name, void *dst, int family)
Resolves a hostname to an IPv4 or IPv6 address.
static void gvm_host_free(gpointer host)
Frees the memory occupied by an gvm_host_t object.
static int cidr6_block_ips(const char *str, struct in6_addr *first, struct in6_addr *last)
Gets the first and last usable IPv4 addresses from a CIDR-expressed block. eg. "192....
int gvm_vhosts_exclude(gvm_host_t *host, const char *excluded_str)
Exclude a list of vhosts from a host's vhosts list.
static gvm_host_t * gvm_host_new()
Creates a new gvm_host_t object.
static int is_long_range_network(const char *str)
Checks if a buffer points to a valid long range-expressed network. "192.168.12.1-192....
unsigned int gvm_hosts_removed(const gvm_hosts_t *hosts)
Gets the count of single values in hosts string that were removed (duplicates / excluded....
static int long_range6_network_ips(const char *str, struct in6_addr *first, struct in6_addr *last)
Gets the first and last IPv6 addresses from a long range-expressed network. eg. "::1:200:7-::1:205:50...
static void gvm_vhost_free(gpointer vhost)
Frees the memory occupied by an gvm_vhost_t object.
gvm_hosts_t * gvm_hosts_new(const gchar *hosts_str)
Creates a new gvm_hosts_t structure and the associated hosts objects from the provided hosts_str.
static int cidr_get_ip(const char *str, struct in_addr *addr)
Gets the IPv4 value from a CIDR-expressed block. eg. For "192.168.1.10/24" it is "192....
static int is_cidr6_block(const char *str)
Checks if a buffer points to an IPv6 CIDR-expressed block. "2620:0:2d0:200::7/120" is valid,...
static void gvm_hosts_add(gvm_hosts_t *hosts, gvm_host_t *host)
Inserts a host object at the end of a hosts collection.
static int short_range_network_ips(const char *str, struct in_addr *first, struct in_addr *last)
Gets the first and last IPv4 addresses from a short range-expressed network. "192....
int gvm_hosts_exclude(gvm_hosts_t *hosts, const char *excluded_str)
Excludes a set of hosts provided as a string from a hosts collection. Not to be used while iterating ...
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....
void gvm_hosts_reverse(gvm_hosts_t *hosts)
Reverses the order of the hosts objects in the collection. Not to be used while iterating over the si...
static int cidr_block_ips(const char *str, struct in_addr *first, struct in_addr *last)
Gets the first and last usable IPv4 addresses from a CIDR-expressed block. eg. "192....
Protos and data structures for Hosts collections and single hosts objects.