shared: move nm_utils_ip._address_clear_host_address() helpers to shared

This commit is contained in:
Thomas Haller 2019-11-19 13:05:09 +01:00
parent 2ef5014f98
commit ec868916c8
3 changed files with 101 additions and 96 deletions

View file

@ -541,6 +541,102 @@ _nm_utils_ip4_prefix_to_netmask (guint32 prefix)
return prefix < 32 ? ~htonl(0xFFFFFFFF >> prefix) : 0xFFFFFFFF;
}
gconstpointer
nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen)
{
g_return_val_if_fail (dst, NULL);
switch (family) {
case AF_INET:
g_return_val_if_fail (plen <= 32, NULL);
if (!src) {
/* allow "self-assignment", by specifying %NULL as source. */
src = dst;
}
*((guint32 *) dst) = nm_utils_ip4_address_clear_host_address (*((guint32 *) src), plen);
break;
case AF_INET6:
nm_utils_ip6_address_clear_host_address (dst, src, plen);
break;
default:
g_return_val_if_reached (NULL);
}
return dst;
}
/* nm_utils_ip4_address_clear_host_address:
* @addr: source ip6 address
* @plen: prefix length of network
*
* returns: the input address, with the host address set to 0.
*/
in_addr_t
nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen)
{
return addr & _nm_utils_ip4_prefix_to_netmask (plen);
}
/* nm_utils_ip6_address_clear_host_address:
* @dst: destination output buffer, will contain the network part of the @src address
* @src: source ip6 address
* @plen: prefix length of network
*
* Note: this function is self assignment safe, to update @src inplace, set both
* @dst and @src to the same destination or set @src NULL.
*/
const struct in6_addr *
nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen)
{
g_return_val_if_fail (plen <= 128, NULL);
g_return_val_if_fail (dst, NULL);
if (!src)
src = dst;
if (plen < 128) {
guint nbytes = plen / 8;
guint nbits = plen % 8;
if (nbytes && dst != src)
memcpy (dst, src, nbytes);
if (nbits) {
dst->s6_addr[nbytes] = (src->s6_addr[nbytes] & (0xFF << (8 - nbits)));
nbytes++;
}
if (nbytes <= 15)
memset (&dst->s6_addr[nbytes], 0, 16 - nbytes);
} else if (src != dst)
*dst = *src;
return dst;
}
int
nm_utils_ip6_address_same_prefix_cmp (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen)
{
int nbytes;
guint8 va, vb, m;
if (plen >= 128)
NM_CMP_DIRECT_MEMCMP (addr_a, addr_b, sizeof (struct in6_addr));
else {
nbytes = plen / 8;
if (nbytes)
NM_CMP_DIRECT_MEMCMP (addr_a, addr_b, nbytes);
plen = plen % 8;
if (plen != 0) {
m = ~((1 << (8 - plen)) - 1);
va = ((((const guint8 *) addr_a))[nbytes]) & m;
vb = ((((const guint8 *) addr_b))[nbytes]) & m;
NM_CMP_DIRECT (va, vb);
}
}
return 0;
}
/**
* _nm_utils_ip4_get_default_prefix:
* @ip: an IPv4 address (in network byte order)

View file

@ -522,6 +522,11 @@ nm_utils_escaped_tokens_escape_gstr (const char *str,
guint32 _nm_utils_ip4_prefix_to_netmask (guint32 prefix);
guint32 _nm_utils_ip4_get_default_prefix (guint32 ip);
gconstpointer nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen);
in_addr_t nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen);
const struct in6_addr *nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen);
int nm_utils_ip6_address_same_prefix_cmp (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen);
gboolean nm_utils_ip_is_site_local (int addr_family,
const void *address);

View file

@ -231,102 +231,6 @@ nm_ethernet_address_is_valid (gconstpointer addr, gssize len)
return TRUE;
}
gconstpointer
nm_utils_ipx_address_clear_host_address (int family, gpointer dst, gconstpointer src, guint8 plen)
{
g_return_val_if_fail (dst, NULL);
switch (family) {
case AF_INET:
g_return_val_if_fail (plen <= 32, NULL);
if (!src) {
/* allow "self-assignment", by specifying %NULL as source. */
src = dst;
}
*((guint32 *) dst) = nm_utils_ip4_address_clear_host_address (*((guint32 *) src), plen);
break;
case AF_INET6:
nm_utils_ip6_address_clear_host_address (dst, src, plen);
break;
default:
g_return_val_if_reached (NULL);
}
return dst;
}
/* nm_utils_ip4_address_clear_host_address:
* @addr: source ip6 address
* @plen: prefix length of network
*
* returns: the input address, with the host address set to 0.
*/
in_addr_t
nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen)
{
return addr & _nm_utils_ip4_prefix_to_netmask (plen);
}
/* nm_utils_ip6_address_clear_host_address:
* @dst: destination output buffer, will contain the network part of the @src address
* @src: source ip6 address
* @plen: prefix length of network
*
* Note: this function is self assignment safe, to update @src inplace, set both
* @dst and @src to the same destination or set @src NULL.
*/
const struct in6_addr *
nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen)
{
g_return_val_if_fail (plen <= 128, NULL);
g_return_val_if_fail (dst, NULL);
if (!src)
src = dst;
if (plen < 128) {
guint nbytes = plen / 8;
guint nbits = plen % 8;
if (nbytes && dst != src)
memcpy (dst, src, nbytes);
if (nbits) {
dst->s6_addr[nbytes] = (src->s6_addr[nbytes] & (0xFF << (8 - nbits)));
nbytes++;
}
if (nbytes <= 15)
memset (&dst->s6_addr[nbytes], 0, 16 - nbytes);
} else if (src != dst)
*dst = *src;
return dst;
}
int
nm_utils_ip6_address_same_prefix_cmp (const struct in6_addr *addr_a, const struct in6_addr *addr_b, guint8 plen)
{
int nbytes;
guint8 va, vb, m;
if (plen >= 128)
NM_CMP_DIRECT_MEMCMP (addr_a, addr_b, sizeof (struct in6_addr));
else {
nbytes = plen / 8;
if (nbytes)
NM_CMP_DIRECT_MEMCMP (addr_a, addr_b, nbytes);
plen = plen % 8;
if (plen != 0) {
m = ~((1 << (8 - plen)) - 1);
va = ((((const guint8 *) addr_a))[nbytes]) & m;
vb = ((((const guint8 *) addr_b))[nbytes]) & m;
NM_CMP_DIRECT (va, vb);
}
}
return 0;
}
/*****************************************************************************/
void