2007-06-27 Dan Williams <dcbw@redhat.com>

* Make SSIDs GByteArrays everywhere
	* Rename "essid" -> "ssid" everywhere that's appropriate
	* Refcount activation_ap member of the 802.11 wireless device class



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2620 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2007-06-27 16:18:52 +00:00
parent 8c33f85a90
commit f4540f0412
22 changed files with 685 additions and 422 deletions

View file

@ -1,3 +1,9 @@
2007-06-27 Dan Williams <dcbw@redhat.com>
* Make SSIDs GByteArrays everywhere
* Rename "essid" -> "ssid" everywhere that's appropriate
* Refcount activation_ap member of the 802.11 wireless device class
2007-06-27 Tambet Ingo <tambet@ximian.com>
* libnm-glib/nm-object.[ch]: Add these to the SVN, oops.

View file

@ -4,7 +4,7 @@
<interface name="org.freedesktop.NetworkManager.AccessPoint">
<property name="Capabilities" type="u" access="read"/>
<property name="Encrypted" type="b" access="read"/>
<property name="Essid" type="s" access="read"/>
<property name="Ssid" type="ay" access="read"/>
<property name="Frequency" type="d" access="read"/>
<property name="HwAddress" type="s" access="read"/>
<property name="Mode" type="i" access="read"/>

View file

@ -3,12 +3,57 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <iwlib.h>
#include <wireless.h>
#include "nm-client.h"
#include "nm-device.h"
#include "nm-device-802-3-ethernet.h"
#include "nm-device-802-11-wireless.h"
/* Shamelessly ripped from the Linux kernel ieee80211 stack */
static gboolean
nm_utils_is_empty_ssid (const char * ssid, int len)
{
/* Single white space is for Linksys APs */
if (len == 1 && ssid[0] == ' ')
return TRUE;
/* Otherwise, if the entire ssid is 0, we assume it is hidden */
while (len--) {
if (ssid[len] != '\0')
return FALSE;
}
return TRUE;
}
static const char *
nm_utils_escape_ssid (const char * ssid, guint32 len)
{
static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
const char *s = ssid;
char *d = escaped;
if (nm_utils_is_empty_ssid (ssid, len)) {
memcpy (escaped, "<hidden>", sizeof ("<hidden>"));
return escaped;
}
len = MIN (len, (guint32) IW_ESSID_MAX_SIZE);
while (len--) {
if (*s == '\0') {
*d++ = '\\';
*d++ = '0';
s++;
} else {
*d++ = *s++;
}
}
*d = '\0';
return escaped;
}
static gboolean
test_wireless_enabled (NMClient *client)
{
@ -120,11 +165,13 @@ dump_ip4_config (NMIP4Config *cfg)
static void
dump_access_point (NMAccessPoint *ap)
{
char *str;
GByteArray * ssid;
char * str;
str = nm_access_point_get_essid (ap);
g_print ("\tEssid: %s\n", str);
g_free (str);
ssid = nm_access_point_get_ssid (ap);
g_print ("\tSsid: %s\n",
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
g_byte_array_free (ssid, TRUE);
str = nm_access_point_get_hw_address (ap);
g_print ("\tMAC Address: %s\n", str);

View file

@ -117,12 +117,12 @@ nm_access_point_is_encrypted (NMAccessPoint *ap)
return nm_object_get_boolean_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "Encrypted");
}
char *
nm_access_point_get_essid (NMAccessPoint *ap)
GByteArray *
nm_access_point_get_ssid (NMAccessPoint *ap)
{
g_return_val_if_fail (NM_IS_ACCESS_POINT (ap), NULL);
return nm_object_get_string_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "Essid");
return nm_object_get_byte_array_property (NM_OBJECT (ap), NM_DBUS_INTERFACE_ACCESS_POINT, "Ssid");
}
gdouble

View file

@ -27,13 +27,13 @@ GType nm_access_point_get_type (void);
NMAccessPoint *nm_access_point_new (DBusGConnection *connection, const char *path);
guint32 nm_access_point_get_capabilities (NMAccessPoint *ap);
gboolean nm_access_point_is_encrypted (NMAccessPoint *ap);
char *nm_access_point_get_essid (NMAccessPoint *ap);
gdouble nm_access_point_get_frequency (NMAccessPoint *ap);
char *nm_access_point_get_hw_address (NMAccessPoint *ap);
int nm_access_point_get_mode (NMAccessPoint *ap);
guint32 nm_access_point_get_rate (NMAccessPoint *ap);
int nm_access_point_get_strength (NMAccessPoint *ap);
guint32 nm_access_point_get_capabilities (NMAccessPoint *ap);
gboolean nm_access_point_is_encrypted (NMAccessPoint *ap);
GByteArray * nm_access_point_get_ssid (NMAccessPoint *ap);
gdouble nm_access_point_get_frequency (NMAccessPoint *ap);
char * nm_access_point_get_hw_address (NMAccessPoint *ap);
int nm_access_point_get_mode (NMAccessPoint *ap);
guint32 nm_access_point_get_rate (NMAccessPoint *ap);
int nm_access_point_get_strength (NMAccessPoint *ap);
#endif /* NM_ACCESS_POINT_H */

View file

@ -301,3 +301,27 @@ nm_object_get_double_property (NMObject *object,
return d;
}
GByteArray *
nm_object_get_byte_array_property (NMObject *object,
const char *interface,
const char *prop_name)
{
GByteArray * array = NULL;
GValue value = {0,};
if (nm_object_get_property (object, interface, prop_name, &value)) {
GArray * tmp = g_value_get_boxed (&value);
int i;
unsigned char byte;
array = g_byte_array_sized_new (tmp->len);
for (i = 0; i < tmp->len; i++) {
byte = g_array_index (tmp, unsigned char, i);
g_byte_array_append (array, &byte, 1);
}
}
return array;
}

View file

@ -64,5 +64,9 @@ gdouble nm_object_get_double_property (NMObject *object,
const char *interface,
const char *prop_name);
GByteArray *nm_object_get_byte_array_property (NMObject *object,
const char *interface,
const char *prop_name);
#endif /* NM_OBJECT_H */

View file

@ -30,7 +30,7 @@
#include "nm-access-point-glue.h"
/* This is a controlled list. Want to add to it? Stop. Ask first. */
static const char * default_essid_list[] =
static const char * default_ssid_list[] =
{
"linksys",
"linksys-a",
@ -49,8 +49,7 @@ typedef struct
char *dbus_path;
/* Scanned or cached values */
char * essid;
char * orig_essid;
GByteArray * ssid;
struct ether_addr address;
int mode; /* from IW_MODE_* in wireless.h */
gint8 strength;
@ -93,16 +92,16 @@ enum {
PROP_0,
PROP_CAPABILITIES,
PROP_ENCRYPTED,
PROP_ESSID,
PROP_SSID,
PROP_FREQUENCY,
PROP_HW_ADDRESS,
PROP_MODE,
PROP_RATE,
PROP_STRENGTH,
LAST_PROP
};
static void
nm_ap_init (NMAccessPoint *ap)
{
@ -121,8 +120,7 @@ finalize (GObject *object)
NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (object);
g_free (priv->dbus_path);
g_free (priv->essid);
g_free (priv->orig_essid);
g_byte_array_free (priv->ssid, TRUE);
g_slist_foreach (priv->user_addresses, (GFunc)g_free, NULL);
g_slist_free (priv->user_addresses);
@ -137,28 +135,28 @@ set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec)
{
NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (object);
const char *essid;
GArray * ssid;
int mode;
switch (prop_id) {
case PROP_CAPABILITIES:
priv->capabilities = g_value_get_uint (value);
break;
case PROP_ESSID:
essid = g_value_get_string (value);
if (priv->essid) {
g_free (priv->essid);
g_free (priv->orig_essid);
priv->essid = NULL;
priv->orig_essid = NULL;
case PROP_SSID:
ssid = g_value_get_boxed (value);
if (priv->ssid) {
g_byte_array_free (priv->ssid, TRUE);
priv->ssid = NULL;
}
if (essid) {
priv->orig_essid = g_strdup (essid);
priv->essid = nm_utils_essid_to_utf8 (essid);
if (ssid) {
int i;
unsigned char byte;
priv->ssid = g_byte_array_sized_new (ssid->len);
for (i = 0; i < ssid->len; i++) {
byte = g_array_index (ssid, unsigned char, i);
g_byte_array_append (priv->ssid, &byte, 1);
}
}
break;
case PROP_FREQUENCY:
priv->freq = g_value_get_double (value);
@ -189,6 +187,8 @@ get_property (GObject *object, guint prop_id,
{
NMAccessPointPrivate *priv = NM_AP_GET_PRIVATE (object);
char hw_addr_buf[20];
GArray * ssid;
int i;
switch (prop_id) {
case PROP_CAPABILITIES:
@ -197,8 +197,12 @@ get_property (GObject *object, guint prop_id,
case PROP_ENCRYPTED:
g_value_set_boolean (value, !(priv->capabilities & NM_802_11_CAP_PROTO_NONE));
break;
case PROP_ESSID:
g_value_set_string (value, priv->essid);
case PROP_SSID:
ssid = g_array_sized_new (FALSE, TRUE, sizeof (unsigned char), priv->ssid->len);
for (i = 0; i < priv->ssid->len; i++)
g_array_append_val (ssid, priv->ssid->data[i]);
g_value_set_boxed (value, ssid);
g_array_free (ssid, TRUE);
break;
case PROP_FREQUENCY:
g_value_set_double (value, priv->freq);
@ -273,12 +277,12 @@ nm_ap_class_init (NMAccessPointClass *ap_class)
G_PARAM_READABLE));
g_object_class_install_property
(object_class, PROP_ESSID,
g_param_spec_string (NM_AP_ESSID,
"ESSID",
"ESSID",
NULL,
G_PARAM_READWRITE));
(object_class, PROP_SSID,
g_param_spec_boxed (NM_AP_SSID,
"SSID",
"SSID",
DBUS_TYPE_G_UCHAR_ARRAY,
G_PARAM_READWRITE));
g_object_class_install_property
(object_class, PROP_FREQUENCY,
@ -381,10 +385,11 @@ nm_ap_new_from_ap (NMAccessPoint *src_ap)
src_priv = NM_AP_GET_PRIVATE (src_ap);
new_priv = NM_AP_GET_PRIVATE (new_ap);
if (src_priv->essid && (strlen (src_priv->essid) > 0))
{
new_priv->essid = g_strdup (src_priv->essid);
new_priv->orig_essid = g_strdup (src_priv->orig_essid);
if (src_priv->ssid) {
new_priv->ssid = g_byte_array_sized_new (src_priv->ssid->len);
g_byte_array_append (new_priv->ssid,
src_priv->ssid->data,
src_priv->ssid->len);
}
memcpy (&new_priv->address, &src_priv->address, sizeof (struct ether_addr));
new_priv->mode = src_priv->mode;
@ -416,21 +421,18 @@ foreach_property_cb (gpointer key, gpointer value, gpointer user_data)
GArray *array = g_value_get_boxed (variant);
if (!strcmp (key, "ssid")) {
char ssid[33];
int ssid_len = sizeof (ssid);
guint32 len = MIN (IW_ESSID_MAX_SIZE, array->len);
GByteArray * ssid;
if (array->len < sizeof (ssid))
ssid_len = array->len;
if (ssid_len <= 0)
return;
/* Stupid ieee80211 layer uses <hidden> */
if (((ssid_len == 8) || (ssid_len == 9))
if (((len == 8) || (len == 9))
&& (memcmp (array->data, "<hidden>", 8) == 0))
return;
memset (&ssid, 0, sizeof (ssid));
memcpy (&ssid, array->data, ssid_len);
ssid[32] = '\0';
nm_ap_set_essid (ap, ssid);
ssid = g_byte_array_sized_new (len);
g_byte_array_append (ssid, array->data, len);
nm_ap_set_ssid (ap, ssid);
g_byte_array_free (ssid, TRUE);
} else if (!strcmp (key, "bssid")) {
struct ether_addr addr;
@ -496,7 +498,7 @@ nm_ap_new_from_properties (GHashTable *properties)
g_get_current_time (&cur_time);
nm_ap_set_last_seen (ap, cur_time.tv_sec);
if (!nm_ap_get_essid (ap))
if (!nm_ap_get_ssid (ap))
nm_ap_set_broadcast (ap, FALSE);
return ap;
@ -542,28 +544,21 @@ void nm_ap_set_timestamp_via_timestamp (NMAccessPoint *ap, const GTimeVal *times
}
/*
* Get/set functions for essid
* Get/set functions for ssid
*
*/
const char * nm_ap_get_essid (const NMAccessPoint *ap)
const GByteArray * nm_ap_get_ssid (const NMAccessPoint *ap)
{
g_return_val_if_fail (NM_IS_AP (ap), NULL);
return NM_AP_GET_PRIVATE (ap)->essid;
return NM_AP_GET_PRIVATE (ap)->ssid;
}
const char * nm_ap_get_orig_essid (const NMAccessPoint *ap)
{
g_return_val_if_fail (NM_IS_AP (ap), NULL);
return NM_AP_GET_PRIVATE (ap)->orig_essid;
}
void nm_ap_set_essid (NMAccessPoint *ap, const char * essid)
void nm_ap_set_ssid (NMAccessPoint *ap, const GByteArray * ssid)
{
g_return_if_fail (NM_IS_AP (ap));
g_object_set (ap, NM_AP_ESSID, essid, NULL);
g_object_set (ap, NM_AP_SSID, ssid, NULL);
}
@ -926,18 +921,20 @@ void nm_ap_set_user_addresses (NMAccessPoint *ap, GSList *list)
}
gboolean nm_ap_has_manufacturer_default_essid (NMAccessPoint *ap)
gboolean nm_ap_has_manufacturer_default_ssid (NMAccessPoint *ap)
{
const char **default_essid = default_essid_list;
const char *this_essid;
const char **default_ssid = default_ssid_list;
const GByteArray * this_ssid;
g_return_val_if_fail (NM_IS_AP (ap), FALSE);
this_essid = NM_AP_GET_PRIVATE (ap)->essid;
this_ssid = NM_AP_GET_PRIVATE (ap)->ssid;
while (*default_essid)
{
if (!strcmp (*(default_essid++), this_essid))
return TRUE;
while (*default_ssid) {
if (this_ssid->len == strlen (*default_ssid)) {
if (!memcmp (*default_ssid, this_ssid->data, this_ssid->len))
return TRUE;
}
default_ssid++;
}
return FALSE;

View file

@ -38,7 +38,7 @@
#define NM_AP_CAPABILITIES "capabilities"
#define NM_AP_ENCRYPTED "encrypted"
#define NM_AP_ESSID "essid"
#define NM_AP_SSID "ssid"
#define NM_AP_FREQUENCY "frequency"
#define NM_AP_HW_ADDRESS "hw-address"
#define NM_AP_MODE "mode"
@ -67,10 +67,8 @@ const GTimeVal * nm_ap_get_timestamp (const NMAccessPoint *ap);
void nm_ap_set_timestamp (NMAccessPoint *ap, glong sec, glong usec);
void nm_ap_set_timestamp_via_timestamp (NMAccessPoint *ap, const GTimeVal *timestamp);
const char * nm_ap_get_essid (const NMAccessPoint *ap);
void nm_ap_set_essid (NMAccessPoint *ap, const char *essid);
/* Get essid in original over-the-air form */
const char * nm_ap_get_orig_essid (const NMAccessPoint *ap);
const GByteArray * nm_ap_get_ssid (const NMAccessPoint * ap);
void nm_ap_set_ssid (NMAccessPoint * ap, const GByteArray * ssid);
guint32 nm_ap_get_capabilities (NMAccessPoint *ap);
void nm_ap_set_capabilities (NMAccessPoint *ap, guint32 capabilities);
@ -125,6 +123,6 @@ void nm_ap_add_capabilities_for_wep (NMAccessPoint *ap);
* This is not intended to return true for all APs with manufacturer defaults. It is intended to return true for
* only the MOST COMMON manufacturing defaults.
*/
gboolean nm_ap_has_manufacturer_default_essid (NMAccessPoint *ap);
gboolean nm_ap_has_manufacturer_default_ssid (NMAccessPoint *ap);
#endif /* NM_ACCESS_POINT_H */

View file

@ -158,22 +158,23 @@ void nm_ap_list_remove_ap (NMAccessPointList *list, NMAccessPoint *ap)
/*
* nm_ap_list_remove_ap_by_essid
* nm_ap_list_remove_ap_by_ssid
*
* Helper to remove an AP from an AP list by the AP's ESSID.
* Helper to remove an AP from an AP list by the AP's SSID.
*
*/
void nm_ap_list_remove_ap_by_essid (NMAccessPointList *list, const char *network)
void
nm_ap_list_remove_ap_by_ssid (NMAccessPointList *list, const GByteArray * ssid)
{
GSList *elt = NULL;
GSList * elt = NULL;
g_return_if_fail (list != NULL);
g_return_if_fail (network != NULL);
g_return_if_fail (ssid != NULL);
for (elt = list->ap_list; elt; elt = g_slist_next (elt)) {
NMAccessPoint * list_ap = (NMAccessPoint *) elt->data;
if (nm_null_safe_strcmp (nm_ap_get_essid (list_ap), network) == 0) {
if (nm_utils_same_ssid (nm_ap_get_ssid (list_ap), ssid)) {
list->ap_list = g_slist_remove_link (list->ap_list, elt);
g_object_unref (list_ap);
g_slist_free (elt);
@ -182,10 +183,10 @@ void nm_ap_list_remove_ap_by_essid (NMAccessPointList *list, const char *network
}
}
/* nm_ap_list_remove_duplicate_essids
/* nm_ap_list_remove_duplicate_ssids
*
*/
void nm_ap_list_remove_duplicate_essids (NMAccessPointList *list)
void nm_ap_list_remove_duplicate_ssids (NMAccessPointList *list)
{
NMAccessPoint *removal_ap;
NMAccessPoint *list_ap_max;
@ -201,12 +202,14 @@ void nm_ap_list_remove_duplicate_essids (NMAccessPointList *list)
for (elt_i = list->ap_list; elt_i; elt_i = g_slist_next (elt_i)) {
NMAccessPoint * list_ap_i = (NMAccessPoint *) elt_i->data;
const GByteArray * list_ap_i_ssid = nm_ap_get_ssid (list_ap_i);
gboolean found = FALSE;
for (elt_j = list->ap_list; elt_j < elt_i; elt_j = g_slist_next (elt_j)) {
NMAccessPoint *list_ap_j = (NMAccessPoint *) elt_j->data;
NMAccessPoint * list_ap_j = (NMAccessPoint *) elt_j->data;
const GByteArray * list_ap_j_ssid = nm_ap_get_ssid (list_ap_j);
if ((found = (nm_null_safe_strcmp (nm_ap_get_essid (list_ap_i), nm_ap_get_essid (list_ap_j)) == 0)))
if ((found = nm_utils_same_ssid (list_ap_i_ssid, list_ap_j_ssid)))
break;
}
@ -219,9 +222,10 @@ void nm_ap_list_remove_duplicate_essids (NMAccessPointList *list)
for (elt_j = g_slist_next (elt_i); elt_j; elt_j = g_slist_next (elt_j)) {
NMAccessPoint *list_ap_j = (NMAccessPoint *) elt_j->data;
const GByteArray * list_ap_j_ssid = nm_ap_get_ssid (list_ap_j);
strengthj = nm_ap_get_strength (list_ap_j);
if (nm_null_safe_strcmp (nm_ap_get_essid (list_ap_i), nm_ap_get_essid (list_ap_j)) == 0) {
if (nm_utils_same_ssid (list_ap_i_ssid, list_ap_j_ssid)) {
if (strengthj > max_strength) {
removal_list = g_slist_append (removal_list, list_ap_max);
list_ap_max = list_ap_j;
@ -242,38 +246,35 @@ void nm_ap_list_remove_duplicate_essids (NMAccessPointList *list)
/*
* nm_ap_list_get_ap_by_essid
* nm_ap_list_get_ap_by_ssid
*
* Search through an access point list and return the access point
* that has a given essid.
* that has a given SSID.
*
*/
NMAccessPoint *nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char *network)
NMAccessPoint *
nm_ap_list_get_ap_by_ssid (NMAccessPointList *list, const GByteArray * ssid)
{
NMAccessPoint *ap;
NMAccessPoint *found_ap = NULL;
NMAPListIter *iter;
if (!network)
return (NULL);
if (!list)
return (NULL);
if (!ssid || !list)
return NULL;
if (!(iter = nm_ap_list_iter_new (list)))
return (NULL);
return NULL;
while ((ap = nm_ap_list_iter_next (iter)))
{
if (nm_ap_get_essid (ap) && (nm_null_safe_strcmp (nm_ap_get_essid (ap), network) == 0))
{
while ((ap = nm_ap_list_iter_next (iter))) {
const GByteArray * ap_ssid = nm_ap_get_ssid (ap);
if (ap_ssid && nm_utils_same_ssid (ap_ssid, ssid)) {
found_ap = ap;
break;
}
}
nm_ap_list_iter_free (iter);
return (found_ap);
return found_ap;
}
@ -362,7 +363,7 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou
{
NMAccessPoint *src_ap = NULL;
if ((src_ap = nm_ap_list_get_ap_by_essid (source, nm_ap_get_essid (dest_ap))))
if ((src_ap = nm_ap_list_get_ap_by_ssid (source, nm_ap_get_ssid (dest_ap))))
{
nm_ap_set_invalid (dest_ap, nm_ap_get_invalid (src_ap));
nm_ap_set_security (dest_ap, nm_ap_get_security (src_ap));
@ -374,45 +375,45 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou
/*
* nm_ap_list_copy_one_essid_by_address
* nm_ap_list_copy_one_ssid_by_address
*
* If the access point doesn't have an ESSID, search through a list of access points
* If the access point doesn't have an SSID, search through a list of access points
* and find one (if any) that has the MAC address of the access point we're looking for.
* If one is found, copy the essid over to the original access point.
* If one is found, copy the SSID over to the original access point.
*
*/
void
nm_ap_list_copy_one_essid_by_address (NMAccessPoint *ap,
NMAccessPointList *search_list)
nm_ap_list_copy_one_ssid_by_address (NMAccessPoint *ap,
NMAccessPointList *search_list)
{
NMAccessPoint *found_ap;
const char *essid;
NMAccessPoint * found_ap;
const GByteArray * ssid;
g_return_if_fail (ap != NULL);
/* Ignore APs that already have an ESSID */
if (!search_list || nm_ap_get_essid (ap))
/* Ignore APs that already have an SSID */
if (!search_list || nm_ap_get_ssid (ap))
return;
found_ap = nm_ap_list_get_ap_by_address (search_list, nm_ap_get_address (ap));
essid = found_ap ? nm_ap_get_essid (found_ap) : NULL;
ssid = found_ap ? nm_ap_get_ssid (found_ap) : NULL;
if (essid)
nm_ap_set_essid (ap, essid);
if (ssid)
nm_ap_set_ssid (ap, ssid);
}
/*
* nm_ap_list_copy_essids_by_address
* nm_ap_list_copy_ssids_by_address
*
* For each blank-essid access point in the destination list, try to find
* For each blank-SSID access point in the destination list, try to find
* an access point in the source list that has the same MAC address, and if
* its found, copy the source access point's essid to the dest access point.
* its found, copy the source access point's SSID to the dest access point.
*
*/
void
nm_ap_list_copy_essids_by_address (NMAccessPointList *dest,
NMAccessPointList *source)
nm_ap_list_copy_ssids_by_address (NMAccessPointList *dest,
NMAccessPointList *source)
{
NMAPListIter *iter;
NMAccessPoint *dest_ap;
@ -424,7 +425,7 @@ nm_ap_list_copy_essids_by_address (NMAccessPointList *dest,
return;
while ((dest_ap = nm_ap_list_iter_next (iter)))
nm_ap_list_copy_one_essid_by_address (dest_ap, source);
nm_ap_list_copy_one_ssid_by_address (dest_ap, source);
nm_ap_list_iter_free (iter);
}
@ -532,6 +533,7 @@ void nm_ap_list_print_members (NMAccessPointList *list, const char *name)
const struct ether_addr * eth_addr = nm_ap_get_address (ap);
char addr[ETH_ALEN];
double freq = nm_ap_get_freq (ap);
const GByteArray * ssid = nm_ap_get_ssid (ap);
if (security)
key = nm_ap_security_get_key (security);
@ -541,7 +543,7 @@ void nm_ap_list_print_members (NMAccessPointList *list, const char *name)
nm_info ("%d)\t'%s' (%p) stamp=%ld enc=%d addr=" MAC_FMT " strength=%d "
"freq=[%f/%d] rate=%d inval=%d mode=%d seen=%ld",
i,
nm_ap_get_essid (ap),
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)",
ap,
timestamp->tv_sec,
nm_ap_get_encrypted (ap),

View file

@ -39,15 +39,15 @@ gboolean nm_ap_list_is_empty (NMAccessPointList *list);
void nm_ap_list_append_ap (NMAccessPointList *list, NMAccessPoint *ap);
void nm_ap_list_remove_ap (NMAccessPointList *list, NMAccessPoint *ap);
void nm_ap_list_remove_ap_by_essid (NMAccessPointList *list, const char *network);
void nm_ap_list_remove_duplicate_essids (NMAccessPointList *list);
void nm_ap_list_remove_ap_by_ssid (NMAccessPointList *list, const GByteArray * ssid);
void nm_ap_list_remove_duplicate_ssids (NMAccessPointList *list);
NMAccessPoint * nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char *network);
NMAccessPoint * nm_ap_list_get_ap_by_ssid (NMAccessPointList *list, const GByteArray * ssid);
NMAccessPoint * nm_ap_list_get_ap_by_address (NMAccessPointList *list, const struct ether_addr *addr);
void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_essids_by_address (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_one_essid_by_address (NMAccessPoint *ap, NMAccessPointList *search_list);
void nm_ap_list_copy_ssids_by_address (NMAccessPointList *dest, NMAccessPointList *source);
void nm_ap_list_copy_one_ssid_by_address (NMAccessPoint *ap, NMAccessPointList *search_list);
NMNetworkType nm_ap_list_get_type (NMAccessPointList *list);

View file

@ -148,10 +148,14 @@ static NMDevice * nm_policy_auto_get_best_device (NMPolicy *policy, NMAccessPoin
highest_priority_dev = NM_DEVICE (best_wireless_dev);
}
#if 0
nm_info ("AUTO: Best wired device = %s, best wireless device = %s (%s)", best_wired_dev ? nm_device_get_iface (best_wired_dev) : "(null)",
best_wireless_dev ? nm_device_get_iface (best_wireless_dev) : "(null)", (best_wireless_dev && *ap) ? nm_ap_get_essid (*ap) : "null" );
#endif
if (FALSE) {
const GByteArray * ssid = (best_wireless_dev && *ap) ? nm_ap_get_ssid (*ap) : NULL;
nm_info ("AUTO: Best wired device = %s, best wireless device = %s (%s)",
best_wired_dev ? nm_device_get_iface (NM_DEVICE (best_wired_dev)) : "(null)",
best_wireless_dev ? nm_device_get_iface (NM_DEVICE (best_wireless_dev)) : "(null)",
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "null" );
}
return highest_priority_dev;
}
@ -161,28 +165,28 @@ create_connection (NMDevice *device, NMAccessPoint *ap)
{
NMConnection *connection = NULL;
NMSetting *setting = NULL;
if (NM_IS_DEVICE_802_3_ETHERNET (device)) {
nm_info ("Will activate connection '%s'.", nm_device_get_iface (device));
setting = nm_setting_wired_new ();
} else if (NM_IS_DEVICE_802_11_WIRELESS (device) && ap) {
NMSettingWireless *wireless;
const char *ssid;
const GByteArray * ssid = nm_ap_get_ssid (ap);
nm_info ("Will activate connection '%s/%s'.",
nm_device_get_iface (device),
nm_ap_get_essid (ap));
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
setting = nm_setting_wireless_new ();
wireless = (NMSettingWireless *) setting;
ssid = nm_ap_get_essid (ap);
wireless->ssid = g_byte_array_sized_new (strlen (ssid));
g_byte_array_append (wireless->ssid, (guint8 *) ssid, strlen (ssid));
wireless->ssid = g_byte_array_sized_new (ssid->len);
g_byte_array_append (wireless->ssid, ssid->data, ssid->len);
wireless->mode = g_strdup ("infrastructure");
} else
} else {
nm_warning ("Unhandled device type '%s'", G_OBJECT_CLASS_NAME (device));
}
if (setting) {
NMSettingInfo *info;
@ -216,7 +220,7 @@ nm_policy_device_change_check (gpointer user_data)
NMPolicy *policy = (NMPolicy *) user_data;
GSList *iter;
NMAccessPoint * ap = NULL;
NMDevice * new_dev;
NMDevice * new_dev = NULL;
NMDevice * old_dev = NULL;
gboolean do_switch = FALSE;
@ -309,9 +313,9 @@ nm_policy_device_change_check (gpointer user_data)
/* Only switch if the old device's wireless config is invalid */
if (NM_IS_DEVICE_802_11_WIRELESS (new_dev)) {
NMAccessPoint *old_ap = nm_device_802_11_wireless_get_activation_ap (NM_DEVICE_802_11_WIRELESS (old_dev));
const char * old_essid = nm_ap_get_essid (old_ap);
const GByteArray * old_ssid = nm_ap_get_ssid (old_ap);
int old_mode = nm_ap_get_mode (old_ap);
const char * new_essid = nm_ap_get_essid (ap);
const GByteArray * new_ssid = nm_ap_get_ssid (ap);
gboolean same_request = FALSE;
/* Schedule new activation if the currently associated
@ -319,23 +323,32 @@ nm_policy_device_change_check (gpointer user_data)
* link to the old access point. We don't switch away
* from Ad-Hoc APs either.
*/
gboolean same_essid = (nm_null_safe_strcmp (old_essid, new_essid) == 0);
gboolean same_ssid = nm_utils_same_ssid (old_ssid, new_ssid);
/* If the "best" AP's essid is the same as the current activation
* request's essid, but the current activation request isn't
/* If the "best" AP's SSID is the same as the current activation
* request's SSID, but the current activation request isn't
* done yet, don't switch. This prevents multiple requests for the
* AP's password on startup.
*/
if ((old_dev == new_dev) && nm_device_is_activating (new_dev) && same_essid)
if ((old_dev == new_dev) && nm_device_is_activating (new_dev) && same_ssid)
same_request = TRUE;
if (!same_request && (!same_essid || !old_has_link) && (old_mode != IW_MODE_ADHOC)) {
if (!same_request && (!same_ssid || !old_has_link) && (old_mode != IW_MODE_ADHOC)) {
char * new_esc_ssid;
char * old_esc_ssid;
new_esc_ssid = g_strdup (new_ssid ? nm_utils_escape_ssid (new_ssid->data, new_ssid->len) : "(none)");
old_esc_ssid = g_strdup (old_ssid ? nm_utils_escape_ssid (old_ssid->data, old_ssid->len) : "(none)");
nm_info ("SWITCH: found better connection '%s/%s'"
" than current connection '%s/%s'. "
"same_ssid=%d, have_link=%d",
nm_device_get_iface (new_dev), new_essid,
nm_device_get_iface (old_dev), old_essid,
same_essid, old_has_link);
nm_device_get_iface (new_dev),
new_esc_ssid,
nm_device_get_iface (old_dev),
old_esc_ssid,
same_ssid, old_has_link);
g_free (new_esc_ssid);
g_free (old_esc_ssid);
do_switch = TRUE;
}
} else if (NM_IS_DEVICE_802_3_ETHERNET (new_dev)) {
@ -346,7 +359,7 @@ nm_policy_device_change_check (gpointer user_data)
}
}
if (do_switch) {
if (do_switch && new_dev) {
NMConnection *connection;
connection = create_connection (new_dev, ap);
@ -446,11 +459,11 @@ nm_policy_device_list_update_from_allowed_list (gpointer user_data)
wdev = NM_DEVICE_802_11_WIRELESS (dev);
if (nm_device_get_capabilities (dev) & NM_DEVICE_CAP_WIRELESS_SCAN) {
/* Once we have the list, copy in any relevant information from our
* Allowed list and fill in the ESSID of base stations that aren't
* broadcasting their ESSID, if we have their MAC address in our
* Allowed list and fill in the SSID of base stations that aren't
* broadcasting their SSID, if we have their MAC address in our
* allowed list.
*/
nm_ap_list_copy_essids_by_address (nm_device_802_11_wireless_ap_list_get (wdev),
nm_ap_list_copy_ssids_by_address (nm_device_802_11_wireless_ap_list_get (wdev),
data->allowed_ap_list);
nm_ap_list_copy_properties (nm_device_802_11_wireless_ap_list_get (wdev),
data->allowed_ap_list);
@ -458,7 +471,7 @@ nm_policy_device_list_update_from_allowed_list (gpointer user_data)
nm_device_802_11_wireless_copy_allowed_to_dev_list (wdev, data->allowed_ap_list);
}
nm_ap_list_remove_duplicate_essids (nm_device_802_11_wireless_ap_list_get (wdev));
nm_ap_list_remove_duplicate_ssids (nm_device_802_11_wireless_ap_list_get (wdev));
}
schedule_change_check ((gpointer) global_policy);

View file

@ -582,3 +582,57 @@ int nm_utils_ip4_netmask_to_prefix (guint32 ip4_netmask)
return (32 - (i-1));
}
/* Shamelessly ripped from the Linux kernel ieee80211 stack */
gboolean
nm_utils_is_empty_ssid (const char * ssid, int len)
{
/* Single white space is for Linksys APs */
if (len == 1 && ssid[0] == ' ')
return TRUE;
/* Otherwise, if the entire ssid is 0, we assume it is hidden */
while (len--) {
if (ssid[len] != '\0')
return FALSE;
}
return TRUE;
}
const char *
nm_utils_escape_ssid (const char * ssid, guint32 len)
{
static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
const char *s = ssid;
char *d = escaped;
if (nm_utils_is_empty_ssid (ssid, len)) {
memcpy (escaped, "<hidden>", sizeof ("<hidden>"));
return escaped;
}
len = MIN (len, (guint32) IW_ESSID_MAX_SIZE);
while (len--) {
if (*s == '\0') {
*d++ = '\\';
*d++ = '0';
s++;
} else {
*d++ = *s++;
}
}
*d = '\0';
return escaped;
}
gboolean
nm_utils_same_ssid (const GByteArray * ssid1, const GByteArray * ssid2)
{
if (ssid1 == ssid2)
return TRUE;
if ((ssid1 && !ssid2) || (!ssid1 && ssid2))
return FALSE;
if (ssid1->len != ssid2->len)
return FALSE;
return memcmp (ssid1->data, ssid2->data, ssid1->len) == 0 ? TRUE : FALSE;
}

View file

@ -106,4 +106,9 @@ struct nl_addr * nm_utils_ip4_addr_to_nl_addr (guint32 ip4_addr);
int nm_utils_ip4_netmask_to_prefix (guint32 ip4_netmask);
gboolean nm_utils_is_empty_ssid (const char * ssid, int len);
const char * nm_utils_escape_ssid (const char *ssid, guint32 len);
gboolean nm_utils_same_ssid (const GByteArray * ssid1, const GByteArray * ssid2);
#endif

View file

@ -393,9 +393,14 @@ found:
NMAccessPoint * list_ap;
char * key;
char * mode;
GByteArray * ssid;
ap = nm_ap_new ();
nm_ap_set_essid (ap, buf);
ssid = g_byte_array_sized_new (strlen (buf));
g_byte_array_append (ssid, buf, strlen (buf));
nm_ap_set_ssid (ap, ssid);
nm_ap_set_timestamp (ap, time (NULL), 0);
nm_ap_set_fallback (ap, TRUE);
@ -495,9 +500,9 @@ found:
g_object_unref (G_OBJECT (security));
}
if ((list_ap = nm_ap_list_get_ap_by_essid (app_data->allowed_ap_list, buf)))
if ((list_ap = nm_ap_list_get_ap_by_ssid (app_data->allowed_ap_list, ssid)))
{
nm_ap_set_essid (list_ap, nm_ap_get_essid (ap));
nm_ap_set_ssid (list_ap, nm_ap_get_ssid (ap));
nm_ap_set_timestamp_via_timestamp (list_ap, nm_ap_get_timestamp (ap));
nm_ap_set_fallback (list_ap, TRUE);
nm_ap_set_security (list_ap, nm_ap_get_security (ap));
@ -507,6 +512,7 @@ found:
/* New AP, just add it to the list */
nm_ap_list_append_ap (app_data->allowed_ap_list, ap);
}
g_byte_array_free (ssid, TRUE);
g_object_unref (ap);
nm_debug ("Adding '%s' to the list of trusted networks", buf);

View file

@ -68,6 +68,7 @@ nm_dbus_get_user_key_for_network_cb (DBusPendingCall *pcall,
NMAccessPoint * ap;
NMAPSecurity * security;
DBusMessageIter iter;
const GByteArray * ssid;
g_return_if_fail (pcall != NULL);
g_return_if_fail (info != NULL);
@ -80,6 +81,7 @@ nm_dbus_get_user_key_for_network_cb (DBusPendingCall *pcall,
ap = nm_device_802_11_wireless_get_activation_ap (NM_DEVICE_802_11_WIRELESS (dev));
g_assert (ap);
ssid = nm_ap_get_ssid (ap);
nm_dbus_send_with_callback_replied (pcall, __func__);
@ -99,7 +101,7 @@ nm_dbus_get_user_key_for_network_cb (DBusPendingCall *pcall,
nm_info ("Activation (%s) New wireless user key request for network"
" '%s' was canceled.",
nm_device_get_iface (dev),
nm_ap_get_essid (ap));
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
} else {
nm_warning ("dbus returned an error.\n (%s) %s\n",
err.name,
@ -121,7 +123,7 @@ nm_dbus_get_user_key_for_network_cb (DBusPendingCall *pcall,
nm_info ("Activation (%s) New wireless user key for network '%s' received.",
nm_device_get_iface (dev),
nm_ap_get_essid (ap));
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
dbus_message_iter_init (reply, &iter);
if ((security = nm_ap_security_new_deserialize (&iter))) {
@ -157,7 +159,7 @@ nm_dbus_get_user_key_for_network (NMDevice *dev,
gint32 attempt = 1;
char * dev_path;
const char * net_path;
const char * essid;
const GByteArray * ssid;
g_return_if_fail (NM_IS_DEVICE (dev));
g_return_if_fail (req != NULL);
@ -172,10 +174,10 @@ nm_dbus_get_user_key_for_network (NMDevice *dev,
ap = nm_device_802_11_wireless_get_activation_ap (NM_DEVICE_802_11_WIRELESS (dev));
g_assert (ap);
essid = nm_ap_get_essid (ap);
ssid = nm_ap_get_ssid (ap);
nm_info ("Activation (%s) New wireless user key requested for network '%s'.",
nm_device_get_iface (dev),
essid);
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
NMI_DBUS_PATH,
@ -189,9 +191,14 @@ nm_dbus_get_user_key_for_network (NMDevice *dev,
dev_path = nm_dbus_get_object_path_for_device (dev);
net_path = nm_ap_get_dbus_path (ap);
if (dev_path && strlen (dev_path) && net_path && strlen (net_path)) {
char buf[IW_ESSID_MAX_SIZE + 1];
char * ptr = &buf[0];
memset (buf, 0, sizeof (buf));
memcpy (buf, ssid->data, MIN (ssid->len, sizeof (buf) - 1));
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path,
DBUS_TYPE_OBJECT_PATH, &net_path,
DBUS_TYPE_STRING, &essid,
DBUS_TYPE_STRING, &ptr,
DBUS_TYPE_INT32, &attempt,
DBUS_TYPE_BOOLEAN, &new_key,
DBUS_TYPE_INVALID);
@ -283,11 +290,13 @@ nm_dbus_update_network_info (NMAccessPoint *ap,
DBusConnection * dbus_connection;
DBusMessage * message;
gboolean fallback;
const char * essid;
const GByteArray * ssid;
gchar * char_bssid;
NMAPSecurity * security;
const struct ether_addr *addr;
DBusMessageIter iter;
char buf[IW_ESSID_MAX_SIZE + 1];
char * ptr = &buf[0];
g_return_if_fail (ap != NULL);
@ -298,8 +307,6 @@ nm_dbus_update_network_info (NMAccessPoint *ap,
goto out;
}
essid = nm_ap_get_essid (ap);
message = dbus_message_new_method_call (NMI_DBUS_SERVICE,
NMI_DBUS_PATH,
NMI_DBUS_INTERFACE,
@ -312,7 +319,10 @@ nm_dbus_update_network_info (NMAccessPoint *ap,
dbus_message_iter_init_append (message, &iter);
/* First argument: ESSID (STRING) */
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &essid);
ssid = nm_ap_get_ssid (ap);
memset (buf, 0, sizeof (buf));
memcpy (buf, ssid->data, MIN (ssid->len, IW_ESSID_MAX_SIZE));
dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &ptr);
/* Second argument: Automatic or user-driven connection? (BOOLEAN) */
dbus_message_iter_append_basic (&iter, DBUS_TYPE_BOOLEAN, &automatic);
@ -404,13 +414,15 @@ static void nm_dbus_get_network_data_cb (DBusPendingCall *pcall, void *user_data
DBusMessage * reply = NULL;
DBusMessageIter iter;
DBusMessageIter subiter;
const char * essid = NULL;
const char * tmp_ssid = NULL;
guint32 tmp_ssid_len;
gint timestamp_secs = -1;
gboolean fallback = FALSE;
GSList * addr_list = NULL;
NMAPSecurity * security;
NMAccessPoint * ap;
NMAccessPoint * list_ap;
GByteArray * ssid;
g_return_if_fail (pcall != NULL);
g_return_if_fail (cb_data != NULL);
@ -425,19 +437,23 @@ static void nm_dbus_get_network_data_cb (DBusPendingCall *pcall, void *user_data
if (!(reply = dbus_pending_call_steal_reply (pcall)))
goto out;
if (dbus_message_is_error (reply, "BadNetworkData"))
{
nm_ap_list_remove_ap_by_essid (cb_data->list, cb_data->network);
if (dbus_message_is_error (reply, "BadNetworkData")) {
guint32 rmv_len = strlen (cb_data->network);
GByteArray * rmv_ssid;
rmv_ssid = g_byte_array_sized_new (rmv_len);
g_byte_array_append (rmv_ssid, cb_data->network, rmv_len);
nm_ap_list_remove_ap_by_ssid (cb_data->list, rmv_ssid);
g_byte_array_free (rmv_ssid, TRUE);
goto out;
}
if (message_is_error (reply))
{
if (message_is_error (reply)) {
DBusError err;
dbus_error_init (&err);
dbus_set_error_from_message (&err, reply);
nm_warning ("nm_dbus_get_network_data_cb(): dbus returned an error.\n (%s) %s\n", err.name, err.message);
nm_warning ("dbus returned an error.\n (%s) %s\n", err.name, err.message);
dbus_error_free (&err);
goto out;
}
@ -447,10 +463,10 @@ static void nm_dbus_get_network_data_cb (DBusPendingCall *pcall, void *user_data
/* First arg: ESSID (STRING) */
if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_STRING)
{
nm_warning ("a message argument (essid) was invalid.");
nm_warning ("a message argument (SSID) was invalid.");
goto out;
}
dbus_message_iter_get_basic (&iter, &essid);
dbus_message_iter_get_basic (&iter, &tmp_ssid);
/* Second arg: Timestamp (INT32) */
if (!dbus_message_iter_next (&iter)
@ -505,7 +521,12 @@ static void nm_dbus_get_network_data_cb (DBusPendingCall *pcall, void *user_data
/* Construct the new access point */
ap = nm_ap_new ();
nm_ap_set_essid (ap, essid);
tmp_ssid_len = MIN (strlen (tmp_ssid), IW_ESSID_MAX_SIZE);
ssid = g_byte_array_sized_new (tmp_ssid_len);
g_byte_array_append (ssid, tmp_ssid, tmp_ssid_len);
nm_ap_set_ssid (ap, ssid);
nm_ap_set_security (ap, security);
nm_ap_add_capabilities_from_security (ap, security);
g_object_unref (G_OBJECT (security)); /* set_security copies the object */
@ -515,9 +536,9 @@ static void nm_dbus_get_network_data_cb (DBusPendingCall *pcall, void *user_data
nm_ap_set_fallback (ap, fallback);
nm_ap_set_user_addresses (ap, addr_list);
if ((list_ap = nm_ap_list_get_ap_by_essid (cb_data->list, essid)))
if ((list_ap = nm_ap_list_get_ap_by_ssid (cb_data->list, ssid)))
{
nm_ap_set_essid (list_ap, nm_ap_get_essid (ap));
nm_ap_set_ssid (list_ap, nm_ap_get_ssid (ap));
nm_ap_set_timestamp_via_timestamp (list_ap, nm_ap_get_timestamp (ap));
nm_ap_set_fallback (list_ap, nm_ap_get_fallback (ap));
nm_ap_set_security (list_ap, nm_ap_get_security (ap));
@ -528,6 +549,7 @@ static void nm_dbus_get_network_data_cb (DBusPendingCall *pcall, void *user_data
/* New AP, just add it to the list */
nm_ap_list_append_ap (cb_data->list, ap);
}
g_byte_array_free (ssid, TRUE);
g_object_unref (ap);
/* Ensure all devices get new information copied into their device lists */

View file

@ -109,7 +109,7 @@ struct _NMDevice80211WirelessPrivate
struct ether_addr hw_addr;
char * cur_essid;
GByteArray * ssid;
gint8 invalid_strength_counter;
iwqual max_qual;
iwqual avg_qual;
@ -212,19 +212,19 @@ nm_device_802_11_wireless_update_bssid (NMDevice80211Wireless *self,
{
struct ether_addr new_bssid;
const struct ether_addr *old_bssid;
const char * new_essid;
const char * old_essid;
const GByteArray * new_ssid;
const GByteArray * old_ssid;
/* Get the current BSSID. If it is valid but does not match the stored value,
* and the ESSID is the same as what we think its supposed to be, update it. */
* and the SSID is the same as what we think its supposed to be, update it. */
nm_device_802_11_wireless_get_bssid (self, &new_bssid);
old_bssid = nm_ap_get_address (ap);
new_essid = nm_device_802_11_wireless_get_essid (self);
old_essid = nm_ap_get_essid (ap);
new_ssid = nm_device_802_11_wireless_get_ssid (self);
old_ssid = nm_ap_get_ssid (ap);
if ( nm_ethernet_address_is_valid (&new_bssid)
&& nm_ethernet_address_is_valid (old_bssid)
&& !nm_ethernet_addresses_are_equal (&new_bssid, old_bssid)
&& !nm_null_safe_strcmp (old_essid, new_essid))
&& nm_utils_same_ssid (old_ssid, new_ssid))
{
gboolean automatic;
gchar new_addr[20];
@ -234,7 +234,10 @@ nm_device_802_11_wireless_update_bssid (NMDevice80211Wireless *self,
memset (old_addr, '\0', sizeof (old_addr));
iw_ether_ntop (&new_bssid, new_addr);
iw_ether_ntop (old_bssid, old_addr);
nm_debug ("Roamed from BSSID %s to %s on wireless network '%s'", old_addr, new_addr, nm_ap_get_essid (ap));
nm_debug ("Roamed from BSSID %s to %s on wireless network '%s'",
old_addr,
new_addr,
nm_utils_escape_ssid (old_ssid->data, old_ssid->len));
nm_ap_set_address (ap, &new_bssid);
@ -623,12 +626,18 @@ static void
real_deactivate_quickly (NMDevice *dev)
{
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev);
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
cleanup_association_attempt (self, TRUE);
/* Clean up stuff, don't leave the card associated */
nm_device_802_11_wireless_set_essid (self, "");
nm_device_802_11_wireless_set_ssid (self, NULL);
nm_device_802_11_wireless_disable_encryption (self);
if (priv->activation_ap) {
g_object_unref (priv->activation_ap);
priv->activation_ap = NULL;
}
}
static void
@ -717,11 +726,10 @@ link_to_specific_ap (NMDevice80211Wireless *self,
if (is_associated (self))
{
const char * dev_essid = nm_device_802_11_wireless_get_essid (self);
const char * ap_essid = nm_ap_get_essid (ap);
const GByteArray * dev_ssid = nm_device_802_11_wireless_get_ssid (self);
const GByteArray * ap_ssid = nm_ap_get_ssid (ap);
if (dev_essid && ap_essid && !strcmp (dev_essid, ap_essid))
{
if (dev_ssid && ap_ssid && nm_utils_same_ssid (dev_ssid, ap_ssid)) {
self->priv->failed_link_count = 0;
have_link = TRUE;
}
@ -743,7 +751,7 @@ get_ap_blacklisted (NMAccessPoint *ap, GSList *addrs)
{
gboolean blacklisted;
blacklisted = nm_ap_has_manufacturer_default_essid (ap);
blacklisted = nm_ap_has_manufacturer_default_ssid (ap);
if (blacklisted)
{
GSList *elt;
@ -794,7 +802,7 @@ get_best_fallback_ap (NMDevice80211Wireless *self)
while ((allowed_ap = nm_ap_list_iter_next (iter)))
{
const char * essid;
const GByteArray * ssid;
GSList * user_addrs;
const GTimeVal * curtime;
gboolean blacklisted;
@ -812,8 +820,8 @@ get_best_fallback_ap (NMDevice80211Wireless *self)
continue;
/* No fallback to networks on the invalid list -- we probably already tried them and failed */
essid = nm_ap_get_essid (allowed_ap);
if (nm_ap_list_get_ap_by_essid (app_data->invalid_ap_list, essid))
ssid = nm_ap_get_ssid (allowed_ap);
if (nm_ap_list_get_ap_by_ssid (app_data->invalid_ap_list, ssid))
continue;
curtime = nm_ap_get_timestamp (allowed_ap);
@ -825,10 +833,13 @@ get_best_fallback_ap (NMDevice80211Wireless *self)
}
nm_ap_list_iter_free (iter);
if (best_ap)
{
if (best_ap) {
const GByteArray * ssid;
nm_ap_set_broadcast (best_ap, FALSE);
nm_info ("Attempting to fallback to wireless network '%s'", nm_ap_get_essid (best_ap));
ssid = nm_ap_get_ssid (best_ap);
nm_info ("Attempting to fallback to wireless network '%s'",
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
}
return best_ap;
@ -871,11 +882,9 @@ nm_device_802_11_wireless_get_best_ap (NMDevice80211Wireless *self)
/* We prefer the currently selected access point if its user-chosen or if there
* is still a hardware link to it.
*/
if ((req = nm_device_get_act_request (NM_DEVICE (self))))
{
if ((cur_ap = nm_device_802_11_wireless_get_activation_ap (self)))
{
const char * essid = nm_ap_get_essid (cur_ap);
if ((req = nm_device_get_act_request (NM_DEVICE (self)))) {
if ((cur_ap = nm_device_802_11_wireless_get_activation_ap (self))) {
const GByteArray * ssid = nm_ap_get_ssid (cur_ap);
gboolean keep = FALSE;
if (nm_ap_get_user_created (cur_ap))
@ -887,8 +896,8 @@ nm_device_802_11_wireless_get_best_ap (NMDevice80211Wireless *self)
/* Only keep if its not in the invalid list and its _is_ in our scanned list */
if ( keep
&& !nm_ap_list_get_ap_by_essid (app_data->invalid_ap_list, essid)
&& nm_device_802_11_wireless_ap_list_get_ap_by_essid (self, essid))
&& !nm_ap_list_get_ap_by_ssid (app_data->invalid_ap_list, ssid)
&& nm_device_802_11_wireless_ap_list_get_ap_by_ssid (self, ssid))
{
return (NMAccessPoint *) g_object_ref (cur_ap);
}
@ -897,16 +906,15 @@ nm_device_802_11_wireless_get_best_ap (NMDevice80211Wireless *self)
if (!(iter = nm_ap_list_iter_new (ap_list)))
return NULL;
while ((scan_ap = nm_ap_list_iter_next (iter)))
{
while ((scan_ap = nm_ap_list_iter_next (iter))) {
NMAccessPoint *tmp_ap;
const char * ap_essid = nm_ap_get_essid (scan_ap);
const GByteArray * ap_ssid = nm_ap_get_ssid (scan_ap);
/* Access points in the "invalid" list cannot be used */
if (nm_ap_list_get_ap_by_essid (app_data->invalid_ap_list, ap_essid))
if (nm_ap_list_get_ap_by_ssid (app_data->invalid_ap_list, ap_ssid))
continue;
if ((tmp_ap = nm_ap_list_get_ap_by_essid (app_data->allowed_ap_list, ap_essid)))
if ((tmp_ap = nm_ap_list_get_ap_by_ssid (app_data->allowed_ap_list, ap_ssid)))
{
const GTimeVal * curtime = nm_ap_get_timestamp (tmp_ap);
gboolean blacklisted;
@ -918,8 +926,7 @@ nm_device_802_11_wireless_get_best_ap (NMDevice80211Wireless *self)
g_slist_foreach (user_addrs, (GFunc) g_free, NULL);
g_slist_free (user_addrs);
if (!blacklisted && (curtime->tv_sec > best_timestamp.tv_sec))
{
if (!blacklisted && (curtime->tv_sec > best_timestamp.tv_sec)) {
best_timestamp = *nm_ap_get_timestamp (tmp_ap);
best_ap = scan_ap;
nm_ap_set_security (best_ap, nm_ap_get_security (tmp_ap));
@ -930,7 +937,6 @@ nm_device_802_11_wireless_get_best_ap (NMDevice80211Wireless *self)
if (!best_ap)
best_ap = get_best_fallback_ap (self);
if (best_ap)
g_object_ref (best_ap);
@ -942,36 +948,28 @@ nm_device_802_11_wireless_set_activation_ap (NMDevice80211Wireless *self,
GByteArray *ssid,
NMAPSecurity *security)
{
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
NMAccessPoint *ap = NULL;
NMData * app_data;
NMAccessPointList * dev_ap_list;
char *essid;
app_data = nm_device_get_app_data (NM_DEVICE (self));
g_assert (app_data);
/* FIXME: handle essid everywhere as GByteArray */
{
essid = g_new (char, ssid->len + 1);
memcpy (essid, ssid->data, ssid->len);
essid[ssid->len] = '\0';
}
nm_debug ("Forcing AP '%s'", essid);
nm_debug ("Forcing AP '%s'", nm_utils_escape_ssid (ssid->data, ssid->len));
/* Find the AP in our card's scan list first.
* If its not there, create an entirely new AP.
*/
dev_ap_list = nm_device_802_11_wireless_ap_list_get (self);
if (!(ap = nm_ap_list_get_ap_by_essid (dev_ap_list, essid)))
{
if (!(ap = nm_ap_list_get_ap_by_ssid (dev_ap_list, ssid))) {
/* We need security information from the user if the network they
* request isn't in our scan list.
*/
if (!security)
{
if (!security) {
nm_warning ("%s: tried to manually connect to network '%s' without "
"providing security information!", __func__, essid);
"providing security information!", __func__,
nm_utils_escape_ssid (ssid->data, ssid->len));
return FALSE;
}
@ -979,7 +977,7 @@ nm_device_802_11_wireless_set_activation_ap (NMDevice80211Wireless *self,
* "fake" access point and add it to the scan list.
*/
ap = nm_ap_new ();
nm_ap_set_essid (ap, essid);
nm_ap_set_ssid (ap, ssid);
nm_ap_set_artificial (ap, TRUE);
nm_ap_set_broadcast (ap, FALSE);
/* Ensure the AP has some capabilities. They will get overwritten
@ -994,7 +992,8 @@ nm_device_802_11_wireless_set_activation_ap (NMDevice80211Wireless *self,
/* If the AP is in the ignore list, we have to remove it since
* the User Knows What's Best.
*/
nm_ap_list_remove_ap_by_essid (app_data->invalid_ap_list, nm_ap_get_essid (ap));
nm_ap_list_remove_ap_by_ssid (app_data->invalid_ap_list,
nm_ap_get_ssid (ap));
/* If we didn't get any security info, make some up. */
if (!security)
@ -1002,13 +1001,17 @@ nm_device_802_11_wireless_set_activation_ap (NMDevice80211Wireless *self,
nm_ap_get_encrypted (ap));
}
g_free (essid);
g_assert (security);
nm_ap_set_security (ap, security);
nm_ap_add_capabilities_from_security (ap, security);
NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self)->activation_ap = ap;
if (priv->activation_ap) {
g_object_unref (priv->activation_ap);
priv->activation_ap = NULL;
}
g_object_ref (ap);
priv->activation_ap = ap;
return TRUE;
}
@ -1034,22 +1037,22 @@ nm_device_802_11_wireless_ap_list_clear (NMDevice80211Wireless *self)
/*
* nm_device_ap_list_get_ap_by_essid
* nm_device_ap_list_get_ap_by_ssid
*
* Get the access point for a specific essid
* Get the access point for a specific SSID
*
*/
NMAccessPoint *
nm_device_802_11_wireless_ap_list_get_ap_by_essid (NMDevice80211Wireless *self,
const char *essid)
nm_device_802_11_wireless_ap_list_get_ap_by_ssid (NMDevice80211Wireless *self,
const GByteArray * ssid)
{
g_return_val_if_fail (self != NULL, NULL);
g_return_val_if_fail (essid != NULL, NULL);
g_return_val_if_fail (ssid != NULL, NULL);
if (!self->priv->ap_list)
return NULL;
return nm_ap_list_get_ap_by_essid (self->priv->ap_list, essid);
return nm_ap_list_get_ap_by_ssid (self->priv->ap_list, ssid);
}
@ -1141,7 +1144,7 @@ impl_device_get_active_networks (NMDevice80211Wireless *device,
NMAccessPoint *ap;
while ((ap = nm_ap_list_iter_next (list_iter))) {
if (nm_ap_get_essid (ap))
if (nm_ap_get_ssid (ap))
g_ptr_array_add (*networks, g_strdup (nm_ap_get_dbus_path (ap)));
}
nm_ap_list_iter_free (list_iter);
@ -1394,109 +1397,129 @@ max_qual->updated);
/*
* nm_device_get_essid
* nm_device_802_11_wireless_get_ssid
*
* If a device is wireless, return the essid that it is attempting
* If a device is wireless, return the ssid that it is attempting
* to use.
*
* Returns: allocated string containing essid. Must be freed by caller.
*
*/
const char *
nm_device_802_11_wireless_get_essid (NMDevice80211Wireless *self)
const GByteArray *
nm_device_802_11_wireless_get_ssid (NMDevice80211Wireless *self)
{
NMSock * sk;
int err;
const char * iface;
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
const char * iface;
int err, sk;
struct iwreq wrq;
char ssid[IW_ESSID_MAX_SIZE + 1];
guint32 len;
g_return_val_if_fail (self != NULL, NULL);
iface = nm_device_get_iface (NM_DEVICE (self));
if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL)))
{
wireless_config info;
nm_ioctl_info ("%s: About to GET 'basic config' for ESSID.", iface);
err = iw_get_basic_config (nm_dev_sock_get_fd (sk), iface, &info);
if (err >= 0)
{
if (self->priv->cur_essid)
g_free (self->priv->cur_essid);
self->priv->cur_essid = g_strdup (info.essid);
}
else
{
nm_warning ("error getting ESSID for device %s: %s",
iface, strerror (errno));
}
nm_dev_sock_close (sk);
sk = socket (AF_INET, SOCK_DGRAM, 0);
if (!sk) {
nm_error ("Couldn't create socket: %d.", errno);
return NULL;
}
return self->priv->cur_essid;
wrq.u.essid.pointer = (caddr_t) &ssid;
wrq.u.essid.length = sizeof (ssid);
wrq.u.essid.flags = 0;
if (iw_get_ext (sk, iface, SIOCGIWESSID, &wrq) < 0) {
nm_error ("Couldn't get SSID: %d", errno);
goto out;
}
if (priv->ssid) {
g_byte_array_free (priv->ssid, TRUE);
priv->ssid = NULL;
}
len = wrq.u.essid.length;
if (!nm_utils_is_empty_ssid (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, ssid, len);
}
out:
close (sk);
return self->priv->ssid;
}
/*
* nm_device_802_11_wireless_set_essid
* nm_device_802_11_wireless_set_ssid
*
* If a device is wireless, set the essid that it should use.
* If a device is wireless, set the SSID that it should use.
*/
void
nm_device_802_11_wireless_set_essid (NMDevice80211Wireless *self,
const char *essid)
nm_device_802_11_wireless_set_ssid (NMDevice80211Wireless *self,
const GByteArray * ssid)
{
NMSock* sk;
int err;
struct iwreq wreq;
char * safe_essid;
const char * iface;
const char * driver;
gint len = 0;
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
int sk, err;
struct iwreq wrq;
const char * iface;
const char * driver;
guint32 len = 0;
char buf[IW_ESSID_MAX_SIZE + 1];
g_return_if_fail (self != NULL);
safe_essid = g_malloc0 (IW_ESSID_MAX_SIZE + 1);
if (essid)
{
len = MIN(IW_ESSID_MAX_SIZE, strlen (essid));
if (len <= 0)
len = 0;
strncpy (safe_essid, essid, len);
sk = socket (AF_INET, SOCK_DGRAM, 0);
if (!sk) {
nm_error ("Couldn't create socket: %d.", errno);
return;
}
iface = nm_device_get_iface (NM_DEVICE (self));
if ((sk = nm_dev_sock_open (iface, DEV_WIRELESS, __FUNCTION__, NULL)))
{
wreq.u.essid.pointer = (caddr_t) safe_essid;
wreq.u.essid.length = len + 1;
wreq.u.essid.flags = (len > 0) ? 1 : 0; /* 1=enable ESSID, 0=disable/any */
nm_ioctl_info ("%s: About to SET IWESSID.", iface);
if ((err = iw_set_ext (nm_dev_sock_get_fd (sk), iface, SIOCSIWESSID, &wreq)) == -1)
{
if (errno != ENODEV)
{
nm_warning ("error setting ESSID to '%s' for device %s: %s",
safe_essid, iface, strerror (errno));
}
}
nm_dev_sock_close (sk);
/* Orinoco cards seem to need extra time here to not screw
* up the firmware, which reboots when you set the ESSID.
* Unfortunately, there's no way to know when the card is back up
* again. Sigh...
*/
driver = nm_device_get_driver (NM_DEVICE (self));
if (!driver || !strcmp (driver, "orinoco"))
sleep (2);
memset (buf, 0, sizeof (buf));
if (ssid) {
len = ssid->len;
memcpy (buf, ssid->data, MIN (sizeof (buf) - 1, len));
}
g_free (safe_essid);
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 */
if (iw_get_ext (sk, iface, SIOCSIWESSID, &wrq) < 0) {
if (errno != ENODEV) {
nm_warning ("error setting SSID to '%s' for device %s: %s",
nm_utils_escape_ssid (ssid->data, ssid->len),
iface, strerror (errno));
}
}
/* Orinoco cards seem to need extra time here to not screw
* up the firmware, which reboots when you set the SSID.
* Unfortunately, there's no way to know when the card is back up
* again. Sigh...
*/
driver = nm_device_get_driver (NM_DEVICE (self));
if (!driver || !strcmp (driver, "orinoco"))
sleep (2);
close (sk);
}
@ -1744,16 +1767,20 @@ ap_need_key (NMDevice80211Wireless *self,
NMAccessPoint *ap,
gboolean *ask_user)
{
const char * essid;
const GByteArray * ssid;
gboolean need_key = FALSE;
NMAPSecurity * security;
const char * iface;
int we_cipher;
const char * esc_ssid = NULL;
g_return_val_if_fail (ap != NULL, FALSE);
g_return_val_if_fail (ask_user != NULL, FALSE);
essid = nm_ap_get_essid (ap);
ssid = nm_ap_get_ssid (ap);
if (ssid)
esc_ssid = nm_utils_escape_ssid (ssid->data, ssid->len);
security = nm_ap_get_security (ap);
g_assert (security);
we_cipher = nm_ap_security_get_we_cipher (security);
@ -1763,7 +1790,7 @@ ap_need_key (NMDevice80211Wireless *self,
if (!nm_ap_get_encrypted (ap))
{
nm_info ("Activation (%s/wireless): access point '%s' is unencrypted, no key needed.",
iface, essid ? essid : "(null)");
iface, esc_ssid ? esc_ssid : "(null)");
/* If the user-specified security info doesn't overlap the
* scanned access point's info, create new info from the scanned
@ -1781,7 +1808,7 @@ ap_need_key (NMDevice80211Wireless *self,
{
nm_info ("Activation (%s/wireless): access point '%s' "
"is encrypted, but NO valid key exists. New key needed.",
iface, essid ? essid : "(null)");
iface, esc_ssid ? esc_ssid : "(null)");
need_key = TRUE;
/* If the user-specified security info doesn't overlap the
@ -1795,7 +1822,7 @@ ap_need_key (NMDevice80211Wireless *self,
{
nm_info ("Activation (%s/wireless): access point '%s' "
"is encrypted, and a key exists. No new key needed.",
iface, essid ? essid : "(null)");
iface, esc_ssid ? esc_ssid : "(null)");
}
}
@ -1876,8 +1903,7 @@ ap_is_auth_required (NMAccessPoint *ap, gboolean *has_key)
static void
merge_scanned_ap (NMDevice80211Wireless *dev,
NMAccessPoint *merge_ap)
{
{
NMAccessPointList *list;
NMAccessPoint *list_ap = NULL;
const struct ether_addr *merge_bssid;
@ -1885,16 +1911,16 @@ merge_scanned_ap (NMDevice80211Wireless *dev,
list = nm_device_802_11_wireless_ap_list_get (dev);
merge_bssid = nm_ap_get_address (merge_ap);
if (nm_ethernet_address_is_valid (merge_bssid) && (list_ap = nm_ap_list_get_ap_by_address (list, merge_bssid)))
{
if ( nm_ethernet_address_is_valid (merge_bssid)
&& (list_ap = nm_ap_list_get_ap_by_address (list, merge_bssid))) {
/* First, we check for an address match. If the merge AP has a valid
* BSSID and the same address as a list AP, then the merge AP and
* the list AP must be the same physical AP. The list AP properties must
* be from a previous scan so the time_last_seen's are not equal. Update
* encryption, authentication method, strength, and the time_last_seen. */
const char *devlist_essid = nm_ap_get_essid (list_ap);
const char *merge_essid = nm_ap_get_essid (merge_ap);
const GByteArray * devlist_ssid = nm_ap_get_ssid (list_ap);
const GByteArray * merge_ssid = nm_ap_get_ssid (merge_ap);
const glong merge_ap_seen = nm_ap_get_last_seen (merge_ap);
nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap));
@ -1908,16 +1934,16 @@ merge_scanned_ap (NMDevice80211Wireless *dev,
nm_ap_set_artificial (list_ap, FALSE);
/* Did the AP's name change? */
if (!devlist_essid || !merge_essid || nm_null_safe_strcmp (devlist_essid, merge_essid)) {
if ( !devlist_ssid
|| !merge_ssid
|| !nm_utils_same_ssid (devlist_ssid, merge_ssid)) {
network_removed (dev, list_ap);
nm_ap_set_essid (list_ap, merge_essid);
nm_ap_set_ssid (list_ap, merge_ssid);
network_added (dev, list_ap);
}
}
else if ((list_ap = nm_ap_list_get_ap_by_essid (list, nm_ap_get_essid (merge_ap))))
{
/* Second, we check for an ESSID match. In this case,
* a list AP has the same non-NULL ESSID as the merge AP. Update the
} else if ((list_ap = nm_ap_list_get_ap_by_ssid (list, nm_ap_get_ssid (merge_ap)))) {
/* Second, we check for an SSID match. In this case,
* a list AP has the same non-NULL SSID as the merge AP. Update the
* encryption and authentication method. Update the strength and address
* except when the time_last_seen of the list AP is the same as the
* time_last_seen of the merge AP and the strength of the list AP is greater
@ -1932,8 +1958,7 @@ merge_scanned_ap (NMDevice80211Wireless *dev,
nm_ap_set_capabilities (list_ap, nm_ap_get_capabilities (merge_ap));
if (!((list_ap_seen == merge_ap_seen)
&& (nm_ap_get_strength (list_ap) >= merge_ap_strength)))
{
&& (nm_ap_get_strength (list_ap) >= merge_ap_strength))) {
nm_ap_set_strength (list_ap, merge_ap_strength);
nm_ap_set_address (list_ap, nm_ap_get_address (merge_ap));
}
@ -1980,14 +2005,14 @@ cull_scan_list (NMDevice80211Wireless * self)
const glong ap_time = nm_ap_get_last_seen (outdated_ap);
gboolean keep_around = FALSE;
guint prune_interval_s;
const char * ssid;
const GByteArray * ssid;
const GByteArray * cur_ssid;
/* Don't ever prune the AP we're currently associated with */
ssid = nm_ap_get_essid (outdated_ap);
if (ssid && cur_ap) {
if (nm_null_safe_strcmp (nm_ap_get_essid (cur_ap), ssid) == 0)
keep_around = TRUE;
}
ssid = nm_ap_get_ssid (outdated_ap);
cur_ssid = cur_ap ? nm_ap_get_ssid (cur_ap) : NULL;
if (ssid && nm_utils_same_ssid (cur_ssid, ssid))
keep_around = TRUE;
prune_interval_s = SCAN_INTERVAL_MAX * 3;
@ -2065,12 +2090,12 @@ supplicant_iface_scanned_ap_cb (NMSupplicantInterface * iface,
set_ap_strength_from_properties (self, ap, properties);
/* 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 the AP is not broadcasting its SSID, try to fill it in here from our
* allowed list where we cache known MAC->SSID associations.
*/
if (!nm_ap_get_essid (ap)) {
if (!nm_ap_get_ssid (ap)) {
nm_ap_set_broadcast (ap, FALSE);
nm_ap_list_copy_one_essid_by_address (ap, app_data->allowed_ap_list);
nm_ap_list_copy_one_ssid_by_address (ap, app_data->allowed_ap_list);
}
/* Add the AP to the device's AP list */
@ -2297,11 +2322,12 @@ supplicant_iface_connection_state_cb_handler (gpointer user_data)
*/
if (nm_device_get_state (dev) == NM_DEVICE_STATE_CONFIG) {
NMAccessPoint *ap = nm_device_802_11_wireless_get_activation_ap (self);
const GByteArray * ssid = nm_ap_get_ssid (ap);
nm_info ("Activation (%s/wireless) Stage 2 of 5 (Device Configure) "
"successful. Connected to wireless network '%s'.",
nm_device_get_iface (dev),
nm_ap_get_essid (ap) ? nm_ap_get_essid (ap) : "(none)");
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
nm_device_activate_schedule_stage3_ip_config_start (dev);
}
} else if (new_state == NM_SUPPLICANT_INTERFACE_CON_STATE_DISCONNECTED) {
@ -2595,9 +2621,9 @@ static NMSupplicantConfig *
build_supplicant_config (NMDevice80211Wireless *self)
{
NMSupplicantConfig * config = NULL;
NMAccessPoint * ap = NULL;
const char * essid;
gboolean is_adhoc;
NMAccessPoint * ap = NULL;
const GByteArray * ssid;
gboolean is_adhoc;
g_return_val_if_fail (self != NULL, NULL);
@ -2614,8 +2640,12 @@ build_supplicant_config (NMDevice80211Wireless *self)
nm_supplicant_config_set_ap_scan (config, 2);
}
essid = nm_ap_get_orig_essid (ap);
nm_supplicant_config_add_option (config, "ssid", essid, -1);
ssid = nm_ap_get_ssid (ap);
if (!ssid) {
nm_warning ("can't add null ssid to config.");
goto error;
}
nm_supplicant_config_add_option (config, "ssid", ssid->data, ssid->len);
/* For non-broadcast networks, we need to set "scan_ssid 1" to scan with probe request frames.
* However, don't try to probe Ad-Hoc networks.
@ -2838,9 +2868,12 @@ real_act_stage4_ip_config_timeout (NMDevice *dev,
*/
if (!ap_is_auth_required (ap, &has_key) && has_key)
{
const GByteArray * ssid = nm_ap_get_ssid (ap);
/* Activation failed, we must have bad encryption key */
nm_debug ("Activation (%s/wireless): could not get IP configuration info for '%s', asking for new key.",
nm_device_get_iface (dev), nm_ap_get_essid (ap) ? nm_ap_get_essid (ap) : "(none)");
nm_device_get_iface (dev),
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
nm_device_state_changed (dev, NM_DEVICE_STATE_NEED_AUTH);
nm_dbus_get_user_key_for_network (dev, nm_device_get_act_request (dev), TRUE);
ret = NM_ACT_STAGE_RETURN_POSTPONE;
@ -2884,7 +2917,7 @@ activation_success_handler (NMDevice *dev)
if (!automatic && (nm_ap_get_mode (ap) == IW_MODE_ADHOC) && nm_ap_get_user_created (ap))
{
NMAccessPointList *ap_list = nm_device_802_11_wireless_ap_list_get (self);
if (!nm_ap_list_get_ap_by_essid (ap_list, nm_ap_get_essid (ap)))
if (!nm_ap_list_get_ap_by_ssid (ap_list, nm_ap_get_ssid (ap)))
nm_ap_list_append_ap (ap_list, ap);
}
@ -2902,6 +2935,7 @@ activation_failure_handler (NMDevice *dev)
NMData * app_data;
NMDevice80211Wireless * self = NM_DEVICE_802_11_WIRELESS (dev);
NMAccessPoint * ap;
const GByteArray * ssid;
app_data = nm_device_get_app_data (dev);
g_assert (app_data);
@ -2929,8 +2963,10 @@ activation_failure_handler (NMDevice *dev)
}
}
nm_info ("Activation (%s) failed for access point (%s)", nm_device_get_iface (dev),
ap ? nm_ap_get_essid (ap) : "(none)");
ssid = nm_ap_get_ssid (ap);
nm_info ("Activation (%s) failed for access point (%s)",
nm_device_get_iface (dev),
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
}
static void
@ -3124,6 +3160,9 @@ nm_device_802_11_wireless_class_init (NMDevice80211WirelessClass *klass)
static void
state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data)
{
NMDevice80211Wireless *self = NM_DEVICE_802_11_WIRELESS (device);
NMDevice80211WirelessPrivate *priv = NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (self);
switch (state) {
case NM_DEVICE_STATE_ACTIVATED:
activation_success_handler (device);
@ -3132,7 +3171,11 @@ state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data)
activation_failure_handler (device);
break;
case NM_DEVICE_STATE_DISCONNECTED:
NM_DEVICE_802_11_WIRELESS_GET_PRIVATE (device)->activation_ap = NULL;
if (priv->activation_ap) {
nm_info ("%s(): clearing activation AP", __func__);
g_object_unref (priv->activation_ap);
priv->activation_ap = NULL;
}
default:
break;
}

View file

@ -83,8 +83,8 @@ NMDevice80211Wireless *nm_device_802_11_wireless_new (const char *iface,
gboolean test_dev,
NMData *app_data);
void nm_device_802_11_wireless_set_essid (NMDevice80211Wireless *self,
const char *essid);
void nm_device_802_11_wireless_set_ssid (NMDevice80211Wireless *self,
const GByteArray * ssid);
void nm_device_802_11_wireless_get_address (NMDevice80211Wireless *dev,
struct ether_addr *addr);
@ -92,7 +92,7 @@ void nm_device_802_11_wireless_get_address (NMDevice80211Wireless *dev,
void nm_device_802_11_wireless_get_bssid (NMDevice80211Wireless *dev,
struct ether_addr *bssid);
const char * nm_device_802_11_wireless_get_essid (NMDevice80211Wireless *self);
const GByteArray * nm_device_802_11_wireless_get_ssid (NMDevice80211Wireless *self);
gboolean nm_device_802_11_wireless_set_mode (NMDevice80211Wireless *self,
const int mode);
@ -114,8 +114,8 @@ NMAccessPoint * nm_device_802_11_wireless_ap_list_get_ap_by_obj_path (NMDevice80
NMAccessPoint * nm_device_802_11_wireless_ap_list_get_ap_by_bssid (NMDevice80211Wireless *dev,
const struct ether_addr *bssid);
NMAccessPoint * nm_device_802_11_wireless_ap_list_get_ap_by_essid (NMDevice80211Wireless *dev,
const char *essid);
NMAccessPoint * nm_device_802_11_wireless_ap_list_get_ap_by_ssid (NMDevice80211Wireless *dev,
const GByteArray * ssid);
int nm_device_802_11_wireless_get_mode (NMDevice80211Wireless *self);

View file

@ -432,7 +432,7 @@ real_act_stage2_config (NMDevice *dev)
* nm_device_activate_stage2_device_config
*
* Determine device parameters and set those on the device, ie
* for wireless devices, set essid, keys, etc.
* for wireless devices, set SSID, keys, etc.
*
*/
static gboolean

View file

@ -37,6 +37,47 @@
#include <nm-device-802-3-ethernet.h>
#include <nm-device-802-11-wireless.h>
/* Shamelessly ripped from the Linux kernel ieee80211 stack */
static gboolean
nm_utils_is_empty_ssid (const char * ssid, int len)
{
/* Single white space is for Linksys APs */
if (len == 1 && ssid[0] == ' ')
return TRUE;
/* Otherwise, if the entire ssid is 0, we assume it is hidden */
while (len--) {
if (ssid[len] != '\0')
return FALSE;
}
return TRUE;
}
static const char *
nm_utils_escape_ssid (const char * ssid, guint32 len)
{
static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
const char *s = ssid;
char *d = escaped;
if (nm_utils_is_empty_ssid (ssid, len)) {
memcpy (escaped, "<hidden>", sizeof ("<hidden>"));
return escaped;
}
len = MIN (len, (guint32) IW_ESSID_MAX_SIZE);
while (len--) {
if (*s == '\0') {
*d++ = '\\';
*d++ = '0';
s++;
} else {
*d++ = *s++;
}
}
*d = '\0';
return escaped;
}
static gboolean
@ -107,7 +148,7 @@ detail_network (gpointer data, gpointer user_data)
GString *str;
gboolean active = FALSE;
guint32 capabilities;
char *essid;
GByteArray * ssid;
char *tmp;
capabilities = nm_access_point_get_capabilities (ap);
@ -142,9 +183,10 @@ detail_network (gpointer data, gpointer user_data)
/* FIXME: broadcast/hidden */
essid = nm_access_point_get_essid (ap);
tmp = g_strdup_printf (" %s%s", active ? "*" : "", essid);
g_free (essid);
ssid = nm_access_point_get_ssid (ap);
tmp = g_strdup_printf (" %s%s", active ? "*" : "",
ssid ? nm_utils_escape_ssid (ssid->data, ssid->len) : "(none)");
g_byte_array_free (ssid, TRUE);
print_string (tmp, str->str);

View file

@ -23,6 +23,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <iwlib.h>
#include <wireless.h>
#include <glib.h>
#include <dbus/dbus.h>
@ -299,55 +301,53 @@ get_encodings_for_lang (const char *lang,
char *
nm_utils_essid_to_utf8 (const char *orig_essid)
nm_utils_ssid_to_utf8 (const char *ssid, guint32 len)
{
char *new_essid = NULL;
char * new_ssid = NULL;
char buf[IW_ESSID_MAX_SIZE + 1];
guint32 buf_len = MIN (sizeof (buf) - 1, len);
char * lang;
char *e1 = NULL, *e2 = NULL, *e3 = NULL;
g_return_val_if_fail (orig_essid != NULL, NULL);
g_return_val_if_fail (ssid != NULL, NULL);
if (g_utf8_validate (orig_essid, -1, NULL))
new_essid = g_strdup (orig_essid);
else
{
char * lang;
char *e1 = NULL, *e2 = NULL, *e3 = NULL;
memset (buf, 0, sizeof (buf));
memcpy (buf, ssid, buf_len);
/* Even if the local encoding is UTF-8, LANG may give
* us a clue as to what encoding ESSIDs are more likely to be in.
*/
g_get_charset ((const char **)(&e1));
if ((lang = getenv ("LANG")))
{
char * dot;
lang = g_ascii_strdown (lang, -1);
if ((dot = strchr (lang, '.')))
*dot = '\0';
get_encodings_for_lang (lang, &e1, &e2, &e3);
g_free (lang);
}
new_essid = g_convert (orig_essid, -1, "UTF-8", e1, NULL, NULL, NULL);
if (!new_essid && e2)
{
new_essid = g_convert (orig_essid, -1, "UTF-8", e2,
NULL, NULL, NULL);
}
if (!new_essid && e3)
{
new_essid = g_convert (orig_essid, -1, "UTF-8", e3,
NULL, NULL, NULL);
}
if (!new_essid)
{
new_essid = g_convert_with_fallback (orig_essid, -1, "UTF-8", e1,
"?", NULL, NULL, NULL);
}
if (g_utf8_validate (buf, buf_len, NULL)) {
new_ssid = g_strdup (buf);
goto out;
}
return new_essid;
/* Even if the local encoding is UTF-8, LANG may give
* us a clue as to what encoding SSIDs are more likely to be in.
*/
g_get_charset ((const char **)(&e1));
if ((lang = getenv ("LANG"))) {
char * dot;
lang = g_ascii_strdown (lang, -1);
if ((dot = strchr (lang, '.')))
*dot = '\0';
get_encodings_for_lang (lang, &e1, &e2, &e3);
g_free (lang);
}
new_ssid = g_convert (buf, buf_len, "UTF-8", e1, NULL, NULL, NULL);
if (!new_ssid && e2) {
new_ssid = g_convert (buf, buf_len, "UTF-8", e2, NULL, NULL, NULL);
}
if (!new_ssid && e3) {
new_ssid = g_convert (buf, buf_len, "UTF-8", e3, NULL, NULL, NULL);
}
if (!new_ssid) {
new_ssid = g_convert_with_fallback (buf, buf_len, "UTF-8", e1,
"?", NULL, NULL, NULL);
}
out:
return new_ssid;
}

View file

@ -129,7 +129,7 @@ G_STMT_START \
gchar *nm_dbus_escape_object_path (const gchar *utf8_string);
gchar *nm_dbus_unescape_object_path (const gchar *object_path);
char *nm_utils_essid_to_utf8 (const char *orig_essid);
char *nm_utils_ssid_to_utf8 (const char *ssid, guint32 len);
/* #define DBUS_PENDING_CALL_DEBUG */