summary refs log tree commit diff
path: root/src/platform/wifi
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/wifi')
-rw-r--r--src/platform/wifi/nm-wifi-utils.c240
-rw-r--r--src/platform/wifi/nm-wifi-utils.h84
-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.c231
-rw-r--r--src/platform/wifi/wifi-utils.h79
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__ */