It's still enabled by default if you don't pass --with-wext=no.
But now it's possible to build without WEXT entirely.
--with-docs=yes \
--enable-more-warnings=yes \
--with-udev-dir=$$dc_install_base/lib/udev \
- --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir)
+ --with-systemdsystemunitdir=$$dc_install_base/$(systemdsystemunitdir) \
+ --with-wext=no
DISTCLEANFILES = intltool-extract intltool-merge intltool-update
AC_DEFINE_UNQUOTED(NM_DIST_VERSION, "$ac_distver", [Define the distribution version string])
fi
-AC_MSG_CHECKING([Linux kernel WEXT headers])
-AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM(
- [[#ifndef __user
- #define __user
- #endif
- #include <sys/types.h>
- #include <linux/types.h>
- #include <sys/socket.h>
- #include <linux/wireless.h>]],
- [[#ifndef IWEVGENIE
- #error "not found"
- #endif]])],
- [ac_have_iwevgenie=yes],
- [ac_have_iwevgenie=no])
-AC_MSG_RESULT($ac_have_iwevgenie)
-if test "$ac_have_iwevgenie" = no; then
- AC_MSG_ERROR(Linux kernel development header linux/wireless.h not installed or not functional)
+dnl
+dnl Default to using WEXT but allow it to be disabled
+dnl
+AC_ARG_WITH(wext, AS_HELP_STRING([--with-wext=yes], [Enable or disable Linux Wireless Extensions]), ac_with_wext=$withval, ac_with_wext="yes")
+if test x"$ac_with_wext" = x"yes"; then
+ AC_MSG_CHECKING([Linux kernel WEXT headers])
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#ifndef __user
+ #define __user
+ #endif
+ #include <sys/types.h>
+ #include <linux/types.h>
+ #include <sys/socket.h>
+ #include <linux/wireless.h>]],
+ [[#ifndef IWEVGENIE
+ #error "not found"
+ #endif]])],
+ [ac_have_iwevgenie=yes],
+ [ac_have_iwevgenie=no])
+ AC_MSG_RESULT($ac_have_iwevgenie)
+ if test "$ac_have_iwevgenie" = no; then
+ AC_MSG_ERROR(Linux kernel development header linux/wireless.h not installed or not functional)
+ fi
+ AC_DEFINE(HAVE_WEXT, 1, [Define if you have Linux Wireless Extensions support])
+else
+ AC_DEFINE(HAVE_WEXT, 0, [Define if you have Linux Wireless Extensions support])
fi
+AM_CONDITIONAL(WITH_WEXT, test x"${ac_with_wext}" = x"yes")
AC_MSG_CHECKING([Linux kernel nl80211 headers])
AC_COMPILE_IFELSE(
src/dnsmasq-manager/Makefile
src/modem-manager/Makefile
src/bluez-manager/Makefile
+src/wifi/Makefile
src/firewall-manager/Makefile
src/settings/Makefile
src/settings/plugins/Makefile
modem-manager \
bluez-manager \
firewall-manager \
+ wifi \
settings
if WITH_WIMAX
-I$(top_srcdir)/src/bluez-manager \
-I$(top_srcdir)/src/firewall-manager \
-I$(top_srcdir)/src/settings \
+ -I$(top_srcdir)/src/wifi \
-I${top_srcdir}/libnm-util \
-I${top_builddir}/libnm-util \
-I${top_srcdir}/callouts
nm-device-private.h \
nm-device-ethernet.c \
nm-device-ethernet.h \
- wifi-utils.c \
- wifi-utils.h \
- wifi-utils-private.h \
- wifi-utils-wext.c \
- wifi-utils-wext.h \
- wifi-utils-nl80211.c \
- wifi-utils-nl80211.h \
nm-device-wifi.c \
nm-device-wifi.h \
nm-device-wired.c \
./ppp-manager/libppp-manager.la \
./modem-manager/libmodem-manager.la \
./bluez-manager/libbluez-manager.la \
+ ./wifi/libwifi-utils.la \
./firewall-manager/libfirewall-manager.la \
./settings/libsettings.la \
./backends/libnmbackend.la \
static gboolean
is_wireless (GUdevDevice *device)
{
- char phy80211_path[255];
- struct stat s;
- const char *path;
const char *tmp;
/* Check devtype, newer kernels (2.6.32+) have this */
if (g_strcmp0 (tmp, "wlan") == 0)
return TRUE;
- /* Check for nl80211 sysfs paths */
- path = g_udev_device_get_sysfs_path (device);
- snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", path);
- if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR)))
- return TRUE;
-
/* Otherwise hit up WEXT directly */
- return wifi_utils_is_wifi (g_udev_device_get_name (device));
+ return wifi_utils_is_wifi (g_udev_device_get_name (device),
+ g_udev_device_get_sysfs_path (device));
}
static gboolean
utils.h
INCLUDES = \
+ -I$(top_srcdir)/src/wifi \
-I$(top_srcdir)/src/settings \
-I$(top_srcdir)/include \
-I$(top_builddir)/include \
-DSBINDIR=\"$(sbindir)\"
libifcfg_rh_io_la_LIBADD = \
+ $(top_builddir)/src/wifi/libwifi-utils.la \
$(top_builddir)/libnm-util/libnm-util.la \
$(GLIB_LIBS) \
$(NSS_LIBS)
#include <unistd.h>
#include <netinet/ether.h>
#include <linux/if.h>
-#include <linux/wireless.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <nm-setting-bond.h>
#include <nm-utils.h>
+#include "wifi-utils.h"
+
#include "common.h"
#include "shvar.h"
#include "utils.h"
return connection;
}
-static gboolean
-is_wireless_device (const char *iface)
-{
- int fd;
- struct iw_range range;
- struct iwreq wrq;
- gboolean is_wireless = FALSE;
-
- g_return_val_if_fail (iface != NULL, FALSE);
-
- fd = socket(AF_INET, SOCK_DGRAM, 0);
- if (fd == -1)
- return FALSE;
-
- memset (&wrq, 0, sizeof (struct iwreq));
- memset (&range, 0, sizeof (struct iw_range));
- strncpy (wrq.ifr_name, iface, IFNAMSIZ);
- wrq.u.data.pointer = (caddr_t) ⦥
- wrq.u.data.length = sizeof (struct iw_range);
-
- if (ioctl (fd, SIOCGIWRANGE, &wrq) == 0)
- is_wireless = TRUE;
- else {
- if (errno == EOPNOTSUPP)
- is_wireless = FALSE;
- else {
- /* Sigh... some wired devices (kvm/qemu) return EINVAL when the
- * device is down even though it's not a wireless device. So try
- * IWNAME as a fallback.
- */
- memset (&wrq, 0, sizeof (struct iwreq));
- strncpy (wrq.ifr_name, iface, IFNAMSIZ);
- if (ioctl (fd, SIOCGIWNAME, &wrq) == 0)
- is_wireless = TRUE;
- }
- }
-
- close (fd);
- return is_wireless;
-}
-
static void
handle_bond_option (NMSettingBond *s_bond,
const char *key,
else if (is_vlan_device (device, parsed))
type = g_strdup (TYPE_VLAN);
/* Test wireless extensions */
- else if (is_wireless_device (device))
+ else if (wifi_utils_is_wifi (device, NULL))
type = g_strdup (TYPE_WIRELESS);
else
type = g_strdup (TYPE_ETHERNET);
test_ifcfg_rh_LDADD = \
$(top_builddir)/libnm-glib/libnm-glib.la \
$(top_builddir)/libnm-util/libnm-util.la \
+ $(top_builddir)/src/wifi/libwifi-utils.la \
$(builddir)/../libifcfg-rh-io.la \
$(DBUS_LIBS)
* Copyright (C) 2006 - 2008 Novell, Inc.
*/
+#include <config.h>
#include <stdio.h>
#include <string.h>
#include <glib.h>
}
}
+#if HAVE_WEXT
+#define DEFAULT_WIFI_DRIVER "nl80211,wext"
+#else
+#define DEFAULT_WIFI_DRIVER "nl80211"
+#endif
+
static void
interface_add (NMSupplicantInterface *self, gboolean is_wireless)
{
driver = g_new0 (GValue, 1);
g_value_init (driver, G_TYPE_STRING);
- g_value_set_string (driver, is_wireless ? "nl80211,wext" : "wired");
+ g_value_set_string (driver, is_wireless ? DEFAULT_WIFI_DRIVER : "wired");
g_hash_table_insert (hash, "Driver", driver);
ifname = g_new0 (GValue, 1);
return NL_SKIP;
}
-static struct nl_msg *nl80211_alloc_msg (WifiDataNl80211 *nl80211,
- guint32 cmd, guint32 flags)
+static struct nl_msg *
+_nl80211_alloc_msg (int id, int ifindex, guint32 cmd, guint32 flags)
{
- struct nl_msg *msg = nlmsg_alloc ();
- if (!msg)
- return NULL;
-
- genlmsg_put (msg, 0, 0, nl80211->id, 0, flags, cmd, 0);
-
- NLA_PUT_U32 (msg, NL80211_ATTR_IFINDEX, nl80211->parent.ifindex);
+ struct nl_msg *msg;
+ msg = nlmsg_alloc ();
+ if (msg) {
+ genlmsg_put (msg, 0, 0, id, 0, flags, cmd, 0);
+ NLA_PUT_U32 (msg, NL80211_ATTR_IFINDEX, ifindex);
+ }
return msg;
nla_put_failure:
return NULL;
}
-static int nl80211_send_and_recv (WifiDataNl80211 *nl80211,
- struct nl_msg *msg,
- int (*valid_handler)(struct nl_msg *, void *),
- void *valid_data)
+static struct nl_msg *
+nl80211_alloc_msg (WifiDataNl80211 *nl80211, guint32 cmd, guint32 flags)
+{
+ return _nl80211_alloc_msg (nl80211->id, nl80211->parent.ifindex, cmd, flags);
+}
+
+/* NOTE: this function consumes 'msg' */
+static int
+_nl80211_send_and_recv (struct nl_sock *nl_sock,
+ struct nl_cb *nl_cb,
+ struct nl_msg *msg,
+ int (*valid_handler)(struct nl_msg *, void *),
+ void *valid_data)
{
struct nl_cb *cb;
int err;
- if (msg == NULL)
- return -ENOMEM;
-
+ g_return_val_if_fail (msg != NULL, -ENOMEM);
g_return_val_if_fail (valid_handler != NULL, -EINVAL);
- cb = nl_cb_clone (nl80211->nl_cb);
+ cb = nl_cb_clone (nl_cb);
if (!cb) {
err = -ENOMEM;
goto out;
}
- err = nl_send_auto_complete (nl80211->nl_sock, msg);
+ err = nl_send_auto_complete (nl_sock, msg);
if (err < 0)
goto out;
err = 1;
-
nl_cb_err (cb, NL_CB_CUSTOM, error_handler, &err);
nl_cb_set (cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
nl_cb_set (cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, valid_handler, valid_data);
while (err > 0)
- nl_recvmsgs (nl80211->nl_sock, cb);
+ nl_recvmsgs (nl_sock, cb);
+
out:
nl_cb_put (cb);
nlmsg_free (msg);
return err;
}
+static int
+nl80211_send_and_recv (WifiDataNl80211 *nl80211,
+ struct nl_msg *msg,
+ int (*valid_handler)(struct nl_msg *, void *),
+ void *valid_data)
+{
+ return _nl80211_send_and_recv (nl80211->nl_sock, nl80211->nl_cb, msg, valid_handler, valid_data);
+}
static void
wifi_nl80211_deinit (WifiData *parent)
return NM_802_11_MODE_UNKNOWN;
return iface_info.mode;
- return NM_802_11_MODE_INFRA;
- return NM_802_11_MODE_ADHOC;
- return NM_802_11_MODE_UNKNOWN;
}
static gboolean
wifi_utils_deinit ((WifiData *) nl80211);
return NULL;
}
+
+static int
+iface_to_index (struct nl_sock *nl_sock, const char *iface)
+{
+ struct nl_cache *link_cache;
+ int err, ifindex;
+
+ /* name to index */
+ err = rtnl_link_alloc_cache (nl_sock, &link_cache);
+ if (err < 0) {
+ nm_log_warn (LOGD_HW, "failed to allocate link cache");
+ return -1;
+ }
+ nl_cache_mngt_provide (link_cache);
+ nl_cache_refill (nl_sock, link_cache);
+ ifindex = rtnl_link_name2i (link_cache, iface);
+ nl_cache_free (link_cache);
+
+ return ifindex;
+}
+
+gboolean
+wifi_nl80211_is_wifi (const char *iface)
+{
+ struct nl_sock *nl_sock;
+ struct nl_cb *nl_cb = NULL;
+ struct nl_msg *msg = NULL;
+ int id, ifindex;
+ struct nl80211_iface_info iface_info = {
+ .mode = NM_802_11_MODE_UNKNOWN,
+ };
+ gboolean is_wifi = FALSE;
+
+ nl_sock = nl_socket_alloc ();
+ if (nl_sock == NULL)
+ return FALSE;
+
+ ifindex = iface_to_index (nl_sock, iface);
+ if (index < 0)
+ return FALSE;
+
+ if (genl_connect (nl_sock))
+ goto error;
+
+ id = genl_ctrl_resolve (nl_sock, "nl80211");
+ if (id < 0)
+ goto error;
+
+ nl_cb = nl_cb_alloc (NL_CB_DEFAULT);
+ if (nl_cb) {
+ msg = _nl80211_alloc_msg (id, ifindex, NL80211_CMD_GET_INTERFACE, 0);
+ if (_nl80211_send_and_recv (nl_sock,
+ nl_cb,
+ msg,
+ nl80211_iface_info_handler,
+ &iface_info) >= 0)
+ is_wifi = (iface_info.mode != NM_802_11_MODE_UNKNOWN);
+ }
+
+ error:
+ if (nl_cb)
+ nl_cb_put (nl_cb);
+ nl_socket_free (nl_sock);
+ return is_wifi;
+}
+
WifiData *wifi_nl80211_init (const char *iface, int ifindex);
+gboolean wifi_nl80211_is_wifi (const char *iface);
+
#endif /* WIFI_UTILS_NL80211_H */
*/
#include <config.h>
+#include <sys/stat.h>
+#include <stdio.h>
#include <string.h>
#include <glib.h>
#include "wifi-utils.h"
#include "wifi-utils-private.h"
-#include "wifi-utils-wext.h"
#include "wifi-utils-nl80211.h"
+#if HAVE_WEXT
+#include "wifi-utils-wext.h"
+#endif
gpointer
wifi_data_new (const char *iface, int ifindex, gsize len)
g_return_val_if_fail (ifindex > 0, NULL);
ret = wifi_nl80211_init (iface, ifindex);
- if (ret != NULL)
- return ret;
-
- return wifi_wext_init (iface, ifindex, check_scan);
+ if (ret == NULL) {
+#if HAVE_WEXT
+ ret = wifi_wext_init (iface, ifindex, check_scan);
+#endif
+ }
+ return ret;
}
NMDeviceWifiCapabilities
}
gboolean
-wifi_utils_is_wifi (const char *iface)
+wifi_utils_is_wifi (const char *iface, const char *sysfs_path)
{
+ char phy80211_path[255];
+ struct stat s;
+
g_return_val_if_fail (iface != NULL, FALSE);
+ if (sysfs_path) {
+ /* Check for nl80211 sysfs paths */
+ snprintf (phy80211_path, sizeof (phy80211_path), "%s/phy80211", sysfs_path);
+ if ((stat (phy80211_path, &s) == 0 && (s.st_mode & S_IFDIR)))
+ return TRUE;
+ }
+
+ if (wifi_nl80211_is_wifi (iface))
+ return TRUE;
+
+#if HAVE_WEXT
if (wifi_wext_is_wifi (iface))
return TRUE;
+#endif
return FALSE;
}
typedef struct WifiData WifiData;
-gboolean wifi_utils_is_wifi (const char *iface);
+gboolean wifi_utils_is_wifi (const char *iface, const char *sysfs_path);
WifiData *wifi_utils_init (const char *iface, int ifindex, gboolean check_scan);