core-utils: add conversions of ipv6 tokens

From/to strings and interface identifiers.
This commit is contained in:
Lubomir Rintel 2016-04-30 16:43:10 +02:00
parent 76ee40cb58
commit 0c40bce314
4 changed files with 122 additions and 6 deletions

View file

@ -296,4 +296,8 @@ typedef enum {
NMBondOptionType
_nm_setting_bond_get_option_type (NMSettingBond *setting, const char *name);
/***********************************************************/
gboolean _nm_utils_inet6_is_token (const struct in6_addr *in6addr);
#endif

View file

@ -3565,6 +3565,40 @@ nm_utils_ipaddr_valid (int family, const char *ip)
return inet_pton (family, ip, buf) == 1;
}
/**
* nm_utils_iinet6_is_token:
* @in6addr: the AF_INET6 address structure
*
* Checks if only the bottom 64bits of the address are set.
*
* Return value: %TRUE or %FALSE
*/
gboolean
_nm_utils_inet6_is_token (const struct in6_addr *in6addr)
{
if ( in6addr->s6_addr[0]
|| in6addr->s6_addr[1]
|| in6addr->s6_addr[2]
|| in6addr->s6_addr[3]
|| in6addr->s6_addr[4]
|| in6addr->s6_addr[5]
|| in6addr->s6_addr[6]
|| in6addr->s6_addr[7])
return FALSE;
if ( in6addr->s6_addr[8]
|| in6addr->s6_addr[9]
|| in6addr->s6_addr[10]
|| in6addr->s6_addr[11]
|| in6addr->s6_addr[12]
|| in6addr->s6_addr[13]
|| in6addr->s6_addr[14]
|| in6addr->s6_addr[15])
return TRUE;
return FALSE;
}
/**
* nm_utils_check_virtual_device_compatibility:
* @virtual_type: a virtual connection type

View file

@ -2866,6 +2866,19 @@ nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
}
return FALSE;
}
/*****************************************************************************/
/**
* nm_utils_ipv6_addr_set_interface_identifier:
* @addr: output token encoded as %in6_addr
* @iid: %NMUtilsIPv6IfaceId interface identifier
*
* Converts the %NMUtilsIPv6IfaceId to an %in6_addr (suitable for use
* with Linux platform). This only copies the lower 8 bytes, ignoring
* the /64 network prefix which is expected to be all-zero for a valid
* token.
*/
void
nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr,
const NMUtilsIPv6IfaceId iid)
@ -2873,6 +2886,14 @@ nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr,
memcpy (addr->s6_addr + 8, &iid.id_u8, 8);
}
/**
* nm_utils_ipv6_interface_identifier_get_from_addr:
* @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token
* @addr: token encoded as %in6_addr
*
* Converts the %in6_addr encoded token (as used by Linux platform) to
* the interface identifier.
*/
void
nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid,
const struct in6_addr *addr)
@ -2880,6 +2901,57 @@ nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid,
memcpy (iid, addr->s6_addr + 8, 8);
}
/**
* nm_utils_ipv6_interface_identifier_get_from_token:
* @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token
* @token: token encoded as string
*
* Converts the %in6_addr encoded token (as used in ip6 settings) to
* the interface identifier.
*
* Returns: %TRUE if the @token is a valid token, %FALSE otherwise
*/
gboolean
nm_utils_ipv6_interface_identifier_get_from_token (NMUtilsIPv6IfaceId *iid,
const char *token)
{
struct in6_addr i6_token;
g_return_val_if_fail (token, FALSE);
if (!inet_pton (AF_INET6, token, &i6_token))
return FALSE;
if (!_nm_utils_inet6_is_token (&i6_token))
return FALSE;
nm_utils_ipv6_interface_identifier_get_from_addr (iid, &i6_token);
return TRUE;
}
/**
* nm_utils_inet6_interface_identifier_to_token:
* @iid: %NMUtilsIPv6IfaceId interface identifier
* @buf: the destination buffer or %NULL
*
* Converts the interface identifier to a string token.
* If the destination buffer it set, set it is used to store the
* resulting token, otherwise an internal static buffer is used.
* The buffer needs to be %NM_UTILS_INET_ADDRSTRLEN characters long.
*
* Returns: a statically allocated array. Do not g_free().
*/
const char *
nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid, char *buf)
{
struct in6_addr i6_token = { .s6_addr = { 0, } };
nm_utils_ipv6_addr_set_interface_identifier (&i6_token, iid);
return nm_utils_inet6_ntop (&i6_token, buf);
}
/*****************************************************************************/
static gboolean
_set_stable_privacy (struct in6_addr *addr,
const char *ifname,

View file

@ -335,24 +335,30 @@ struct _NMUtilsIPv6IfaceId {
#define NM_UTILS_IPV6_IFACE_ID_INIT { { .id = 0 } }
void nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr,
const NMUtilsIPv6IfaceId iid);
void nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid,
const struct in6_addr *addr);
gboolean nm_utils_ipv6_interface_identifier_get_from_token (NMUtilsIPv6IfaceId *iid,
const char *token);
const char *nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid,
char *buf);
gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type,
const guint8 *hwaddr,
guint len,
guint dev_id,
NMUtilsIPv6IfaceId *out_iid);
void nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr,
const NMUtilsIPv6IfaceId iid);
gboolean nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr,
const char *ifname,
const char *uuid,
guint dad_counter,
GError **error);
void nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid,
const struct in6_addr *addr);
void nm_utils_array_remove_at_indexes (GArray *array, const guint *indexes_to_delete, gsize len);
void nm_utils_setpgid (gpointer unused);