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_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;

View file

@ -25,11 +25,14 @@
*/
#include "config.h"
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <arpa/inet.h>
#include <netinet/ether.h>
#include <linux/if_infiniband.h>
#include <glib.h>
#include <glib-object.h>
@ -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);
}

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);
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 */

View file

@ -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)
{

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);
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);

View file

@ -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));

View file

@ -31,6 +31,7 @@
#include <netinet/in.h>
#include <string.h>
#include <net/ethernet.h>
#include <netinet/ether.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <signal.h>
@ -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)

View file

@ -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));

View file

@ -21,6 +21,7 @@
#include <string.h>
#include <stdlib.h>
#include <netinet/ether.h>
#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);

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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) {

View file

@ -34,6 +34,7 @@
#include <nm-setting-wireless.h>
#include <nm-setting-bluetooth.h>
#include <nm-setting-8021x.h>
#include <nm-utils.h>
#include <arpa/inet.h>
#include <netinet/ether.h>
#include <string.h>
@ -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;
}
}

View file

@ -25,6 +25,7 @@
#include <net/ethernet.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <netinet/ether.h>
#include <WiMaxAPI.h>
#include <WiMaxAPIEx.h>
@ -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)