mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-23 19:24:38 +00:00
2004-07-05 Dan Williams <dcbw@redhat.com>
* dispatcher-daemon/NetworkManagerDispatcher.c - A bit more descriptive state message - Don't segfault when reading directory * src/NetworkManager.h - Remove NMData desired_ap member, its now per-device rather than global * src/NetworkManager.c - Remove references to desired_ap - Move the allowed AP list refresh stuff into a thread * src/NetworkManagerDevice.c src/NetworkManagerDevice.h - Each wireless device now has a "best ap" - Make device activate/deactivate functions per-device - Make wireless scanning per-device - Add IPv4 address discover functions, stub IPv6 ones - Move ethernet address validation functions to NetworkManagerUtils.c - Add wireless access point accessor function - Get/Set functions for "best ap" * src/NetworkManagerPolicy.c - Move activate/deactivate stuff into NetworkManagerDevice.c, per-device - Deal with per-device "best ap" rather than data->desired_apa - Implement allowed access point worker thread - Add nm_policy_essid_is_allowed() function * src/NetworkManagerUtils.c src/NetworkManagerUtils.h - Add nm_ethernet_address_is_valid() function - Add IPv4/IPv6 address get functions * src/NetworkManagerWireless.c src/NetworkManagerWireless.h - Move scanning stuff into NetworkManagerDevice.c, per-device git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@12 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
parent
d340cafffa
commit
019e2337bf
39
ChangeLog
39
ChangeLog
|
@ -1,3 +1,42 @@
|
|||
2004-07-05 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
* dispatcher-daemon/NetworkManagerDispatcher.c
|
||||
- A bit more descriptive state message
|
||||
- Don't segfault when reading directory
|
||||
|
||||
* src/NetworkManager.h
|
||||
- Remove NMData desired_ap member, its now
|
||||
per-device rather than global
|
||||
|
||||
* src/NetworkManager.c
|
||||
- Remove references to desired_ap
|
||||
- Move the allowed AP list refresh stuff into a thread
|
||||
|
||||
* src/NetworkManagerDevice.c
|
||||
src/NetworkManagerDevice.h
|
||||
- Each wireless device now has a "best ap"
|
||||
- Make device activate/deactivate functions per-device
|
||||
- Make wireless scanning per-device
|
||||
- Add IPv4 address discover functions, stub IPv6 ones
|
||||
- Move ethernet address validation functions to NetworkManagerUtils.c
|
||||
- Add wireless access point accessor function
|
||||
- Get/Set functions for "best ap"
|
||||
|
||||
* src/NetworkManagerPolicy.c
|
||||
- Move activate/deactivate stuff into NetworkManagerDevice.c, per-device
|
||||
- Deal with per-device "best ap" rather than data->desired_apa
|
||||
- Implement allowed access point worker thread
|
||||
- Add nm_policy_essid_is_allowed() function
|
||||
|
||||
* src/NetworkManagerUtils.c
|
||||
src/NetworkManagerUtils.h
|
||||
- Add nm_ethernet_address_is_valid() function
|
||||
- Add IPv4/IPv6 address get functions
|
||||
|
||||
* src/NetworkManagerWireless.c
|
||||
src/NetworkManagerWireless.h
|
||||
- Move scanning stuff into NetworkManagerDevice.c, per-device
|
||||
|
||||
2004-06-29 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
* dispatcher-daemon/NetworkManagerDispatcher.c
|
||||
|
|
|
@ -58,7 +58,7 @@ void nmd_execute_scripts (NMDAction action, char *iface_name)
|
|||
return;
|
||||
}
|
||||
|
||||
while (dir)
|
||||
do
|
||||
{
|
||||
errno = 0;
|
||||
if ((ent = readdir (dir)) != NULL)
|
||||
|
@ -83,9 +83,8 @@ void nmd_execute_scripts (NMDAction action, char *iface_name)
|
|||
system (cmd);
|
||||
}
|
||||
}
|
||||
else fprintf( stderr, "d_name = %s, errno = %d\n", ent->d_name, errno);
|
||||
}
|
||||
}
|
||||
} while (ent);
|
||||
|
||||
closedir (dir);
|
||||
}
|
||||
|
@ -173,7 +172,9 @@ static DBusHandlerResult nmd_dbus_filter (DBusConnection *connection, DBusMessag
|
|||
{
|
||||
char *dev_iface_name = nmd_get_device_name (connection, dev_object_path);
|
||||
|
||||
fprintf (stderr, "Device %s (%s) now has state %d.\n", dev_object_path, dev_iface_name, action);
|
||||
fprintf (stderr, "Device %s (%s) is now %s.\n", dev_object_path, dev_iface_name,
|
||||
(action == NMD_DEVICE_NOW_INACTIVE ? "down" :
|
||||
(action == NMD_DEVICE_NOW_ACTIVE ? "up" : "error")));
|
||||
|
||||
nmd_execute_scripts (action, dev_iface_name);
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ static GMainLoop *loop = NULL;
|
|||
static NMData *nm_data = NULL;
|
||||
gboolean debug = TRUE;
|
||||
static gboolean quit = FALSE;
|
||||
|
||||
extern gboolean allowed_ap_worker_exit;
|
||||
|
||||
static void nm_data_free (NMData *data);
|
||||
|
||||
|
@ -342,6 +342,11 @@ gboolean nm_link_state_monitor (gpointer user_data)
|
|||
nm_device_bring_up (dev);
|
||||
|
||||
nm_device_update_link_active (dev, FALSE);
|
||||
|
||||
/* Check if the device's IP address has changed
|
||||
* (ie dhcp lease renew/address change)
|
||||
*/
|
||||
/* Implement me */
|
||||
}
|
||||
|
||||
element = g_slist_next (element);
|
||||
|
@ -482,7 +487,6 @@ static void nm_data_free (NMData *data)
|
|||
nm_device_unref (data->active_device);
|
||||
|
||||
nm_data_allowed_ap_list_free (data);
|
||||
nm_ap_unref (data->desired_ap);
|
||||
}
|
||||
|
||||
|
||||
|
@ -546,6 +550,7 @@ int main( int argc, char *argv[] )
|
|||
guint policy_source;
|
||||
guint wireless_scan_source;
|
||||
gboolean become_daemon = TRUE;
|
||||
GThread *allowed_ap_thread = NULL;
|
||||
|
||||
/* Parse options */
|
||||
while (1)
|
||||
|
@ -649,6 +654,7 @@ int main( int argc, char *argv[] )
|
|||
|
||||
/* Initialize our list of allowed access points */
|
||||
nm_policy_update_allowed_access_points (nm_data);
|
||||
allowed_ap_thread = g_thread_create (nm_policy_allowed_ap_refresh_worker, nm_data, FALSE, NULL);
|
||||
|
||||
/* Create our dbus service */
|
||||
nm_data->dbus_connection = nm_dbus_init ();
|
||||
|
@ -670,19 +676,19 @@ int main( int argc, char *argv[] )
|
|||
wireless_scan_source = g_timeout_add (10000, nm_wireless_scan_monitor, nm_data);
|
||||
|
||||
/* Watch all devices that HAL knows about for state changes */
|
||||
/* Don't need this now because our polling function takes care of it and
|
||||
* HAL drops the ball for some cards.
|
||||
*/
|
||||
hal_device_property_watch_all (nm_data->hal_ctx);
|
||||
|
||||
/* Since we do what dhclient does, and do it better, kill dhclient */
|
||||
/* We run dhclient when we need to, and we don't want any stray ones
|
||||
* lying around upon launch.
|
||||
*/
|
||||
system ("killall dhclient");
|
||||
|
||||
/* Run the main loop, all events processed by callbacks from libhal. */
|
||||
/* Wheeee!!! */
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
g_main_loop_run (loop);
|
||||
|
||||
/* Kill the watch functions */
|
||||
/* Kill the watch functions & threads */
|
||||
allowed_ap_worker_exit = TRUE;
|
||||
g_source_remove (link_source);
|
||||
g_source_remove (policy_source);
|
||||
g_source_remove (wireless_scan_source);
|
||||
|
|
|
@ -37,7 +37,6 @@ struct NMData
|
|||
GMutex *state_modified_mutex;
|
||||
GSList *allowed_ap_list;
|
||||
GMutex *allowed_ap_list_mutex;
|
||||
NMAccessPoint *desired_ap;
|
||||
DBusConnection *dbus_connection;
|
||||
};
|
||||
|
||||
|
|
|
@ -24,8 +24,6 @@
|
|||
#include <dbus/dbus-glib.h>
|
||||
#include <hal/libhal.h>
|
||||
#include <iwlib.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
|
||||
#include "NetworkManager.h"
|
||||
#include "NetworkManagerDevice.h"
|
||||
|
@ -165,6 +163,7 @@ typedef struct NMDeviceWirelessOptions
|
|||
gboolean supports_wireless_scan;
|
||||
GMutex *ap_list_mutex;
|
||||
GSList *ap_list;
|
||||
NMAccessPoint *best_ap;
|
||||
} NMDeviceWirelessOptions;
|
||||
|
||||
typedef struct NMDeviceWiredOptions
|
||||
|
@ -188,6 +187,8 @@ struct NMDevice
|
|||
gchar *iface;
|
||||
NMIfaceType iface_type;
|
||||
gboolean link_active;
|
||||
guint32 ip_address;
|
||||
/* FIXME: ipv6 address too */
|
||||
NMDeviceOptions dev_options;
|
||||
};
|
||||
|
||||
|
@ -263,6 +264,7 @@ void nm_device_unref (NMDevice *dev)
|
|||
{
|
||||
g_free (dev->dev_options.wireless.cur_essid);
|
||||
g_mutex_free (dev->dev_options.wireless.ap_list_mutex);
|
||||
nm_ap_unref (dev->dev_options.wireless.best_ap);
|
||||
}
|
||||
|
||||
dev->udi = NULL;
|
||||
|
@ -350,11 +352,11 @@ gboolean nm_device_get_supports_wireless_scan (NMDevice *dev)
|
|||
* Updates the link state for a particular device.
|
||||
*
|
||||
*/
|
||||
gboolean nm_device_update_link_active (NMDevice *dev, gboolean check_mii)
|
||||
void nm_device_update_link_active (NMDevice *dev, gboolean check_mii)
|
||||
{
|
||||
gboolean link_active = FALSE;
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* FIXME
|
||||
* For wireless cards, the best indicator of a "link" at this time
|
||||
|
@ -371,23 +373,7 @@ gboolean nm_device_update_link_active (NMDevice *dev, gboolean check_mii)
|
|||
|
||||
iwlib_socket = iw_sockets_open ();
|
||||
if (iw_get_ext (iwlib_socket, nm_device_get_iface (dev), SIOCGIWAP, &wrq) >= 0)
|
||||
{
|
||||
struct ether_addr invalid_addr1;
|
||||
struct ether_addr invalid_addr2;
|
||||
struct ether_addr invalid_addr3;
|
||||
struct ether_addr ap_addr;
|
||||
|
||||
/* Compare the AP address the card has with invalid ethernet MAC addresses.
|
||||
*/
|
||||
memcpy (&ap_addr, &(wrq.u.ap_addr.sa_data), sizeof (struct ether_addr));
|
||||
memset (&invalid_addr1, 0xFF, sizeof(struct ether_addr));
|
||||
memset (&invalid_addr2, 0x00, sizeof(struct ether_addr));
|
||||
memset (&invalid_addr2, 0x44, sizeof(struct ether_addr));
|
||||
if ( (memcmp(&ap_addr, &invalid_addr1, sizeof(struct ether_addr)) != 0)
|
||||
&& (memcmp(&ap_addr, &invalid_addr2, sizeof(struct ether_addr)) != 0)
|
||||
&& (memcmp(&ap_addr, &invalid_addr3, sizeof(struct ether_addr)) != 0))
|
||||
link_active = TRUE;
|
||||
}
|
||||
link_active = nm_ethernet_address_is_valid (&(wrq.u.ap_addr.sa_data));
|
||||
close (iwlib_socket);
|
||||
break;
|
||||
}
|
||||
|
@ -413,7 +399,6 @@ gboolean nm_device_update_link_active (NMDevice *dev, gboolean check_mii)
|
|||
nm_device_set_link_active (dev, link_active);
|
||||
nm_data_set_state_modified (nm_get_global_data(), TRUE);
|
||||
}
|
||||
return (link_active);
|
||||
}
|
||||
|
||||
|
||||
|
@ -499,6 +484,30 @@ void nm_device_set_essid (NMDevice *dev, const char *essid)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_get_ap_address
|
||||
*
|
||||
* If a device is wireless, get the access point's ethernet address
|
||||
* that the card is associated with.
|
||||
*/
|
||||
void nm_device_get_ap_address (NMDevice *dev, struct ether_addr *addr)
|
||||
{
|
||||
int iwlib_socket;
|
||||
struct iwreq wrq;
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
g_return_if_fail (addr != NULL);
|
||||
|
||||
/* Do we have a valid MAC address? */
|
||||
iwlib_socket = iw_sockets_open ();
|
||||
if (iw_get_ext (iwlib_socket, nm_device_get_iface (dev), SIOCGIWAP, &wrq) >= 0)
|
||||
memcpy (addr, &(wrq.u.ap_addr.sa_data), sizeof (struct ether_addr));
|
||||
else
|
||||
memset (addr, 0, sizeof (struct ether_addr));
|
||||
close (iwlib_socket);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_set_wep_key
|
||||
*
|
||||
|
@ -564,6 +573,46 @@ void nm_device_set_wep_key (NMDevice *dev, const char *wep_key)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_get_ip4_address
|
||||
*
|
||||
* Get a device's IPv4 address
|
||||
*
|
||||
*/
|
||||
guint32 nm_device_get_ip4_address(NMDevice *dev)
|
||||
{
|
||||
struct ifreq req;
|
||||
int socket;
|
||||
|
||||
g_return_val_if_fail (dev != NULL, 0);
|
||||
g_return_val_if_fail (nm_device_get_iface (dev) != NULL, 0);
|
||||
|
||||
socket = nm_get_network_control_socket ();
|
||||
if (socket < 0)
|
||||
return (0);
|
||||
|
||||
strncpy ((char *)(&req.ifr_name), nm_device_get_iface (dev), 16); // 16 == IF_NAMESIZE
|
||||
if (ioctl (socket, SIOCGIFADDR, &req) != 0)
|
||||
return (0);
|
||||
|
||||
return (((struct sockaddr_in *)(&req.ifr_addr))->sin_addr.s_addr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_get_ip6_address
|
||||
*
|
||||
* Get a device's IPv6 address
|
||||
*
|
||||
*/
|
||||
void nm_device_get_ip6_address(NMDevice *dev)
|
||||
{
|
||||
/* FIXME
|
||||
* Implement
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_set_up_down
|
||||
*
|
||||
|
@ -651,6 +700,158 @@ gboolean nm_device_is_up (NMDevice *dev)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_activate
|
||||
*
|
||||
* Activate the device, bringing it up and getting it an
|
||||
* IP address.
|
||||
*
|
||||
*/
|
||||
gboolean nm_device_activate (NMDevice *dev)
|
||||
{
|
||||
unsigned char buf[500];
|
||||
gboolean success = FALSE;
|
||||
unsigned char *iface;
|
||||
unsigned char hostname[500] = "\0";
|
||||
int host_err;
|
||||
NMData *data = nm_get_global_data ();
|
||||
int dhclient_err;
|
||||
FILE *pidfile;
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
g_return_val_if_fail (data != NULL, FALSE);
|
||||
|
||||
/* If its a wireless device, set the ESSID and WEP key */
|
||||
if (nm_device_get_iface_type (dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET)
|
||||
{
|
||||
NMAccessPoint *ap = nm_device_get_best_ap (dev);
|
||||
|
||||
/* If the card is just inserted, we may not have had a chance to scan yet */
|
||||
if (!ap)
|
||||
{
|
||||
nm_device_do_wireless_scan (dev);
|
||||
ap = nm_device_get_best_ap (dev);
|
||||
}
|
||||
|
||||
/* If there is a desired AP to connect to, use that essid and possible WEP key */
|
||||
if (nm_ap_get_essid (ap) != NULL)
|
||||
{
|
||||
nm_device_bring_down (dev);
|
||||
|
||||
nm_device_set_essid (dev, nm_ap_get_essid (ap));
|
||||
|
||||
/* Disable WEP */
|
||||
nm_device_set_wep_key (dev, NULL);
|
||||
if (nm_ap_get_wep_key (ap))
|
||||
nm_device_set_wep_key (dev, nm_ap_get_wep_key (ap));
|
||||
}
|
||||
NM_DEBUG_PRINT_2 ("nm_device_activate(%s) using essid '%s'\n", nm_device_get_iface (dev), nm_ap_get_essid (ap));
|
||||
}
|
||||
|
||||
/* Bring the device up */
|
||||
if (!nm_device_is_up (dev));
|
||||
nm_device_bring_up (dev);
|
||||
|
||||
/* Kill the old default route */
|
||||
snprintf (buf, 500, "/sbin/ip route del default");
|
||||
system (buf);
|
||||
|
||||
/* Find and kill the previous dhclient process for this interface */
|
||||
iface = nm_device_get_iface (dev);
|
||||
snprintf (buf, 500, "/var/run/dhclient-%s.pid", iface);
|
||||
pidfile = fopen (buf, "r");
|
||||
if (pidfile)
|
||||
{
|
||||
int len;
|
||||
unsigned char s_pid[20];
|
||||
pid_t n_pid = -1;
|
||||
|
||||
memset (s_pid, 0, 20);
|
||||
fgets (s_pid, 19, pidfile);
|
||||
len = strnlen (s_pid, 20);
|
||||
fclose (pidfile);
|
||||
|
||||
n_pid = atoi (s_pid);
|
||||
if (n_pid > 0)
|
||||
kill (n_pid, 9);
|
||||
}
|
||||
|
||||
snprintf (buf, 500, "/sbin/dhclient -1 -q -lf /var/lib/dhcp/dhclient-%s.leases -pf /var/run/dhclient-%s.pid -cf /etc/dhclient-%s.conf %s\n",
|
||||
iface, iface, iface, iface);
|
||||
dhclient_err = system (buf);
|
||||
if (dhclient_err != 0)
|
||||
{
|
||||
/* Interfaces cannot be down if they are the active interface,
|
||||
* otherwise we cannot use them for scanning or link detection.
|
||||
* If dhclient doesn't get a DHCP address, it will take the interface
|
||||
* down, so we reactivate it here.
|
||||
*/
|
||||
if (nm_device_get_iface_type (dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET)
|
||||
{
|
||||
nm_device_set_essid (dev, "");
|
||||
nm_device_set_wep_key (dev, NULL);
|
||||
}
|
||||
|
||||
nm_device_bring_up (dev);
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
/* Set the hostname back to what it was before so that X11 doesn't
|
||||
* puke when the hostname changes, and so users can actually launch stuff.
|
||||
*/
|
||||
if (host_err >= 0)
|
||||
sethostname (hostname, strlen (hostname));
|
||||
|
||||
/* Restart the nameservice caching daemon to make apps aware of new DNS servers */
|
||||
snprintf (buf, 500, "/sbin/service nscd restart");
|
||||
system (buf);
|
||||
|
||||
nm_dbus_signal_device_now_active (data->dbus_connection, dev);
|
||||
|
||||
return (success);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_deactivate
|
||||
*
|
||||
* Remove a device's routing table entries and IP address.
|
||||
*
|
||||
*/
|
||||
gboolean nm_device_deactivate (NMDevice *dev)
|
||||
{
|
||||
unsigned char buf[500];
|
||||
unsigned char *iface;
|
||||
gboolean success = FALSE;
|
||||
NMData *data = nm_get_global_data ();
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
g_return_val_if_fail (data != NULL, FALSE);
|
||||
|
||||
iface = nm_device_get_iface (dev);
|
||||
|
||||
/* Take out any entries in the routing table and any IP address the old interface
|
||||
* had.
|
||||
*/
|
||||
if (iface && strlen (iface))
|
||||
{
|
||||
/* Remove routing table entries */
|
||||
snprintf (buf, 500, "/sbin/ip route flush dev %s", iface);
|
||||
system (buf);
|
||||
|
||||
/* Remove ip address */
|
||||
snprintf (buf, 500, "/sbin/ip address flush dev %s", iface);
|
||||
system (buf);
|
||||
|
||||
success = TRUE;
|
||||
}
|
||||
|
||||
nm_dbus_signal_device_no_longer_active (data->dbus_connection, dev);
|
||||
|
||||
return (success);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_ap_list_add
|
||||
*
|
||||
|
@ -712,7 +913,7 @@ void nm_device_ap_list_clear (NMDevice *dev)
|
|||
|
||||
|
||||
/*
|
||||
* nm_device_ap_list_get_copy
|
||||
* nm_device_ap_list_get_ap
|
||||
*
|
||||
* Copy the list of ESSIDs
|
||||
*
|
||||
|
@ -751,6 +952,255 @@ NMAccessPoint *nm_device_ap_list_get_ap (NMDevice *dev, int index)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get/Set functions for "best" access point
|
||||
*
|
||||
*/
|
||||
NMAccessPoint *nm_device_get_best_ap (NMDevice *dev)
|
||||
{
|
||||
g_return_val_if_fail (dev != NULL, NULL);
|
||||
g_return_val_if_fail (nm_device_get_iface_type (dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET, NULL);
|
||||
|
||||
return (dev->dev_options.wireless.best_ap);
|
||||
}
|
||||
|
||||
void nm_device_set_best_ap (NMDevice *dev, NMAccessPoint *ap)
|
||||
{
|
||||
g_return_if_fail (dev != NULL);
|
||||
g_return_if_fail (ap != NULL);
|
||||
g_return_if_fail (nm_device_get_iface_type (dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET);
|
||||
|
||||
if (dev->dev_options.wireless.best_ap)
|
||||
nm_ap_unref (dev->dev_options.wireless.best_ap);
|
||||
|
||||
nm_ap_ref (ap);
|
||||
dev->dev_options.wireless.best_ap = ap;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_do_normal_scan
|
||||
*
|
||||
* Scan for access points on cards that support wireless scanning.
|
||||
*
|
||||
*/
|
||||
static void nm_device_do_normal_scan (NMDevice *dev)
|
||||
{
|
||||
int iwlib_socket;
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* Device must be up before we can scan */
|
||||
if (!nm_device_is_up (dev))
|
||||
nm_device_bring_up (dev);
|
||||
|
||||
iwlib_socket = iw_sockets_open ();
|
||||
if (iwlib_socket >= 0)
|
||||
{
|
||||
wireless_scan_head scan_results = { NULL, 0 };
|
||||
wireless_scan *tmp_ap;
|
||||
int err;
|
||||
NMAccessPoint *highest_priority_ap = NULL;
|
||||
int highest_priority = NM_AP_PRIORITY_WORST;
|
||||
|
||||
/* Clear out the device's ap list */
|
||||
nm_device_ap_list_clear (dev);
|
||||
|
||||
err = iw_scan (iwlib_socket, nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
|
||||
|
||||
/* Iterate over scan results and pick a "most" preferred access point. */
|
||||
tmp_ap = scan_results.result;
|
||||
while (tmp_ap)
|
||||
{
|
||||
/* Blank essids usually indicate an AP that is not broadcasting its essid,
|
||||
* but since its not broadcasting the essid, we cannot use that ap yet.
|
||||
*/
|
||||
if (tmp_ap->b.has_essid && tmp_ap->b.essid_on && (strlen (tmp_ap->b.essid) > 0))
|
||||
{
|
||||
NMAccessPoint *nm_ap = nm_ap_new ();
|
||||
|
||||
/* Copy over info from scan to local structure */
|
||||
nm_ap_set_essid (nm_ap, tmp_ap->b.essid);
|
||||
|
||||
if (tmp_ap->has_ap_addr)
|
||||
{
|
||||
char buf[20];
|
||||
|
||||
memset (&buf[0], 0, 20);
|
||||
iw_ether_ntop((const struct ether_addr *) (tmp_ap->ap_addr.sa_data), &buf[0]);
|
||||
nm_ap_set_address (nm_ap, buf);
|
||||
}
|
||||
|
||||
nm_ap_set_quality (nm_ap, tmp_ap->stats.qual.qual);
|
||||
|
||||
if (tmp_ap->b.has_freq)
|
||||
nm_ap_set_freq (nm_ap, tmp_ap->b.freq);
|
||||
|
||||
/* Add the AP to the device's AP list, no matter if its allowed or not */
|
||||
nm_device_ap_list_add (dev, nm_ap);
|
||||
|
||||
if (nm_wireless_is_most_prefered_ap (nm_ap, &highest_priority))
|
||||
{
|
||||
if (highest_priority_ap)
|
||||
nm_ap_unref (highest_priority_ap);
|
||||
|
||||
highest_priority_ap = nm_ap_new_from_ap (nm_ap);
|
||||
}
|
||||
nm_ap_unref (nm_ap);
|
||||
}
|
||||
tmp_ap = tmp_ap->next;
|
||||
}
|
||||
nm_dispose_scan_results (scan_results.result);
|
||||
|
||||
/* If we have the "most" preferred access point, and its different than the current
|
||||
* access point, switch to it during the next cycle.
|
||||
*/
|
||||
if ( highest_priority_ap
|
||||
&& (!nm_device_get_best_ap (dev) || (nm_null_safe_strcmp (nm_device_get_essid (dev), nm_ap_get_essid (highest_priority_ap)) != 0)))
|
||||
{
|
||||
nm_device_set_best_ap (dev, nm_ap_new_from_ap (highest_priority_ap));
|
||||
nm_data_set_state_modified (nm_get_global_data (), TRUE);
|
||||
|
||||
nm_ap_unref (highest_priority_ap);
|
||||
}
|
||||
close (iwlib_socket);
|
||||
}
|
||||
else
|
||||
NM_DEBUG_PRINT_1 ("nm_device_do_normal_scan() could not get a control socket for the wireless card %s.\n", nm_device_get_iface (dev) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_do_pseudo_scan
|
||||
*
|
||||
* Brute-force the allowed access point list to find one that works, if any.
|
||||
*
|
||||
* FIXME
|
||||
* There's probably a better way to do the non-scanning access point discovery
|
||||
* than brute forcing it like this, but that makes the state machine here oh so
|
||||
* much more complicated.
|
||||
*/
|
||||
static void nm_device_do_pseudo_scan (NMDevice *dev)
|
||||
{
|
||||
NMData *data = nm_get_global_data ();
|
||||
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
nm_device_ref (dev);
|
||||
|
||||
fprintf (stderr, "Begining try all\n" );
|
||||
/* Acquire allowed AP list mutex, silently fail if we cannot */
|
||||
if (nm_try_acquire_mutex (data->allowed_ap_list_mutex, __FUNCTION__))
|
||||
{
|
||||
GSList *element = data->allowed_ap_list;
|
||||
|
||||
/* Turn off the essid so we can tell if its changed when
|
||||
* we set it below.
|
||||
*/
|
||||
nm_device_set_essid (dev, "");
|
||||
|
||||
while (element)
|
||||
{
|
||||
NMAccessPoint *ap = (NMAccessPoint *)(element->data);
|
||||
|
||||
/* Attempt to associate with this access point */
|
||||
if (ap)
|
||||
{
|
||||
struct iwreq wrq;
|
||||
int iwlib_socket;
|
||||
gboolean valid = FALSE;
|
||||
struct ether_addr save_ap_addr;
|
||||
struct ether_addr cur_ap_addr;
|
||||
|
||||
fprintf( stderr, "Looking at AP %s\n", nm_ap_get_essid (ap) );
|
||||
|
||||
if (!nm_device_is_up (dev));
|
||||
nm_device_bring_up (dev);
|
||||
|
||||
/* Save the MAC address */
|
||||
nm_device_get_ap_address (dev, &save_ap_addr);
|
||||
|
||||
nm_device_set_essid (dev, nm_ap_get_essid (ap));
|
||||
if (nm_ap_get_wep_key (ap))
|
||||
nm_device_set_wep_key (dev, nm_ap_get_wep_key (ap));
|
||||
else
|
||||
nm_device_set_wep_key (dev, NULL);
|
||||
|
||||
/* Wait a bit for association */
|
||||
g_usleep (G_USEC_PER_SEC * 2);
|
||||
|
||||
/* Do we have a valid MAC address? */
|
||||
nm_device_get_ap_address (dev, &cur_ap_addr);
|
||||
valid = nm_ethernet_address_is_valid (&cur_ap_addr);
|
||||
fprintf( stderr, "Current ap ether is: %s save = %s\n", iw_ether_ntoa (&cur_ap_addr), iw_ether_ntoa(&save_ap_addr));
|
||||
|
||||
/* If the ap address we had before, and the ap address we
|
||||
* have now, are the same, AP is invalid. Certain cards (orinoco)
|
||||
* will let the essid change, but the the card won't actually de-associate
|
||||
* from the previous access point if it can't associate with the new one
|
||||
* (ie signal too weak, etc).
|
||||
*/
|
||||
if (valid && (memcmp (&save_ap_addr, &cur_ap_addr, sizeof (struct ether_addr)) == 0))
|
||||
valid = FALSE;
|
||||
|
||||
/* FIXME
|
||||
* We should probably lock access to data->desired_ap
|
||||
*/
|
||||
if (valid)
|
||||
{
|
||||
fprintf( stderr, "AP %s looks good, setting to desired\n", nm_ap_get_essid (ap));
|
||||
nm_device_set_best_ap (dev, nm_ap_new_from_ap (ap));
|
||||
nm_data_set_state_modified (nm_get_global_data (), TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
element = g_slist_next (element);
|
||||
}
|
||||
|
||||
nm_unlock_mutex (data->allowed_ap_list_mutex, __FUNCTION__);
|
||||
fprintf( stderr, "Try all done.\n");
|
||||
}
|
||||
|
||||
nm_device_unref (dev);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_do_wireless_scan
|
||||
*
|
||||
* Get a list of access points this device can see.
|
||||
*
|
||||
*/
|
||||
void nm_device_do_wireless_scan (NMDevice *dev)
|
||||
{
|
||||
NMData *data = nm_get_global_data ();
|
||||
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (dev != NULL);
|
||||
g_return_if_fail (nm_device_get_iface_type (dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET);
|
||||
|
||||
if (nm_device_get_supports_wireless_scan (dev))
|
||||
nm_device_do_normal_scan (dev);
|
||||
else
|
||||
{
|
||||
struct ether_addr ap_addr;
|
||||
|
||||
/* We can't pseudo-scan without switching APs, therefore
|
||||
* if the card has a valid access point and its an allowed
|
||||
* access point, don't pseudo-scan for others.
|
||||
*/
|
||||
nm_device_get_ap_address (dev, &ap_addr);
|
||||
if ( !nm_ethernet_address_is_valid (&ap_addr)
|
||||
|| !nm_policy_essid_is_allowed (data, nm_device_get_essid (dev))
|
||||
|| !nm_device_get_best_ap (dev))
|
||||
{
|
||||
nm_device_do_pseudo_scan (dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************/
|
||||
/* Code ripped from HAL */
|
||||
/* minor modifications made for */
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#define NETWORK_MANAGER_DEVICE_H
|
||||
|
||||
#include "NetworkManager.h"
|
||||
#include <net/ethernet.h>
|
||||
|
||||
/*
|
||||
* Types of NetworkManager devices
|
||||
|
@ -53,18 +54,29 @@ NMIfaceType nm_device_get_iface_type (NMDevice *dev);
|
|||
|
||||
gboolean nm_device_get_link_active (NMDevice *dev);
|
||||
void nm_device_set_link_active (NMDevice *dev, const gboolean active);
|
||||
gboolean nm_device_update_link_active (NMDevice *dev, gboolean check_mii);
|
||||
|
||||
gboolean nm_device_check_link_status (NMDevice *dev);
|
||||
void nm_device_update_link_active (NMDevice *dev, gboolean check_mii);
|
||||
|
||||
char * nm_device_get_essid (NMDevice *dev);
|
||||
void nm_device_set_essid (NMDevice *dev, const char *essid);
|
||||
|
||||
void nm_device_get_ap_address (NMDevice *dev, struct ether_addr *addr);
|
||||
|
||||
guint32 nm_device_get_ip4_address (NMDevice *dev);
|
||||
void nm_device_update_ip4_address (NMDevice *dev);
|
||||
|
||||
void nm_device_get_ip6_address (NMDevice *dev);
|
||||
|
||||
gboolean nm_device_get_supports_wireless_scan (NMDevice *dev);
|
||||
void nm_device_do_wireless_scan (NMDevice *dev);
|
||||
NMAccessPoint *nm_device_get_best_ap (NMDevice *dev);
|
||||
void nm_device_set_best_ap (NMDevice *dev, NMAccessPoint *ap);
|
||||
|
||||
/* There is no function to get the WEP key since that's a slight security risk */
|
||||
void nm_device_set_wep_key (NMDevice *dev, const char *wep_key);
|
||||
|
||||
gboolean nm_device_deactivate (NMDevice *dev);
|
||||
gboolean nm_device_activate (NMDevice *dev);
|
||||
|
||||
void nm_device_bring_up (NMDevice *dev);
|
||||
void nm_device_bring_down (NMDevice *dev);
|
||||
gboolean nm_device_is_up (NMDevice *dev);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* Dan Williams <dcbw@redhat.com>
|
||||
|
@ -26,137 +27,16 @@
|
|||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
#include "NetworkManagerPolicy.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "NetworkManagerAP.h"
|
||||
|
||||
gboolean allowed_ap_worker_exit = FALSE;
|
||||
extern gboolean debug;
|
||||
|
||||
|
||||
/*
|
||||
* nm_policy_activate_device
|
||||
*
|
||||
* Performs interface switching and related networking goo.
|
||||
*
|
||||
*/
|
||||
static void nm_policy_switch_device (NMData *data, NMDevice *switch_to_dev, NMDevice *old_dev)
|
||||
{
|
||||
unsigned char buf[500];
|
||||
unsigned char hostname[500] = "\0";
|
||||
const unsigned char *new_iface;
|
||||
int host_err;
|
||||
int dhclient_err;
|
||||
FILE *pidfile;
|
||||
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (switch_to_dev != NULL);
|
||||
g_return_if_fail (nm_device_get_iface (switch_to_dev));
|
||||
g_return_if_fail (strlen (nm_device_get_iface (switch_to_dev)) >= 0);
|
||||
|
||||
/* If its a wireless device, set the ESSID and WEP key */
|
||||
if (nm_device_get_iface_type (switch_to_dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET)
|
||||
{
|
||||
/* If there is a desired AP to connect to, use that essid and possible WEP key */
|
||||
if ( data->desired_ap
|
||||
&& (nm_ap_get_essid (data->desired_ap) != NULL))
|
||||
{
|
||||
nm_device_bring_down (switch_to_dev);
|
||||
|
||||
nm_device_set_essid (switch_to_dev, nm_ap_get_essid (data->desired_ap));
|
||||
|
||||
/* Disable WEP */
|
||||
nm_device_set_wep_key (switch_to_dev, NULL);
|
||||
if (nm_ap_get_wep_key (data->desired_ap))
|
||||
nm_device_set_wep_key (switch_to_dev, nm_ap_get_wep_key (data->desired_ap));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the card isn't up, bring it up so that we can scan. We may be too early here to have
|
||||
* gotten all the scanning results, and therefore have no desired_ap. Just wait.
|
||||
*/
|
||||
if (!nm_device_is_up (switch_to_dev));
|
||||
nm_device_bring_up (switch_to_dev);
|
||||
|
||||
NM_DEBUG_PRINT ("nm_policy_activate_interface() could not find a desired AP. Card doesn't support scanning?\n");
|
||||
return; /* Don't associate with any non-allowed access points */
|
||||
}
|
||||
|
||||
NM_DEBUG_PRINT_1 ("nm_policy_activate_interface() using essid '%s'\n", nm_ap_get_essid (data->desired_ap));
|
||||
}
|
||||
|
||||
host_err = gethostname (hostname, 500);
|
||||
|
||||
/* Take out any entries in the routing table and any IP address the old interface
|
||||
* had.
|
||||
*/
|
||||
if (old_dev && strlen (nm_device_get_iface (old_dev)))
|
||||
{
|
||||
/* Remove routing table entries */
|
||||
snprintf (buf, 500, "/sbin/ip route flush dev %s", nm_device_get_iface (old_dev));
|
||||
system (buf);
|
||||
|
||||
/* Remove ip address */
|
||||
snprintf (buf, 500, "/sbin/ip address flush dev %s", nm_device_get_iface (old_dev));
|
||||
system (buf);
|
||||
}
|
||||
|
||||
/* Bring the device up */
|
||||
if (!nm_device_is_up (switch_to_dev));
|
||||
nm_device_bring_up (switch_to_dev);
|
||||
|
||||
/* Kill the old default route */
|
||||
snprintf (buf, 500, "/sbin/ip route del default");
|
||||
system (buf);
|
||||
|
||||
/* Find and kill the previous dhclient process for this interface */
|
||||
new_iface = nm_device_get_iface (switch_to_dev);
|
||||
snprintf (buf, 500, "/var/run/dhclient-%s.pid", new_iface);
|
||||
pidfile = fopen (buf, "r");
|
||||
if (pidfile)
|
||||
{
|
||||
int len;
|
||||
unsigned char s_pid[20];
|
||||
pid_t n_pid = -1;
|
||||
|
||||
memset (s_pid, 0, 20);
|
||||
fgets (s_pid, 19, pidfile);
|
||||
len = strnlen (s_pid, 20);
|
||||
fclose (pidfile);
|
||||
|
||||
n_pid = atoi (s_pid);
|
||||
if (n_pid > 0)
|
||||
kill (n_pid, 9);
|
||||
}
|
||||
|
||||
snprintf (buf, 500, "/sbin/dhclient -1 -q -lf /var/lib/dhcp/dhclient-%s.leases -pf /var/run/dhclient-%s.pid -cf /etc/dhclient-%s.conf %s\n",
|
||||
new_iface, new_iface, new_iface, new_iface);
|
||||
dhclient_err = system (buf);
|
||||
if (dhclient_err != 0)
|
||||
{
|
||||
/* Wireless devices cannot be down if they are the active interface,
|
||||
* otherwise we cannot use them for scanning.
|
||||
*/
|
||||
if (nm_device_get_iface_type (switch_to_dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET)
|
||||
{
|
||||
nm_device_set_essid (switch_to_dev, "");
|
||||
nm_device_set_wep_key (switch_to_dev, NULL);
|
||||
nm_device_bring_up (switch_to_dev);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the hostname back to what it was before so that X11 doesn't
|
||||
* puke when the hostname changes, so that users can actually launch stuff.
|
||||
*/
|
||||
if (host_err >= 0)
|
||||
sethostname (hostname, strlen (hostname));
|
||||
|
||||
/* Restart the nameservice caching daemon to make apps aware of new DNS servers */
|
||||
snprintf (buf, 500, "/sbin/service nscd restart");
|
||||
system (buf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_state_modification_monitor
|
||||
*
|
||||
|
@ -276,13 +156,11 @@ gboolean nm_state_modification_monitor (gpointer user_data)
|
|||
*/
|
||||
if (nm_device_get_iface_type (highest_priority_dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET)
|
||||
{
|
||||
/* If we don't yet have a desired AP, attempt to get one. */
|
||||
if (!data->desired_ap)
|
||||
nm_wireless_do_scan (data, highest_priority_dev);
|
||||
NMAccessPoint *ap = nm_device_get_best_ap (highest_priority_dev);
|
||||
|
||||
if ( data->desired_ap
|
||||
&& (nm_null_safe_strcmp (nm_device_get_essid (highest_priority_dev), nm_ap_get_essid (data->desired_ap)) != 0)
|
||||
&& (strlen (nm_ap_get_essid (data->desired_ap)) > 0))
|
||||
if ( ap
|
||||
&& (nm_null_safe_strcmp (nm_device_get_essid (highest_priority_dev), nm_ap_get_essid (ap)) != 0)
|
||||
&& (strlen (nm_ap_get_essid (ap)) > 0))
|
||||
essid_change_needed = TRUE;
|
||||
}
|
||||
|
||||
|
@ -302,9 +180,7 @@ gboolean nm_state_modification_monitor (gpointer user_data)
|
|||
* after a main loop iteration, we make a much more complicated state machine.
|
||||
*/
|
||||
if (data->active_device)
|
||||
nm_dbus_signal_device_no_longer_active (data->dbus_connection, data->active_device);
|
||||
|
||||
nm_policy_switch_device (data, highest_priority_dev, data->active_device);
|
||||
nm_device_deactivate (data->active_device);
|
||||
|
||||
if (data->active_device)
|
||||
nm_device_unref (data->active_device);
|
||||
|
@ -312,7 +188,7 @@ gboolean nm_state_modification_monitor (gpointer user_data)
|
|||
data->active_device = highest_priority_dev;
|
||||
nm_device_ref (data->active_device);
|
||||
|
||||
nm_dbus_signal_device_now_active (data->dbus_connection, data->active_device);
|
||||
nm_device_activate (data->active_device);
|
||||
|
||||
NM_DEBUG_PRINT ("**** Switched.\n");
|
||||
}
|
||||
|
@ -327,6 +203,41 @@ gboolean nm_state_modification_monitor (gpointer user_data)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_policy_allowed_ap_refresh_worker
|
||||
*
|
||||
* Worker thread function to periodically refresh the allowed
|
||||
* access point list with updated data.
|
||||
*
|
||||
*/
|
||||
gpointer nm_policy_allowed_ap_refresh_worker (gpointer user_data)
|
||||
{
|
||||
NMData *data = (NMData *)(user_data);
|
||||
struct timeval timeout;
|
||||
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
/* Simply loop and every 20s update the available allowed ap data */
|
||||
while (!allowed_ap_worker_exit)
|
||||
{
|
||||
int err;
|
||||
|
||||
timeout.tv_sec = 20;
|
||||
timeout.tv_usec = 0;
|
||||
|
||||
/* Wait, but don't execute the update if select () returned an error,
|
||||
* since it may have immediately returned, so that we don't hammer
|
||||
* GConf (or the hard drive).
|
||||
*/
|
||||
err = select (0, NULL, NULL, NULL, &timeout);
|
||||
if (err >= 0)
|
||||
nm_policy_update_allowed_access_points (data);
|
||||
}
|
||||
|
||||
g_thread_exit (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_policy_update_allowed_access_points
|
||||
*
|
||||
|
@ -341,7 +252,7 @@ void nm_policy_update_allowed_access_points (NMData *data)
|
|||
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
if (nm_try_acquire_mutex (data->allowed_ap_list_mutex, NULL))
|
||||
if (nm_try_acquire_mutex (data->allowed_ap_list_mutex, __FUNCTION__))
|
||||
{
|
||||
ap_file = fopen (NM_ALLOWED_AP_FILE, "r");
|
||||
if (ap_file)
|
||||
|
@ -425,11 +336,49 @@ void nm_policy_update_allowed_access_points (NMData *data)
|
|||
fclose (ap_file);
|
||||
}
|
||||
else
|
||||
NM_DEBUG_PRINT_1( "nm_policy_update_allowed_access_points() could not open and lock allowed ap list file %s. errno %d\n", NM_ALLOWED_AP_FILE );
|
||||
NM_DEBUG_PRINT_2( "nm_policy_update_allowed_access_points() could not open allowed ap list file %s. errno %d\n", NM_ALLOWED_AP_FILE, errno );
|
||||
|
||||
nm_unlock_mutex (data->allowed_ap_list_mutex, NULL);
|
||||
nm_unlock_mutex (data->allowed_ap_list_mutex, __FUNCTION__);
|
||||
}
|
||||
else
|
||||
NM_DEBUG_PRINT( "nm_policy_update_allowed_access_points() could not lock allowed ap list mutex\n" );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_policy_essid_is_allowed
|
||||
*
|
||||
* Searches for a specific essid in the list of allowed access points.
|
||||
*/
|
||||
gboolean nm_policy_essid_is_allowed (NMData *data, const unsigned char *essid)
|
||||
{
|
||||
gboolean allowed = FALSE;
|
||||
|
||||
g_return_val_if_fail (data != NULL, FALSE);
|
||||
g_return_val_if_fail (essid != NULL, FALSE);
|
||||
|
||||
if (strlen (essid) <= 0)
|
||||
return FALSE;
|
||||
|
||||
/* Acquire allowed AP list mutex, silently fail if we cannot */
|
||||
if (nm_try_acquire_mutex (data->allowed_ap_list_mutex, __FUNCTION__))
|
||||
{
|
||||
GSList *element = data->allowed_ap_list;
|
||||
|
||||
while (element)
|
||||
{
|
||||
NMAccessPoint *ap = (NMAccessPoint *)(element->data);
|
||||
|
||||
if (ap && (nm_null_safe_strcmp (nm_ap_get_essid (ap), essid) == 0))
|
||||
{
|
||||
allowed = TRUE;
|
||||
break;
|
||||
}
|
||||
element = g_slist_next (element);
|
||||
}
|
||||
|
||||
nm_unlock_mutex (data->allowed_ap_list_mutex, __FUNCTION__);
|
||||
}
|
||||
|
||||
return (allowed);
|
||||
}
|
||||
|
|
|
@ -25,8 +25,12 @@
|
|||
#include "NetworkManager.h"
|
||||
#include "NetworkManagerDevice.h"
|
||||
|
||||
gboolean nm_state_modification_monitor (gpointer user_data);
|
||||
gboolean nm_state_modification_monitor (gpointer user_data);
|
||||
|
||||
void nm_policy_update_allowed_access_points (NMData *data);
|
||||
void nm_policy_update_allowed_access_points (NMData *data);
|
||||
|
||||
gboolean nm_policy_essid_is_allowed (NMData *data, const unsigned char *essid);
|
||||
|
||||
gpointer nm_policy_allowed_ap_refresh_worker (gpointer user_data);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/sockios.h>
|
||||
|
||||
#include "NetworkManager.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
@ -126,6 +127,30 @@ int nm_get_network_control_socket (void)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_ethernet_address_is_valid
|
||||
*
|
||||
* Compares an ethernet address against known invalid addresses.
|
||||
*
|
||||
*/
|
||||
gboolean nm_ethernet_address_is_valid (struct ether_addr *test_addr)
|
||||
{
|
||||
gboolean valid = FALSE;
|
||||
struct ether_addr invalid_addr1 = { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} };
|
||||
struct ether_addr invalid_addr2 = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
|
||||
struct ether_addr invalid_addr3 = { {0x44, 0x44, 0x44, 0x44, 0x44, 0x44} };
|
||||
|
||||
g_return_if_fail (test_addr != NULL);
|
||||
|
||||
/* Compare the AP address the card has with invalid ethernet MAC addresses. */
|
||||
if ( (memcmp(test_addr, &invalid_addr1, sizeof(struct ether_addr)) != 0)
|
||||
&& (memcmp(test_addr, &invalid_addr2, sizeof(struct ether_addr)) != 0)
|
||||
&& (memcmp(test_addr, &invalid_addr3, sizeof(struct ether_addr)) != 0))
|
||||
valid = TRUE;
|
||||
|
||||
return (valid);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_dispose_scan_results
|
||||
|
@ -145,3 +170,43 @@ void nm_dispose_scan_results (wireless_scan *result_list)
|
|||
free (tmp2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_get_ip4_address_for_device
|
||||
*
|
||||
* Get a device's IPv4 address
|
||||
*
|
||||
*/
|
||||
guint32 nm_get_ip4_address_for_device(NMDevice *dev)
|
||||
{
|
||||
struct ifreq req;
|
||||
int socket;
|
||||
|
||||
g_return_val_if_fail (dev != NULL, 0);
|
||||
g_return_val_if_fail (nm_device_get_iface (dev) != NULL, 0);
|
||||
|
||||
socket = nm_get_network_control_socket ();
|
||||
if (socket < 0)
|
||||
return (0);
|
||||
|
||||
strncpy ((char *)(&req.ifr_name), nm_device_get_iface (dev), 16); // 16 == IF_NAMESIZE
|
||||
if (ioctl (socket, SIOCGIFADDR, &req) != 0)
|
||||
return (0);
|
||||
|
||||
return (((struct sockaddr_in *)(&req.ifr_addr))->sin_addr.s_addr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_get_ip6_address_for_device
|
||||
*
|
||||
* Get a device's IPv6 address
|
||||
*
|
||||
*/
|
||||
void nm_get_ip6_address_for_device(NMDevice *dev)
|
||||
{
|
||||
/* FIXME
|
||||
* Implement
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -24,9 +24,11 @@
|
|||
|
||||
#include <glib.h>
|
||||
#include <stdio.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <iwlib.h>
|
||||
|
||||
#include "NetworkManager.h"
|
||||
#include "NetworkManagerDevice.h"
|
||||
|
||||
#define NM_DEBUG_PRINT( s ) if (debug) fprintf( stderr, s );
|
||||
#define NM_DEBUG_PRINT_1( s, a ) if (debug) fprintf( stderr, s, a );
|
||||
|
@ -42,6 +44,11 @@ int nm_null_safe_strcmp (const char *s1, const char *s2);
|
|||
|
||||
int nm_get_network_control_socket (void);
|
||||
|
||||
gboolean nm_ethernet_address_is_valid (struct ether_addr *test_addr);
|
||||
|
||||
void nm_dispose_scan_results (wireless_scan *result_list);
|
||||
|
||||
guint32 nm_get_ipv4_address_for_device (NMDevice *dev);
|
||||
void nm_get_ipv6_address_for_device (NMDevice *dev);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,7 +37,7 @@ extern gboolean debug;
|
|||
* both allowed _and_ has a better priority than highest_priority.
|
||||
*
|
||||
*/
|
||||
static gboolean nm_wireless_is_most_prefered_ap (NMAccessPoint *ap, int *highest_priority)
|
||||
gboolean nm_wireless_is_most_prefered_ap (NMAccessPoint *ap, int *highest_priority)
|
||||
{
|
||||
NMData *data = nm_get_global_data ();
|
||||
GSList *element;
|
||||
|
@ -77,108 +77,6 @@ static gboolean nm_wireless_is_most_prefered_ap (NMAccessPoint *ap, int *highest
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_wireless_do_scan
|
||||
*
|
||||
* Runs the actual scan fore access points.
|
||||
*
|
||||
*/
|
||||
void nm_wireless_do_scan (NMData *data, NMDevice *dev)
|
||||
{
|
||||
int iwlib_socket;
|
||||
|
||||
g_return_if_fail (data != NULL);
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
if (nm_device_get_iface_type (dev) != NM_IFACE_TYPE_WIRELESS_ETHERNET)
|
||||
return;
|
||||
|
||||
if (nm_device_get_supports_wireless_scan (dev) == FALSE)
|
||||
return;
|
||||
|
||||
/* Device must be up before we can scan */
|
||||
if (!nm_device_is_up (dev))
|
||||
nm_device_bring_up (dev);
|
||||
|
||||
iwlib_socket = iw_sockets_open ();
|
||||
if (iwlib_socket >= 0)
|
||||
{
|
||||
wireless_scan_head scan_results = { NULL, 0 };
|
||||
wireless_scan *tmp_ap;
|
||||
int err;
|
||||
NMAccessPoint *highest_priority_ap = NULL;
|
||||
int highest_priority = NM_AP_PRIORITY_WORST;
|
||||
|
||||
/* Clear out the device's ap list */
|
||||
nm_device_ap_list_clear (dev);
|
||||
|
||||
err = iw_scan (iwlib_socket, nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
|
||||
|
||||
/* Iterate over scan results and pick a "most" preferred access point. */
|
||||
tmp_ap = scan_results.result;
|
||||
while (tmp_ap)
|
||||
{
|
||||
/* Blank essids usually indicate an AP that is not broadcasting its essid,
|
||||
* but since its not broadcasting the essid, we cannot use that ap yet.
|
||||
*/
|
||||
if (tmp_ap->b.has_essid && tmp_ap->b.essid_on && (strlen (tmp_ap->b.essid) > 0))
|
||||
{
|
||||
NMAccessPoint *nm_ap = nm_ap_new ();
|
||||
|
||||
/* Copy over info from scan to local structure */
|
||||
nm_ap_set_essid (nm_ap, tmp_ap->b.essid);
|
||||
|
||||
if (tmp_ap->has_ap_addr)
|
||||
{
|
||||
char buf[20];
|
||||
|
||||
memset (&buf[0], 0, 20);
|
||||
iw_ether_ntop((const struct ether_addr *) (tmp_ap->ap_addr.sa_data), &buf[0]);
|
||||
nm_ap_set_address (nm_ap, buf);
|
||||
}
|
||||
|
||||
nm_ap_set_quality (nm_ap, tmp_ap->stats.qual.qual);
|
||||
|
||||
if (tmp_ap->b.has_freq)
|
||||
nm_ap_set_freq (nm_ap, tmp_ap->b.freq);
|
||||
|
||||
/* Add the AP to the device's AP list, no matter if its allowed or not */
|
||||
nm_device_ap_list_add (dev, nm_ap);
|
||||
|
||||
if (nm_wireless_is_most_prefered_ap (nm_ap, &highest_priority))
|
||||
{
|
||||
if (highest_priority_ap)
|
||||
nm_ap_unref (highest_priority_ap);
|
||||
|
||||
highest_priority_ap = nm_ap_new_from_ap (nm_ap);
|
||||
}
|
||||
nm_ap_unref (nm_ap);
|
||||
}
|
||||
tmp_ap = tmp_ap->next;
|
||||
}
|
||||
nm_dispose_scan_results (scan_results.result);
|
||||
|
||||
/* If we have the "most" preferred access point, and its different than the current
|
||||
* access point, switch to it during the next cycle.
|
||||
*/
|
||||
if ( highest_priority_ap
|
||||
&& (!data->desired_ap || (nm_null_safe_strcmp (nm_device_get_essid (dev), nm_ap_get_essid (highest_priority_ap)) != 0)))
|
||||
{
|
||||
if (data->desired_ap)
|
||||
nm_ap_unref (data->desired_ap);
|
||||
|
||||
data->desired_ap = nm_ap_new_from_ap (highest_priority_ap);
|
||||
data->state_modified = TRUE;
|
||||
|
||||
nm_ap_unref (highest_priority_ap);
|
||||
}
|
||||
close (iwlib_socket);
|
||||
}
|
||||
else
|
||||
NM_DEBUG_PRINT ("nm_wireless_do_scan() could not get a control socket for the wireless card.\n" );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_wireless_scan_monitor
|
||||
*
|
||||
|
@ -188,23 +86,19 @@ void nm_wireless_do_scan (NMData *data, NMDevice *dev)
|
|||
gboolean nm_wireless_scan_monitor (gpointer user_data)
|
||||
{
|
||||
NMData *data = (NMData *)user_data;
|
||||
GSList *element;
|
||||
NMDevice *dev;
|
||||
|
||||
g_return_val_if_fail (data != NULL, TRUE);
|
||||
|
||||
if (!data->active_device)
|
||||
return (TRUE);
|
||||
|
||||
/* Grab a current list of allowed access points */
|
||||
nm_policy_update_allowed_access_points (data);
|
||||
|
||||
/* Attempt to acquire mutex for device list iteration.
|
||||
/* Attempt to acquire mutex so that data->active_device sticks around.
|
||||
* If the acquire fails, just ignore the scan completely.
|
||||
*/
|
||||
if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
|
||||
{
|
||||
if (data->active_device && (nm_device_get_iface_type (data->active_device) == NM_IFACE_TYPE_WIRELESS_ETHERNET))
|
||||
nm_wireless_do_scan (data, data->active_device);
|
||||
nm_device_do_wireless_scan (data->active_device);
|
||||
|
||||
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,11 @@
|
|||
#ifndef NETWORK_MANAGER_WIRELESS_H
|
||||
#define NETWORK_MANAGER_WIRELESS_H
|
||||
|
||||
#include "NetworkManager.h"
|
||||
#include "NetworkManagerDevice.h"
|
||||
|
||||
|
||||
gboolean nm_wireless_is_most_prefered_ap (NMAccessPoint *ap, int *highest_priority);
|
||||
|
||||
gboolean nm_wireless_scan_monitor (gpointer user_data);
|
||||
|
||||
|
|
Loading…
Reference in a new issue