diff options
Diffstat (limited to 'src/platform/wifi')
| -rw-r--r-- | src/platform/wifi/nm-wifi-utils.c | 240 | ||||
| -rw-r--r-- | src/platform/wifi/nm-wifi-utils.h | 84 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils-nl80211.c (renamed from src/platform/wifi/nm-wifi-utils-nl80211.c) | 252 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils-nl80211.h (renamed from src/platform/wifi/nm-wifi-utils-nl80211.h) | 15 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils-private.h (renamed from src/platform/wifi/nm-wifi-utils-private.h) | 48 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils-wext.c (renamed from src/platform/wifi/nm-wifi-utils-wext.c) | 139 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils-wext.h (renamed from src/platform/wifi/nm-wifi-utils-wext.h) | 17 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils.c | 231 | ||||
| -rw-r--r-- | src/platform/wifi/wifi-utils.h | 79 |
9 files changed, 512 insertions, 593 deletions
diff --git a/src/platform/wifi/nm-wifi-utils.c b/src/platform/wifi/nm-wifi-utils.c deleted file mode 100644 index 25d71c6a..00000000 --- a/src/platform/wifi/nm-wifi-utils.c +++ /dev/null @@ -1,240 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2005 - 2018 Red Hat, Inc. - * Copyright (C) 2006 - 2008 Novell, Inc. - */ - -#include "nm-default.h" - -#include "nm-wifi-utils.h" - -#include <sys/stat.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> - -#include "nm-wifi-utils-private.h" -#include "nm-wifi-utils-nl80211.h" -#if HAVE_WEXT -#include "nm-wifi-utils-wext.h" -#endif -#include "nm-core-utils.h" - -#include "platform/nm-platform-utils.h" - -G_DEFINE_ABSTRACT_TYPE (NMWifiUtils, nm_wifi_utils, G_TYPE_OBJECT) - -/*****************************************************************************/ - -static void -nm_wifi_utils_init (NMWifiUtils *self) -{ -} - -static void -nm_wifi_utils_class_init (NMWifiUtilsClass *klass) -{ -} - -NMWifiUtils * -nm_wifi_utils_new (int ifindex, struct nl_sock *genl, gboolean check_scan) -{ - NMWifiUtils *ret; - - g_return_val_if_fail (ifindex > 0, NULL); - - ret = nm_wifi_utils_nl80211_new (ifindex, genl); - -#if HAVE_WEXT - if (ret == NULL) - ret = nm_wifi_utils_wext_new (ifindex, check_scan); -#endif - - return ret; -} - -NMDeviceWifiCapabilities -nm_wifi_utils_get_caps (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, NM_WIFI_DEVICE_CAP_NONE); - - return data->caps; -} - -NM80211Mode -nm_wifi_utils_get_mode (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, NM_802_11_MODE_UNKNOWN); - return NM_WIFI_UTILS_GET_CLASS (data)->get_mode (data); -} - -gboolean -nm_wifi_utils_set_mode (NMWifiUtils *data, const NM80211Mode mode) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail ( (mode == NM_802_11_MODE_INFRA) - || (mode == NM_802_11_MODE_AP) - || (mode == NM_802_11_MODE_ADHOC), FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - - /* nl80211 probably doesn't need this */ - return klass->set_mode ? klass->set_mode (data, mode) : TRUE; -} - -gboolean -nm_wifi_utils_set_powersave (NMWifiUtils *data, guint32 powersave) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - return klass->set_powersave ? klass->set_powersave (data, powersave) : TRUE; -} - -NMSettingWirelessWakeOnWLan -nm_wifi_utils_get_wake_on_wlan (NMWifiUtils *data) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - - return klass->get_wake_on_wlan ? klass->get_wake_on_wlan (data) : NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; -} - -gboolean -nm_wifi_utils_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - return klass->set_wake_on_wlan ? klass->set_wake_on_wlan (data, wowl) : FALSE; -} - -guint32 -nm_wifi_utils_get_freq (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->get_freq (data); -} - -guint32 -nm_wifi_utils_find_freq (NMWifiUtils *data, const guint32 *freqs) -{ - g_return_val_if_fail (data != NULL, 0); - g_return_val_if_fail (freqs != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->find_freq (data, freqs); -} - -gboolean -nm_wifi_utils_get_bssid (NMWifiUtils *data, guint8 *out_bssid) -{ - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (out_bssid != NULL, FALSE); - - memset (out_bssid, 0, ETH_ALEN); - return NM_WIFI_UTILS_GET_CLASS (data)->get_bssid (data, out_bssid); -} - -guint32 -nm_wifi_utils_get_rate (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->get_rate (data); -} - -int -nm_wifi_utils_get_qual (NMWifiUtils *data) -{ - g_return_val_if_fail (data != NULL, 0); - return NM_WIFI_UTILS_GET_CLASS (data)->get_qual (data); -} - -gboolean -nm_wifi_utils_is_wifi (int dirfd, const char *ifname) -{ - g_return_val_if_fail (dirfd >= 0, FALSE); - - if (faccessat (dirfd, "phy80211", F_OK, 0) == 0) - return TRUE; -#if HAVE_WEXT - if (nm_wifi_utils_wext_is_wifi (ifname)) - return TRUE; -#endif - return FALSE; -} - -/* OLPC Mesh-only functions */ - -guint32 -nm_wifi_utils_get_mesh_channel (NMWifiUtils *data) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - g_return_val_if_fail (klass->get_mesh_channel != NULL, FALSE); - - return klass->get_mesh_channel (data); -} - -gboolean -nm_wifi_utils_set_mesh_channel (NMWifiUtils *data, guint32 channel) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - g_return_val_if_fail (channel <= 13, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - g_return_val_if_fail (klass->set_mesh_channel != NULL, FALSE); - - return klass->set_mesh_channel (data, channel); -} - -gboolean -nm_wifi_utils_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - g_return_val_if_fail (klass->set_mesh_ssid != NULL, FALSE); - - return klass->set_mesh_ssid (data, ssid, len); -} - -gboolean -nm_wifi_utils_indicate_addressing_running (NMWifiUtils *data, gboolean running) -{ - NMWifiUtilsClass *klass; - - g_return_val_if_fail (data != NULL, FALSE); - - klass = NM_WIFI_UTILS_GET_CLASS (data); - return klass->indicate_addressing_running ? klass->indicate_addressing_running (data, running) : FALSE; -} diff --git a/src/platform/wifi/nm-wifi-utils.h b/src/platform/wifi/nm-wifi-utils.h deleted file mode 100644 index 6cd178bd..00000000 --- a/src/platform/wifi/nm-wifi-utils.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* NetworkManager -- Network link manager - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2005 - 2018 Red Hat, Inc. - * Copyright (C) 2006 - 2008 Novell, Inc. - */ - -#ifndef __WIFI_UTILS_H__ -#define __WIFI_UTILS_H__ - -#include <net/ethernet.h> - -#include "nm-dbus-interface.h" -#include "nm-setting-wireless.h" -#include "platform/nm-netlink.h" - -typedef struct NMWifiUtils NMWifiUtils; - -#define NM_TYPE_WIFI_UTILS (nm_wifi_utils_get_type ()) -#define NM_WIFI_UTILS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_UTILS, NMWifiUtils)) -#define NM_WIFI_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_UTILS, NMWifiUtilsClass)) -#define NM_IS_WIFI_UTILS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_UTILS)) -#define NM_IS_WIFI_UTILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_UTILS)) -#define NM_WIFI_UTILS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_UTILS, NMWifiUtilsClass)) - -GType nm_wifi_utils_get_type (void); - -gboolean nm_wifi_utils_is_wifi (int dirfd, const char *ifname); - -NMWifiUtils *nm_wifi_utils_new (int ifindex, struct nl_sock *genl, gboolean check_scan); - -NMDeviceWifiCapabilities nm_wifi_utils_get_caps (NMWifiUtils *data); - -NM80211Mode nm_wifi_utils_get_mode (NMWifiUtils *data); - -gboolean nm_wifi_utils_set_mode (NMWifiUtils *data, const NM80211Mode mode); - -/* Returns frequency in MHz */ -guint32 nm_wifi_utils_get_freq (NMWifiUtils *data); - -/* Return the first supported frequency in the zero-terminated list. - * Frequencies are specified in MHz. */ -guint32 nm_wifi_utils_find_freq (NMWifiUtils *data, const guint32 *freqs); - -/* out_bssid must be ETH_ALEN bytes */ -gboolean nm_wifi_utils_get_bssid (NMWifiUtils *data, guint8 *out_bssid); - -/* Returns current bitrate in Kbps */ -guint32 nm_wifi_utils_get_rate (NMWifiUtils *data); - -/* Returns quality 0 - 100% on succes, or -1 on error */ -int nm_wifi_utils_get_qual (NMWifiUtils *data); - -/* Tells the driver DHCP or SLAAC is running */ -gboolean nm_wifi_utils_indicate_addressing_running (NMWifiUtils *data, gboolean running); - -gboolean nm_wifi_utils_set_powersave (NMWifiUtils *data, guint32 powersave); - -NMSettingWirelessWakeOnWLan nm_wifi_utils_get_wake_on_wlan (NMWifiUtils *data); - -gboolean nm_wifi_utils_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl); - -/* OLPC Mesh-only functions */ -guint32 nm_wifi_utils_get_mesh_channel (NMWifiUtils *data); - -gboolean nm_wifi_utils_set_mesh_channel (NMWifiUtils *data, guint32 channel); - -gboolean nm_wifi_utils_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len); - -#endif /* __WIFI_UTILS_H__ */ diff --git a/src/platform/wifi/nm-wifi-utils-nl80211.c b/src/platform/wifi/wifi-utils-nl80211.c index b3bb2bb6..6c2ff3f5 100644 --- a/src/platform/wifi/nm-wifi-utils-nl80211.c +++ b/src/platform/wifi/wifi-utils-nl80211.c @@ -15,14 +15,14 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2018 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. * Copyright (C) 2011 Intel Corporation. All rights reserved. */ #include "nm-default.h" -#include "nm-wifi-utils-nl80211.h" +#include "wifi-utils-nl80211.h" #include <errno.h> #include <string.h> @@ -32,7 +32,7 @@ #include <linux/nl80211.h> #include "platform/nm-netlink.h" -#include "nm-wifi-utils-private.h" +#include "wifi-utils-private.h" #include "platform/nm-platform.h" #include "platform/nm-platform-utils.h" #include "nm-utils.h" @@ -47,20 +47,14 @@ } G_STMT_END typedef struct { - NMWifiUtils parent; + WifiData parent; struct nl_sock *nl_sock; guint32 *freqs; int id; int num_freqs; int phy; bool can_wowlan:1; -} NMWifiUtilsNl80211; - -typedef struct { - NMWifiUtilsClass parent; -} NMWifiUtilsNl80211Class; - -G_DEFINE_TYPE (NMWifiUtilsNl80211, nm_wifi_utils_nl80211, NM_TYPE_WIFI_UTILS) +} WifiDataNl80211; static int ack_handler (struct nl_msg *msg, void *arg) @@ -103,7 +97,7 @@ nla_put_failure: } static struct nl_msg * -nl80211_alloc_msg (NMWifiUtilsNl80211 *nl80211, guint32 cmd, guint32 flags) +nl80211_alloc_msg (WifiDataNl80211 *nl80211, guint32 cmd, guint32 flags) { return _nl80211_alloc_msg (nl80211->id, nl80211->parent.ifindex, nl80211->phy, cmd, flags); } @@ -160,7 +154,7 @@ _nl80211_send_and_recv (struct nl_sock *nl_sock, } static int -nl80211_send_and_recv (NMWifiUtilsNl80211 *nl80211, +nl80211_send_and_recv (WifiDataNl80211 *nl80211, struct nl_msg *msg, int (*valid_handler) (struct nl_msg *, void *), void *valid_data) @@ -170,11 +164,13 @@ nl80211_send_and_recv (NMWifiUtilsNl80211 *nl80211, } static void -dispose (GObject *object) +wifi_nl80211_deinit (WifiData *parent) { - NMWifiUtilsNl80211 *nl80211 = NM_WIFI_UTILS_NL80211 (object); + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) parent; - g_clear_pointer (&nl80211->freqs, g_free); + if (nl80211->nl_sock) + nl_socket_free (nl80211->nl_sock); + g_free (nl80211->freqs); } struct nl80211_iface_info { @@ -211,9 +207,9 @@ nl80211_iface_info_handler (struct nl_msg *msg, void *arg) } static NM80211Mode -wifi_nl80211_get_mode (NMWifiUtils *data) +wifi_nl80211_get_mode (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_iface_info iface_info = { .mode = NM_802_11_MODE_UNKNOWN, }; @@ -229,9 +225,9 @@ wifi_nl80211_get_mode (NMWifiUtils *data) } static gboolean -wifi_nl80211_set_mode (NMWifiUtils *data, const NM80211Mode mode) +wifi_nl80211_set_mode (WifiData *data, const NM80211Mode mode) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -259,9 +255,9 @@ nla_put_failure: } static gboolean -wifi_nl80211_set_powersave (NMWifiUtils *data, guint32 powersave) +wifi_nl80211_set_powersave (WifiData *data, guint32 powersave) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -275,64 +271,10 @@ nla_put_failure: return FALSE; } -static int -nl80211_get_wake_on_wlan_handler (struct nl_msg *msg, void *arg) -{ - NMSettingWirelessWakeOnWLan *wowl = arg; - struct nlattr *attrs[NL80211_ATTR_MAX + 1]; - struct nlattr *trig[NUM_NL80211_WOWLAN_TRIG]; - struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); - - nla_parse (attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), - genlmsg_attrlen(gnlh, 0), NULL); - - if (!attrs[NL80211_ATTR_WOWLAN_TRIGGERS]) - return NL_SKIP; - - nla_parse (trig, MAX_NL80211_WOWLAN_TRIG, - nla_data (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), - nla_len (attrs[NL80211_ATTR_WOWLAN_TRIGGERS]), - NULL); - - *wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_NONE; - if (trig[NL80211_WOWLAN_TRIG_ANY]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY; - if (trig[NL80211_WOWLAN_TRIG_DISCONNECT]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_DISCONNECT; - if (trig[NL80211_WOWLAN_TRIG_MAGIC_PKT]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_MAGIC; - if (trig[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_GTK_REKEY_FAILURE; - if (trig[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_EAP_IDENTITY_REQUEST; - if (trig[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_4WAY_HANDSHAKE; - if (trig[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_RFKILL_RELEASE; - if (trig[NL80211_WOWLAN_TRIG_TCP_CONNECTION]) - *wowl |= NM_SETTING_WIRELESS_WAKE_ON_WLAN_TCP; - - return NL_SKIP; -} - -static NMSettingWirelessWakeOnWLan -wifi_nl80211_get_wake_on_wlan (NMWifiUtils *data) -{ - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; - NMSettingWirelessWakeOnWLan wowl = NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE; - nm_auto_nlmsg struct nl_msg *msg = NULL; - - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0); - - nl80211_send_and_recv (nl80211, msg, nl80211_get_wake_on_wlan_handler, &wowl); - - return wowl; -} - static gboolean -wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl) +wifi_nl80211_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; struct nlattr *triggers; int err; @@ -340,11 +282,11 @@ wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wo if (wowl == NM_SETTING_WIRELESS_WAKE_ON_WLAN_IGNORE) return TRUE; - msg = nl80211_alloc_msg (nl80211, NL80211_CMD_SET_WOWLAN, 0); + msg = nl80211_alloc_msg(nl80211, NL80211_CMD_SET_WOWLAN, 0); if (!msg) return FALSE; - triggers = nla_nest_start (msg, NL80211_ATTR_WOWLAN_TRIGGERS); + triggers = nla_nest_start(msg, NL80211_ATTR_WOWLAN_TRIGGERS); if (NM_FLAGS_HAS (wowl, NM_SETTING_WIRELESS_WAKE_ON_WLAN_ANY)) NLA_PUT_FLAG (msg, NL80211_WOWLAN_TRIG_ANY); @@ -364,8 +306,7 @@ wifi_nl80211_set_wake_on_wlan (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wo nla_nest_end(msg, triggers); err = nl80211_send_and_recv (nl80211, msg, NULL, NULL); - - return err >= 0; + return err ? FALSE : TRUE; nla_put_failure: return FALSE; @@ -491,7 +432,7 @@ nl80211_bss_dump_handler (struct nl_msg *msg, void *arg) } static void -nl80211_get_bss_info (NMWifiUtilsNl80211 *nl80211, +nl80211_get_bss_info (WifiDataNl80211 *nl80211, struct nl80211_bss_info *bss_info) { nm_auto_nlmsg struct nl_msg *msg = NULL; @@ -504,9 +445,9 @@ nl80211_get_bss_info (NMWifiUtilsNl80211 *nl80211, } static guint32 -wifi_nl80211_get_freq (NMWifiUtils *data) +wifi_nl80211_get_freq (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_bss_info bss_info; nl80211_get_bss_info (nl80211, &bss_info); @@ -515,9 +456,9 @@ wifi_nl80211_get_freq (NMWifiUtils *data) } static guint32 -wifi_nl80211_find_freq (NMWifiUtils *data, const guint32 *freqs) +wifi_nl80211_find_freq (WifiData *data, const guint32 *freqs) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; int i; for (i = 0; i < nl80211->num_freqs; i++) { @@ -531,9 +472,9 @@ wifi_nl80211_find_freq (NMWifiUtils *data, const guint32 *freqs) } static gboolean -wifi_nl80211_get_bssid (NMWifiUtils *data, guint8 *out_bssid) +wifi_nl80211_get_bssid (WifiData *data, guint8 *out_bssid) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_bss_info bss_info; nl80211_get_bss_info (nl80211, &bss_info); @@ -615,7 +556,7 @@ nl80211_station_handler (struct nl_msg *msg, void *arg) } static void -nl80211_get_ap_info (NMWifiUtilsNl80211 *nl80211, +nl80211_get_ap_info (WifiDataNl80211 *nl80211, struct nl80211_station_info *sta_info) { nm_auto_nlmsg struct nl_msg *msg = NULL; @@ -645,9 +586,9 @@ nla_put_failure: } static guint32 -wifi_nl80211_get_rate (NMWifiUtils *data) +wifi_nl80211_get_rate (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_station_info sta_info; nl80211_get_ap_info (nl80211, &sta_info); @@ -656,9 +597,9 @@ wifi_nl80211_get_rate (NMWifiUtils *data) } static int -wifi_nl80211_get_qual (NMWifiUtils *data) +wifi_nl80211_get_qual (WifiData *data) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; struct nl80211_station_info sta_info; nl80211_get_ap_info (nl80211, &sta_info); @@ -666,9 +607,9 @@ wifi_nl80211_get_qual (NMWifiUtils *data) } static gboolean -wifi_nl80211_indicate_addressing_running (NMWifiUtils *data, gboolean running) +wifi_nl80211_indicate_addressing_running (WifiData *data, gboolean running) { - NMWifiUtilsNl80211 *nl80211 = (NMWifiUtilsNl80211 *) data; + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; nm_auto_nlmsg struct nl_msg *msg = NULL; int err; @@ -697,6 +638,44 @@ nla_put_failure: return FALSE; } +struct nl80211_wowlan_info { + gboolean enabled; +}; + +static int +nl80211_wowlan_handler (struct nl_msg *msg, void *arg) +{ + struct nlattr *tb[NL80211_ATTR_MAX + 1]; + struct genlmsghdr *gnlh = nlmsg_data (nlmsg_hdr (msg)); + struct nl80211_wowlan_info *info = arg; + + info->enabled = FALSE; + + if (nla_parse (tb, NL80211_ATTR_MAX, genlmsg_attrdata (gnlh, 0), + genlmsg_attrlen (gnlh, 0), NULL) < 0) + return NL_SKIP; + + if (tb[NL80211_ATTR_WOWLAN_TRIGGERS]) + info->enabled = TRUE; + + return NL_SKIP; +} + +static gboolean +wifi_nl80211_get_wowlan (WifiData *data) +{ + WifiDataNl80211 *nl80211 = (WifiDataNl80211 *) data; + nm_auto_nlmsg struct nl_msg *msg = NULL; + struct nl80211_wowlan_info info; + + if (!nl80211->can_wowlan) + return FALSE; + + msg = nl80211_alloc_msg (nl80211, NL80211_CMD_GET_WOWLAN, 0); + nl80211_send_and_recv (nl80211, msg, nl80211_wowlan_handler, &info); + return info.enabled; +} + struct nl80211_device_info { int phy; guint32 *freqs; @@ -900,58 +879,48 @@ static int nl80211_wiphy_info_handler (struct nl_msg *msg, void *arg) return NL_SKIP; } -static void -nm_wifi_utils_nl80211_init (NMWifiUtilsNl80211 *self) -{ -} - -static void -nm_wifi_utils_nl80211_class_init (NMWifiUtilsNl80211Class *klass) +WifiData * +wifi_nl80211_init (int ifindex) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMWifiUtilsClass *wifi_utils_class = NM_WIFI_UTILS_CLASS (klass); - - object_class->dispose = dispose; - - wifi_utils_class->get_mode = wifi_nl80211_get_mode; - wifi_utils_class->set_mode = wifi_nl80211_set_mode; - wifi_utils_class->set_powersave = wifi_nl80211_set_powersave; - wifi_utils_class->get_wake_on_wlan = wifi_nl80211_get_wake_on_wlan, - wifi_utils_class->set_wake_on_wlan = wifi_nl80211_set_wake_on_wlan, - wifi_utils_class->get_freq = wifi_nl80211_get_freq; - wifi_utils_class->find_freq = wifi_nl80211_find_freq; - wifi_utils_class->get_bssid = wifi_nl80211_get_bssid; - wifi_utils_class->get_rate = wifi_nl80211_get_rate; - wifi_utils_class->get_qual = wifi_nl80211_get_qual; - wifi_utils_class->indicate_addressing_running = wifi_nl80211_indicate_addressing_running; -} - -NMWifiUtils * -nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl) -{ - gs_unref_object NMWifiUtilsNl80211 *nl80211 = NULL; + static const WifiDataClass klass = { + .struct_size = sizeof (WifiDataNl80211), + .get_mode = wifi_nl80211_get_mode, + .set_mode = wifi_nl80211_set_mode, + .set_powersave = wifi_nl80211_set_powersave, + .set_wake_on_wlan = wifi_nl80211_set_wake_on_wlan, + .get_freq = wifi_nl80211_get_freq, + .find_freq = wifi_nl80211_find_freq, + .get_bssid = wifi_nl80211_get_bssid, + .get_rate = wifi_nl80211_get_rate, + .get_qual = wifi_nl80211_get_qual, + .get_wowlan = wifi_nl80211_get_wowlan, + .indicate_addressing_running = wifi_nl80211_indicate_addressing_running, + .deinit = wifi_nl80211_deinit, + }; + WifiDataNl80211 *nl80211; nm_auto_nlmsg struct nl_msg *msg = NULL; struct nl80211_device_info device_info = {}; char ifname[IFNAMSIZ]; - if (!genl) - return NULL; - if (!nmp_utils_if_indextoname (ifindex, ifname)) { _LOGW (LOGD_PLATFORM | LOGD_WIFI, "can't determine interface name for ifindex %d", ifindex); nm_sprintf_buf (ifname, "if %d", ifindex); } - nl80211 = g_object_new (NM_TYPE_WIFI_UTILS_NL80211, NULL); + nl80211 = wifi_data_new (&klass, ifindex); + + nl80211->nl_sock = nl_socket_alloc (); + if (nl80211->nl_sock == NULL) + goto error; - nl80211->parent.ifindex = ifindex; - nl80211->nl_sock = genl; + if (nl_connect (nl80211->nl_sock, NETLINK_GENERIC)) + goto error; nl80211->id = genl_ctrl_resolve (nl80211->nl_sock, "nl80211"); if (nl80211->id < 0) { _LOGD (LOGD_WIFI, "genl_ctrl_resolve: failed to resolve \"nl80211\""); - return NULL; + goto error; } nl80211->phy = -1; @@ -963,42 +932,42 @@ nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl) _LOGD (LOGD_PLATFORM | LOGD_WIFI, "(%s): NL80211_CMD_GET_WIPHY request failed", ifname); - return NULL; + goto error; } if (!device_info.success) { _LOGD (LOGD_PLATFORM | LOGD_WIFI, "(%s): NL80211_CMD_GET_WIPHY request indicated failure", ifname); - return NULL; + goto error; } if (!device_info.supported) { _LOGD (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver does not fully support nl80211, falling back to WEXT", ifname); - return NULL; + goto error; } if (!device_info.can_scan_ssid) { _LOGE (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver does not support SSID scans", ifname); - return NULL; + goto error; } if (device_info.num_freqs == 0 || device_info.freqs == NULL) { nm_log_err (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver reports no supported frequencies", ifname); - return NULL; + goto error; } if (device_info.caps == 0) { _LOGE (LOGD_PLATFORM | LOGD_WIFI, "(%s): driver doesn't report support of any encryption", ifname); - return NULL; + goto error; } nl80211->phy = device_info.phy; @@ -1010,5 +979,10 @@ nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl) _LOGI (LOGD_PLATFORM | LOGD_WIFI, "(%s): using nl80211 for WiFi device control", ifname); - return (NMWifiUtils *) g_steal_pointer (&nl80211); + return (WifiData *) nl80211; + +error: + wifi_utils_unref ((WifiData *) nl80211); + return NULL; } + diff --git a/src/platform/wifi/nm-wifi-utils-nl80211.h b/src/platform/wifi/wifi-utils-nl80211.h index 27f67697..aff24555 100644 --- a/src/platform/wifi/nm-wifi-utils-nl80211.h +++ b/src/platform/wifi/wifi-utils-nl80211.h @@ -16,24 +16,13 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * Copyright (C) 2011 Intel Corporation. All rights reserved. - * Copyright (C) 2018 Red Hat, Inc. */ #ifndef __WIFI_UTILS_NL80211_H__ #define __WIFI_UTILS_NL80211_H__ -#include "nm-wifi-utils.h" -#include "platform/nm-netlink.h" +#include "wifi-utils.h" -#define NM_TYPE_WIFI_UTILS_NL80211 (nm_wifi_utils_nl80211_get_type ()) -#define NM_WIFI_UTILS_NL80211(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211)) -#define NM_WIFI_UTILS_NL80211_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211Class)) -#define NM_IS_WIFI_UTILS_NL80211(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_UTILS_NL80211)) -#define NM_IS_WIFI_UTILS_NL80211_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_UTILS_NL80211)) -#define NM_WIFI_UTILS_NL80211_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_UTILS_NL80211, NMWifiUtilsNl80211Class)) - -GType nm_wifi_utils_nl80211_get_type (void); - -NMWifiUtils *nm_wifi_utils_nl80211_new (int ifindex, struct nl_sock *genl); +WifiData *wifi_nl80211_init (int ifindex); #endif /* __WIFI_UTILS_NL80211_H__ */ diff --git a/src/platform/wifi/nm-wifi-utils-private.h b/src/platform/wifi/wifi-utils-private.h index bcbc1c51..627108cb 100644 --- a/src/platform/wifi/nm-wifi-utils-private.h +++ b/src/platform/wifi/wifi-utils-private.h @@ -15,65 +15,67 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2018 Red Hat, Inc. + * Copyright (C) 2011 Red Hat, Inc. */ #ifndef __WIFI_UTILS_PRIVATE_H__ #define __WIFI_UTILS_PRIVATE_H__ #include "nm-dbus-interface.h" -#include "nm-wifi-utils.h" +#include "wifi-utils.h" typedef struct { - GObjectClass parent; + gsize struct_size; - NM80211Mode (*get_mode) (NMWifiUtils *data); + NM80211Mode (*get_mode) (WifiData *data); - gboolean (*set_mode) (NMWifiUtils *data, const NM80211Mode mode); + gboolean (*set_mode) (WifiData *data, const NM80211Mode mode); /* Set power saving mode on an interface */ - gboolean (*set_powersave) (NMWifiUtils *data, guint32 powersave); - - /* Get WakeOnWLAN configuration on an interface */ - NMSettingWirelessWakeOnWLan (*get_wake_on_wlan) (NMWifiUtils *data); + gboolean (*set_powersave) (WifiData *data, guint32 powersave); /* Set WakeOnWLAN mode on an interface */ - gboolean (*set_wake_on_wlan) (NMWifiUtils *data, NMSettingWirelessWakeOnWLan wowl); + gboolean (*set_wake_on_wlan) (WifiData *data, NMSettingWirelessWakeOnWLan wowl); /* Return current frequency in MHz (really associated BSS frequency) */ - guint32 (*get_freq) (NMWifiUtils *data); + guint32 (*get_freq) (WifiData *data); /* Return first supported frequency in the zero-terminated list */ - guint32 (*find_freq) (NMWifiUtils *data, const guint32 *freqs); + guint32 (*find_freq) (WifiData *data, const guint32 *freqs); /* Return current bitrate in Kbps */ - guint32 (*get_rate) (NMWifiUtils *data); + guint32 (*get_rate) (WifiData *data); - gboolean (*get_bssid) (NMWifiUtils *data, guint8 *out_bssid); + gboolean (*get_bssid) (WifiData *data, guint8 *out_bssid); /* Return a signal strength percentage 0 - 100% for the current BSSID; * return -1 on errors or if not associated. */ - int (*get_qual) (NMWifiUtils *data); + int (*get_qual) (WifiData *data); + + void (*deinit) (WifiData *data); + + gboolean (*get_wowlan) (WifiData *data); /* OLPC Mesh-only functions */ - guint32 (*get_mesh_channel) (NMWifiUtils *data); + guint32 (*get_mesh_channel) (WifiData *data); /* channel == 0 means "auto channel" */ - gboolean (*set_mesh_channel) (NMWifiUtils *data, guint32 channel); + gboolean (*set_mesh_channel) (WifiData *data, guint32 channel); /* ssid == NULL means "auto SSID" */ - gboolean (*set_mesh_ssid) (NMWifiUtils *data, const guint8 *ssid, gsize len); + gboolean (*set_mesh_ssid) (WifiData *data, const guint8 *ssid, gsize len); - gboolean (*indicate_addressing_running) (NMWifiUtils *data, gboolean running); -} NMWifiUtilsClass; - -struct NMWifiUtils { - GObject parent; + gboolean (*indicate_addressing_running) (WifiData *data, gboolean running); +} WifiDataClass; +struct WifiData { + const WifiDataClass *klass; int ifindex; NMDeviceWifiCapabilities caps; }; +gpointer wifi_data_new (const WifiDataClass *klass, int ifindex); + #endif /* __WIFI_UTILS_PRIVATE_H__ */ diff --git a/src/platform/wifi/nm-wifi-utils-wext.c b/src/platform/wifi/wifi-utils-wext.c index e52ae5a3..c8744f79 100644 --- a/src/platform/wifi/nm-wifi-utils-wext.c +++ b/src/platform/wifi/wifi-utils-wext.c @@ -15,13 +15,13 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2005 - 2018 Red Hat, Inc. + * Copyright (C) 2005 - 2011 Red Hat, Inc. * Copyright (C) 2006 - 2008 Novell, Inc. */ #include "nm-default.h" -#include "nm-wifi-utils-wext.h" +#include "wifi-utils-wext.h" #include <errno.h> #include <string.h> @@ -38,24 +38,17 @@ #include <sys/socket.h> #include <linux/wireless.h> -#include "nm-wifi-utils-private.h" +#include "wifi-utils-private.h" #include "nm-utils.h" #include "platform/nm-platform-utils.h" -#include "nm-core-internal.h" typedef struct { - NMWifiUtils parent; + WifiData parent; int fd; struct iw_quality max_qual; gint8 num_freqs; guint32 freqs[IW_MAX_FREQUENCIES]; -} NMWifiUtilsWext; - -typedef struct { - NMWifiUtilsClass parent; -} NMWifiUtilsWextClass; - -G_DEFINE_TYPE (NMWifiUtilsWext, nm_wifi_utils_wext, NM_TYPE_WIFI_UTILS) +} WifiDataWext; /* Until a new wireless-tools comes out that has the defs and the structure, * need to copy them here. @@ -101,11 +94,11 @@ iw_freq_to_uint32 (const struct iw_freq *freq) } static void -dispose (GObject *object) +wifi_wext_deinit (WifiData *parent) { - NMWifiUtilsWext *wext = NM_WIFI_UTILS_WEXT (object); + WifiDataWext *wext = (WifiDataWext *) parent; - wext->fd = nm_close (wext->fd); + nm_close (wext->fd); } static gboolean @@ -125,9 +118,9 @@ get_ifname (int ifindex, char *buffer, const char *op) } static NM80211Mode -wifi_wext_get_mode_ifname (NMWifiUtils *data, const char *ifname) +wifi_wext_get_mode_ifname (WifiData *data, const char *ifname) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; memset (&wrq, 0, sizeof (struct iwreq)); @@ -157,7 +150,7 @@ wifi_wext_get_mode_ifname (NMWifiUtils *data, const char *ifname) } static NM80211Mode -wifi_wext_get_mode (NMWifiUtils *data) +wifi_wext_get_mode (WifiData *data) { char ifname[IFNAMSIZ]; @@ -168,9 +161,9 @@ wifi_wext_get_mode (NMWifiUtils *data) } static gboolean -wifi_wext_set_mode (NMWifiUtils *data, const NM80211Mode mode) +wifi_wext_set_mode (WifiData *data, const NM80211Mode mode) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -210,9 +203,9 @@ wifi_wext_set_mode (NMWifiUtils *data, const NM80211Mode mode) } static gboolean -wifi_wext_set_powersave (NMWifiUtils *data, guint32 powersave) +wifi_wext_set_powersave (WifiData *data, guint32 powersave) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -239,9 +232,9 @@ wifi_wext_set_powersave (NMWifiUtils *data, guint32 powersave) } static guint32 -wifi_wext_get_freq (NMWifiUtils *data) +wifi_wext_get_freq (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -261,9 +254,9 @@ wifi_wext_get_freq (NMWifiUtils *data) } static guint32 -wifi_wext_find_freq (NMWifiUtils *data, const guint32 *freqs) +wifi_wext_find_freq (WifiData *data, const guint32 *freqs) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; int i; for (i = 0; i < wext->num_freqs; i++) { @@ -277,9 +270,9 @@ wifi_wext_find_freq (NMWifiUtils *data, const guint32 *freqs) } static gboolean -wifi_wext_get_bssid (NMWifiUtils *data, guint8 *out_bssid) +wifi_wext_get_bssid (WifiData *data, guint8 *out_bssid) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -299,9 +292,9 @@ wifi_wext_get_bssid (NMWifiUtils *data, guint8 *out_bssid) } static guint32 -wifi_wext_get_rate (NMWifiUtils *data) +wifi_wext_get_rate (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; int err; char ifname[IFNAMSIZ]; @@ -410,9 +403,9 @@ wext_qual_to_percent (const struct iw_quality *qual, } static int -wifi_wext_get_qual (NMWifiUtils *data) +wifi_wext_get_qual (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; struct iw_statistics stats; char ifname[IFNAMSIZ]; @@ -440,13 +433,13 @@ wifi_wext_get_qual (NMWifiUtils *data) /* OLPC Mesh-only functions */ static guint32 -wifi_wext_get_mesh_channel (NMWifiUtils *data) +wifi_wext_get_mesh_channel (WifiData *data) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; guint32 freq; int i; - freq = nm_wifi_utils_get_freq (data); + freq = wifi_utils_get_freq (data); for (i = 0; i < wext->num_freqs; i++) { if (freq == wext->freqs[i]) return i + 1; @@ -455,9 +448,9 @@ wifi_wext_get_mesh_channel (NMWifiUtils *data) } static gboolean -wifi_wext_set_mesh_channel (NMWifiUtils *data, guint32 channel) +wifi_wext_set_mesh_channel (WifiData *data, guint32 channel) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char ifname[IFNAMSIZ]; @@ -484,9 +477,9 @@ wifi_wext_set_mesh_channel (NMWifiUtils *data, guint32 channel) } static gboolean -wifi_wext_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) +wifi_wext_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len) { - NMWifiUtilsWext *wext = (NMWifiUtilsWext *) data; + WifiDataWext *wext = (WifiDataWext *) data; struct iwreq wrq; char buf[IW_ESSID_MAX_SIZE + 1]; char ifname[IFNAMSIZ]; @@ -507,13 +500,11 @@ wifi_wext_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) return TRUE; if (errno != ENODEV) { - gs_free char *ssid_str = NULL; - errsv = errno; _LOGE (LOGD_PLATFORM | LOGD_WIFI | LOGD_OLPC, "(%s): error setting SSID to '%s': %s", ifname, - (ssid_str = _nm_utils_ssid_to_string_arr (ssid, len)), + ssid ? nm_utils_escape_ssid (ssid, len) : "(null)", strerror (errsv)); } @@ -523,7 +514,7 @@ wifi_wext_set_mesh_ssid (NMWifiUtils *data, const guint8 *ssid, gsize len) /*****************************************************************************/ static gboolean -wext_can_scan_ifname (NMWifiUtilsWext *wext, const char *ifname) +wext_can_scan_ifname (WifiDataWext *wext, const char *ifname) { struct iwreq wrq; @@ -537,7 +528,7 @@ wext_can_scan_ifname (NMWifiUtilsWext *wext, const char *ifname) } static gboolean -wext_get_range_ifname (NMWifiUtilsWext *wext, +wext_get_range_ifname (WifiDataWext *wext, const char *ifname, struct iw_range *range, guint32 *response_len) @@ -586,7 +577,7 @@ wext_get_range_ifname (NMWifiUtilsWext *wext, NM_WIFI_DEVICE_CAP_RSN) static guint32 -wext_get_caps (NMWifiUtilsWext *wext, const char *ifname, struct iw_range *range) +wext_get_caps (WifiDataWext *wext, const char *ifname, struct iw_range *range) { guint32 caps = NM_WIFI_DEVICE_CAP_NONE; @@ -635,38 +626,25 @@ wext_get_caps (NMWifiUtilsWext *wext, const char *ifname, struct iw_range *range return caps; } -/*****************************************************************************/ - -static void -nm_wifi_utils_wext_init (NMWifiUtilsWext *self) -{ -} - -static void -nm_wifi_utils_wext_class_init (NMWifiUtilsWextClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMWifiUtilsClass *wifi_utils_class = NM_WIFI_UTILS_CLASS (klass); - - object_class->dispose = dispose; - - wifi_utils_class->get_mode = wifi_wext_get_mode; - wifi_utils_class->set_mode = wifi_wext_set_mode; - wifi_utils_class->set_powersave = wifi_wext_set_powersave; - wifi_utils_class->get_freq = wifi_wext_get_freq; - wifi_utils_class->find_freq = wifi_wext_find_freq; - wifi_utils_class->get_bssid = wifi_wext_get_bssid; - wifi_utils_class->get_rate = wifi_wext_get_rate; - wifi_utils_class->get_qual = wifi_wext_get_qual; - wifi_utils_class->get_mesh_channel = wifi_wext_get_mesh_channel; - wifi_utils_class->set_mesh_channel = wifi_wext_set_mesh_channel; - wifi_utils_class->set_mesh_ssid = wifi_wext_set_mesh_ssid; -} - -NMWifiUtils * -nm_wifi_utils_wext_new (int ifindex, gboolean check_scan) +WifiData * +wifi_wext_init (int ifindex, gboolean check_scan) { - NMWifiUtilsWext *wext; + static const WifiDataClass klass = { + .struct_size = sizeof (WifiDataWext), + .get_mode = wifi_wext_get_mode, + .set_mode = wifi_wext_set_mode, + .set_powersave = wifi_wext_set_powersave, + .get_freq = wifi_wext_get_freq, + .find_freq = wifi_wext_find_freq, + .get_bssid = wifi_wext_get_bssid, + .get_rate = wifi_wext_get_rate, + .get_qual = wifi_wext_get_qual, + .deinit = wifi_wext_deinit, + .get_mesh_channel = wifi_wext_get_mesh_channel, + .set_mesh_channel = wifi_wext_set_mesh_channel, + .set_mesh_ssid = wifi_wext_set_mesh_ssid, + }; + WifiDataWext *wext; struct iw_range range; guint32 response_len = 0; struct iw_range_with_scan_capa *scan_capa_range; @@ -680,9 +658,8 @@ nm_wifi_utils_wext_new (int ifindex, gboolean check_scan) return NULL; } - wext = g_object_new (NM_TYPE_WIFI_UTILS_WEXT, NULL); + wext = wifi_data_new (&klass, ifindex); - wext->parent.ifindex = ifindex; wext->fd = socket (PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); if (wext->fd < 0) goto error; @@ -754,15 +731,15 @@ nm_wifi_utils_wext_new (int ifindex, gboolean check_scan) "(%s): using WEXT for WiFi device control", ifname); - return (NMWifiUtils *) wext; + return (WifiData *) wext; error: - g_object_unref (wext); + wifi_utils_unref ((WifiData *) wext); return NULL; } gboolean -nm_wifi_utils_wext_is_wifi (const char *iface) +wifi_wext_is_wifi (const char *iface) { int fd; struct iwreq iwr; diff --git a/src/platform/wifi/nm-wifi-utils-wext.h b/src/platform/wifi/wifi-utils-wext.h index 44b11afb..3ef5a173 100644 --- a/src/platform/wifi/nm-wifi-utils-wext.h +++ b/src/platform/wifi/wifi-utils-wext.h @@ -15,25 +15,16 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * - * Copyright (C) 2011 - 2018 Red Hat, Inc. + * Copyright (C) 2011 Red Hat, Inc. */ #ifndef __WIFI_UTILS_WEXT_H__ #define __WIFI_UTILS_WEXT_H__ -#include "nm-wifi-utils.h" +#include "wifi-utils.h" -#define NM_TYPE_WIFI_UTILS_WEXT (nm_wifi_utils_wext_get_type ()) -#define NM_WIFI_UTILS_WEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWext)) -#define NM_WIFI_UTILS_WEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWextClass)) -#define NM_IS_WIFI_UTILS_WEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_WIFI_UTILS_WEXT)) -#define NM_IS_WIFI_UTILS_WEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_WIFI_UTILS_WEXT)) -#define NM_WIFI_UTILS_WEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_WIFI_UTILS_WEXT, NMWifiUtilsWextClass)) +WifiData *wifi_wext_init (int ifindex, gboolean check_scan); -GType nm_wifi_utils_wext_get_type (void); - -NMWifiUtils *nm_wifi_utils_wext_new (int ifindex, gboolean check_scan); - -gboolean nm_wifi_utils_wext_is_wifi (const char *iface); +gboolean wifi_wext_is_wifi (const char *iface); #endif /* __WIFI_UTILS_WEXT_H__ */ diff --git a/src/platform/wifi/wifi-utils.c b/src/platform/wifi/wifi-utils.c new file mode 100644 index 00000000..b3dd92ba --- /dev/null +++ b/src/platform/wifi/wifi-utils.c @@ -0,0 +1,231 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#include "nm-default.h" + +#include "wifi-utils.h" + +#include <sys/stat.h> +#include <stdio.h> +#include <string.h> +#include <fcntl.h> + +#include "wifi-utils-private.h" +#include "wifi-utils-nl80211.h" +#if HAVE_WEXT +#include "wifi-utils-wext.h" +#endif +#include "nm-core-utils.h" + +#include "platform/nm-platform-utils.h" + +gpointer +wifi_data_new (const WifiDataClass *klass, int ifindex) +{ + WifiData *data; + + nm_assert (klass); + nm_assert (klass->struct_size > sizeof (WifiData)); + + data = g_malloc0 (klass->struct_size); + data->klass = klass; + data->ifindex = ifindex; + return data; +} + +/*****************************************************************************/ + +WifiData * +wifi_utils_init (int ifindex, gboolean check_scan) +{ + WifiData *ret; + + g_return_val_if_fail (ifindex > 0, NULL); + + ret = wifi_nl80211_init (ifindex); + if (ret == NULL) { +#if HAVE_WEXT + ret = wifi_wext_init (ifindex, check_scan); +#endif + } + return ret; +} + +int +wifi_utils_get_ifindex (WifiData *data) +{ + g_return_val_if_fail (data != NULL, -1); + + return data->ifindex; +} + +NMDeviceWifiCapabilities +wifi_utils_get_caps (WifiData *data) +{ + g_return_val_if_fail (data != NULL, NM_WIFI_DEVICE_CAP_NONE); + + return data->caps; +} + +NM80211Mode +wifi_utils_get_mode (WifiData *data) +{ + g_return_val_if_fail (data != NULL, NM_802_11_MODE_UNKNOWN); + return data->klass->get_mode (data); +} + +gboolean +wifi_utils_set_mode (WifiData *data, const NM80211Mode mode) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail ( (mode == NM_802_11_MODE_INFRA) + || (mode == NM_802_11_MODE_AP) + || (mode == NM_802_11_MODE_ADHOC), FALSE); + + /* nl80211 probably doesn't need this */ + return data->klass->set_mode ? data->klass->set_mode (data, mode) : TRUE; +} + +gboolean +wifi_utils_set_powersave (WifiData *data, guint32 powersave) +{ + g_return_val_if_fail (data != NULL, FALSE); + + return data->klass->set_powersave ? data->klass->set_powersave (data, powersave) : TRUE; +} + +gboolean +wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl) +{ + g_return_val_if_fail (data != NULL, FALSE); + + return data->klass->set_wake_on_wlan ? + data->klass->set_wake_on_wlan (data, wowl) : FALSE; +} + +guint32 +wifi_utils_get_freq (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->klass->get_freq (data); +} + +guint32 +wifi_utils_find_freq (WifiData *data, const guint32 *freqs) +{ + g_return_val_if_fail (data != NULL, 0); + g_return_val_if_fail (freqs != NULL, 0); + return data->klass->find_freq (data, freqs); +} + +gboolean +wifi_utils_get_bssid (WifiData *data, guint8 *out_bssid) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (out_bssid != NULL, FALSE); + + memset (out_bssid, 0, ETH_ALEN); + return data->klass->get_bssid (data, out_bssid); +} + +guint32 +wifi_utils_get_rate (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->klass->get_rate (data); +} + +int +wifi_utils_get_qual (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + return data->klass->get_qual (data); +} + +gboolean +wifi_utils_get_wowlan (WifiData *data) +{ + g_return_val_if_fail (data != NULL, 0); + + if (!data->klass->get_wowlan) + return FALSE; + return data->klass->get_wowlan (data); +} + +void +wifi_utils_unref (WifiData *data) +{ + g_return_if_fail (data != NULL); + + data->klass->deinit (data); + g_free (data); +} + +gboolean +wifi_utils_is_wifi (int dirfd, const char *ifname) +{ + g_return_val_if_fail (dirfd >= 0, FALSE); + + if (faccessat (dirfd, "phy80211", F_OK, 0) == 0) + return TRUE; +#if HAVE_WEXT + if (wifi_wext_is_wifi (ifname)) + return TRUE; +#endif + return FALSE; +} + +/* OLPC Mesh-only functions */ + +guint32 +wifi_utils_get_mesh_channel (WifiData *data) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data->klass->get_mesh_channel != NULL, FALSE); + return data->klass->get_mesh_channel (data); +} + +gboolean +wifi_utils_set_mesh_channel (WifiData *data, guint32 channel) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (channel <= 13, FALSE); + g_return_val_if_fail (data->klass->set_mesh_channel != NULL, FALSE); + return data->klass->set_mesh_channel (data, channel); +} + +gboolean +wifi_utils_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len) +{ + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data->klass->set_mesh_ssid != NULL, FALSE); + return data->klass->set_mesh_ssid (data, ssid, len); +} + +gboolean +wifi_utils_indicate_addressing_running (WifiData *data, gboolean running) +{ + g_return_val_if_fail (data != NULL, FALSE); + if (data->klass->indicate_addressing_running) + return data->klass->indicate_addressing_running (data, running); + return FALSE; +} + diff --git a/src/platform/wifi/wifi-utils.h b/src/platform/wifi/wifi-utils.h new file mode 100644 index 00000000..c69561de --- /dev/null +++ b/src/platform/wifi/wifi-utils.h @@ -0,0 +1,79 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* NetworkManager -- Network link manager + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2005 - 2011 Red Hat, Inc. + * Copyright (C) 2006 - 2008 Novell, Inc. + */ + +#ifndef __WIFI_UTILS_H__ +#define __WIFI_UTILS_H__ + +#include <net/ethernet.h> + +#include "nm-dbus-interface.h" +#include "nm-setting-wireless.h" + +typedef struct WifiData WifiData; + +gboolean wifi_utils_is_wifi (int dirfd, const char *ifname); + +WifiData *wifi_utils_init (int ifindex, gboolean check_scan); + +int wifi_utils_get_ifindex (WifiData *data); + +void wifi_utils_unref (WifiData *data); + +NMDeviceWifiCapabilities wifi_utils_get_caps (WifiData *data); + +NM80211Mode wifi_utils_get_mode (WifiData *data); + +gboolean wifi_utils_set_mode (WifiData *data, const NM80211Mode mode); + +/* Returns frequency in MHz */ +guint32 wifi_utils_get_freq (WifiData *data); + +/* Return the first supported frequency in the zero-terminated list. + * Frequencies are specified in MHz. */ +guint32 wifi_utils_find_freq (WifiData *data, const guint32 *freqs); + +/* out_bssid must be ETH_ALEN bytes */ +gboolean wifi_utils_get_bssid (WifiData *data, guint8 *out_bssid); + +/* Returns current bitrate in Kbps */ +guint32 wifi_utils_get_rate (WifiData *data); + +/* Returns quality 0 - 100% on succes, or -1 on error */ +int wifi_utils_get_qual (WifiData *data); + +/* Tells the driver DHCP or SLAAC is running */ +gboolean wifi_utils_indicate_addressing_running (WifiData *data, gboolean running); + +/* Returns true if WoWLAN is enabled on device */ +gboolean wifi_utils_get_wowlan (WifiData *data); + +gboolean wifi_utils_set_powersave (WifiData *data, guint32 powersave); + +gboolean wifi_utils_set_wake_on_wlan (WifiData *data, NMSettingWirelessWakeOnWLan wowl); + +/* OLPC Mesh-only functions */ +guint32 wifi_utils_get_mesh_channel (WifiData *data); + +gboolean wifi_utils_set_mesh_channel (WifiData *data, guint32 channel); + +gboolean wifi_utils_set_mesh_ssid (WifiData *data, const guint8 *ssid, gsize len); + +#endif /* __WIFI_UTILS_H__ */ |