1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
3
* Copyright (C) 2011 Richard Hughes <richard@hughsie.com>
5
* Licensed under the GNU General Public License Version 2
7
* This program is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU General Public License as published by
9
* the Free Software Foundation; either version 2 of the License, or
10
* (at your option) any later version.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
#include <glib-object.h>
25
#include <glib/gi18n.h>
26
#include <arpa/inet.h>
27
#include <netinet/ether.h>
29
#include <nm-device-ethernet.h>
30
#include <nm-device-modem.h>
31
#include <nm-device-wifi.h>
32
#include <nm-device-wimax.h>
33
#include <nm-device-infiniband.h>
36
#include "net-device.h"
38
#define NET_DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NET_TYPE_DEVICE, NetDevicePrivate))
40
struct _NetDevicePrivate
52
G_DEFINE_TYPE (NetDevice, net_device, NET_TYPE_OBJECT)
54
/* return value must be freed by caller with g_free() */
56
get_mac_address_of_connection (NMConnection *connection)
61
const GByteArray *mac = NULL;
63
/* check the connection type */
64
if (nm_connection_is_type (connection,
65
NM_SETTING_WIRELESS_SETTING_NAME)) {
66
/* check wireless settings */
67
NMSettingWireless *s_wireless = nm_connection_get_setting_wireless (connection);
70
mac = nm_setting_wireless_get_mac_address (s_wireless);
72
return nm_utils_hwaddr_ntoa (mac->data, ARPHRD_ETHER);
73
} else if (nm_connection_is_type (connection,
74
NM_SETTING_WIRED_SETTING_NAME)) {
75
/* check wired settings */
76
NMSettingWired *s_wired = nm_connection_get_setting_wired (connection);
79
mac = nm_setting_wired_get_mac_address (s_wired);
81
return nm_utils_hwaddr_ntoa (mac->data, ARPHRD_ETHER);
82
} else if (nm_connection_is_type (connection,
83
NM_SETTING_WIMAX_SETTING_NAME)) {
84
/* check wimax settings */
85
NMSettingWimax *s_wimax = nm_connection_get_setting_wimax (connection);
88
mac = nm_setting_wimax_get_mac_address (s_wimax);
90
return nm_utils_hwaddr_ntoa (mac->data, ARPHRD_ETHER);
91
} else if (nm_connection_is_type (connection,
92
NM_SETTING_INFINIBAND_SETTING_NAME)) {
93
/* check infiniband settings */
94
NMSettingInfiniband *s_infiniband = \
95
nm_connection_get_setting_infiniband (connection);
98
mac = nm_setting_infiniband_get_mac_address (s_infiniband);
100
return nm_utils_hwaddr_ntoa (mac->data,
103
/* no MAC address found */
107
/* return value must not be freed! */
109
get_mac_address_of_device (NMDevice *device)
111
const gchar *mac = NULL;
112
switch (nm_device_get_device_type (device)) {
113
case NM_DEVICE_TYPE_WIFI:
115
NMDeviceWifi *device_wifi = NM_DEVICE_WIFI (device);
116
mac = nm_device_wifi_get_hw_address (device_wifi);
119
case NM_DEVICE_TYPE_ETHERNET:
121
NMDeviceEthernet *device_ethernet = NM_DEVICE_ETHERNET (device);
122
mac = nm_device_ethernet_get_hw_address (device_ethernet);
125
case NM_DEVICE_TYPE_WIMAX:
127
NMDeviceWimax *device_wimax = NM_DEVICE_WIMAX (device);
128
mac = nm_device_wimax_get_hw_address (device_wimax);
131
case NM_DEVICE_TYPE_INFINIBAND:
133
NMDeviceInfiniband *device_infiniband = \
134
NM_DEVICE_INFINIBAND (device);
135
mac = nm_device_infiniband_get_hw_address (device_infiniband);
141
/* no MAC address found */
145
/* returns TRUE if both MACs are equal */
147
compare_mac_device_with_mac_connection (NMDevice *device,
148
NMConnection *connection)
150
const gchar *mac_dev = NULL;
151
gchar *mac_conn = NULL;
153
mac_dev = get_mac_address_of_device (device);
154
if (mac_dev != NULL) {
155
mac_conn = get_mac_address_of_connection (connection);
157
/* compare both MACs */
158
if (g_strcmp0 (mac_dev, mac_conn) == 0) {
169
valid_connections_for_device (NMRemoteSettings *remote_settings,
172
GSList *all, *filtered, *iterator, *valid;
173
NMConnection *connection;
174
NMSettingConnection *s_con;
176
all = nm_remote_settings_list_connections (remote_settings);
177
filtered = nm_device_filter_connections (device->priv->nm_device, all);
181
for (iterator = filtered; iterator; iterator = iterator->next) {
182
connection = iterator->data;
183
s_con = nm_connection_get_setting_connection (connection);
187
if (nm_setting_connection_get_master (s_con))
190
valid = g_slist_prepend (valid, connection);
192
g_slist_free (filtered);
194
return g_slist_reverse (valid);
198
net_device_get_find_connection (NetDevice *device)
200
GSList *list, *iterator;
201
NMConnection *connection = NULL;
202
NMActiveConnection *ac;
203
NMRemoteSettings *remote_settings;
205
/* is the device available in a active connection? */
206
remote_settings = net_object_get_remote_settings (NET_OBJECT (device));
207
ac = nm_device_get_active_connection (device->priv->nm_device);
209
return (NMConnection*)nm_remote_settings_get_connection_by_path (remote_settings,
210
nm_active_connection_get_connection (ac));
213
/* not found in active connections - check all available connections */
214
list = valid_connections_for_device (remote_settings, device);
216
/* if list has only one connection, use this connection */
217
if (g_slist_length (list) == 1) {
218
connection = list->data;
222
/* is there connection with the MAC address of the device? */
223
for (iterator = list; iterator; iterator = iterator->next) {
224
connection = iterator->data;
225
if (compare_mac_device_with_mac_connection (device->priv->nm_device,
232
/* no connection found for the given device */
240
state_changed_cb (NMDevice *device,
241
NMDeviceState new_state,
242
NMDeviceState old_state,
243
NMDeviceStateReason reason,
244
NetDevice *net_device)
246
net_object_emit_changed (NET_OBJECT (net_device));
247
net_object_refresh (NET_OBJECT (net_device));
251
net_device_get_nm_device (NetDevice *device)
253
return device->priv->nm_device;
257
net_device_edit (NetObject *object)
261
GError *error = NULL;
262
NetDevice *device = NET_DEVICE (object);
263
NMConnection *connection;
265
connection = net_device_get_find_connection (device);
266
uuid = nm_connection_get_uuid (connection);
267
cmdline = g_strdup_printf ("nm-connection-editor --edit %s", uuid);
268
g_debug ("Launching '%s'\n", cmdline);
269
if (!g_spawn_command_line_async (cmdline, &error)) {
270
g_warning ("Failed to launch nm-connection-editor: %s", error->message);
271
g_error_free (error);
277
* net_device_get_property:
280
net_device_get_property (GObject *device_,
285
NetDevice *net_device = NET_DEVICE (device_);
286
NetDevicePrivate *priv = net_device->priv;
290
g_value_set_object (value, priv->nm_device);
293
G_OBJECT_WARN_INVALID_PROPERTY_ID (net_device, prop_id, pspec);
299
* net_device_set_property:
302
net_device_set_property (GObject *device_,
307
NetDevice *net_device = NET_DEVICE (device_);
308
NetDevicePrivate *priv = net_device->priv;
312
if (priv->changed_id != 0) {
313
g_signal_handler_disconnect (priv->nm_device,
316
priv->nm_device = g_value_dup_object (value);
317
priv->changed_id = g_signal_connect (priv->nm_device,
319
G_CALLBACK (state_changed_cb),
323
G_OBJECT_WARN_INVALID_PROPERTY_ID (net_device, prop_id, pspec);
329
net_device_finalize (GObject *object)
331
NetDevice *device = NET_DEVICE (object);
332
NetDevicePrivate *priv = device->priv;
334
if (priv->changed_id != 0) {
335
g_signal_handler_disconnect (priv->nm_device,
338
if (priv->nm_device != NULL)
339
g_object_unref (priv->nm_device);
341
G_OBJECT_CLASS (net_device_parent_class)->finalize (object);
345
net_device_class_init (NetDeviceClass *klass)
348
GObjectClass *object_class = G_OBJECT_CLASS (klass);
349
NetObjectClass *parent_class = NET_OBJECT_CLASS (klass);
351
object_class->finalize = net_device_finalize;
352
object_class->get_property = net_device_get_property;
353
object_class->set_property = net_device_set_property;
354
parent_class->edit = net_device_edit;
356
pspec = g_param_spec_object ("nm-device", NULL, NULL,
358
G_PARAM_READWRITE | G_PARAM_CONSTRUCT);
359
g_object_class_install_property (object_class, PROP_DEVICE, pspec);
361
g_type_class_add_private (klass, sizeof (NetDevicePrivate));
365
net_device_init (NetDevice *device)
367
device->priv = NET_DEVICE_GET_PRIVATE (device);
371
net_device_new (void)
374
device = g_object_new (NET_TYPE_DEVICE,
377
return NET_DEVICE (device);