mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-14 14:50:30 +01:00
wifi/mesh: require WEXT 21 or later
Seriously, get a kernel more recent than 2007. Really.
This commit is contained in:
parent
9549c70d94
commit
5e3c51fa4e
2 changed files with 50 additions and 117 deletions
|
|
@ -104,7 +104,6 @@ struct _NMDeviceOlpcMeshPrivate
|
|||
gint8 num_freqs;
|
||||
guint32 freqs[IW_MAX_FREQUENCIES];
|
||||
|
||||
guint8 we_version;
|
||||
gboolean up;
|
||||
|
||||
NMDevice * companion;
|
||||
|
|
@ -147,44 +146,7 @@ nm_olpc_mesh_error_get_type (void)
|
|||
static guint32
|
||||
real_get_generic_capabilities (NMDevice *dev)
|
||||
{
|
||||
int fd;
|
||||
guint32 caps = NM_DEVICE_CAP_NONE;
|
||||
struct iw_range range;
|
||||
struct iwreq wrq;
|
||||
const char *iface = nm_device_get_iface (dev);
|
||||
|
||||
/* Check for Wireless Extensions support >= 16 for wireless devices */
|
||||
|
||||
fd = socket (PF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
nm_log_warn (LOGD_OLPC_MESH, "couldn't open control socket.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
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) {
|
||||
nm_log_warn (LOGD_OLPC_MESH, "couldn't get driver range information.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ((wrq.u.data.length < 300) || (range.we_version_compiled < 16)) {
|
||||
nm_log_warn (LOGD_OLPC_MESH,
|
||||
"(%s): driver's Wireless Extensions version (%d) is too old.",
|
||||
iface, range.we_version_compiled);
|
||||
goto out;
|
||||
} else {
|
||||
caps |= NM_DEVICE_CAP_NM_SUPPORTED;
|
||||
}
|
||||
|
||||
out:
|
||||
if (fd >= 0)
|
||||
close (fd);
|
||||
return caps;
|
||||
return NM_DEVICE_CAP_NM_SUPPORTED;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -193,7 +155,6 @@ nm_device_olpc_mesh_init (NMDeviceOlpcMesh * self)
|
|||
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
|
||||
|
||||
priv->dispose_has_run = FALSE;
|
||||
priv->we_version = 0;
|
||||
priv->companion = NULL;
|
||||
priv->stage1_waiting = FALSE;
|
||||
|
||||
|
|
@ -276,15 +237,24 @@ constructor (GType type,
|
|||
wrq.u.data.pointer = (caddr_t) ⦥
|
||||
wrq.u.data.length = sizeof (struct iw_range);
|
||||
|
||||
if (ioctl (fd, SIOCGIWRANGE, &wrq) < 0)
|
||||
if (ioctl (fd, SIOCGIWRANGE, &wrq) < 0) {
|
||||
nm_log_info (LOGD_HW | LOGD_WIFI, "(%s): driver WEXT range request failed",
|
||||
nm_device_get_iface (NM_DEVICE (self)));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((wrq.u.data.length < 300) || (range.we_version_compiled < 21)) {
|
||||
nm_log_info (LOGD_HW | LOGD_WIFI,
|
||||
"(%s): driver WEXT version too old (got %d, expected >= 21)",
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
range.we_version_compiled);
|
||||
goto error;
|
||||
}
|
||||
|
||||
priv->num_freqs = MIN (range.num_frequency, IW_MAX_FREQUENCIES);
|
||||
for (i = 0; i < priv->num_freqs; i++)
|
||||
priv->freqs[i] = iw_freq_to_uint32 (&range.freq[i]);
|
||||
|
||||
priv->we_version = range.we_version_compiled;
|
||||
|
||||
close (fd);
|
||||
|
||||
/* shorter timeout for mesh connectivity */
|
||||
|
|
@ -531,7 +501,6 @@ nm_device_olpc_mesh_set_channel (NMDeviceOlpcMesh *self, guint32 channel)
|
|||
static void
|
||||
nm_device_olpc_mesh_set_ssid (NMDeviceOlpcMesh *self, const GByteArray * ssid)
|
||||
{
|
||||
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
|
||||
int sk;
|
||||
struct iwreq wrq;
|
||||
const char * iface;
|
||||
|
|
@ -554,24 +523,10 @@ nm_device_olpc_mesh_set_ssid (NMDeviceOlpcMesh *self, const GByteArray * ssid)
|
|||
memcpy (buf, ssid->data, MIN (sizeof (buf) - 1, len));
|
||||
}
|
||||
wrq.u.essid.pointer = (caddr_t) buf;
|
||||
|
||||
if (priv->we_version < 21) {
|
||||
/* For historic reasons, set SSID length to include one extra
|
||||
* character, C string nul termination, even though SSID is
|
||||
* really an octet string that should not be presented as a C
|
||||
* string. Some Linux drivers decrement the length by one and
|
||||
* can thus end up missing the last octet of the SSID if the
|
||||
* length is not incremented here. WE-21 changes this to
|
||||
* explicitly require the length _not_ to include nul
|
||||
* termination. */
|
||||
if (len)
|
||||
len++;
|
||||
}
|
||||
wrq.u.essid.length = len;
|
||||
wrq.u.essid.flags = (len > 0) ? 1 : 0; /* 1=enable SSID, 0=disable/any */
|
||||
|
||||
strncpy (wrq.ifr_name, iface, IFNAMSIZ);
|
||||
|
||||
if (ioctl (sk, SIOCSIWESSID, &wrq) < 0) {
|
||||
if (errno != ENODEV) {
|
||||
nm_log_err (LOGD_OLPC_MESH, "(%s): error setting SSID to '%s': %s",
|
||||
|
|
|
|||
|
|
@ -154,7 +154,6 @@ struct _NMDeviceWifiPrivate {
|
|||
guint link_timeout_id;
|
||||
|
||||
/* Static options from driver */
|
||||
guint8 we_version;
|
||||
guint32 capabilities;
|
||||
gboolean has_scan_capa_ssid;
|
||||
};
|
||||
|
|
@ -504,29 +503,14 @@ static guint32
|
|||
real_get_generic_capabilities (NMDevice *dev)
|
||||
{
|
||||
int fd, err;
|
||||
guint32 caps = NM_DEVICE_CAP_NONE, response_len = 0;
|
||||
guint32 caps = NM_DEVICE_CAP_NONE;
|
||||
struct iwreq wrq;
|
||||
struct iw_range range;
|
||||
const char *iface = nm_device_get_iface (dev);
|
||||
gboolean success;
|
||||
|
||||
memset (&range, 0, sizeof (struct iw_range));
|
||||
success = wireless_get_range (NM_DEVICE_WIFI (dev), &range, &response_len);
|
||||
if (!success)
|
||||
return NM_DEVICE_CAP_NONE;
|
||||
|
||||
/* Check for Wireless Extensions support >= 16 for wireless devices */
|
||||
if ((response_len < 300) || (range.we_version_compiled < 16)) {
|
||||
nm_log_err (LOGD_HW | LOGD_WIFI,
|
||||
"(%s): driver's Wireless Extensions version (%d) is too old.",
|
||||
iface, range.we_version_compiled);
|
||||
return NM_DEVICE_CAP_NONE;
|
||||
}
|
||||
|
||||
fd = socket (PF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
nm_log_err (LOGD_HW, "(%s): couldn't open control socket.", iface);
|
||||
goto out;
|
||||
return NM_DEVICE_CAP_NONE;
|
||||
}
|
||||
|
||||
/* Cards that don't scan aren't supported */
|
||||
|
|
@ -539,7 +523,6 @@ real_get_generic_capabilities (NMDevice *dev)
|
|||
else
|
||||
caps |= NM_DEVICE_CAP_NM_SUPPORTED;
|
||||
|
||||
out:
|
||||
return caps;
|
||||
}
|
||||
|
||||
|
|
@ -549,11 +532,8 @@ out:
|
|||
NM_WIFI_DEVICE_CAP_RSN)
|
||||
|
||||
static guint32
|
||||
get_wireless_capabilities (NMDeviceWifi *self,
|
||||
iwrange * range,
|
||||
guint32 data_len)
|
||||
get_wireless_capabilities (NMDeviceWifi *self, iwrange *range)
|
||||
{
|
||||
guint32 minlen;
|
||||
guint32 caps = NM_WIFI_DEVICE_CAP_NONE;
|
||||
const char * iface;
|
||||
|
||||
|
|
@ -562,39 +542,35 @@ get_wireless_capabilities (NMDeviceWifi *self,
|
|||
|
||||
iface = nm_device_get_iface (NM_DEVICE (self));
|
||||
|
||||
minlen = ((char *) &range->enc_capa) - (char *) range + sizeof (range->enc_capa);
|
||||
|
||||
/* All drivers should support WEP by default */
|
||||
caps |= NM_WIFI_DEVICE_CAP_CIPHER_WEP40 | NM_WIFI_DEVICE_CAP_CIPHER_WEP104;
|
||||
|
||||
if ((data_len >= minlen) && range->we_version_compiled >= 18) {
|
||||
if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP)
|
||||
caps |= NM_WIFI_DEVICE_CAP_CIPHER_TKIP;
|
||||
if (range->enc_capa & IW_ENC_CAPA_CIPHER_TKIP)
|
||||
caps |= NM_WIFI_DEVICE_CAP_CIPHER_TKIP;
|
||||
|
||||
if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
|
||||
caps |= NM_WIFI_DEVICE_CAP_CIPHER_CCMP;
|
||||
if (range->enc_capa & IW_ENC_CAPA_CIPHER_CCMP)
|
||||
caps |= NM_WIFI_DEVICE_CAP_CIPHER_CCMP;
|
||||
|
||||
if (range->enc_capa & IW_ENC_CAPA_WPA)
|
||||
caps |= NM_WIFI_DEVICE_CAP_WPA;
|
||||
if (range->enc_capa & IW_ENC_CAPA_WPA)
|
||||
caps |= NM_WIFI_DEVICE_CAP_WPA;
|
||||
|
||||
if (range->enc_capa & IW_ENC_CAPA_WPA2)
|
||||
caps |= NM_WIFI_DEVICE_CAP_RSN;
|
||||
if (range->enc_capa & IW_ENC_CAPA_WPA2)
|
||||
caps |= NM_WIFI_DEVICE_CAP_RSN;
|
||||
|
||||
/* Check for cipher support but not WPA support */
|
||||
if ( (caps & (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | NM_WIFI_DEVICE_CAP_CIPHER_CCMP))
|
||||
&& !(caps & (NM_WIFI_DEVICE_CAP_WPA | NM_WIFI_DEVICE_CAP_RSN))) {
|
||||
nm_log_warn (LOGD_WIFI, "%s: device supports WPA ciphers but not WPA protocol; "
|
||||
"WPA unavailable.", iface);
|
||||
caps &= ~WPA_CAPS;
|
||||
}
|
||||
/* Check for cipher support but not WPA support */
|
||||
if ( (caps & (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | NM_WIFI_DEVICE_CAP_CIPHER_CCMP))
|
||||
&& !(caps & (NM_WIFI_DEVICE_CAP_WPA | NM_WIFI_DEVICE_CAP_RSN))) {
|
||||
nm_log_warn (LOGD_WIFI, "%s: device supports WPA ciphers but not WPA protocol; "
|
||||
"WPA unavailable.", iface);
|
||||
caps &= ~WPA_CAPS;
|
||||
}
|
||||
|
||||
/* Check for WPA support but not cipher support */
|
||||
if ( (caps & (NM_WIFI_DEVICE_CAP_WPA | NM_WIFI_DEVICE_CAP_RSN))
|
||||
&& !(caps & (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | NM_WIFI_DEVICE_CAP_CIPHER_CCMP))) {
|
||||
nm_log_warn (LOGD_WIFI, "%s: device supports WPA protocol but not WPA ciphers; "
|
||||
"WPA unavailable.", iface);
|
||||
caps &= ~WPA_CAPS;
|
||||
}
|
||||
/* Check for WPA support but not cipher support */
|
||||
if ( (caps & (NM_WIFI_DEVICE_CAP_WPA | NM_WIFI_DEVICE_CAP_RSN))
|
||||
&& !(caps & (NM_WIFI_DEVICE_CAP_CIPHER_TKIP | NM_WIFI_DEVICE_CAP_CIPHER_CCMP))) {
|
||||
nm_log_warn (LOGD_WIFI, "%s: device supports WPA protocol but not WPA ciphers; "
|
||||
"WPA unavailable.", iface);
|
||||
caps &= ~WPA_CAPS;
|
||||
}
|
||||
|
||||
return caps;
|
||||
|
|
@ -666,8 +642,19 @@ constructor (GType type,
|
|||
|
||||
memset (&range, 0, sizeof (struct iw_range));
|
||||
success = wireless_get_range (NM_DEVICE_WIFI (object), &range, &response_len);
|
||||
if (!success)
|
||||
if (!success) {
|
||||
nm_log_info (LOGD_HW | LOGD_WIFI, "(%s): driver WEXT range request failed",
|
||||
nm_device_get_iface (NM_DEVICE (self)));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if ((response_len < 300) || (range.we_version_compiled < 21)) {
|
||||
nm_log_info (LOGD_HW | LOGD_WIFI,
|
||||
"(%s): driver WEXT version too old (got %d, expected >= 21)",
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
range.we_version_compiled);
|
||||
goto error;
|
||||
}
|
||||
|
||||
priv->max_qual.qual = range.max_qual.qual;
|
||||
priv->max_qual.level = range.max_qual.level;
|
||||
|
|
@ -678,8 +665,6 @@ constructor (GType type,
|
|||
for (i = 0; i < priv->num_freqs; i++)
|
||||
priv->freqs[i] = iw_freq_to_uint32 (&range.freq[i]);
|
||||
|
||||
priv->we_version = range.we_version_compiled;
|
||||
|
||||
/* Check for the ability to scan specific SSIDs. Until the scan_capa
|
||||
* field gets added to wireless-tools, need to work around that by casting
|
||||
* to the custom structure.
|
||||
|
|
@ -699,7 +684,7 @@ constructor (GType type,
|
|||
}
|
||||
|
||||
/* 802.11 wireless-specific capabilities */
|
||||
priv->capabilities = get_wireless_capabilities (self, &range, response_len);
|
||||
priv->capabilities = get_wireless_capabilities (self, &range);
|
||||
|
||||
/* Connect to the supplicant manager */
|
||||
priv->supplicant.mgr = nm_supplicant_manager_get ();
|
||||
|
|
@ -1870,13 +1855,6 @@ nm_device_wifi_get_ssid (NMDeviceWifi *self)
|
|||
|
||||
len = wrq.u.essid.length;
|
||||
if (!nm_utils_is_empty_ssid ((guint8 *) ssid, len)) {
|
||||
/* Some drivers include nul termination in the SSID, so let's
|
||||
* remove it here before further processing. WE-21 changes this
|
||||
* to explicitly require the length _not_ to include nul
|
||||
* termination. */
|
||||
if (len > 0 && ssid[len - 1] == '\0' && priv->we_version < 21)
|
||||
len--;
|
||||
|
||||
priv->ssid = g_byte_array_sized_new (len);
|
||||
g_byte_array_append (priv->ssid, (const guint8 *) ssid, len);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue