NetworkManager/src/NetworkManagerAPList.c
Tambet Ingo c40051389c 2007-02-16 Tambet Ingo <tambet@ximian.com>
* introspection/nm-ip4-config.xml: Implement.

	* libnm-glib/libnm-glib-test.c: Use new DBUS API in tests.

	* libnm-glib/nm-ip4-config.c:
	* libnm-glib/nm-ip4-config.c: Implement.

	* src/nm-ap-security[-*]: Remove circular dependencies between APs and AP
	securities. APs reference security.

	* src/nm-device-802-11-wireless.c: Implement missing properties that need to
	be exported over DBUS.

	* src/nm-device-802-3-ethernet.c: Ditto.

	* src/NetworkManagerAP.c:
	* src/NetworkManagerAP.h:
		- Convert to GObject, export over DBUS.

	* src/nm-ip4-config.h:
	* src/nm-ip4-config.h:
		- Convert to GObject, export over DBUS.




git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2322 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
2007-02-16 11:23:49 +00:00

560 lines
12 KiB
C

/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#include <glib.h>
#include <dbus/dbus-glib.h>
#include <netinet/ether.h>
#include "NetworkManagerAP.h"
#include "NetworkManagerAPList.h"
#include "NetworkManagerUtils.h"
#include "NetworkManagerDbus.h"
#include "nm-utils.h"
#include "nm-dbus-manager.h"
struct NMAccessPointList
{
guint refcount;
NMNetworkType type;
GSList * ap_list;
};
/*
* nm_ap_list_new
*
* Creates a new empty access point list
*
*/
NMAccessPointList *nm_ap_list_new (NMNetworkType type)
{
NMAccessPointList *list = g_slice_new0 (NMAccessPointList);
nm_ap_list_ref (list);
list->type = type;
return list;
}
/*
* nm_ap_list_ref
*
* Increases the refcount of the ap list
*
*/
void nm_ap_list_ref (NMAccessPointList *list)
{
g_return_if_fail (list != NULL);
list->refcount++;
}
/*
* nm_ap_list_unref
*
* Decreases the refcount of the ap list, and if it reaches
* 0 frees the structure.
*
*/
void nm_ap_list_unref (NMAccessPointList *list)
{
if (!list)
return;
list->refcount--;
if (list->refcount <= 0) {
g_slist_foreach (list->ap_list, (GFunc) g_object_unref, NULL);
g_slist_free (list->ap_list);
g_slice_free (NMAccessPointList, list);
}
}
/*
* nm_ap_list_size
*
* Return size of the access point list
*
*/
guint nm_ap_list_size (NMAccessPointList *list)
{
g_return_val_if_fail (list != NULL, 0);
return g_slist_length (list->ap_list);
}
/*
* nm_ap_list_is_empty
*
* Returns whether or not the access point list has any access points
* in it.
*
*/
gboolean nm_ap_list_is_empty (NMAccessPointList *list)
{
return ((list->ap_list == NULL));
}
/*
* nm_ap_list_append_ap
*
* Helper to append an AP to an ap list of a certain type.
*
*/
void nm_ap_list_append_ap (NMAccessPointList *list, NMAccessPoint *ap)
{
g_return_if_fail (list != NULL);
g_return_if_fail (ap != NULL);
list->ap_list = g_slist_append (list->ap_list, g_object_ref (ap));
}
/*
* nm_ap_list_remove_ap
*
* Helper to remove an AP to an ap list of a certain type.
*
*/
void nm_ap_list_remove_ap (NMAccessPointList *list, NMAccessPoint *ap)
{
GSList *elt = NULL;
g_return_if_fail (list != NULL);
g_return_if_fail (ap != NULL);
for (elt = list->ap_list; elt; elt = g_slist_next (elt)) {
NMAccessPoint * list_ap = (NMAccessPoint *) elt->data;
if (list_ap == ap) {
list->ap_list = g_slist_remove_link (list->ap_list, elt);
g_object_unref (list_ap);
g_slist_free (elt);
break;
}
}
}
/*
* nm_ap_list_remove_ap_by_essid
*
* Helper to remove an AP from an AP list by the AP's ESSID.
*
*/
void nm_ap_list_remove_ap_by_essid (NMAccessPointList *list, const char *network)
{
GSList *elt = NULL;
g_return_if_fail (list != NULL);
g_return_if_fail (network != 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) {
list->ap_list = g_slist_remove_link (list->ap_list, elt);
g_object_unref (list_ap);
g_slist_free (elt);
break;
}
}
}
/* nm_ap_list_remove_duplicate_essids
*
*/
void nm_ap_list_remove_duplicate_essids (NMAccessPointList *list)
{
NMAccessPoint *removal_ap;
NMAccessPoint *list_ap_max;
GSList *elt_i = NULL;
GSList *elt_j = NULL;
GSList *elt_max = NULL;
GSList *removal_list = NULL;
GSList *elt;
gint8 max_strength = 0;
gint8 strengthj = 0;
g_return_if_fail (list != NULL);
for (elt_i = list->ap_list; elt_i; elt_i = g_slist_next (elt_i)) {
NMAccessPoint * list_ap_i = (NMAccessPoint *) elt_i->data;
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;
if ((found = (nm_null_safe_strcmp (nm_ap_get_essid (list_ap_i), nm_ap_get_essid (list_ap_j)) == 0)))
break;
}
if (found)
continue;
elt_max = elt_i;
list_ap_max = (NMAccessPoint *)(elt_i->data);
max_strength = nm_ap_get_strength (list_ap_i);
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;
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 (strengthj > max_strength) {
removal_list = g_slist_append (removal_list, list_ap_max);
list_ap_max = list_ap_j;
max_strength = strengthj;
} else {
removal_list = g_slist_append (removal_list, list_ap_j);
}
}
}
}
for (elt = removal_list; elt; elt = g_slist_next (elt)) {
if ((removal_ap = (NMAccessPoint *)(elt->data)))
nm_ap_list_remove_ap (list, removal_ap);
}
g_slist_free (removal_list);
}
/*
* nm_ap_list_get_ap_by_essid
*
* Search through an access point list and return the access point
* that has a given essid.
*
*/
NMAccessPoint *nm_ap_list_get_ap_by_essid (NMAccessPointList *list, const char *network)
{
NMAccessPoint *ap;
NMAccessPoint *found_ap = NULL;
NMAPListIter *iter;
if (!network)
return (NULL);
if (!list)
return (NULL);
if (!(iter = nm_ap_list_iter_new (list)))
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))
{
found_ap = ap;
break;
}
}
nm_ap_list_iter_free (iter);
return (found_ap);
}
/*
* nm_ap_list_get_ap_by_address
*
* Search through an access point list and return the access point
* that has a given AP address.
*
*/
NMAccessPoint *nm_ap_list_get_ap_by_address (NMAccessPointList *list, const struct ether_addr *addr)
{
NMAccessPoint *ap;
NMAccessPoint *found_ap = NULL;
NMAPListIter *iter;
if (!addr)
return (NULL);
if (!list)
return (NULL);
if (!(iter = nm_ap_list_iter_new (list)))
return (NULL);
while ((ap = nm_ap_list_iter_next (iter)))
{
GSList *user_addrs;
gboolean success = FALSE;
if (nm_ap_get_address (ap) && (memcmp (addr, nm_ap_get_address (ap), sizeof (struct ether_addr)) == 0))
success = TRUE;
if (!success && (user_addrs = nm_ap_get_user_addresses (ap)))
{
char char_addr[20];
GSList *elt;
memset (&char_addr[0], 0, 20);
iw_ether_ntop (addr, &char_addr[0]);
for (elt = user_addrs; elt; elt = g_slist_next (elt))
{
if (elt->data && !strcmp (elt->data, &char_addr[0]))
{
success = TRUE;
break;
}
}
g_slist_foreach (user_addrs, (GFunc)g_free, NULL);
g_slist_free (user_addrs);
}
if (success)
{
found_ap = ap;
break;
}
}
nm_ap_list_iter_free (iter);
return (found_ap);
}
/*
* nm_ap_list_copy_properties
*
* Update properties (like encryption keys or timestamps) in one access point list from
* access points in another list, if the APs in the first list are present
* in the second.
*
*/
void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *source)
{
NMAPListIter *iter;
NMAccessPoint *dest_ap;
if (!dest || !source)
return;
if (!(iter = nm_ap_list_iter_new (dest)))
return;
while ((dest_ap = nm_ap_list_iter_next (iter)))
{
NMAccessPoint *src_ap = NULL;
if ((src_ap = nm_ap_list_get_ap_by_essid (source, nm_ap_get_essid (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));
nm_ap_set_timestamp_via_timestamp (dest_ap, nm_ap_get_timestamp (src_ap));
}
}
nm_ap_list_iter_free (iter);
}
/*
* nm_ap_list_copy_one_essid_by_address
*
* If the access point doesn't have an ESSID, 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.
*
*/
void
nm_ap_list_copy_one_essid_by_address (NMAccessPoint *ap,
NMAccessPointList *search_list)
{
NMAccessPoint *found_ap;
const char *essid;
g_return_if_fail (ap != NULL);
/* Ignore APs that already have an ESSID */
if (!search_list || nm_ap_get_essid (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;
if (essid)
nm_ap_set_essid (ap, essid);
}
/*
* nm_ap_list_copy_essids_by_address
*
* For each blank-essid 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.
*
*/
void
nm_ap_list_copy_essids_by_address (NMAccessPointList *dest,
NMAccessPointList *source)
{
NMAPListIter *iter;
NMAccessPoint *dest_ap;
if (!dest || !source)
return;
if (!(iter = nm_ap_list_iter_new (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_iter_free (iter);
}
/*
* nm_ap_list_get_type
*
* Return the type of an AP list
*
*/
NMNetworkType nm_ap_list_get_type (NMAccessPointList *list)
{
g_return_val_if_fail (list != NULL, NETWORK_TYPE_UNKNOWN);
return (list->type);
}
struct NMAPListIter
{
NMAccessPointList * list;
GSList * cur_pos;
gboolean valid;
};
NMAPListIter * nm_ap_list_iter_new (NMAccessPointList *list)
{
NMAPListIter *iter;
g_return_val_if_fail (list != NULL, NULL);
iter = g_slice_new (NMAPListIter);
iter->list = list;
iter->cur_pos = list->ap_list;
iter->valid = FALSE;
return iter;
}
NMAccessPoint * nm_ap_list_iter_get_ap (NMAPListIter *iter)
{
g_return_val_if_fail (iter != NULL, NULL);
g_return_val_if_fail (iter->valid, NULL);
if (!iter->cur_pos)
return (NULL);
return ((NMAccessPoint *)(iter->cur_pos->data));
}
NMAccessPoint * nm_ap_list_iter_next (NMAPListIter *iter)
{
g_return_val_if_fail (iter != NULL, NULL);
if (iter->valid) {
iter->cur_pos = g_slist_next (iter->cur_pos);
} else {
iter->valid = TRUE;
iter->cur_pos = iter->list->ap_list;
}
return (nm_ap_list_iter_get_ap (iter));
}
void nm_ap_list_iter_free (NMAPListIter *iter)
{
g_return_if_fail (iter != NULL);
memset (iter, 0, sizeof (struct NMAPListIter));
g_slice_free (NMAPListIter, iter);
}
#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
#define MAC_ARG(x) ((guint8*)(x))[0],((guint8*)(x))[1],((guint8*)(x))[2],((guint8*)(x))[3],((guint8*)(x))[4],((guint8*)(x))[5]
/*
* nm_ap_list_print_members
*
* Print the information about each access point in an AP list
*
*/
void nm_ap_list_print_members (NMAccessPointList *list, const char *name)
{
NMAccessPoint * ap;
NMAPListIter * iter;
int i = 0;
g_return_if_fail (list != NULL);
g_return_if_fail (name != NULL);
if (!(iter = nm_ap_list_iter_new (list)))
return;
nm_info ("AP_LIST_PRINT: printing members of '%s'", name);
while ((ap = nm_ap_list_iter_next (iter))) {
const GTimeVal * timestamp = nm_ap_get_timestamp (ap);
const GTimeVal * seen = nm_ap_get_last_seen (ap);
NMAPSecurity * security = nm_ap_get_security (ap);
const char * key = "";
const struct ether_addr * eth_addr = nm_ap_get_address (ap);
char addr[ETH_ALEN];
double freq = nm_ap_get_freq (ap);
if (security)
key = nm_ap_security_get_key (security);
memcpy (&addr, eth_addr, ETH_ALEN);
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),
ap,
timestamp->tv_sec,
nm_ap_get_encrypted (ap),
MAC_ARG (addr),
nm_ap_get_strength (ap),
(freq > 20) ? freq : 0,
(freq < 20) ? (int) freq : 0,
nm_ap_get_rate (ap),
nm_ap_get_invalid (ap),
nm_ap_get_mode (ap),
seen->tv_sec);
i++;
}
nm_info ("AP_LIST_PRINT: done");
nm_ap_list_iter_free (iter);
}