2005-10-15 Dan Williams <dcbw@redhat.com>
Move scanning code into NetworkManager rather than use iwlib's iw_scan() function, so that we can figure out AP capabilities. * NetworkManager.h - Add AP capability bits * src/NetworkManagerAP.[ch] - Add capability field to NMAccessPoint structure - Add WPA & RSN Information Element fields and accessor functions to NMAccessPoint * src/NetworkManagerDevice.c - Remove usage of iw_scan - Add scanning code to NetworkManager rather than use iw_scan() from iwlib * src/NetworkManagerUtils.[ch] - (nm_dispose_scan_results): remove, unused git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@1023 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
21
ChangeLog
21
ChangeLog
@@ -1,3 +1,24 @@
|
|||||||
|
2005-10-15 Dan Williams <dcbw@redhat.com>
|
||||||
|
|
||||||
|
Move scanning code into NetworkManager rather than use iwlib's
|
||||||
|
iw_scan() function, so that we can figure out AP capabilities.
|
||||||
|
|
||||||
|
* NetworkManager.h
|
||||||
|
- Add AP capability bits
|
||||||
|
|
||||||
|
* src/NetworkManagerAP.[ch]
|
||||||
|
- Add capability field to NMAccessPoint structure
|
||||||
|
- Add WPA & RSN Information Element fields and accessor
|
||||||
|
functions to NMAccessPoint
|
||||||
|
|
||||||
|
* src/NetworkManagerDevice.c
|
||||||
|
- Remove usage of iw_scan
|
||||||
|
- Add scanning code to NetworkManager rather than use
|
||||||
|
iw_scan() from iwlib
|
||||||
|
|
||||||
|
* src/NetworkManagerUtils.[ch]
|
||||||
|
- (nm_dispose_scan_results): remove, unused
|
||||||
|
|
||||||
2005-10-14 Christopher Aillon <caillon@redhat.com>
|
2005-10-14 Christopher Aillon <caillon@redhat.com>
|
||||||
|
|
||||||
* gnome/libnm_glib/libnm_glib.c:
|
* gnome/libnm_glib/libnm_glib.c:
|
||||||
|
@@ -132,6 +132,16 @@ typedef enum NMEncKeyType
|
|||||||
#define NM_DEVICE_CAP_WPA_PSK 0x0008
|
#define NM_DEVICE_CAP_WPA_PSK 0x0008
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Access Point capability bits
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define NM_AP_CAP_NONE 0x0000
|
||||||
|
#define NM_AP_CAP_WEP 0x0001
|
||||||
|
#define NM_AP_CAP_WPA1 0x0002
|
||||||
|
#define NM_AP_CAP_WPA2 0x0004
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wireless network modes
|
* Wireless network modes
|
||||||
*/
|
*/
|
||||||
|
@@ -30,29 +30,36 @@
|
|||||||
*/
|
*/
|
||||||
struct NMAccessPoint
|
struct NMAccessPoint
|
||||||
{
|
{
|
||||||
guint refcount;
|
guint refcount;
|
||||||
char *essid;
|
char * essid;
|
||||||
struct ether_addr *address;
|
struct ether_addr * address;
|
||||||
NMNetworkMode mode;
|
NMNetworkMode mode;
|
||||||
gint8 strength;
|
gint8 strength;
|
||||||
double freq;
|
double freq;
|
||||||
guint16 rate;
|
guint16 rate;
|
||||||
gboolean encrypted;
|
gboolean encrypted;
|
||||||
|
guint32 capabilities;
|
||||||
|
|
||||||
|
/* WPA auxiliary information */
|
||||||
|
guint8 * wpa_ie;
|
||||||
|
guint32 wpa_ie_len;
|
||||||
|
guint8 * rsn_ie;
|
||||||
|
guint32 rsn_ie_len;
|
||||||
|
|
||||||
/* Non-scanned attributes */
|
/* Non-scanned attributes */
|
||||||
gboolean invalid;
|
gboolean invalid;
|
||||||
gboolean matched; /* used in ap list diffing */
|
gboolean matched; /* used in ap list diffing */
|
||||||
gboolean artificial; /* Whether or not the AP is from a scan */
|
gboolean artificial; /* Whether or not the AP is from a scan */
|
||||||
gboolean user_created; /* Whether or not the AP was created by the user with "Create network..." */
|
gboolean user_created; /* Whether or not the AP was created by the user with "Create network..." */
|
||||||
GTimeVal last_seen; /* Last time the AP was seen in a scan */
|
GTimeVal last_seen; /* Last time the AP was seen in a scan */
|
||||||
|
|
||||||
/* Things from user prefs/NetworkManagerInfo */
|
/* Things from user prefs/NetworkManagerInfo */
|
||||||
gboolean trusted;
|
gboolean trusted;
|
||||||
char *enc_key;
|
char * enc_key;
|
||||||
NMEncKeyType enc_type;
|
NMEncKeyType enc_type;
|
||||||
NMDeviceAuthMethod auth_method;
|
NMDeviceAuthMethod auth_method;
|
||||||
GTimeVal timestamp;
|
GTimeVal timestamp;
|
||||||
GSList *user_addresses;
|
GSList * user_addresses;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This is a controlled list. Want to add to it? Stop. Ask first. */
|
/* This is a controlled list. Want to add to it? Stop. Ask first. */
|
||||||
@@ -639,3 +646,67 @@ gboolean nm_ap_has_manufacturer_default_essid (NMAccessPoint *ap)
|
|||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const guint8 * nm_ap_get_wpa_ie (NMAccessPoint *ap, guint32 *length)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (ap != NULL, NULL);
|
||||||
|
g_return_val_if_fail (length != NULL, NULL);
|
||||||
|
|
||||||
|
*length = ap->wpa_ie_len;
|
||||||
|
return ap->wpa_ie;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nm_ap_set_wpa_ie (NMAccessPoint *ap, const guint8 *wpa_ie, guint32 length)
|
||||||
|
{
|
||||||
|
g_return_if_fail (ap != NULL);
|
||||||
|
|
||||||
|
if (wpa_ie)
|
||||||
|
g_return_if_fail ((length > 0) && (length <= AP_MAX_WPA_IE_LEN));
|
||||||
|
|
||||||
|
if (ap->wpa_ie)
|
||||||
|
{
|
||||||
|
g_free (ap->wpa_ie);
|
||||||
|
ap->wpa_ie = NULL;
|
||||||
|
ap->wpa_ie_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wpa_ie)
|
||||||
|
{
|
||||||
|
ap->wpa_ie = g_malloc0 (length);
|
||||||
|
ap->wpa_ie_len = length;
|
||||||
|
memcpy (ap->wpa_ie, wpa_ie, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const guint8 * nm_ap_get_rsn_ie (NMAccessPoint *ap, guint32 *length)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (ap != NULL, NULL);
|
||||||
|
g_return_val_if_fail (length != NULL, NULL);
|
||||||
|
|
||||||
|
*length = ap->rsn_ie_len;
|
||||||
|
return ap->rsn_ie;
|
||||||
|
}
|
||||||
|
|
||||||
|
void nm_ap_set_rsn_ie (NMAccessPoint *ap, const guint8 *rsn_ie, guint32 length)
|
||||||
|
{
|
||||||
|
g_return_if_fail (ap != NULL);
|
||||||
|
|
||||||
|
if (rsn_ie)
|
||||||
|
g_return_if_fail ((length > 0) && (length <= AP_MAX_WPA_IE_LEN));
|
||||||
|
|
||||||
|
if (ap->rsn_ie)
|
||||||
|
{
|
||||||
|
g_free (ap->rsn_ie);
|
||||||
|
ap->rsn_ie = NULL;
|
||||||
|
ap->rsn_ie_len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rsn_ie)
|
||||||
|
{
|
||||||
|
ap->rsn_ie = g_malloc0 (length);
|
||||||
|
ap->rsn_ie_len = length;
|
||||||
|
memcpy (ap->rsn_ie, rsn_ie, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -28,6 +28,9 @@
|
|||||||
|
|
||||||
typedef struct NMAccessPoint NMAccessPoint;
|
typedef struct NMAccessPoint NMAccessPoint;
|
||||||
|
|
||||||
|
#define AP_MAX_WPA_IE_LEN 40
|
||||||
|
|
||||||
|
|
||||||
NMAccessPoint * nm_ap_new (void);
|
NMAccessPoint * nm_ap_new (void);
|
||||||
NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *ap);
|
NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *ap);
|
||||||
|
|
||||||
@@ -43,7 +46,7 @@ void nm_ap_set_essid (NMAccessPoint *ap, const char *essid);
|
|||||||
const char * nm_ap_get_enc_key_source (const NMAccessPoint *ap);
|
const char * nm_ap_get_enc_key_source (const NMAccessPoint *ap);
|
||||||
char * nm_ap_get_enc_key_hashed (const NMAccessPoint *ap);
|
char * nm_ap_get_enc_key_hashed (const NMAccessPoint *ap);
|
||||||
void nm_ap_set_enc_key_source (NMAccessPoint *ap, const char *key, NMEncKeyType type);
|
void nm_ap_set_enc_key_source (NMAccessPoint *ap, const char *key, NMEncKeyType type);
|
||||||
NMEncKeyType nm_ap_get_enc_type (const NMAccessPoint *ap);
|
NMEncKeyType nm_ap_get_enc_type (const NMAccessPoint *ap);
|
||||||
|
|
||||||
NMDeviceAuthMethod nm_ap_get_auth_method (const NMAccessPoint *ap);
|
NMDeviceAuthMethod nm_ap_get_auth_method (const NMAccessPoint *ap);
|
||||||
void nm_ap_set_auth_method (NMAccessPoint *ap, const NMDeviceAuthMethod auth_method);
|
void nm_ap_set_auth_method (NMAccessPoint *ap, const NMDeviceAuthMethod auth_method);
|
||||||
@@ -91,6 +94,12 @@ void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list);
|
|||||||
gboolean nm_ap_is_enc_key_valid (NMAccessPoint *ap);
|
gboolean nm_ap_is_enc_key_valid (NMAccessPoint *ap);
|
||||||
gboolean nm_is_enc_key_valid (const char *key, NMEncKeyType key_type);
|
gboolean nm_is_enc_key_valid (const char *key, NMEncKeyType key_type);
|
||||||
|
|
||||||
|
const guint8 * nm_ap_get_wpa_ie (NMAccessPoint *ap, guint32 *length);
|
||||||
|
void nm_ap_set_wpa_ie (NMAccessPoint *ap, const guint8 *wpa_ie, guint32 length);
|
||||||
|
|
||||||
|
const guint8 * nm_ap_get_rsn_ie (NMAccessPoint *ap, guint32 *length);
|
||||||
|
void nm_ap_set_rsn_ie (NMAccessPoint *ap, const guint8 *rsn_ie, guint32 length);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NOTE:
|
* NOTE:
|
||||||
* This is not intended to return true for all APs with manufacturer defaults. It is intended to return true for
|
* This is not intended to return true for all APs with manufacturer defaults. It is intended to return true for
|
||||||
|
@@ -56,6 +56,10 @@ static guint32 nm_device_discover_capabilities (NMDevice *dev);
|
|||||||
static gboolean nm_is_driver_supported (NMDevice *dev);
|
static gboolean nm_is_driver_supported (NMDevice *dev);
|
||||||
static guint32 nm_device_wireless_discover_capabilities (NMDevice *dev);
|
static guint32 nm_device_wireless_discover_capabilities (NMDevice *dev);
|
||||||
|
|
||||||
|
static guint8 * get_scan_results(NMDevice *dev, NMSock *sk, guint32 *data_len);
|
||||||
|
static gboolean process_scan_results (NMDevice *dev, const guint8 *res_buf, guint32 res_buf_len);
|
||||||
|
|
||||||
|
|
||||||
static void nm_device_activate_schedule_stage1_device_prepare (NMActRequest *req);
|
static void nm_device_activate_schedule_stage1_device_prepare (NMActRequest *req);
|
||||||
static void nm_device_activate_schedule_stage2_device_config (NMActRequest *req);
|
static void nm_device_activate_schedule_stage2_device_config (NMActRequest *req);
|
||||||
static void nm_device_activate_schedule_stage3_ip_config_start (NMActRequest *req);
|
static void nm_device_activate_schedule_stage3_ip_config_start (NMActRequest *req);
|
||||||
@@ -63,8 +67,9 @@ static void nm_device_activate_schedule_stage5_ip_config_commit (NMActRequest *r
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
NMDevice *dev;
|
NMDevice * dev;
|
||||||
struct wireless_scan_head scan_head;
|
guint8 * results;
|
||||||
|
guint32 results_len;
|
||||||
} NMWirelessScanResults;
|
} NMWirelessScanResults;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -637,9 +642,9 @@ static guint32 nm_device_wireless_discover_capabilities (NMDevice *dev)
|
|||||||
{
|
{
|
||||||
if ((sk = nm_dev_sock_open (dev, DEV_WIRELESS, __FUNCTION__, NULL)))
|
if ((sk = nm_dev_sock_open (dev, DEV_WIRELESS, __FUNCTION__, NULL)))
|
||||||
{
|
{
|
||||||
guint8 we_ver = dev->options.wireless.we_version;
|
struct iwreq wrq;
|
||||||
err = iw_scan (nm_dev_sock_get_fd (sk), (char *) nm_device_get_iface (dev), we_ver, &scan_data);
|
memset (&wrq, 0, sizeof (struct iwreq));
|
||||||
nm_dispose_scan_results (scan_data.result);
|
err = iw_set_ext (nm_dev_sock_get_fd (sk), nm_device_get_iface (dev), SIOCSIWSCAN, &wrq);
|
||||||
if (!((err == -1) && (errno == EOPNOTSUPP)))
|
if (!((err == -1) && (errno == EOPNOTSUPP)))
|
||||||
caps |= NM_DEVICE_CAP_WIRELESS_SCAN;
|
caps |= NM_DEVICE_CAP_WIRELESS_SCAN;
|
||||||
nm_dev_sock_close (sk);
|
nm_dev_sock_close (sk);
|
||||||
@@ -3937,120 +3942,24 @@ static void nm_device_wireless_schedule_scan (NMDevice *dev)
|
|||||||
*/
|
*/
|
||||||
static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
|
static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
|
||||||
{
|
{
|
||||||
NMWirelessScanResults *results = (NMWirelessScanResults *)user_data;
|
NMWirelessScanResults * cb_data = (NMWirelessScanResults *)user_data;
|
||||||
NMDevice *dev;
|
NMDevice * dev;
|
||||||
wireless_scan *tmp_ap;
|
GTimeVal cur_time;
|
||||||
NMAPListIter *iter;
|
NMAPListIter * iter = NULL;
|
||||||
GTimeVal cur_time;
|
|
||||||
gboolean list_changed = FALSE;
|
|
||||||
|
|
||||||
g_return_val_if_fail (results != NULL, FALSE);
|
g_return_val_if_fail (cb_data != NULL, FALSE);
|
||||||
|
|
||||||
dev = results->dev;
|
dev = cb_data->dev;
|
||||||
if (!dev || !results->scan_head.result)
|
if (!dev || !cb_data->results)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
g_get_current_time (&cur_time);
|
if (!process_scan_results (dev, cb_data->results, cb_data->results_len))
|
||||||
|
nm_warning ("nm_device_wireless_process_scan_results(%s): process_scan_results() returned an error.", nm_device_get_iface (dev));
|
||||||
/* Translate iwlib scan results to NM access point list */
|
|
||||||
for (tmp_ap = results->scan_head.result; tmp_ap; tmp_ap = tmp_ap->next)
|
|
||||||
{
|
|
||||||
/* We need at least an ESSID or a MAC address for each access point */
|
|
||||||
if (tmp_ap->b.has_essid || tmp_ap->has_ap_addr)
|
|
||||||
{
|
|
||||||
NMAccessPoint *nm_ap = nm_ap_new ();
|
|
||||||
int percent;
|
|
||||||
gboolean new = FALSE;
|
|
||||||
gboolean strength_changed = FALSE;
|
|
||||||
gboolean success = FALSE;
|
|
||||||
|
|
||||||
/* Copy over info from scan to local structure */
|
|
||||||
|
|
||||||
/* ipw2x00 drivers fill in an essid of "<hidden>" if they think the access point
|
|
||||||
* is hiding its MAC address. Sigh.
|
|
||||||
*/
|
|
||||||
if ( !tmp_ap->b.has_essid
|
|
||||||
|| (tmp_ap->b.essid && !strlen (tmp_ap->b.essid))
|
|
||||||
|| (tmp_ap->b.essid && !strcmp (tmp_ap->b.essid, "<hidden>"))) /* Stupid ipw drivers use <hidden> */
|
|
||||||
nm_ap_set_essid (nm_ap, NULL);
|
|
||||||
else
|
|
||||||
nm_ap_set_essid (nm_ap, tmp_ap->b.essid);
|
|
||||||
|
|
||||||
if (tmp_ap->b.has_key && (tmp_ap->b.key_flags & IW_ENCODE_DISABLED))
|
|
||||||
{
|
|
||||||
nm_ap_set_encrypted (nm_ap, FALSE);
|
|
||||||
nm_ap_set_auth_method (nm_ap, NM_DEVICE_AUTH_METHOD_NONE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nm_ap_set_encrypted (nm_ap, TRUE);
|
|
||||||
nm_ap_set_auth_method (nm_ap, NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tmp_ap->has_ap_addr)
|
|
||||||
nm_ap_set_address (nm_ap, (const struct ether_addr *)(tmp_ap->ap_addr.sa_data));
|
|
||||||
|
|
||||||
if (tmp_ap->b.has_mode)
|
|
||||||
{
|
|
||||||
NMNetworkMode mode = NETWORK_MODE_INFRA;
|
|
||||||
switch (tmp_ap->b.mode)
|
|
||||||
{
|
|
||||||
case IW_MODE_INFRA:
|
|
||||||
mode = NETWORK_MODE_INFRA;
|
|
||||||
break;
|
|
||||||
case IW_MODE_ADHOC:
|
|
||||||
mode = NETWORK_MODE_ADHOC;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
mode = NETWORK_MODE_INFRA;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
nm_ap_set_mode (nm_ap, mode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
nm_ap_set_mode (nm_ap, NETWORK_MODE_INFRA);
|
|
||||||
|
|
||||||
percent = nm_wireless_qual_to_percent (&(tmp_ap->stats.qual),
|
|
||||||
(const iwqual *)(&dev->options.wireless.max_qual),
|
|
||||||
(const iwqual *)(&dev->options.wireless.avg_qual));
|
|
||||||
nm_ap_set_strength (nm_ap, percent);
|
|
||||||
|
|
||||||
if (tmp_ap->b.has_freq)
|
|
||||||
nm_ap_set_freq (nm_ap, tmp_ap->b.freq);
|
|
||||||
|
|
||||||
nm_ap_set_last_seen (nm_ap, &cur_time);
|
|
||||||
|
|
||||||
/* If the AP is not broadcasting its ESSID, try to fill it in here from our
|
|
||||||
* allowed list where we cache known MAC->ESSID associations.
|
|
||||||
*/
|
|
||||||
if (!nm_ap_get_essid (nm_ap))
|
|
||||||
nm_ap_list_copy_one_essid_by_address (nm_ap, dev->app_data->allowed_ap_list);
|
|
||||||
|
|
||||||
/* Add the AP to the device's AP list */
|
|
||||||
success = nm_ap_list_merge_scanned_ap (nm_device_ap_list_get (dev), nm_ap, &new, &strength_changed);
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
/* Handle dbus signals that we need to broadcast when the AP is added to the list or changes strength */
|
|
||||||
if (new)
|
|
||||||
{
|
|
||||||
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, nm_ap,
|
|
||||||
NETWORK_STATUS_APPEARED, -1);
|
|
||||||
list_changed = TRUE;
|
|
||||||
}
|
|
||||||
else if (strength_changed)
|
|
||||||
{
|
|
||||||
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, nm_ap,
|
|
||||||
NETWORK_STATUS_STRENGTH_CHANGED, nm_ap_get_strength (nm_ap));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nm_ap_unref (nm_ap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Once we have the list, copy in any relevant information from our Allowed list. */
|
/* Once we have the list, copy in any relevant information from our Allowed list. */
|
||||||
nm_ap_list_copy_properties (nm_device_ap_list_get (dev), dev->app_data->allowed_ap_list);
|
nm_ap_list_copy_properties (nm_device_ap_list_get (dev), dev->app_data->allowed_ap_list);
|
||||||
|
|
||||||
/* Walk the access point list and remove any access points older than 120s */
|
/* Walk the access point list and remove any access points older than 180s */
|
||||||
g_get_current_time (&cur_time);
|
g_get_current_time (&cur_time);
|
||||||
if (nm_device_ap_list_get (dev) && (iter = nm_ap_list_iter_new (nm_device_ap_list_get (dev))))
|
if (nm_device_ap_list_get (dev) && (iter = nm_ap_list_iter_new (nm_device_ap_list_get (dev))))
|
||||||
{
|
{
|
||||||
@@ -4071,12 +3980,12 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
|
|||||||
const GTimeVal *ap_time = nm_ap_get_last_seen (outdated_ap);
|
const GTimeVal *ap_time = nm_ap_get_last_seen (outdated_ap);
|
||||||
gboolean keep_around = FALSE;
|
gboolean keep_around = FALSE;
|
||||||
|
|
||||||
/* Don't ever get prune the AP we're currently associated with */
|
/* Don't ever prune the AP we're currently associated with */
|
||||||
if ( nm_ap_get_essid (outdated_ap)
|
if ( nm_ap_get_essid (outdated_ap)
|
||||||
&& (cur_ap && (nm_null_safe_strcmp (nm_ap_get_essid (cur_ap), nm_ap_get_essid (outdated_ap))) == 0))
|
&& (cur_ap && (nm_null_safe_strcmp (nm_ap_get_essid (cur_ap), nm_ap_get_essid (outdated_ap))) == 0))
|
||||||
keep_around = TRUE;
|
keep_around = TRUE;
|
||||||
|
|
||||||
if (!keep_around && (ap_time->tv_sec + 120 < cur_time.tv_sec))
|
if (!keep_around && (ap_time->tv_sec + 180 < cur_time.tv_sec))
|
||||||
outdated_list = g_slist_append (outdated_list, outdated_ap);
|
outdated_list = g_slist_append (outdated_list, outdated_ap);
|
||||||
}
|
}
|
||||||
nm_ap_list_iter_free (iter);
|
nm_ap_list_iter_free (iter);
|
||||||
@@ -4090,7 +3999,6 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
|
|||||||
{
|
{
|
||||||
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, outdated_ap, NETWORK_STATUS_DISAPPEARED, -1);
|
nm_dbus_signal_wireless_network_change (dev->app_data->dbus_connection, dev, outdated_ap, NETWORK_STATUS_DISAPPEARED, -1);
|
||||||
nm_ap_list_remove_ap (nm_device_ap_list_get (dev), outdated_ap);
|
nm_ap_list_remove_ap (nm_device_ap_list_get (dev), outdated_ap);
|
||||||
list_changed = TRUE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g_slist_free (outdated_list);
|
g_slist_free (outdated_list);
|
||||||
@@ -4102,58 +4010,6 @@ static gboolean nm_device_wireless_process_scan_results (gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static gboolean nm_completion_scan_has_results (int tries, nm_completion_args args)
|
|
||||||
{
|
|
||||||
NMDevice * dev = args[0];
|
|
||||||
gboolean * err = args[1];
|
|
||||||
NMSock * sk = args[2];
|
|
||||||
NMWirelessScanResults * scan_results = args[3];
|
|
||||||
int rc;
|
|
||||||
guint8 we_ver;
|
|
||||||
|
|
||||||
g_return_val_if_fail (dev != NULL, TRUE);
|
|
||||||
g_return_val_if_fail (err != NULL, TRUE);
|
|
||||||
g_return_val_if_fail (scan_results != NULL, TRUE);
|
|
||||||
|
|
||||||
we_ver = dev->options.wireless.we_version;
|
|
||||||
rc = iw_scan (nm_dev_sock_get_fd (sk), (char *)nm_device_get_iface (dev), we_ver, &(scan_results->scan_head));
|
|
||||||
*err = FALSE;
|
|
||||||
if (rc == -1 && errno == ETIME)
|
|
||||||
{
|
|
||||||
/* Scans take time. iw_scan's timeout is 15 seconds, so if the card hasn't returned
|
|
||||||
* scan results after two consecutive runs of iw_scan(), the card sucks.
|
|
||||||
*/
|
|
||||||
if (tries >= 1)
|
|
||||||
{
|
|
||||||
nm_warning ("Warning: the wireless card (%s) requires too much time for scans. Its driver needs to be fixed.", nm_device_get_iface (dev));
|
|
||||||
scan_results->scan_head.result = NULL;
|
|
||||||
*err = TRUE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Give the card one more chance to return scan results */
|
|
||||||
scan_results->scan_head.result = NULL;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((rc == -1 && errno == ENODATA) || (rc == 0 && scan_results->scan_head.result == NULL))
|
|
||||||
{
|
|
||||||
/* Card hasn't had time yet to compile full access point list.
|
|
||||||
* Give it some more time and scan again. If that doesn't
|
|
||||||
* work, we eventually give up. */
|
|
||||||
scan_results->scan_head.result = NULL;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
else if (rc == -1)
|
|
||||||
{
|
|
||||||
scan_results->scan_head.result = NULL;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_device_wireless_scan
|
* nm_device_wireless_scan
|
||||||
*
|
*
|
||||||
@@ -4166,6 +4022,8 @@ static gboolean nm_device_wireless_scan (gpointer user_data)
|
|||||||
NMDevice * dev = NULL;
|
NMDevice * dev = NULL;
|
||||||
NMWirelessScanResults * scan_results = NULL;
|
NMWirelessScanResults * scan_results = NULL;
|
||||||
guint32 caps;
|
guint32 caps;
|
||||||
|
guint8 * results = NULL;
|
||||||
|
guint32 results_len = 0;
|
||||||
|
|
||||||
g_return_val_if_fail (scan_cb != NULL, FALSE);
|
g_return_val_if_fail (scan_cb != NULL, FALSE);
|
||||||
|
|
||||||
@@ -4234,10 +4092,7 @@ static gboolean nm_device_wireless_scan (gpointer user_data)
|
|||||||
double orig_freq = 0;
|
double orig_freq = 0;
|
||||||
int orig_rate = 0;
|
int orig_rate = 0;
|
||||||
const int interval = 20;
|
const int interval = 20;
|
||||||
const int assoc_pause = nm_device_get_association_pause_value (dev);
|
struct iwreq wrq;
|
||||||
const int delay = G_USEC_PER_SEC / interval;
|
|
||||||
const int max_tries = assoc_pause * interval;
|
|
||||||
nm_completion_args args;
|
|
||||||
|
|
||||||
orig_mode = nm_device_get_mode (dev);
|
orig_mode = nm_device_get_mode (dev);
|
||||||
if (orig_mode == NETWORK_MODE_ADHOC)
|
if (orig_mode == NETWORK_MODE_ADHOC)
|
||||||
@@ -4252,13 +4107,30 @@ static gboolean nm_device_wireless_scan (gpointer user_data)
|
|||||||
nm_device_set_mode (dev, NETWORK_MODE_INFRA);
|
nm_device_set_mode (dev, NETWORK_MODE_INFRA);
|
||||||
nm_device_set_frequency (dev, 0);
|
nm_device_set_frequency (dev, 0);
|
||||||
|
|
||||||
scan_results = g_malloc0 (sizeof (NMWirelessScanResults));
|
wrq.u.data.pointer = NULL;
|
||||||
|
wrq.u.data.flags = 0;
|
||||||
|
wrq.u.data.length = 0;
|
||||||
|
if (iw_set_ext (nm_dev_sock_get_fd (sk), nm_device_get_iface (dev), SIOCSIWSCAN, &wrq) < 0)
|
||||||
|
{
|
||||||
|
nm_warning ("nm_device_wireless_scan(%s): couldn't trigger wireless scan. errno = %d",
|
||||||
|
nm_device_get_iface (dev), errno);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Initial pause for card to return data */
|
||||||
|
g_usleep (G_USEC_PER_SEC / 4);
|
||||||
|
|
||||||
args[0] = dev;
|
if ((results = get_scan_results (dev, sk, &results_len)))
|
||||||
args[1] = &err;
|
{
|
||||||
args[2] = sk;
|
scan_results = g_malloc0 (sizeof (NMWirelessScanResults));
|
||||||
args[3] = scan_results;
|
nm_device_ref (dev);
|
||||||
nm_wait_for_completion (max_tries, delay, nm_completion_scan_has_results, NULL, args);
|
scan_results->dev = dev;
|
||||||
|
scan_results->results = results;
|
||||||
|
scan_results->results_len = results_len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nm_warning ("nm_device_wireless_scan(%s): get_scan_results() returned an error.", nm_device_get_iface (dev));
|
||||||
|
}
|
||||||
|
|
||||||
nm_device_set_mode (dev, orig_mode);
|
nm_device_set_mode (dev, orig_mode);
|
||||||
/* Only set frequency if ad-hoc mode */
|
/* Only set frequency if ad-hoc mode */
|
||||||
@@ -4269,28 +4141,20 @@ static gboolean nm_device_wireless_scan (gpointer user_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nm_dev_sock_close (sk);
|
nm_dev_sock_close (sk);
|
||||||
|
|
||||||
if (!scan_results->scan_head.result)
|
|
||||||
{
|
|
||||||
g_free (scan_results);
|
|
||||||
scan_results = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
nm_unlock_mutex (dev->options.wireless.scan_mutex, __FUNCTION__);
|
nm_unlock_mutex (dev->options.wireless.scan_mutex, __FUNCTION__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* We run the scan processing function from the main thread, since it must deliver
|
/* We run the scan processing function from the main thread, since it must deliver
|
||||||
* messages over DBUS. Plus, that way the main thread is the only thread that has
|
* messages over DBUS. Plus, that way the main thread is the only thread that has
|
||||||
* to modify the device's access point list.
|
* to modify the device's access point list.
|
||||||
*/
|
*/
|
||||||
if ((scan_results != NULL) && (scan_results->scan_head.result != NULL))
|
if (scan_results != NULL)
|
||||||
{
|
{
|
||||||
guint scan_process_source_id = 0;
|
guint scan_process_source_id = 0;
|
||||||
GSource *scan_process_source = g_idle_source_new ();
|
GSource * scan_process_source = g_idle_source_new ();
|
||||||
GTimeVal cur_time;
|
GTimeVal cur_time;
|
||||||
|
|
||||||
scan_results->dev = dev;
|
|
||||||
g_source_set_callback (scan_process_source, nm_device_wireless_process_scan_results, scan_results, NULL);
|
g_source_set_callback (scan_process_source, nm_device_wireless_process_scan_results, scan_results, NULL);
|
||||||
scan_process_source_id = g_source_attach (scan_process_source, dev->app_data->main_context);
|
scan_process_source_id = g_source_attach (scan_process_source, dev->app_data->main_context);
|
||||||
g_source_unref (scan_process_source);
|
g_source_unref (scan_process_source);
|
||||||
@@ -4500,10 +4364,6 @@ out:
|
|||||||
return supports_mii;
|
return supports_mii;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************/
|
|
||||||
/* End Code ripped from HAL */
|
|
||||||
/****************************************/
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************/
|
/****************************************/
|
||||||
/* Test device routes */
|
/* Test device routes */
|
||||||
@@ -4520,3 +4380,338 @@ gboolean nm_device_is_test_device (NMDevice *dev)
|
|||||||
return (dev->test_device);
|
return (dev->test_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************/
|
||||||
|
/* Start code ripped from wpa_supplicant */
|
||||||
|
/*****************************************/
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2005, Jouni Malinen <jkmaline@cc.hut.fi>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
static int hex2num(char c)
|
||||||
|
{
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
return c - '0';
|
||||||
|
if (c >= 'a' && c <= 'f')
|
||||||
|
return c - 'a' + 10;
|
||||||
|
if (c >= 'A' && c <= 'F')
|
||||||
|
return c - 'A' + 10;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int hex2byte(const char *hex)
|
||||||
|
{
|
||||||
|
int a, b;
|
||||||
|
a = hex2num(*hex++);
|
||||||
|
if (a < 0)
|
||||||
|
return -1;
|
||||||
|
b = hex2num(*hex++);
|
||||||
|
if (b < 0)
|
||||||
|
return -1;
|
||||||
|
return (a << 4) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hexstr2bin(const char *hex, u8 *buf, size_t len)
|
||||||
|
{
|
||||||
|
int i, a;
|
||||||
|
const char *ipos = hex;
|
||||||
|
u8 *opos = buf;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
a = hex2byte(ipos);
|
||||||
|
if (a < 0)
|
||||||
|
return -1;
|
||||||
|
*opos++ = a;
|
||||||
|
ipos += 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static guint8 * get_scan_results (NMDevice *dev, NMSock *sk, guint32 *data_len)
|
||||||
|
{
|
||||||
|
struct iwreq iwr;
|
||||||
|
guint8 *res_buf;
|
||||||
|
size_t len, res_buf_len = 1000;
|
||||||
|
guint8 tries = 0;
|
||||||
|
|
||||||
|
g_return_val_if_fail (dev != NULL, NULL);
|
||||||
|
g_return_val_if_fail (nm_device_is_wireless (dev), NULL);
|
||||||
|
g_return_val_if_fail (sk != NULL, NULL);
|
||||||
|
|
||||||
|
*data_len = 0;
|
||||||
|
|
||||||
|
res_buf_len = IW_SCAN_MAX_DATA;
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
res_buf = g_malloc (res_buf_len);
|
||||||
|
if (res_buf == NULL)
|
||||||
|
return NULL;
|
||||||
|
memset (&iwr, 0, sizeof(iwr));
|
||||||
|
iwr.u.data.pointer = res_buf;
|
||||||
|
iwr.u.data.flags = 0;
|
||||||
|
iwr.u.data.length = res_buf_len;
|
||||||
|
|
||||||
|
if (iw_get_ext (nm_dev_sock_get_fd (sk), nm_device_get_iface (dev), SIOCGIWSCAN, &iwr) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if ((errno == E2BIG) && (res_buf_len < 100000))
|
||||||
|
{
|
||||||
|
g_free (res_buf);
|
||||||
|
res_buf = NULL;
|
||||||
|
res_buf_len *= 2;
|
||||||
|
}
|
||||||
|
else if (errno == EAGAIN)
|
||||||
|
{
|
||||||
|
/* If the card doesn't return results after 20s, it sucks. */
|
||||||
|
if (tries > 20)
|
||||||
|
{
|
||||||
|
nm_warning ("get_scan_results(): card took too much time scanning. Get a better one.");
|
||||||
|
free (res_buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free (res_buf);
|
||||||
|
g_usleep (G_USEC_PER_SEC / 10);
|
||||||
|
tries++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nm_warning ("get_scan_results(): card returned too much scan info.");
|
||||||
|
g_free (res_buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*data_len = iwr.u.data.length;
|
||||||
|
return res_buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static gboolean process_scan_results (NMDevice *dev, const guint8 *res_buf, guint32 res_buf_len)
|
||||||
|
{
|
||||||
|
char *pos, *end, *custom, *genie, *gpos, *gend;
|
||||||
|
NMAccessPoint *ap = NULL;
|
||||||
|
size_t clen;
|
||||||
|
struct iw_event iwe_buf, *iwe = &iwe_buf;
|
||||||
|
|
||||||
|
g_return_val_if_fail (dev != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (res_buf != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (res_buf_len > 0, FALSE);
|
||||||
|
|
||||||
|
pos = (char *) res_buf;
|
||||||
|
end = (char *) res_buf + res_buf_len;
|
||||||
|
|
||||||
|
while (pos + IW_EV_LCP_LEN <= end)
|
||||||
|
{
|
||||||
|
int ssid_len;
|
||||||
|
/* Event data may be unaligned, so make a local, aligned copy
|
||||||
|
* before processing. */
|
||||||
|
memcpy (&iwe_buf, pos, IW_EV_LCP_LEN);
|
||||||
|
if (iwe->len <= IW_EV_LCP_LEN)
|
||||||
|
break;
|
||||||
|
|
||||||
|
custom = pos + IW_EV_POINT_LEN;
|
||||||
|
if (dev->options.wireless.we_version > 18 &&
|
||||||
|
(iwe->cmd == SIOCGIWESSID ||
|
||||||
|
iwe->cmd == SIOCGIWENCODE ||
|
||||||
|
iwe->cmd == IWEVGENIE ||
|
||||||
|
iwe->cmd == IWEVCUSTOM))
|
||||||
|
{
|
||||||
|
/* WE-19 removed the pointer from struct iw_point */
|
||||||
|
char *dpos = (char *) &iwe_buf.u.data.length;
|
||||||
|
int dlen = dpos - (char *) &iwe_buf;
|
||||||
|
memcpy (dpos, pos + IW_EV_LCP_LEN, sizeof (struct iw_event) - dlen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy (&iwe_buf, pos, sizeof (struct iw_event));
|
||||||
|
custom += IW_EV_POINT_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (iwe->cmd)
|
||||||
|
{
|
||||||
|
case SIOCGIWAP:
|
||||||
|
/* New access point record */
|
||||||
|
|
||||||
|
/* Merge previous AP */
|
||||||
|
if (ap)
|
||||||
|
{
|
||||||
|
gboolean new = FALSE;
|
||||||
|
gboolean strength_changed = FALSE;
|
||||||
|
GTimeVal cur_time;
|
||||||
|
|
||||||
|
g_get_current_time (&cur_time);
|
||||||
|
nm_ap_set_last_seen (ap, &cur_time);
|
||||||
|
|
||||||
|
/* If the AP is not broadcasting its ESSID, try to fill it in here from our
|
||||||
|
* allowed list where we cache known MAC->ESSID associations.
|
||||||
|
*/
|
||||||
|
if (!nm_ap_get_essid (ap))
|
||||||
|
nm_ap_list_copy_one_essid_by_address (ap, dev->app_data->allowed_ap_list);
|
||||||
|
|
||||||
|
/* Add the AP to the device's AP list */
|
||||||
|
if (nm_ap_list_merge_scanned_ap (nm_device_ap_list_get (dev), ap, &new, &strength_changed))
|
||||||
|
{
|
||||||
|
DBusConnection *con = dev->app_data->dbus_connection;
|
||||||
|
/* Handle dbus signals that we need to broadcast when the AP is added to the list or changes strength */
|
||||||
|
if (new)
|
||||||
|
nm_dbus_signal_wireless_network_change (con, dev, ap, NETWORK_STATUS_APPEARED, -1);
|
||||||
|
else if (strength_changed)
|
||||||
|
{
|
||||||
|
nm_dbus_signal_wireless_network_change (con, dev, ap, NETWORK_STATUS_STRENGTH_CHANGED,
|
||||||
|
nm_ap_get_strength (ap));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nm_ap_unref (ap);
|
||||||
|
ap = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* New AP with some defaults */
|
||||||
|
ap = nm_ap_new ();
|
||||||
|
nm_ap_set_address (ap, (const struct ether_addr *)(iwe->u.ap_addr.sa_data));
|
||||||
|
nm_ap_set_auth_method (ap, NM_DEVICE_AUTH_METHOD_NONE);
|
||||||
|
nm_ap_set_mode (ap, NETWORK_MODE_INFRA);
|
||||||
|
break;
|
||||||
|
case SIOCGIWMODE:
|
||||||
|
switch (iwe->u.mode)
|
||||||
|
{
|
||||||
|
case IW_MODE_ADHOC:
|
||||||
|
nm_ap_set_mode (ap, NETWORK_MODE_ADHOC);
|
||||||
|
break;
|
||||||
|
case IW_MODE_MASTER:
|
||||||
|
case IW_MODE_INFRA:
|
||||||
|
nm_ap_set_mode (ap, NETWORK_MODE_INFRA);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SIOCGIWESSID:
|
||||||
|
ssid_len = iwe->u.essid.length;
|
||||||
|
if (custom + ssid_len > end)
|
||||||
|
break;
|
||||||
|
if (iwe->u.essid.flags && (ssid_len > 0) && (ssid_len <= IW_ESSID_MAX_SIZE))
|
||||||
|
{
|
||||||
|
gboolean set = TRUE;
|
||||||
|
char *essid = g_malloc (IW_ESSID_MAX_SIZE + 1);
|
||||||
|
memcpy (essid, custom, ssid_len);
|
||||||
|
essid[ssid_len] = '\0';
|
||||||
|
if ((strlen (essid) >= 8) && (strcmp (essid, "<hidden>") != 0)) /* Stupid ipw drivers use <hidden> */
|
||||||
|
set = FALSE;
|
||||||
|
if (set)
|
||||||
|
nm_ap_set_essid (ap, essid);
|
||||||
|
g_free (essid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SIOCGIWFREQ:
|
||||||
|
nm_ap_set_freq (ap, iw_freq2float(&(iwe->u.freq)));
|
||||||
|
break;
|
||||||
|
case IWEVQUAL:
|
||||||
|
nm_ap_set_strength (ap, nm_wireless_qual_to_percent (&(iwe->u.qual),
|
||||||
|
(const iwqual *)(&dev->options.wireless.max_qual),
|
||||||
|
(const iwqual *)(&dev->options.wireless.avg_qual)));
|
||||||
|
break;
|
||||||
|
case SIOCGIWENCODE:
|
||||||
|
if (!(iwe->u.data.flags & IW_ENCODE_DISABLED))
|
||||||
|
{
|
||||||
|
nm_ap_set_encrypted (ap, TRUE);
|
||||||
|
nm_ap_set_auth_method (ap, NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#if 0
|
||||||
|
case SIOCGIWRATE:
|
||||||
|
custom = pos + IW_EV_LCP_LEN;
|
||||||
|
clen = iwe->len;
|
||||||
|
if (custom + clen > end)
|
||||||
|
break;
|
||||||
|
maxrate = 0;
|
||||||
|
while (((ssize_t) clen) >= sizeof(struct iw_param)) {
|
||||||
|
/* Note: may be misaligned, make a local,
|
||||||
|
* aligned copy */
|
||||||
|
memcpy(&p, custom, sizeof(struct iw_param));
|
||||||
|
if (p.value > maxrate)
|
||||||
|
maxrate = p.value;
|
||||||
|
clen -= sizeof(struct iw_param);
|
||||||
|
custom += sizeof(struct iw_param);
|
||||||
|
}
|
||||||
|
results[ap_num].maxrate = maxrate;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case IWEVGENIE:
|
||||||
|
#define GENERIC_INFO_ELEM 0xdd
|
||||||
|
#define RSN_INFO_ELEM 0x30
|
||||||
|
gpos = genie = custom;
|
||||||
|
gend = genie + iwe->u.data.length;
|
||||||
|
if (gend > end)
|
||||||
|
{
|
||||||
|
nm_warning ("get_scan_results(): IWEVGENIE overflow.");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while ((gpos + 1 < gend) && (gpos + 2 + (u8) gpos[1] <= gend))
|
||||||
|
{
|
||||||
|
u8 ie = gpos[0], ielen = gpos[1] + 2;
|
||||||
|
if (ielen > AP_MAX_WPA_IE_LEN)
|
||||||
|
{
|
||||||
|
gpos += ielen;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
switch (ie)
|
||||||
|
{
|
||||||
|
case GENERIC_INFO_ELEM:
|
||||||
|
if ((ielen < 2 + 4) || (memcmp (&gpos[2], "\x00\x50\xf2\x01", 4) != 0))
|
||||||
|
break;
|
||||||
|
nm_ap_set_wpa_ie (ap, gpos, ielen);
|
||||||
|
break;
|
||||||
|
case RSN_INFO_ELEM:
|
||||||
|
nm_ap_set_rsn_ie (ap, gpos, ielen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gpos += ielen;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case IWEVCUSTOM:
|
||||||
|
clen = iwe->u.data.length;
|
||||||
|
if (custom + clen > end)
|
||||||
|
break;
|
||||||
|
if (clen > 7 && ((strncmp (custom, "wpa_ie=", 7) == 0) || (strncmp (custom, "rsn_ie=", 7) == 0)))
|
||||||
|
{
|
||||||
|
char *spos;
|
||||||
|
int bytes;
|
||||||
|
char *ie_buf;
|
||||||
|
|
||||||
|
spos = custom + 7;
|
||||||
|
bytes = custom + clen - spos;
|
||||||
|
if (bytes & 1)
|
||||||
|
break;
|
||||||
|
bytes /= 2;
|
||||||
|
if (bytes > AP_MAX_WPA_IE_LEN)
|
||||||
|
{
|
||||||
|
nm_warning ("get_scan_results(): IE was too long (%d bytes).", bytes);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ie_buf = g_malloc0 (bytes);
|
||||||
|
hexstr2bin (spos, ie_buf, bytes);
|
||||||
|
if (strncmp (custom, "wpa_ie=", 7) == 0)
|
||||||
|
nm_ap_set_wpa_ie (ap, ie_buf, bytes);
|
||||||
|
else if (strncmp (custom, "rsn_ie=", 7) == 0)
|
||||||
|
nm_ap_set_rsn_ie (ap, ie_buf, bytes);
|
||||||
|
g_free (ie_buf);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += iwe->len;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************/
|
||||||
|
/* End code ripped from wpa_supplicant */
|
||||||
|
/*****************************************/
|
||||||
|
@@ -351,26 +351,6 @@ gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* nm_dispose_scan_results
|
|
||||||
*
|
|
||||||
* Free memory used by the wireless scan results structure
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void nm_dispose_scan_results (wireless_scan *result_list)
|
|
||||||
{
|
|
||||||
wireless_scan *tmp = result_list;
|
|
||||||
|
|
||||||
while (tmp)
|
|
||||||
{
|
|
||||||
wireless_scan *tmp2 = tmp;
|
|
||||||
|
|
||||||
tmp = tmp->next;
|
|
||||||
free (tmp2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_spawn_process
|
* nm_spawn_process
|
||||||
*
|
*
|
||||||
|
@@ -58,8 +58,6 @@ int nm_null_safe_strcmp (const char *s1, const char *s2);
|
|||||||
|
|
||||||
gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr);
|
gboolean nm_ethernet_address_is_valid (const struct ether_addr *test_addr);
|
||||||
|
|
||||||
void nm_dispose_scan_results (wireless_scan *result_list);
|
|
||||||
|
|
||||||
int nm_spawn_process (const char *args);
|
int nm_spawn_process (const char *args);
|
||||||
|
|
||||||
void nm_print_device_capabilities (NMDevice *dev);
|
void nm_print_device_capabilities (NMDevice *dev);
|
||||||
|
Reference in New Issue
Block a user