Wake on LAN support. NetworkManager?
- From: Holger Macht <holger homac de>
- To: networkmanager-list gnome org
- Subject: Wake on LAN support. NetworkManager?
- Date: Wed, 27 Jun 2007 11:37:30 +0200
Hi,
I'm currently looking for a place to integrate Wake On LAN
capabilities/enablement. As a logical result, NetworkManager came to my
mind.
When talking about Wake On LAN, I'm talking about the functionality
ethtool provides, and about the network drivers which implement ethtool
support. I've already created a proof-of-concept patch. The current work
is based on NetworkManager-0.6.5, just because it's the most recent stable
release.
I've added three new D-Bus methods:
getWakeOnLanEnabled
getWakeOnLanSupported
setWakeOnLanEnabled
So this mail is not a "please commit", but rather a question if it makes
sense to integrate into NetworkManager at all. The other possibility would
be to add to HAL if it doesn't fit into the NetworkManager concept.
Comments?
- Holger
Index: include/NetworkManager.h
===================================================================
--- include/NetworkManager.h (revision 2617)
+++ include/NetworkManager.h (working copy)
@@ -89,6 +89,7 @@
#define NM_DEVICE_CAP_NM_SUPPORTED 0x00000001
#define NM_DEVICE_CAP_CARRIER_DETECT 0x00000002
#define NM_DEVICE_CAP_WIRELESS_SCAN 0x00000004
+#define NM_DEVICE_CAP_WAKE_ON_LAN 0x00000008
/* 802.11 wireless-specific device capability bits */
Index: src/nm-dbus-nm.c
===================================================================
--- src/nm-dbus-nm.c (revision 2617)
+++ src/nm-dbus-nm.c (working copy)
@@ -37,6 +37,7 @@
#include "nm-ap-security.h"
#include "nm-device-802-3-ethernet.h"
#include "nm-device-802-11-wireless.h"
+#include "nm-ethtool-wol.h"
/*
@@ -533,6 +534,109 @@
return reply;
}
+static DBusMessage *nm_dbus_nm_set_wol_enabled (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
+{
+ DBusMessage *reply = NULL;
+ DBusError err;
+ char *dev_path;
+ int enable;
+ NMDevice *dev;
+
+ g_return_val_if_fail (data && data->data && connection && message, NULL);
+
+ dbus_error_init (&err);
+
+ if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &dev_path,
+ DBUS_TYPE_BOOLEAN, &enable, DBUS_TYPE_INVALID))
+ {
+ reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "InvalidArguments",
+ "NetworkManager::setWakeOnLanEnabled called with invalid arguments.");
+ goto out;
+ }
+
+ if ((dev = nm_dbus_get_device_from_escaped_object_path (data->data, dev_path)))
+ {
+ int ret;
+
+ if (enable == 1)
+ ret = nm_ethtool_wol_enable(nm_device_get_iface (dev))
+ else
+ ret = nm_ethtool_wol_disable(nm_device_get_iface (dev));
+ if (ret < 0)
+ reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "RequestFailed",
+ "Could not enable wake on LAN.");
+ }
+ else
+ {
+ reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound",
+ "The requested network device does not exist.");
+ }
+
+out:
+ if (dbus_error_is_set (&err))
+ dbus_error_free (&err);
+
+ return (reply);
+}
+
+static DBusMessage *nm_dbus_nm_get_wol_status (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data,
+ int supported)
+{
+ DBusMessage *reply = NULL;
+ DBusError err;
+ char *dev_path;
+
+ g_return_val_if_fail (data && data->data && connection && message, NULL);
+
+ dbus_error_init (&err);
+ if (dbus_message_get_args (message, &err, DBUS_TYPE_STRING, &dev_path, DBUS_TYPE_INVALID))
+ {
+ NMDevice *dev;
+
+ if ((dev = nm_dbus_get_device_from_escaped_object_path (data->data, dev_path)))
+ {
+ int value;
+
+ if (supported) {
+ value = nm_ethtool_wol_supported (nm_device_get_iface (dev));
+ } else
+ value = nm_ethtool_wol_enabled (nm_device_get_iface (dev));
+
+ if (value < 0)
+ reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NoWakeOnLan",
+ "Could not get wake on LAN capability.");
+ else
+ if ((reply = dbus_message_new_method_return (message)))
+ dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &value, DBUS_TYPE_INVALID);
+ }
+ else
+ {
+ reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound",
+ "The requested network device does not exist.");
+ }
+ }
+ else
+ {
+ reply = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceBad",
+ "The device ID was bad.");
+ }
+
+ if (dbus_error_is_set (&err))
+ dbus_error_free (&err);
+
+ return (reply);
+}
+
+static DBusMessage *nm_dbus_nm_get_wol_enabled (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
+{
+ return nm_dbus_nm_get_wol_status (connection, message, data, 0);
+}
+
+static DBusMessage *nm_dbus_nm_get_wol_supported (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
+{
+ return nm_dbus_nm_get_wol_status (connection, message, data, 1);
+}
+
static DBusMessage *nm_dbus_nm_sleep (DBusConnection *connection, DBusMessage *message, NMDbusCBData *data)
{
NMData *app_data;
@@ -676,6 +780,9 @@
nm_dbus_method_list_add_method (list, "createWirelessNetwork", nm_dbus_nm_create_wireless_network);
nm_dbus_method_list_add_method (list, "setWirelessEnabled", nm_dbus_nm_set_wireless_enabled);
nm_dbus_method_list_add_method (list, "getWirelessEnabled", nm_dbus_nm_get_wireless_enabled);
+ nm_dbus_method_list_add_method (list, "getWakeOnLanEnabled", nm_dbus_nm_get_wol_enabled);
+ nm_dbus_method_list_add_method (list, "getWakeOnLanSupported", nm_dbus_nm_get_wol_supported);
+ nm_dbus_method_list_add_method (list, "setWakeOnLanEnabled", nm_dbus_nm_set_wol_enabled);
nm_dbus_method_list_add_method (list, "sleep", nm_dbus_nm_sleep);
nm_dbus_method_list_add_method (list, "wake", nm_dbus_nm_wake);
nm_dbus_method_list_add_method (list, "state", nm_dbus_nm_get_state);
Index: src/nm-device-802-3-ethernet.c
===================================================================
--- src/nm-device-802-3-ethernet.c (revision 2617)
+++ src/nm-device-802-3-ethernet.c (working copy)
@@ -34,6 +34,7 @@
#include "NetworkManagerPolicy.h"
#include "nm-utils.h"
#include "kernel-types.h"
+#include "nm-ethtool-wol.h"
#define NM_DEVICE_802_3_ETHERNET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_DEVICE_802_3_ETHERNET, NMDevice8023EthernetPrivate))
Index: src/nm-ethtool-wol.c
===================================================================
--- src/nm-ethtool-wol.c (revision 0)
+++ src/nm-ethtool-wol.c (revision 0)
@@ -0,0 +1,110 @@
+/*
+ * Author Holger Macht <holger homac de>
+ *
+ * Released under GPLv2
+ *
+ * Based on code from ethtool
+ */
+
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <net/if.h>
+#include <getopt.h>
+#include <linux/sockios.h>
+
+#include "nm-ethtool-wol.h"
+
+#define SIOCETHTOOL 0x8946
+#define WAKE_MAGIC (1 << 5)
+#define ETHTOOL_GWOL 0x00000005 /* Get wake-on-lan options. */
+#define ETHTOOL_SWOL 0x00000006 /* Set wake-on-lan options, priv. */
+
+#define SOPASS_MAX 6
+/* wake-on-lan settings */
+struct wolinfo {
+ int cmd;
+ int supported;
+ int wolopts;
+ int sopass[SOPASS_MAX]; /* SecureOn(tm) password */
+};
+
+static int wol_request (const char *dev, struct wolinfo *wol)
+{
+ struct ifreq ifr;
+ int fd;
+ int ret;
+
+ /* Setup our control structures. */
+ memset(&ifr, 0, sizeof(ifr));
+ strcpy(ifr.ifr_name, dev);
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ perror("Cannot get control socket");
+ return -1;
+ }
+
+ ifr.ifr_data = (caddr_t)wol;
+ if (ioctl(fd, SIOCETHTOOL, &ifr)) {
+ perror("Cannot get wake-on-lan settings");
+ ret = -1;
+ goto out;
+ }
+
+ if (wol->supported & WAKE_MAGIC)
+ ret = 1;
+ else
+ ret = 0;
+
+out:
+ close(fd);
+
+ return ret;
+}
+
+/* get one of 'supported' or 'enabled' capabilites */
+int nm_ethtool_wol_status (const char *dev, enum NM_ETHTOOL_WOL_STATUS request)
+{
+ struct wolinfo wol;
+
+ if (request != NM_ETHTOOL_WOL_SUPPORTED && request != NM_ETHTOOL_WOL_SUPPORTED)
+ return -1;
+
+ wol.cmd = ETHTOOL_GWOL;
+ if (wol_request(dev, &wol) < 0)
+ return -1;
+
+ if (request == NM_ETHTOOL_WOL_SUPPORTED && (wol.supported & WAKE_MAGIC))
+ return 1;
+ else if (request == NM_ETHTOOL_WOL_ENABLED && (wol.wolopts & WAKE_MAGIC))
+ return 1;
+ else
+ return 0;
+}
+
+/* enables or disables WOL depending on the arg enable */
+int nm_ethtool_wol_change (const char *dev, int enable)
+{
+ struct wolinfo wol;
+ int data = 0;
+
+ wol.cmd = ETHTOOL_SWOL;
+ if (enable == 1)
+ data |= WAKE_MAGIC;
+ wol.wolopts = data;
+ if (wol_request(dev, &wol) < 0) {
+ fprintf(stderr, "Cannot enable WOL\n");
+ return -1;
+ }
+
+ if (wol.wolopts & WAKE_MAGIC) {
+ return 1;
+ } else
+ return 0;
+
+ return 0;
+}
Index: src/nm-ethtool-wol.h
===================================================================
--- src/nm-ethtool-wol.h (revision 0)
+++ src/nm-ethtool-wol.h (revision 0)
@@ -0,0 +1,20 @@
+/*
+ * Author Holger Macht <holger homac de>
+ *
+ * Released under GPLv2
+ *
+ * Based on code from ethtool
+ */
+
+#ifndef NM_ETHTOOL_WOL_H
+#define NM_ETHTOOL_WOL_H
+
+enum NM_ETHTOOL_WOL_STATUS { NM_ETHTOOL_WOL_SUPPORTED, NM_ETHTOOL_WOL_ENABLED };
+
+#define nm_ethtool_wol_enable(dev) nm_ethtool_wol_change(dev,NM_ETHTOOL_WOL_SUPPORTED);
+#define nm_ethtool_wol_disable(dev) nm_ethtool_wol_change(dev,NM_ETHTOOL_WOL_ENABLED);
+
+#define nm_ethtool_wol_supported(dev) nm_ethtool_wol_status(dev,1);
+#define nm_ethtool_wol_enabled(dev) nm_ethtool_wol_status(dev,0);
+
+#endif
Index: src/Makefile.am
===================================================================
--- src/Makefile.am (revision 2617)
+++ src/Makefile.am (working copy)
@@ -29,6 +29,8 @@
NetworkManagerDbusUtils.h \
nm-dbus-nm.c \
nm-dbus-nm.h \
+ nm-ethtool-wol.c \
+ nm-ethtool-wol.h \
nm-dbus-device.c \
nm-dbus-device.h \
nm-dbus-net.c \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]