|
Packit Service |
a1bd4f |
/* SPDX-License-Identifier: GPL-2.0+ */
|
|
Packit |
5756e2 |
/*
|
|
Packit |
5756e2 |
* Copyright (C) 2013 Red Hat, Inc.
|
|
Packit |
5756e2 |
*/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/**
|
|
Packit |
5756e2 |
* SECTION:nmt-mac-entry
|
|
Packit |
5756e2 |
* @short_description: #NmtNewtEntry for hardware address entry
|
|
Packit |
5756e2 |
*
|
|
Packit |
5756e2 |
* #NmtMacEntry is an #NmtNewtEntry for entering hardware addresses.
|
|
Packit |
5756e2 |
* It will only allow typing characters that are valid in a hardware
|
|
Packit |
5756e2 |
* address, and will set its #NmtNewtWidget:valid property depending
|
|
Packit |
5756e2 |
* on whether it currently contains a valid hardware address.
|
|
Packit |
5756e2 |
*/
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nm-default.h"
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
#include "nmt-mac-entry.h"
|
|
Packit |
5756e2 |
|
|
Packit Service |
d0b836 |
#include <linux/if_ether.h>
|
|
Packit Service |
d0b836 |
#include <linux/if_infiniband.h>
|
|
Packit Service |
d0b836 |
|
|
Packit |
5756e2 |
#include "nm-libnm-core-intern/nm-common-macros.h"
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
G_DEFINE_TYPE(NmtMacEntry, nmt_mac_entry, NMT_TYPE_NEWT_ENTRY)
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
#define NMT_MAC_ENTRY_GET_PRIVATE(o) \
|
|
Packit Service |
a1bd4f |
(G_TYPE_INSTANCE_GET_PRIVATE((o), NMT_TYPE_MAC_ENTRY, NmtMacEntryPrivate))
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
typedef struct {
|
|
Packit Service |
a1bd4f |
int mac_length;
|
|
Packit Service |
a1bd4f |
int mac_str_length;
|
|
Packit Service |
a1bd4f |
NmtMacEntryType entry_type;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
} NmtMacEntryPrivate;
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
enum {
|
|
Packit Service |
a1bd4f |
PROP_0,
|
|
Packit Service |
a1bd4f |
PROP_MAC_LENGTH,
|
|
Packit Service |
a1bd4f |
PROP_MAC_ADDRESS,
|
|
Packit Service |
a1bd4f |
PROP_ENTRY_TYPE,
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
LAST_PROP
|
|
Packit |
5756e2 |
};
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
/**
|
|
Packit |
5756e2 |
* nmt_mac_entry_new:
|
|
Packit |
5756e2 |
* @width: the width in characters of the entry
|
|
Packit |
5756e2 |
* @mac_length: the length in bytes of the hardware address
|
|
Packit |
5756e2 |
* (either %ETH_ALEN or %INFINIBAND_ALEN)
|
|
Packit |
5756e2 |
* @entry_type: the type of the entry.
|
|
Packit |
5756e2 |
*
|
|
Packit |
5756e2 |
* Creates a new #NmtMacEntry.
|
|
Packit |
5756e2 |
*
|
|
Packit |
5756e2 |
* Returns: a new #NmtMacEntry.
|
|
Packit |
5756e2 |
*/
|
|
Packit |
5756e2 |
NmtNewtWidget *
|
|
Packit Service |
a1bd4f |
nmt_mac_entry_new(int width, int mac_length, NmtMacEntryType entry_type)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
return g_object_new(NMT_TYPE_MAC_ENTRY,
|
|
Packit Service |
a1bd4f |
"width",
|
|
Packit Service |
a1bd4f |
width,
|
|
Packit Service |
a1bd4f |
"mac-length",
|
|
Packit Service |
a1bd4f |
mac_length,
|
|
Packit Service |
a1bd4f |
"entry-type",
|
|
Packit Service |
a1bd4f |
(int) entry_type,
|
|
Packit Service |
a1bd4f |
NULL);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static gboolean
|
|
Packit Service |
a1bd4f |
mac_filter(NmtNewtEntry *entry, const char *text, int ch, int position, gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE(entry);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (priv->entry_type != NMT_MAC_ENTRY_TYPE_MAC)
|
|
Packit Service |
a1bd4f |
return TRUE;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (position >= priv->mac_str_length)
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
return g_ascii_isxdigit(ch) || ch == ':';
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static gboolean
|
|
Packit Service |
a1bd4f |
mac_validator(NmtNewtEntry *entry, const char *text, gpointer user_data)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE(entry);
|
|
Packit Service |
a1bd4f |
const char * p;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!*text)
|
|
Packit Service |
a1bd4f |
return TRUE;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (priv->entry_type == NMT_MAC_ENTRY_TYPE_CLONED) {
|
|
Packit Service |
a1bd4f |
if (NM_CLONED_MAC_IS_SPECIAL(text))
|
|
Packit Service |
a1bd4f |
return TRUE;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
p = text;
|
|
Packit Service |
a1bd4f |
while (g_ascii_isxdigit(p[0]) && g_ascii_isxdigit(p[1]) && p[2] == ':')
|
|
Packit Service |
a1bd4f |
p += 3;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!g_ascii_isxdigit(p[0]) || !g_ascii_isxdigit(p[1]))
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit Service |
a1bd4f |
p += 2;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (!*p)
|
|
Packit Service |
a1bd4f |
return (p - text == priv->mac_str_length);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
if (g_ascii_isxdigit(p[0]) && !p[1] && p - text < priv->mac_str_length) {
|
|
Packit Service |
a1bd4f |
char *fixed = g_strdup_printf("%.*s:%c", (int) (p - text), text, *p);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
nmt_newt_entry_set_text(entry, fixed);
|
|
Packit Service |
a1bd4f |
g_free(fixed);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* FIXME: NmtNewtEntry doesn't correctly deal with us calling set_text()
|
|
Packit Service |
a1bd4f |
* from inside the validator.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
nmt_newt_widget_needs_rebuild(NMT_NEWT_WIDGET(entry));
|
|
Packit Service |
a1bd4f |
}
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
return FALSE;
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
nmt_mac_entry_init(NmtMacEntry *entry)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
nmt_newt_entry_set_filter(NMT_NEWT_ENTRY(entry), mac_filter, NULL);
|
|
Packit Service |
a1bd4f |
nmt_newt_entry_set_validator(NMT_NEWT_ENTRY(entry), mac_validator, NULL);
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
nmt_mac_entry_notify(GObject *object, GParamSpec *pspec)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
if (G_OBJECT_CLASS(nmt_mac_entry_parent_class)->notify)
|
|
Packit Service |
a1bd4f |
G_OBJECT_CLASS(nmt_mac_entry_parent_class)->notify(object, pspec);
|
|
Packit |
5756e2 |
|
|
Packit Service |
a1bd4f |
if (pspec->owner_type == NMT_TYPE_NEWT_ENTRY && !strcmp(pspec->name, "text"))
|
|
Packit Service |
a1bd4f |
g_object_notify(object, "mac-address");
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
nmt_mac_entry_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE(object);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
switch (prop_id) {
|
|
Packit Service |
a1bd4f |
case PROP_MAC_LENGTH:
|
|
Packit Service |
a1bd4f |
priv->mac_length = g_value_get_int(value);
|
|
Packit Service |
a1bd4f |
priv->mac_str_length = priv->mac_length * 3 - 1;
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case PROP_MAC_ADDRESS:
|
|
Packit Service |
a1bd4f |
nmt_newt_entry_set_text(NMT_NEWT_ENTRY(object), g_value_get_string(value));
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case PROP_ENTRY_TYPE:
|
|
Packit Service |
a1bd4f |
/* construct-only */
|
|
Packit Service |
a1bd4f |
priv->entry_type = g_value_get_int(value);
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
default:
|
|
Packit Service |
a1bd4f |
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
nmt_mac_entry_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
NmtMacEntryPrivate *priv = NMT_MAC_ENTRY_GET_PRIVATE(object);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
switch (prop_id) {
|
|
Packit Service |
a1bd4f |
case PROP_MAC_LENGTH:
|
|
Packit Service |
a1bd4f |
g_value_set_int(value, priv->mac_length);
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case PROP_MAC_ADDRESS:
|
|
Packit Service |
a1bd4f |
g_value_set_string(value,
|
|
Packit Service |
a1bd4f |
nm_str_not_empty(nmt_newt_entry_get_text(NMT_NEWT_ENTRY(object))));
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
case PROP_ENTRY_TYPE:
|
|
Packit Service |
a1bd4f |
g_value_set_int(value, priv->entry_type);
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
default:
|
|
Packit Service |
a1bd4f |
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
|
Packit Service |
a1bd4f |
break;
|
|
Packit Service |
a1bd4f |
}
|
|
Packit |
5756e2 |
}
|
|
Packit |
5756e2 |
|
|
Packit |
5756e2 |
static void
|
|
Packit Service |
a1bd4f |
nmt_mac_entry_class_init(NmtMacEntryClass *entry_class)
|
|
Packit |
5756e2 |
{
|
|
Packit Service |
a1bd4f |
GObjectClass *object_class = G_OBJECT_CLASS(entry_class);
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
g_type_class_add_private(entry_class, sizeof(NmtMacEntryPrivate));
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/* virtual methods */
|
|
Packit Service |
a1bd4f |
object_class->notify = nmt_mac_entry_notify;
|
|
Packit Service |
a1bd4f |
object_class->set_property = nmt_mac_entry_set_property;
|
|
Packit Service |
a1bd4f |
object_class->get_property = nmt_mac_entry_get_property;
|
|
Packit Service |
a1bd4f |
|
|
Packit Service |
a1bd4f |
/**
|
|
Packit Service |
a1bd4f |
* NmtMacEntry:mac-length:
|
|
Packit Service |
a1bd4f |
*
|
|
Packit Service |
a1bd4f |
* The length in bytes of the hardware address type the entry
|
|
Packit Service |
a1bd4f |
* accepts: either %ETH_ALEN or %INFINIBAND_ALEN.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
g_object_class_install_property(object_class,
|
|
Packit Service |
a1bd4f |
PROP_MAC_LENGTH,
|
|
Packit Service |
a1bd4f |
g_param_spec_int("mac-length",
|
|
Packit Service |
a1bd4f |
"",
|
|
Packit Service |
a1bd4f |
"",
|
|
Packit Service |
a1bd4f |
0,
|
|
Packit Service |
a1bd4f |
INFINIBAND_ALEN,
|
|
Packit Service |
a1bd4f |
ETH_ALEN,
|
|
Packit Service |
a1bd4f |
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
|
Packit Service |
a1bd4f |
/**
|
|
Packit Service |
a1bd4f |
* NmtMacEntry:mac-address:
|
|
Packit Service |
a1bd4f |
*
|
|
Packit Service |
a1bd4f |
* The MAC address, as a string (as with the various #NMSetting
|
|
Packit Service |
a1bd4f |
* "mac-address" properties).
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
g_object_class_install_property(
|
|
Packit Service |
a1bd4f |
object_class,
|
|
Packit Service |
a1bd4f |
PROP_MAC_ADDRESS,
|
|
Packit Service |
a1bd4f |
g_param_spec_string("mac-address",
|
|
Packit Service |
a1bd4f |
"",
|
|
Packit Service |
a1bd4f |
"",
|
|
Packit Service |
a1bd4f |
NULL,
|
|
Packit Service |
a1bd4f |
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
|
|
Packit Service |
a1bd4f |
/**
|
|
Packit Service |
a1bd4f |
* NmtMacEntry:entry-type:
|
|
Packit Service |
a1bd4f |
*
|
|
Packit Service |
a1bd4f |
* The type of the #NmtMacEntry. Can be either used for plain
|
|
Packit Service |
a1bd4f |
* MAC addresses or for the extended format for cloned MAC addresses.
|
|
Packit Service |
a1bd4f |
*/
|
|
Packit Service |
a1bd4f |
g_object_class_install_property(
|
|
Packit Service |
a1bd4f |
object_class,
|
|
Packit Service |
a1bd4f |
PROP_ENTRY_TYPE,
|
|
Packit Service |
a1bd4f |
g_param_spec_int("entry-type",
|
|
Packit Service |
a1bd4f |
"",
|
|
Packit Service |
a1bd4f |
"",
|
|
Packit Service |
a1bd4f |
NMT_MAC_ENTRY_TYPE_MAC,
|
|
Packit Service |
a1bd4f |
NMT_MAC_ENTRY_TYPE_CLONED,
|
|
Packit Service |
a1bd4f |
NMT_MAC_ENTRY_TYPE_MAC,
|
|
Packit Service |
a1bd4f |
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
|
|
Packit |
5756e2 |
}
|