core: add function nm_utils_ip6_address_clear_host_address()
Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
@@ -75,6 +75,50 @@ nm_ethernet_address_is_valid (const struct ether_addr *test_addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 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 save, to update @src inplace, set both
|
||||||
|
* @dst and @src to the same destination.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen)
|
||||||
|
{
|
||||||
|
g_return_if_fail (plen <= 128);
|
||||||
|
g_return_if_fail (src);
|
||||||
|
g_return_if_fail (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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
nm_spawn_process (const char *args)
|
nm_spawn_process (const char *args)
|
||||||
{
|
{
|
||||||
|
@@ -35,6 +35,9 @@
|
|||||||
|
|
||||||
gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr);
|
gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr);
|
||||||
|
|
||||||
|
in_addr_t nm_utils_ip4_address_clear_host_address (in_addr_t addr, guint8 plen);
|
||||||
|
void nm_utils_ip6_address_clear_host_address (struct in6_addr *dst, const struct in6_addr *src, guint8 plen);
|
||||||
|
|
||||||
int nm_spawn_process (const char *args);
|
int nm_spawn_process (const char *args);
|
||||||
|
|
||||||
gboolean nm_match_spec_string (const GSList *specs, const char *string);
|
gboolean nm_match_spec_string (const GSList *specs, const char *string);
|
||||||
|
@@ -428,29 +428,6 @@ fill_address_from_mac (struct in6_addr *address, const char *mac)
|
|||||||
memcpy (identifier + 5, mac + 3, 3);
|
memcpy (identifier + 5, mac + 3, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure the given address is masked with its prefix and that all host
|
|
||||||
* bits are set to zero. Some IPv6 router advertisement daemons (eg, radvd)
|
|
||||||
* don't enforce this in their configuration.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
set_address_masked (struct in6_addr *dst, struct in6_addr *src, guint8 plen)
|
|
||||||
{
|
|
||||||
guint nbytes = plen / 8;
|
|
||||||
guint nbits = plen % 8;
|
|
||||||
|
|
||||||
g_return_if_fail (plen <= 128);
|
|
||||||
g_assert (src);
|
|
||||||
g_assert (dst);
|
|
||||||
|
|
||||||
if (plen >= 128)
|
|
||||||
*dst = *src;
|
|
||||||
else {
|
|
||||||
memset (dst, 0, sizeof (*dst));
|
|
||||||
memcpy (dst, src, nbytes);
|
|
||||||
dst->s6_addr[nbytes] = (src->s6_addr[nbytes] & (0xFF << (8 - nbits)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
||||||
{
|
{
|
||||||
@@ -529,7 +506,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
|||||||
/* Device route */
|
/* Device route */
|
||||||
memset (&route, 0, sizeof (route));
|
memset (&route, 0, sizeof (route));
|
||||||
route.plen = ndp_msg_opt_prefix_len (msg, offset);
|
route.plen = ndp_msg_opt_prefix_len (msg, offset);
|
||||||
set_address_masked (&route.network, ndp_msg_opt_prefix (msg, offset), route.plen);
|
nm_utils_ip6_address_clear_host_address (&route.network, ndp_msg_opt_prefix (msg, offset), route.plen);
|
||||||
route.timestamp = now;
|
route.timestamp = now;
|
||||||
if (ndp_msg_opt_prefix_flag_on_link (msg, offset)) {
|
if (ndp_msg_opt_prefix_flag_on_link (msg, offset)) {
|
||||||
route.lifetime = ndp_msg_opt_prefix_valid_time (msg, offset);
|
route.lifetime = ndp_msg_opt_prefix_valid_time (msg, offset);
|
||||||
@@ -560,7 +537,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
|||||||
memset (&route, 0, sizeof (route));
|
memset (&route, 0, sizeof (route));
|
||||||
route.gateway = gateway.address;
|
route.gateway = gateway.address;
|
||||||
route.plen = ndp_msg_opt_route_prefix_len (msg, offset);
|
route.plen = ndp_msg_opt_route_prefix_len (msg, offset);
|
||||||
set_address_masked (&route.network, ndp_msg_opt_route_prefix (msg, offset), route.plen);
|
nm_utils_ip6_address_clear_host_address (&route.network, ndp_msg_opt_route_prefix (msg, offset), route.plen);
|
||||||
route.timestamp = now;
|
route.timestamp = now;
|
||||||
route.lifetime = ndp_msg_opt_route_lifetime (msg, offset);
|
route.lifetime = ndp_msg_opt_route_lifetime (msg, offset);
|
||||||
route.preference = translate_preference (ndp_msg_opt_route_preference (msg, offset));
|
route.preference = translate_preference (ndp_msg_opt_route_preference (msg, offset));
|
||||||
|
@@ -60,6 +60,76 @@ test_nm_utils_ascii_str_to_int64 (void)
|
|||||||
test_nm_utils_ascii_str_to_int64_do ("\r\n\t10000\t\n\t\n", 10, 0, 10000, -1, 0, 10000);
|
test_nm_utils_ascii_str_to_int64_do ("\r\n\t10000\t\n\t\n", 10, 0, 10000, -1, 0, 10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Reference implementation for nm_utils_ip6_address_clear_host_address.
|
||||||
|
* Taken originally from set_address_masked(), src/rdisc/nm-lndp-rdisc.c
|
||||||
|
**/
|
||||||
|
static void
|
||||||
|
ip6_address_clear_host_address_reference (struct in6_addr *dst, struct in6_addr *src, guint8 plen)
|
||||||
|
{
|
||||||
|
guint nbytes = plen / 8;
|
||||||
|
guint nbits = plen % 8;
|
||||||
|
|
||||||
|
g_return_if_fail (plen <= 128);
|
||||||
|
g_assert (src);
|
||||||
|
g_assert (dst);
|
||||||
|
|
||||||
|
if (plen >= 128)
|
||||||
|
*dst = *src;
|
||||||
|
else {
|
||||||
|
memset (dst, 0, sizeof (*dst));
|
||||||
|
memcpy (dst, src, nbytes);
|
||||||
|
dst->s6_addr[nbytes] = (src->s6_addr[nbytes] & (0xFF << (8 - nbits)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_randomize_in6_addr (struct in6_addr *addr, GRand *rand)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i < 4; i++)
|
||||||
|
((guint32 *)addr)[i] = g_rand_int (rand);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_nm_utils_ip6_address_clear_host_address (void)
|
||||||
|
{
|
||||||
|
GRand *rand = g_rand_new ();
|
||||||
|
int plen, i;
|
||||||
|
|
||||||
|
g_rand_set_seed (rand, 0);
|
||||||
|
|
||||||
|
for (plen = 0; plen <= 128; plen++) {
|
||||||
|
for (i =0; i<50; i++) {
|
||||||
|
struct in6_addr addr_src, addr_ref;
|
||||||
|
struct in6_addr addr1, addr2;
|
||||||
|
|
||||||
|
_randomize_in6_addr (&addr_src, rand);
|
||||||
|
_randomize_in6_addr (&addr_ref, rand);
|
||||||
|
_randomize_in6_addr (&addr1, rand);
|
||||||
|
_randomize_in6_addr (&addr2, rand);
|
||||||
|
|
||||||
|
addr1 = addr_src;
|
||||||
|
ip6_address_clear_host_address_reference (&addr_ref, &addr1, plen);
|
||||||
|
|
||||||
|
_randomize_in6_addr (&addr1, rand);
|
||||||
|
_randomize_in6_addr (&addr2, rand);
|
||||||
|
addr1 = addr_src;
|
||||||
|
nm_utils_ip6_address_clear_host_address (&addr2, &addr1, plen);
|
||||||
|
g_assert_cmpint (memcmp (&addr1, &addr_src, sizeof (struct in6_addr)), ==, 0);
|
||||||
|
g_assert_cmpint (memcmp (&addr2, &addr_ref, sizeof (struct in6_addr)), ==, 0);
|
||||||
|
|
||||||
|
/* test for self assignment/inplace update. */
|
||||||
|
_randomize_in6_addr (&addr1, rand);
|
||||||
|
addr1 = addr_src;
|
||||||
|
nm_utils_ip6_address_clear_host_address (&addr1, &addr1, plen);
|
||||||
|
g_assert_cmpint (memcmp (&addr1, &addr_ref, sizeof (struct in6_addr)), ==, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
g_rand_free (rand);
|
||||||
|
}
|
||||||
|
|
||||||
/*******************************************/
|
/*******************************************/
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -70,6 +140,7 @@ main (int argc, char **argv)
|
|||||||
g_type_init ();
|
g_type_init ();
|
||||||
|
|
||||||
g_test_add_func ("/general/nm_utils_ascii_str_to_int64", test_nm_utils_ascii_str_to_int64);
|
g_test_add_func ("/general/nm_utils_ascii_str_to_int64", test_nm_utils_ascii_str_to_int64);
|
||||||
|
g_test_add_func ("/general/nm_utils_ip6_address_clear_host_address", test_nm_utils_ip6_address_clear_host_address);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user