diff --git a/libnm-util/libnm-util.ver b/libnm-util/libnm-util.ver index 6a7bc098d..888c9e10e 100644 --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -439,6 +439,10 @@ global: nm_utils_deinit; nm_utils_escape_ssid; nm_utils_gvalue_hash_dup; + nm_utils_hwaddr_atoba; + nm_utils_hwaddr_aton; + nm_utils_hwaddr_len; + nm_utils_hwaddr_ntoa; nm_utils_init; nm_utils_ip4_addresses_from_gvalue; nm_utils_ip4_addresses_to_gvalue; diff --git a/libnm-util/nm-utils.c b/libnm-util/nm-utils.c index 073a66882..b40e814b3 100644 --- a/libnm-util/nm-utils.c +++ b/libnm-util/nm-utils.c @@ -25,11 +25,14 @@ */ #include "config.h" +#include #include #include #include #include #include +#include +#include #include #include @@ -2386,3 +2389,114 @@ nm_utils_wifi_is_channel_valid (guint32 channel, const char *band) return FALSE; } +/** + * nm_utils_hwaddr_len: + * @type: the type of address; either %ARPHRD_ETHER or %ARPHRD_INFINIBAND + * + * Returns the length in octets of a hardware address of type @type. + * + * Return value: the length + */ +int +nm_utils_hwaddr_len (int type) +{ + if (type == ARPHRD_ETHER) + return ETH_ALEN; + else if (type == ARPHRD_INFINIBAND) + return INFINIBAND_ALEN; + else + g_return_val_if_reached (-1); +} + +#define HEXVAL(c) ((c) <= '9' ? (c) - '0' : ((c) & 0x4F) - 'A' + 10) + +/** + * nm_utils_hwaddr_aton: + * @asc: the ASCII representation of a hardware address + * @type: the type of address; either %ARPHRD_ETHER or %ARPHRD_INFINIBAND + * @buffer: buffer to store the result into + * + * Parses @asc and converts it to binary form in @buffer. See + * nm_utils_hwaddr_atoba() if you'd rather have the result in a + * #GByteArray. + * + * Return value: @buffer, or %NULL if @asc couldn't be parsed + */ +guint8 * +nm_utils_hwaddr_aton (const char *asc, int type, gpointer buffer) +{ + const char *in = asc; + guint8 *out = (guint8 *)buffer; + int left = nm_utils_hwaddr_len (type); + + while (left && *in) { + if (!isxdigit (in[0]) || !isxdigit (in[1])) + return NULL; + + *out++ = (HEXVAL (in[0]) << 4) + HEXVAL (in[1]); + left--; + in += 2; + if (*in) { + if (*in != ':') + return NULL; + in++; + } + } + + if (left == 0 && !*in) + return buffer; + else + return NULL; +} + +/** + * nm_utils_hwaddr_atoba: + * @asc: the ASCII representation of a hardware address + * @type: the type of address; either %ARPHRD_ETHER or %ARPHRD_INFINIBAND + * + * Parses @asc and converts it to binary form in a #GByteArray. See + * nm_utils_hwaddr_aton() if you don't want a #GByteArray. + * + * Return value: a new #GByteArray, or %NULL if @asc couldn't be + * parsed + */ +GByteArray * +nm_utils_hwaddr_atoba (const char *asc, int type) +{ + GByteArray *ba; + int len = nm_utils_hwaddr_len (type); + + ba = g_byte_array_sized_new (len); + ba->len = len; + if (!nm_utils_hwaddr_aton (asc, type, ba->data)) { + g_byte_array_unref (ba); + return NULL; + } + + return ba; +} + +/** + * nm_utils_hwaddr_ntoa: + * @addr: a binary hardware address + * @type: the type of address; either %ARPHRD_ETHER or %ARPHRD_INFINIBAND + * + * Converts @addr to textual form. + * + * Return value: (transfer full): the textual form of @addr + */ +char * +nm_utils_hwaddr_ntoa (gconstpointer addr, int type) +{ + const guint8 *in = addr; + GString *out = g_string_new (NULL); + int left = nm_utils_hwaddr_len (type); + + while (left--) { + if (out->len) + g_string_append_c (out, ':'); + g_string_append_printf (out, "%02X", *in++); + } + + return g_string_free (out, FALSE); +} diff --git a/libnm-util/nm-utils.h b/libnm-util/nm-utils.h index 6a1792689..d858d3fb2 100644 --- a/libnm-util/nm-utils.h +++ b/libnm-util/nm-utils.h @@ -118,6 +118,20 @@ guint32 nm_utils_wifi_channel_to_freq (guint32 channel, const char *band); guint32 nm_utils_wifi_find_next_channel (guint32 channel, int direction, char *band); gboolean nm_utils_wifi_is_channel_valid (guint32 channel, const char *band); +/** + * NM_UTILS_HWADDR_LEN_MAX: + * + * The maximum length of a hardware address of a type known by + * nm_utils_hwaddr_len() or nm_utils_hwaddr_aton(). This can be used + * as the size of the buffer passed to nm_utils_hwaddr_aton(). + */ +#define NM_UTILS_HWADDR_LEN_MAX 20 /* INFINIBAND_ALEN */ + +int nm_utils_hwaddr_len (int type) G_GNUC_PURE; +char *nm_utils_hwaddr_ntoa (gconstpointer addr, int type); +GByteArray *nm_utils_hwaddr_atoba (const char *asc, int type); +guint8 *nm_utils_hwaddr_aton (const char *asc, int type, gpointer buffer); + G_END_DECLS #endif /* NM_UTILS_H */ diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 451de6d00..2e823b02c 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -159,18 +159,6 @@ nm_utils_ip4_prefix_to_netmask (guint32 prefix) return (guint32) htonl (netmask); } -char * -nm_ether_ntop (const struct ether_addr *mac) -{ - /* we like leading zeros and all-caps, instead - * of what glibc's ether_ntop() gives us - */ - return g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", - mac->ether_addr_octet[0], mac->ether_addr_octet[1], - mac->ether_addr_octet[2], mac->ether_addr_octet[3], - mac->ether_addr_octet[4], mac->ether_addr_octet[5]); -} - void nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting) { diff --git a/src/NetworkManagerUtils.h b/src/NetworkManagerUtils.h index 1bf741ed3..d3736c519 100644 --- a/src/NetworkManagerUtils.h +++ b/src/NetworkManagerUtils.h @@ -37,8 +37,6 @@ gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr); int nm_spawn_process (const char *args); -char *nm_ether_ntop (const struct ether_addr *mac); - void nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting); void nm_utils_merge_ip6_config (NMIP6Config *ip6_config, NMSettingIP6Config *setting); diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index afd5e14c9..33d33c907 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -61,6 +61,7 @@ #include "nm-properties-changed-signal.h" #include "nm-dhcp-manager.h" #include "nm-netlink-utils.h" +#include "nm-utils.h" #include "nm-device-ethernet-glue.h" @@ -1761,7 +1762,7 @@ spec_match_list (NMDevice *device, const GSList *specs) char *hwaddr; gboolean matched; - hwaddr = nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr); + hwaddr = nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER); matched = nm_match_spec_hwaddr (specs, hwaddr); g_free (hwaddr); @@ -1947,10 +1948,10 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_HW_ADDRESS: - g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->hw_addr)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->hw_addr, ARPHRD_ETHER)); break; case PROP_PERM_HW_ADDRESS: - g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER)); break; case PROP_SPEED: g_value_set_uint (value, nm_device_ethernet_get_speed (self)); diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index a12e19979..53a3b205e 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -492,7 +493,7 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_HW_ADDRESS: nm_device_olpc_mesh_get_address (device, &hw_addr); - g_value_take_string (value, nm_ether_ntop (&hw_addr)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&hw_addr, ARPHRD_ETHER)); break; case PROP_COMPANION: if (priv->companion) diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index a133c8316..468cb33a0 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -732,13 +732,13 @@ periodic_update (NMDeviceWifi *self) if (new_ap) { new_bssid = nm_ap_get_address (new_ap); - new_addr = nm_ether_ntop (new_bssid); + new_addr = nm_utils_hwaddr_ntoa (new_bssid, ARPHRD_ETHER); new_ssid = nm_ap_get_ssid (new_ap); } if (priv->current_ap) { old_bssid = nm_ap_get_address (priv->current_ap); - old_addr = nm_ether_ntop (old_bssid); + old_addr = nm_utils_hwaddr_ntoa (old_bssid, ARPHRD_ETHER); old_ssid = nm_ap_get_ssid (priv->current_ap); } @@ -2963,7 +2963,7 @@ spec_match_list (NMDevice *device, const GSList *specs) char *hwaddr; gboolean matched; - hwaddr = nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr); + hwaddr = nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER); matched = nm_match_spec_hwaddr (specs, hwaddr); g_free (hwaddr); @@ -3196,10 +3196,10 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_HW_ADDRESS: - g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->hw_addr)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->hw_addr, ARPHRD_ETHER)); break; case PROP_PERM_HW_ADDRESS: - g_value_take_string (value, nm_ether_ntop ((struct ether_addr *) &priv->perm_hw_addr)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->perm_hw_addr, ARPHRD_ETHER)); break; case PROP_MODE: g_value_set_uint (value, wifi_utils_get_mode (priv->wifi_data)); diff --git a/src/nm-wifi-ap.c b/src/nm-wifi-ap.c index 2bb3f3e6e..d211d1996 100644 --- a/src/nm-wifi-ap.c +++ b/src/nm-wifi-ap.c @@ -21,6 +21,7 @@ #include #include +#include #include "nm-wifi-ap.h" #include "nm-wifi-ap-utils.h" @@ -181,7 +182,7 @@ get_property (GObject *object, guint prop_id, g_value_set_uint (value, priv->freq); break; case PROP_HW_ADDRESS: - g_value_take_string (value, nm_ether_ntop (&priv->address)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&priv->address, ARPHRD_ETHER)); break; case PROP_MODE: g_value_set_uint (value, priv->mode); diff --git a/src/settings/nm-settings-connection.c b/src/settings/nm-settings-connection.c index cdad83256..836d1c049 100644 --- a/src/settings/nm-settings-connection.c +++ b/src/settings/nm-settings-connection.c @@ -1576,7 +1576,7 @@ nm_settings_connection_add_seen_bssid (NMSettingsConnection *connection, return; /* Already in the list */ /* Add the new BSSID; let the hash take ownership of the allocated BSSID string */ - bssid_str = nm_ether_ntop (seen_bssid); + bssid_str = nm_utils_hwaddr_ntoa (seen_bssid, ARPHRD_ETHER); g_return_if_fail (bssid_str != NULL); g_hash_table_insert (priv->seen_bssids, mac_dup (seen_bssid), bssid_str); diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index a681edd02..6bb616805 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -206,7 +206,6 @@ static gboolean read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError **error) { char *value = NULL; - struct ether_addr *mac; g_return_val_if_fail (ifcfg != NULL, FALSE); g_return_val_if_fail (array != NULL, FALSE); @@ -220,8 +219,8 @@ read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError return TRUE; } - mac = ether_aton (value); - if (!mac) { + *array = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER); + if (!*array) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "%s: the MAC address '%s' was invalid.", key, value); g_free (value); @@ -229,8 +228,6 @@ read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError } g_free (value); - *array = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN); return TRUE; } @@ -2947,19 +2944,16 @@ make_wireless_setting (shvarFile *ifcfg, value = svGetValue (ifcfg, "BSSID", FALSE); if (value) { - struct ether_addr *eth; GByteArray *bssid; - eth = ether_aton (value); - if (!eth) { + bssid = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER); + if (!bssid) { g_set_error (error, IFCFG_PLUGIN_ERROR, 0, "Invalid BSSID '%s'", value); g_free (value); goto error; } - bssid = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (bssid, eth->ether_addr_octet, ETH_ALEN); g_object_set (s_wireless, NM_SETTING_WIRELESS_BSSID, bssid, NULL); g_byte_array_free (bssid, TRUE); g_free (value); diff --git a/src/settings/plugins/ifnet/connection_parser.c b/src/settings/plugins/ifnet/connection_parser.c index b4aaa8d2f..81e466ea0 100644 --- a/src/settings/plugins/ifnet/connection_parser.c +++ b/src/settings/plugins/ifnet/connection_parser.c @@ -509,20 +509,17 @@ static gboolean read_mac_address (const char *conn_name, GByteArray **array, GError **error) { const char *value = ifnet_get_data (conn_name, "mac"); - struct ether_addr *mac; if (!value || !strlen (value)) return TRUE; - mac = ether_aton (value); - if (!mac) { + *array = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER); + if (!*array) { g_set_error (error, ifnet_plugin_error_quark (), 0, - "The MAC address '%s' was invalid.", value); + "The MAC address '%s' was invalid.", value); return FALSE; } - *array = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN); return TRUE; } @@ -1012,18 +1009,15 @@ make_wireless_connection_setting (const char *conn_name, /* BSSID setting */ value = wpa_get_value (conn_name, "bssid"); if (value) { - struct ether_addr *eth; GByteArray *bssid; - eth = ether_aton (value); - if (!eth) { + bssid = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER); + if (!bssid) { g_set_error (error, ifnet_plugin_error_quark (), 0, - "Invalid BSSID '%s'", value); + "Invalid BSSID '%s'", value); goto error; } - bssid = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (bssid, eth->ether_addr_octet, ETH_ALEN); g_object_set (wireless_setting, NM_SETTING_WIRELESS_BSSID, bssid, NULL); g_byte_array_free (bssid, TRUE); diff --git a/src/settings/plugins/ifupdown/plugin.c b/src/settings/plugins/ifupdown/plugin.c index c0c509aad..2447c0e55 100644 --- a/src/settings/plugins/ifupdown/plugin.c +++ b/src/settings/plugins/ifupdown/plugin.c @@ -190,7 +190,6 @@ bind_device_to_connection (SCPluginIfupdown *self, NMSetting *s_wired = NULL; NMSetting *s_wifi = NULL; const char *iface, *address; - struct ether_addr *tmp_mac; iface = g_udev_device_get_name (device); if (!iface) { @@ -204,16 +203,13 @@ bind_device_to_connection (SCPluginIfupdown *self, return; } - tmp_mac = ether_aton (address); + mac_address = nm_utils_hwaddr_atoba (address, ARPHRD_ETHER); if (!tmp_mac) { PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s", address, iface); return; } - mac_address = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (mac_address, &(tmp_mac->ether_addr_octet[0]), ETH_ALEN); - s_wired = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRED); s_wifi = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRELESS); if (s_wired) { diff --git a/src/settings/plugins/keyfile/reader.c b/src/settings/plugins/keyfile/reader.c index 4128b9f2c..dd1868c95 100644 --- a/src/settings/plugins/keyfile/reader.c +++ b/src/settings/plugins/keyfile/reader.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -650,7 +651,6 @@ static void mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) { const char *setting_name = nm_setting_get_name (setting); - struct ether_addr *eth; char *tmp_string = NULL, *p; gint *tmp_list; GByteArray *array = NULL; @@ -668,11 +668,9 @@ mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, cons } if (i == 5) { /* parse as a MAC address */ - eth = ether_aton (tmp_string); - if (eth) { + array = nm_utils_hwaddr_atoba (tmp_string, ARPHRD_ETHER); + if (array) { g_free (tmp_string); - array = g_byte_array_sized_new (ETH_ALEN); - g_byte_array_append (array, eth->ether_addr_octet, ETH_ALEN); goto done; } } diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 2d8553a09..cf6993020 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -1434,7 +1435,7 @@ get_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_HW_ADDRESS: nm_device_wimax_get_hw_address (self, &hw_addr); - g_value_take_string (value, nm_ether_ntop (&hw_addr)); + g_value_take_string (value, nm_utils_hwaddr_ntoa (&hw_addr, ARPHRD_ETHER)); break; case PROP_ACTIVE_NSP: if (priv->current_nsp)