diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2016-04-30 16:43:10 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2016-05-30 16:19:20 +0200 |
commit | 0c40bce3140666658d51de7217e3d9eade2aa4d7 (patch) | |
tree | eb5b833e5907c066bbbcfa92b4e2a14b36e8b61e | |
parent | 76ee40cb58e6778df8d911ebbbf57932c957a60d (diff) | |
download | NetworkManager-0c40bce3140666658d51de7217e3d9eade2aa4d7.tar.gz |
core-utils: add conversions of ipv6 tokens
From/to strings and interface identifiers.
-rw-r--r-- | libnm-core/nm-core-internal.h | 4 | ||||
-rw-r--r-- | libnm-core/nm-utils.c | 34 | ||||
-rw-r--r-- | src/nm-core-utils.c | 72 | ||||
-rw-r--r-- | src/nm-core-utils.h | 18 |
4 files changed, 122 insertions, 6 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 2041a1d3a1..a09ee26c48 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -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 diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 81676e9f1f..7a87dc18c4 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -3566,6 +3566,40 @@ nm_utils_ipaddr_valid (int family, const char *ip) } /** + * 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 * @other_type: a connection type to test against @virtual_type diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 5d6c74c57a..276dc1c406 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -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, diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 8b54113cb3..a203a8ef71 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -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); |