mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-04-21 00:40:46 +02:00
wifi: probe-scan for hidden SSIDs
This commit is contained in:
parent
bbd2c6e2e6
commit
62888a13c9
3 changed files with 97 additions and 5 deletions
|
|
@ -153,8 +153,6 @@ struct _NMDeviceWifiPrivate {
|
|||
NMDeviceWifiCapabilities capabilities;
|
||||
};
|
||||
|
||||
static gboolean request_wireless_scan (gpointer user_data);
|
||||
|
||||
static void schedule_scan (NMDeviceWifi *self, gboolean backoff);
|
||||
|
||||
static void cancel_pending_scan (NMDeviceWifi *self);
|
||||
|
|
@ -1544,21 +1542,103 @@ check_scanning_allowed (NMDeviceWifi *self)
|
|||
return g_value_get_boolean (&retval);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
hidden_filter_func (NMConnectionProvider *provider,
|
||||
NMConnection *connection,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMSettingWireless *s_wifi;
|
||||
|
||||
s_wifi = (NMSettingWireless *) nm_connection_get_setting_wireless (connection);
|
||||
return s_wifi ? nm_setting_wireless_get_hidden (s_wifi) : FALSE;
|
||||
}
|
||||
|
||||
static GPtrArray *
|
||||
build_hidden_probe_list (NMDeviceWifi *self)
|
||||
{
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
guint max_scan_ssids = nm_supplicant_interface_get_max_scan_ssids (priv->supplicant.iface);
|
||||
NMConnectionProvider *provider = nm_device_get_connection_provider (NM_DEVICE (self));
|
||||
GSList *connections, *iter;
|
||||
GPtrArray *ssids = NULL;
|
||||
static GByteArray *nullssid = NULL;
|
||||
|
||||
/* Need at least two: wildcard SSID and one or more hidden SSIDs */
|
||||
if (max_scan_ssids < 2)
|
||||
return NULL;
|
||||
|
||||
/* Static wildcard SSID used for every scan */
|
||||
if (G_UNLIKELY (nullssid == NULL))
|
||||
nullssid = g_byte_array_new ();
|
||||
|
||||
connections = nm_connection_provider_get_best_connections (provider,
|
||||
max_scan_ssids - 1,
|
||||
NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NULL,
|
||||
hidden_filter_func,
|
||||
NULL);
|
||||
if (connections && connections->data) {
|
||||
ssids = g_ptr_array_sized_new (max_scan_ssids - 1);
|
||||
g_ptr_array_add (ssids, nullssid); /* Add wildcard SSID */
|
||||
}
|
||||
|
||||
for (iter = connections; iter; iter = g_slist_next (iter)) {
|
||||
NMConnection *connection = iter->data;
|
||||
NMSettingWireless *s_wifi;
|
||||
const GByteArray *ssid;
|
||||
|
||||
s_wifi = (NMSettingWireless *) nm_connection_get_setting_wireless (connection);
|
||||
g_assert (s_wifi);
|
||||
ssid = nm_setting_wireless_get_ssid (s_wifi);
|
||||
g_assert (ssid);
|
||||
g_ptr_array_add (ssids, (gpointer) ssid);
|
||||
}
|
||||
g_slist_free (connections);
|
||||
|
||||
return ssids;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
request_wireless_scan (gpointer user_data)
|
||||
{
|
||||
NMDeviceWifi *self = NM_DEVICE_WIFI (user_data);
|
||||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
gboolean backoff = FALSE;
|
||||
GPtrArray *ssids = NULL;
|
||||
|
||||
if (check_scanning_allowed (self)) {
|
||||
nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scanning requested",
|
||||
nm_device_get_iface (NM_DEVICE (self)));
|
||||
|
||||
if (nm_supplicant_interface_request_scan (priv->supplicant.iface)) {
|
||||
ssids = build_hidden_probe_list (self);
|
||||
|
||||
if (nm_logging_level_enabled (LOGL_DEBUG)) {
|
||||
if (ssids) {
|
||||
guint i;
|
||||
char *foo;
|
||||
|
||||
for (i = 0; i < ssids->len; i++) {
|
||||
foo = nm_utils_ssid_to_utf8 (g_ptr_array_index (ssids, i));
|
||||
nm_log_dbg (LOGD_WIFI_SCAN, "(%s): (%d) probe scanning SSID '%s'",
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
i, foo ? foo : "<hidden>");
|
||||
g_free (foo);
|
||||
}
|
||||
} else {
|
||||
nm_log_dbg (LOGD_WIFI_SCAN, "(%s): no SSIDs to probe scan",
|
||||
nm_device_get_iface (NM_DEVICE (self)));
|
||||
}
|
||||
}
|
||||
|
||||
if (nm_supplicant_interface_request_scan (priv->supplicant.iface, ssids)) {
|
||||
/* success */
|
||||
backoff = TRUE;
|
||||
}
|
||||
|
||||
if (ssids) {
|
||||
/* Elements owned by the connections, so we don't free them here */
|
||||
g_ptr_array_free (ssids, TRUE);
|
||||
}
|
||||
} else {
|
||||
nm_log_dbg (LOGD_WIFI_SCAN, "(%s): scan requested but not allowed at this time",
|
||||
nm_device_get_iface (NM_DEVICE (self)));
|
||||
|
|
|
|||
|
|
@ -1202,8 +1202,18 @@ string_to_gvalue (const char *str)
|
|||
return val;
|
||||
}
|
||||
|
||||
static GValue *
|
||||
byte_array_array_to_gvalue (const GPtrArray *array)
|
||||
{
|
||||
GValue *val = g_slice_new0 (GValue);
|
||||
|
||||
g_value_init (val, DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR);
|
||||
g_value_set_boxed (val, array);
|
||||
return val;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_supplicant_interface_request_scan (NMSupplicantInterface * self)
|
||||
nm_supplicant_interface_request_scan (NMSupplicantInterface *self, const GPtrArray *ssids)
|
||||
{
|
||||
NMSupplicantInterfacePrivate *priv;
|
||||
NMSupplicantInfo *info;
|
||||
|
|
@ -1217,6 +1227,8 @@ nm_supplicant_interface_request_scan (NMSupplicantInterface * self)
|
|||
/* Scan parameters */
|
||||
hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, destroy_gvalue);
|
||||
g_hash_table_insert (hash, "Type", string_to_gvalue ("active"));
|
||||
if (ssids)
|
||||
g_hash_table_insert (hash, "SSIDs", byte_array_array_to_gvalue (ssids));
|
||||
|
||||
info = nm_supplicant_info_new (self, priv->iface_proxy, priv->other_pcalls);
|
||||
call = dbus_g_proxy_begin_call (priv->iface_proxy, "Scan",
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ const char * nm_supplicant_interface_get_device (NMSupplicantInterface * iface);
|
|||
|
||||
const char *nm_supplicant_interface_get_object_path (NMSupplicantInterface * iface);
|
||||
|
||||
gboolean nm_supplicant_interface_request_scan (NMSupplicantInterface * self);
|
||||
gboolean nm_supplicant_interface_request_scan (NMSupplicantInterface * self, const GPtrArray *ssids);
|
||||
|
||||
guint32 nm_supplicant_interface_get_state (NMSupplicantInterface * self);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue