libnm-util: add ether_ntoa/ether_aton-like utility methods

nm_utils_hwaddr_ntoa() and nm_utils_hwaddr_aton() are like
ether_ntoa()/ether_aton(), but handle IPoIB too.

nm_utils_hwaddr_atoba() is like _aton() but returns a GByteArray,
since that's what's wanted in many places.

Also remove nm_ether_ntop() and replace uses of it with
nm_utils_hwaddr_ntoa().
This commit is contained in:
Dan Winship
2011-10-10 16:00:28 -04:00
committed by Dan Williams
parent 3dcfd305d6
commit 2510c617ec
15 changed files with 162 additions and 58 deletions

View File

@@ -439,6 +439,10 @@ global:
nm_utils_deinit; nm_utils_deinit;
nm_utils_escape_ssid; nm_utils_escape_ssid;
nm_utils_gvalue_hash_dup; 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_init;
nm_utils_ip4_addresses_from_gvalue; nm_utils_ip4_addresses_from_gvalue;
nm_utils_ip4_addresses_to_gvalue; nm_utils_ip4_addresses_to_gvalue;

View File

@@ -25,11 +25,14 @@
*/ */
#include "config.h" #include "config.h"
#include <ctype.h>
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/ether.h>
#include <linux/if_infiniband.h>
#include <glib.h> #include <glib.h>
#include <glib-object.h> #include <glib-object.h>
@@ -2386,3 +2389,114 @@ nm_utils_wifi_is_channel_valid (guint32 channel, const char *band)
return FALSE; 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);
}

View File

@@ -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); 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); 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 G_END_DECLS
#endif /* NM_UTILS_H */ #endif /* NM_UTILS_H */

View File

@@ -159,18 +159,6 @@ nm_utils_ip4_prefix_to_netmask (guint32 prefix)
return (guint32) htonl (netmask); 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 void
nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting) nm_utils_merge_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting)
{ {

View File

@@ -37,8 +37,6 @@ gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr);
int nm_spawn_process (const char *args); 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_ip4_config (NMIP4Config *ip4_config, NMSettingIP4Config *setting);
void nm_utils_merge_ip6_config (NMIP6Config *ip6_config, NMSettingIP6Config *setting); void nm_utils_merge_ip6_config (NMIP6Config *ip6_config, NMSettingIP6Config *setting);

View File

@@ -61,6 +61,7 @@
#include "nm-properties-changed-signal.h" #include "nm-properties-changed-signal.h"
#include "nm-dhcp-manager.h" #include "nm-dhcp-manager.h"
#include "nm-netlink-utils.h" #include "nm-netlink-utils.h"
#include "nm-utils.h"
#include "nm-device-ethernet-glue.h" #include "nm-device-ethernet-glue.h"
@@ -1761,7 +1762,7 @@ spec_match_list (NMDevice *device, const GSList *specs)
char *hwaddr; char *hwaddr;
gboolean matched; 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); matched = nm_match_spec_hwaddr (specs, hwaddr);
g_free (hwaddr); g_free (hwaddr);
@@ -1947,10 +1948,10 @@ get_property (GObject *object, guint prop_id,
switch (prop_id) { switch (prop_id) {
case PROP_HW_ADDRESS: 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; break;
case PROP_PERM_HW_ADDRESS: 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; break;
case PROP_SPEED: case PROP_SPEED:
g_value_set_uint (value, nm_device_ethernet_get_speed (self)); g_value_set_uint (value, nm_device_ethernet_get_speed (self));

View File

@@ -31,6 +31,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <string.h> #include <string.h>
#include <net/ethernet.h> #include <net/ethernet.h>
#include <netinet/ether.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <signal.h> #include <signal.h>
@@ -492,7 +493,7 @@ get_property (GObject *object, guint prop_id,
switch (prop_id) { switch (prop_id) {
case PROP_HW_ADDRESS: case PROP_HW_ADDRESS:
nm_device_olpc_mesh_get_address (device, &hw_addr); 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; break;
case PROP_COMPANION: case PROP_COMPANION:
if (priv->companion) if (priv->companion)

View File

@@ -732,13 +732,13 @@ periodic_update (NMDeviceWifi *self)
if (new_ap) { if (new_ap) {
new_bssid = nm_ap_get_address (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); new_ssid = nm_ap_get_ssid (new_ap);
} }
if (priv->current_ap) { if (priv->current_ap) {
old_bssid = nm_ap_get_address (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); old_ssid = nm_ap_get_ssid (priv->current_ap);
} }
@@ -2963,7 +2963,7 @@ spec_match_list (NMDevice *device, const GSList *specs)
char *hwaddr; char *hwaddr;
gboolean matched; 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); matched = nm_match_spec_hwaddr (specs, hwaddr);
g_free (hwaddr); g_free (hwaddr);
@@ -3196,10 +3196,10 @@ get_property (GObject *object, guint prop_id,
switch (prop_id) { switch (prop_id) {
case PROP_HW_ADDRESS: 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; break;
case PROP_PERM_HW_ADDRESS: 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; break;
case PROP_MODE: case PROP_MODE:
g_value_set_uint (value, wifi_utils_get_mode (priv->wifi_data)); g_value_set_uint (value, wifi_utils_get_mode (priv->wifi_data));

View File

@@ -21,6 +21,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <netinet/ether.h>
#include "nm-wifi-ap.h" #include "nm-wifi-ap.h"
#include "nm-wifi-ap-utils.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); g_value_set_uint (value, priv->freq);
break; break;
case PROP_HW_ADDRESS: 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; break;
case PROP_MODE: case PROP_MODE:
g_value_set_uint (value, priv->mode); g_value_set_uint (value, priv->mode);

View File

@@ -1576,7 +1576,7 @@ nm_settings_connection_add_seen_bssid (NMSettingsConnection *connection,
return; /* Already in the list */ return; /* Already in the list */
/* Add the new BSSID; let the hash take ownership of the allocated BSSID string */ /* 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_return_if_fail (bssid_str != NULL);
g_hash_table_insert (priv->seen_bssids, mac_dup (seen_bssid), bssid_str); g_hash_table_insert (priv->seen_bssids, mac_dup (seen_bssid), bssid_str);

View File

@@ -206,7 +206,6 @@ static gboolean
read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError **error) read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError **error)
{ {
char *value = NULL; char *value = NULL;
struct ether_addr *mac;
g_return_val_if_fail (ifcfg != NULL, FALSE); g_return_val_if_fail (ifcfg != NULL, FALSE);
g_return_val_if_fail (array != 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; return TRUE;
} }
mac = ether_aton (value); *array = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER);
if (!mac) { if (!*array) {
g_set_error (error, IFCFG_PLUGIN_ERROR, 0, g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
"%s: the MAC address '%s' was invalid.", key, value); "%s: the MAC address '%s' was invalid.", key, value);
g_free (value); g_free (value);
@@ -229,8 +228,6 @@ read_mac_address (shvarFile *ifcfg, const char *key, GByteArray **array, GError
} }
g_free (value); 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; return TRUE;
} }
@@ -2947,19 +2944,16 @@ make_wireless_setting (shvarFile *ifcfg,
value = svGetValue (ifcfg, "BSSID", FALSE); value = svGetValue (ifcfg, "BSSID", FALSE);
if (value) { if (value) {
struct ether_addr *eth;
GByteArray *bssid; GByteArray *bssid;
eth = ether_aton (value); bssid = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER);
if (!eth) { if (!bssid) {
g_set_error (error, IFCFG_PLUGIN_ERROR, 0, g_set_error (error, IFCFG_PLUGIN_ERROR, 0,
"Invalid BSSID '%s'", value); "Invalid BSSID '%s'", value);
g_free (value); g_free (value);
goto error; 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_object_set (s_wireless, NM_SETTING_WIRELESS_BSSID, bssid, NULL);
g_byte_array_free (bssid, TRUE); g_byte_array_free (bssid, TRUE);
g_free (value); g_free (value);

View File

@@ -509,20 +509,17 @@ static gboolean
read_mac_address (const char *conn_name, GByteArray **array, GError **error) read_mac_address (const char *conn_name, GByteArray **array, GError **error)
{ {
const char *value = ifnet_get_data (conn_name, "mac"); const char *value = ifnet_get_data (conn_name, "mac");
struct ether_addr *mac;
if (!value || !strlen (value)) if (!value || !strlen (value))
return TRUE; return TRUE;
mac = ether_aton (value); *array = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER);
if (!mac) { if (!*array) {
g_set_error (error, ifnet_plugin_error_quark (), 0, 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; return FALSE;
} }
*array = g_byte_array_sized_new (ETH_ALEN);
g_byte_array_append (*array, (guint8 *) mac->ether_addr_octet, ETH_ALEN);
return TRUE; return TRUE;
} }
@@ -1012,18 +1009,15 @@ make_wireless_connection_setting (const char *conn_name,
/* BSSID setting */ /* BSSID setting */
value = wpa_get_value (conn_name, "bssid"); value = wpa_get_value (conn_name, "bssid");
if (value) { if (value) {
struct ether_addr *eth;
GByteArray *bssid; GByteArray *bssid;
eth = ether_aton (value); bssid = nm_utils_hwaddr_atoba (value, ARPHRD_ETHER);
if (!eth) { if (!bssid) {
g_set_error (error, ifnet_plugin_error_quark (), 0, g_set_error (error, ifnet_plugin_error_quark (), 0,
"Invalid BSSID '%s'", value); "Invalid BSSID '%s'", value);
goto error; 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, g_object_set (wireless_setting, NM_SETTING_WIRELESS_BSSID,
bssid, NULL); bssid, NULL);
g_byte_array_free (bssid, TRUE); g_byte_array_free (bssid, TRUE);

View File

@@ -190,7 +190,6 @@ bind_device_to_connection (SCPluginIfupdown *self,
NMSetting *s_wired = NULL; NMSetting *s_wired = NULL;
NMSetting *s_wifi = NULL; NMSetting *s_wifi = NULL;
const char *iface, *address; const char *iface, *address;
struct ether_addr *tmp_mac;
iface = g_udev_device_get_name (device); iface = g_udev_device_get_name (device);
if (!iface) { if (!iface) {
@@ -204,16 +203,13 @@ bind_device_to_connection (SCPluginIfupdown *self,
return; return;
} }
tmp_mac = ether_aton (address); mac_address = nm_utils_hwaddr_atoba (address, ARPHRD_ETHER);
if (!tmp_mac) { if (!tmp_mac) {
PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s", PLUGIN_WARN ("SCPluginIfupdown", "failed to parse MAC address '%s' for %s",
address, iface); address, iface);
return; 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_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); s_wifi = nm_connection_get_setting (NM_CONNECTION (exported), NM_TYPE_SETTING_WIRELESS);
if (s_wired) { if (s_wired) {

View File

@@ -34,6 +34,7 @@
#include <nm-setting-wireless.h> #include <nm-setting-wireless.h>
#include <nm-setting-bluetooth.h> #include <nm-setting-bluetooth.h>
#include <nm-setting-8021x.h> #include <nm-setting-8021x.h>
#include <nm-utils.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netinet/ether.h> #include <netinet/ether.h>
#include <string.h> #include <string.h>
@@ -650,7 +651,6 @@ static void
mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path) mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, const char *keyfile_path)
{ {
const char *setting_name = nm_setting_get_name (setting); const char *setting_name = nm_setting_get_name (setting);
struct ether_addr *eth;
char *tmp_string = NULL, *p; char *tmp_string = NULL, *p;
gint *tmp_list; gint *tmp_list;
GByteArray *array = NULL; GByteArray *array = NULL;
@@ -668,11 +668,9 @@ mac_address_parser (NMSetting *setting, const char *key, GKeyFile *keyfile, cons
} }
if (i == 5) { if (i == 5) {
/* parse as a MAC address */ /* parse as a MAC address */
eth = ether_aton (tmp_string); array = nm_utils_hwaddr_atoba (tmp_string, ARPHRD_ETHER);
if (eth) { if (array) {
g_free (tmp_string); 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; goto done;
} }
} }

View File

@@ -25,6 +25,7 @@
#include <net/ethernet.h> #include <net/ethernet.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <linux/if.h> #include <linux/if.h>
#include <netinet/ether.h>
#include <WiMaxAPI.h> #include <WiMaxAPI.h>
#include <WiMaxAPIEx.h> #include <WiMaxAPIEx.h>
@@ -1434,7 +1435,7 @@ get_property (GObject *object, guint prop_id,
switch (prop_id) { switch (prop_id) {
case PROP_HW_ADDRESS: case PROP_HW_ADDRESS:
nm_device_wimax_get_hw_address (self, &hw_addr); 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; break;
case PROP_ACTIVE_NSP: case PROP_ACTIVE_NSP:
if (priv->current_nsp) if (priv->current_nsp)