2004-08-31 Dan Williams <dcbw@redhat.com>
* Remove 'debug' extern global from all files since we now use syslog() * src/NetworkManager.[ch] - Break out routine that get the net.interface property from HAL, removing that logic from nm_create_device_and_add_to_list() - (nm_create_device_and_add_to_list): make this a bit more general so it doesn't do the talking to HAL. Also add arguments to facilitate the create of test devices. - (nm_data_mark_state_changed): rename from nm_data_set_state_modified() - (nm_data_new, main, nm_print_usage): add new argument "--enable-test-devices" which makes NetworkManager listen for dbus commands to create test devices, which have no backing hardware. Use when you're on a plane for example, and/or forgot your wireless card at home. Test devices _cannot_ be created unless NM is started with --enable-test-devices. * src/NetworkManagerDbus.[ch] - New "getLinkActive" method for devices - New "setLinkActive" method for devices (only works on test devices) - New "createTestDevice" method on NetworkManager object to create a test device of a specified type (ie wired, wireless). UDI is created from scratch, as is the interface name. Only works when NM is started with --enable-test-devices switch. - New "removeTestDevice" method on NetworkManager object which removes a test device. Only works when NM is started with --enable-test-devices * src/NetworkManagerDevice.[ch] - Logic to facilitate test devices. Add variables to NMDevice struct to indicate whether a device is a test device or not, and what its link status is. - Deal with test devices in most functions. For those that work directly on hardware special-case test devices. - (nm_device_new): don't create a test device if test devices weren't enabled on the command-line. - (nm_device_update_link_active): split out logic for wired and wireless device link checking to separate functions to facilitate test device link checking. - (nm_device_set_enc_key): Since some drivers for wireless cards are daft and don't make a distinction between System Authentication and Encryption (namely Cisco aironet), we use Open System auth when setting a WEP key on the card. We don't deal with Shared Key auth yet. - (nm_device_activation_worker): split the activation cancel check logic out into a separate routine nm_device_activation_cancel_if_needed() - (nm_device_activation_signal_cancel): rename from nm_device_activation_cancel() - (nm_device_fake_ap_list): Test wireless devices obviously cannot scan, so create a list of fake access points that they can "see" - (nm_device_is_test_device): return whether or not a device is a test device * src/NetworkManagerPolicy.c - (nm_policy_get_best_device): attempt to deal with wireless network selection, previously if you "locked"/forced NM to use a wireless device but then selected a wireless network for NM to use, it would switch to a wired device. So, if the active device is wireless and it has a "forced" best AP, use it if the "forced" best AP is still valid - (nm_state_modification_monitor): deal with NULL best devices, for example there were no usable network devices, or the last one was removed * src/backends/NetworkManager*.c - Deal with test devices, mostly just return success for operations like getting a DHCP address * test/nmtestdevices.c - Test tool to create/remove/link-switch test devices git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@112 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
@@ -47,42 +47,66 @@
|
||||
*/
|
||||
static GMainLoop *loop = NULL;
|
||||
static NMData *nm_data = NULL;
|
||||
gboolean debug = TRUE;
|
||||
extern gboolean allowed_ap_worker_exit;
|
||||
|
||||
static void nm_data_free (NMData *data);
|
||||
|
||||
|
||||
/*
|
||||
* nm_get_device_interface_from_hal
|
||||
*
|
||||
* Queries HAL for the "net.interface" property of a device and returns
|
||||
* it if successful.
|
||||
*
|
||||
*/
|
||||
static char *nm_get_device_interface_from_hal (LibHalContext *ctx, const char *udi)
|
||||
{
|
||||
char *iface = NULL;
|
||||
|
||||
if (hal_device_property_exists (ctx, udi, "net.interface"))
|
||||
{
|
||||
char *temp = hal_device_get_property_string (ctx, udi, "net.interface");
|
||||
iface = g_strdup (temp);
|
||||
hal_free_string (temp);
|
||||
}
|
||||
|
||||
return (iface);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_create_device_and_add_to_list
|
||||
*
|
||||
* Create a new NLM device and add it to our device list.
|
||||
* Create a new network device and add it to our device list.
|
||||
*
|
||||
* Returns: newly allocated device on success
|
||||
* NULL on failure
|
||||
*/
|
||||
NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi)
|
||||
NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, const char *iface,
|
||||
gboolean test_device, NMDeviceType test_device_type)
|
||||
{
|
||||
NMDevice *dev = NULL;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (data != NULL, NULL);
|
||||
g_return_val_if_fail (udi != NULL, NULL);
|
||||
g_return_val_if_fail (iface != NULL, NULL);
|
||||
|
||||
if (hal_device_property_exists (data->hal_ctx, udi, "net.interface"))
|
||||
/* If we are called to create a test devices, but test devices weren't enabled
|
||||
* on the command-line, don't create the device.
|
||||
*/
|
||||
if (!data->enable_test_devices && test_device)
|
||||
{
|
||||
gchar *iface_name = hal_device_get_property_string (data->hal_ctx, udi, "net.interface");
|
||||
|
||||
/* Make sure the device is not already in the device list */
|
||||
if ((dev = nm_get_device_by_iface (data, iface_name)))
|
||||
{
|
||||
hal_free_string (iface_name);
|
||||
syslog (LOG_ERR, "nm_create_device_and_add_to_list(): attempt to create a test device,"
|
||||
" but test devices were not enabled on the command line. Will not create the device.\n");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if ((dev = nm_device_new (iface_name, data)))
|
||||
{
|
||||
/* Make sure the device is not already in the device list */
|
||||
if ((dev = nm_get_device_by_iface (data, iface)))
|
||||
return (NULL);
|
||||
|
||||
if ((dev = nm_device_new (iface, test_device, test_device_type, data)))
|
||||
{
|
||||
/* Build up the device structure */
|
||||
nm_device_set_udi (dev, udi);
|
||||
|
||||
@@ -96,26 +120,20 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi)
|
||||
|
||||
data->dev_list = g_slist_append (data->dev_list, dev);
|
||||
nm_device_deactivate (dev, TRUE);
|
||||
success = TRUE;
|
||||
|
||||
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
||||
} else syslog( LOG_ERR, "nm_create_device_and_add_to_list() could not acquire device list mutex." );
|
||||
} else syslog( LOG_ERR, "nm_create_device_and_add_to_list() could not allocate device data." );
|
||||
|
||||
hal_free_string (iface_name);
|
||||
|
||||
if (success)
|
||||
{
|
||||
nm_data_set_state_modified (data, TRUE);
|
||||
nm_data_mark_state_changed (data);
|
||||
nm_dbus_signal_device_status_change (data->dbus_connection, dev, DEVICE_LIST_CHANGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If we couldn't add the device to our list, free its data. */
|
||||
syslog( LOG_ERR, "nm_create_device_and_add_to_list() could not acquire device list mutex." );
|
||||
nm_device_unref (dev);
|
||||
dev = NULL;
|
||||
}
|
||||
}
|
||||
} else syslog( LOG_ERR, "nm_create_device_and_add_to_list() could not allocate device data." );
|
||||
|
||||
return (dev);
|
||||
}
|
||||
@@ -159,14 +177,14 @@ void nm_remove_device_from_list (NMData *data, const char *udi)
|
||||
data->user_device = NULL;
|
||||
}
|
||||
|
||||
nm_device_activation_cancel (dev);
|
||||
nm_device_activation_signal_cancel (dev);
|
||||
nm_device_unref (dev);
|
||||
|
||||
/* Remove the device entry from the device list and free its data */
|
||||
data->dev_list = g_slist_remove_link (data->dev_list, element);
|
||||
nm_device_unref (element->data);
|
||||
g_slist_free (element);
|
||||
nm_data_set_state_modified (data, TRUE);
|
||||
nm_data_mark_state_changed (data);
|
||||
nm_dbus_signal_device_status_change (data->dbus_connection, dev, DEVICE_LIST_CHANGE);
|
||||
|
||||
break;
|
||||
@@ -195,6 +213,7 @@ static void nm_hal_mainloop_integration (LibHalContext *ctx, DBusConnection * db
|
||||
static void nm_hal_device_added (LibHalContext *ctx, const char *udi)
|
||||
{
|
||||
NMData *data = (NMData *)hal_ctx_get_user_data (ctx);
|
||||
char *iface = NULL;
|
||||
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
@@ -204,7 +223,11 @@ static void nm_hal_device_added (LibHalContext *ctx, const char *udi)
|
||||
* so this call will fail, and it will actually be added when hal sets the device's
|
||||
* capabilities a bit later on.
|
||||
*/
|
||||
nm_create_device_and_add_to_list (data, udi);
|
||||
if ((iface = nm_get_device_interface_from_hal (data->hal_ctx, udi)))
|
||||
{
|
||||
nm_create_device_and_add_to_list (data, udi, iface, FALSE, DEVICE_TYPE_DONT_KNOW);
|
||||
g_free (iface);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,7 +260,15 @@ static void nm_hal_device_new_capability (LibHalContext *ctx, const char *udi, c
|
||||
syslog( LOG_DEBUG, "nm_hal_device_new_capability() called with udi = %s, capability = %s", udi, capability );
|
||||
|
||||
if (capability && (strcmp (capability, "net.ethernet") == 0))
|
||||
nm_create_device_and_add_to_list (data, udi);
|
||||
{
|
||||
char *iface;
|
||||
|
||||
if ((iface = nm_get_device_interface_from_hal (data->hal_ctx, udi)))
|
||||
{
|
||||
nm_create_device_and_add_to_list (data, udi, iface, FALSE, DEVICE_TYPE_DONT_KNOW);
|
||||
g_free (iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -282,7 +313,15 @@ static void nm_add_initial_devices (NMData *data)
|
||||
if (net_devices)
|
||||
{
|
||||
for (i = 0; i < num_net_devices; i++)
|
||||
nm_create_device_and_add_to_list (data, net_devices[i]);
|
||||
{
|
||||
char *iface;
|
||||
|
||||
if ((iface = nm_get_device_interface_from_hal (data->hal_ctx, net_devices[i])))
|
||||
{
|
||||
nm_create_device_and_add_to_list (data, net_devices[i], iface, FALSE, DEVICE_TYPE_DONT_KNOW);
|
||||
g_free (iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hal_free_string_array (net_devices);
|
||||
@@ -382,7 +421,7 @@ static LibHalFunctions hal_functions =
|
||||
* Create data structure used in callbacks from libhal.
|
||||
*
|
||||
*/
|
||||
static NMData *nm_data_new (void)
|
||||
static NMData *nm_data_new (gboolean enable_test_devices)
|
||||
{
|
||||
NMData *data;
|
||||
|
||||
@@ -417,6 +456,7 @@ static NMData *nm_data_new (void)
|
||||
}
|
||||
|
||||
data->state_modified = TRUE;
|
||||
data->enable_test_devices = enable_test_devices;
|
||||
|
||||
return (data);
|
||||
}
|
||||
@@ -450,17 +490,17 @@ static void nm_data_free (NMData *data)
|
||||
|
||||
|
||||
/*
|
||||
* nm_data_set_state_modified
|
||||
* nm_data_mark_state_changed
|
||||
*
|
||||
* Locked function to protect state modification changes.
|
||||
* Notify our timeout that the networking state has changed in some way.
|
||||
*
|
||||
*/
|
||||
void nm_data_set_state_modified (NMData *data, gboolean modified)
|
||||
void nm_data_mark_state_changed (NMData *data)
|
||||
{
|
||||
g_return_if_fail (data != NULL);
|
||||
|
||||
g_mutex_lock (data->state_modified_mutex);
|
||||
data->state_modified = modified;
|
||||
data->state_modified = TRUE;
|
||||
g_mutex_unlock (data->state_modified_mutex);
|
||||
}
|
||||
|
||||
@@ -477,6 +517,7 @@ static void nm_print_usage (void)
|
||||
fprintf (stderr,
|
||||
"\n"
|
||||
" --no-daemon Don't become a daemon\n"
|
||||
" --enable-test-devices Allow dummy devices to be created via DBUS methods [DEBUG]\n"
|
||||
" --help Show this information and exit\n"
|
||||
"\n"
|
||||
"NetworkManager monitors all network connections and automatically\n"
|
||||
@@ -498,6 +539,7 @@ int main( int argc, char *argv[] )
|
||||
guint policy_source;
|
||||
guint wireless_scan_source;
|
||||
gboolean become_daemon = TRUE;
|
||||
gboolean enable_test_devices = FALSE;
|
||||
|
||||
/* Parse options */
|
||||
while (1)
|
||||
@@ -508,6 +550,7 @@ int main( int argc, char *argv[] )
|
||||
|
||||
static struct option options[] = {
|
||||
{"no-daemon", 0, NULL, 0},
|
||||
{"enable-test-devices", 0, NULL, 0},
|
||||
{"help", 0, NULL, 0},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
@@ -527,6 +570,8 @@ int main( int argc, char *argv[] )
|
||||
}
|
||||
else if (strcmp (opt, "no-daemon") == 0)
|
||||
become_daemon = FALSE;
|
||||
else if (strcmp (opt, "enable-test-devices") == 0)
|
||||
enable_test_devices = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -554,7 +599,7 @@ int main( int argc, char *argv[] )
|
||||
nm_system_load_device_modules ();
|
||||
|
||||
/* Initialize our instance data */
|
||||
nm_data = nm_data_new ();
|
||||
nm_data = nm_data_new (enable_test_devices);
|
||||
if (!nm_data)
|
||||
{
|
||||
syslog( LOG_CRIT, "nm_data_new() failed... Not enough memory?");
|
||||
|
@@ -28,11 +28,12 @@
|
||||
#include <hal/libhal.h>
|
||||
#include "NetworkManagerAP.h"
|
||||
|
||||
struct NMData
|
||||
typedef struct NMData
|
||||
{
|
||||
LibHalContext *hal_ctx;
|
||||
DBusConnection *dbus_connection;
|
||||
gboolean info_daemon_avail;
|
||||
gboolean enable_test_devices;
|
||||
|
||||
GSList *dev_list;
|
||||
GMutex *dev_list_mutex;
|
||||
@@ -50,10 +51,24 @@ struct NMData
|
||||
struct NMAccessPointList *trusted_ap_list;
|
||||
struct NMAccessPointList *preferred_ap_list;
|
||||
struct NMAccessPointList *invalid_ap_list;
|
||||
};
|
||||
} NMData;
|
||||
|
||||
typedef struct NMData NMData;
|
||||
/*
|
||||
* Types of NetworkManager devices
|
||||
*/
|
||||
typedef enum NMDeviceType
|
||||
{
|
||||
DEVICE_TYPE_DONT_KNOW = 0,
|
||||
DEVICE_TYPE_WIRED_ETHERNET,
|
||||
DEVICE_TYPE_WIRELESS_ETHERNET
|
||||
} NMDeviceType;
|
||||
|
||||
void nm_data_set_state_modified (NMData *data, gboolean modified);
|
||||
|
||||
struct NMDevice *nm_create_device_and_add_to_list (NMData *data, const char *udi, const char *iface,
|
||||
gboolean test_device, NMDeviceType test_device_type);
|
||||
|
||||
void nm_remove_device_from_list (NMData *data, const char *udi);
|
||||
|
||||
void nm_data_mark_state_changed (NMData *data);
|
||||
|
||||
#endif
|
||||
|
@@ -23,8 +23,6 @@
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "NetworkManagerWireless.h"
|
||||
|
||||
extern gboolean debug;
|
||||
|
||||
|
||||
/*
|
||||
* Encapsulates Access Point information
|
||||
@@ -32,7 +30,7 @@ extern gboolean debug;
|
||||
struct NMAccessPoint
|
||||
{
|
||||
guint refcount;
|
||||
gchar *essid;
|
||||
char *essid;
|
||||
struct ether_addr *address;
|
||||
guint8 quality;
|
||||
double freq;
|
||||
|
@@ -26,7 +26,6 @@
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "NetworkManagerDbus.h"
|
||||
|
||||
extern gboolean debug;
|
||||
|
||||
struct NMAccessPointList
|
||||
{
|
||||
|
@@ -26,7 +26,6 @@
|
||||
#include <stdarg.h>
|
||||
#include <iwlib.h>
|
||||
|
||||
extern gboolean debug;
|
||||
|
||||
#include "NetworkManager.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
@@ -36,6 +35,8 @@ extern gboolean debug;
|
||||
#include "NetworkManagerAPList.h"
|
||||
|
||||
|
||||
static int test_dev_num = 0;
|
||||
|
||||
/*
|
||||
* nm_dbus_create_error_message
|
||||
*
|
||||
@@ -242,7 +243,7 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB
|
||||
data->user_device = dev;
|
||||
|
||||
nm_unlock_mutex (data->user_device_mutex, __FUNCTION__);
|
||||
nm_data_set_state_modified (data, TRUE);
|
||||
nm_data_mark_state_changed (data);
|
||||
}
|
||||
|
||||
return (reply_message);
|
||||
@@ -827,7 +828,7 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes
|
||||
{
|
||||
data->update_ap_lists = TRUE;
|
||||
data->info_daemon_avail = TRUE;
|
||||
nm_data_set_state_modified (data, TRUE);
|
||||
nm_data_mark_state_changed (data);
|
||||
}
|
||||
/* Don't set handled = TRUE since other filter functions on this dbus connection
|
||||
* may want to know about service signals.
|
||||
@@ -844,7 +845,7 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes
|
||||
{
|
||||
data->update_ap_lists = TRUE;
|
||||
data->info_daemon_avail = FALSE;
|
||||
nm_data_set_state_modified (data, TRUE);
|
||||
nm_data_mark_state_changed (data);
|
||||
}
|
||||
/* Don't set handled = TRUE since other filter functions on this dbus connection
|
||||
* may want to know about service signals.
|
||||
@@ -873,7 +874,7 @@ static DBusHandlerResult nm_dbus_nmi_filter (DBusConnection *connection, DBusMes
|
||||
{
|
||||
syslog( LOG_DEBUG, "updating active device's best ap");
|
||||
nm_device_update_best_ap (data->active_device);
|
||||
nm_data_set_state_modified (data, TRUE);
|
||||
nm_data_mark_state_changed (data);
|
||||
syslog( LOG_DEBUG, "Device's best ap now '%s'", nm_ap_get_essid (nm_device_get_best_ap (data->active_device)));
|
||||
}
|
||||
handled = TRUE;
|
||||
@@ -1068,6 +1069,27 @@ static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection,
|
||||
"The device cannot see any wireless networks."));
|
||||
}
|
||||
}
|
||||
else if (strcmp ("getLinkActive", request) == 0)
|
||||
dbus_message_append_args (reply_message, DBUS_TYPE_BOOLEAN, nm_device_get_link_active (dev), DBUS_TYPE_INVALID);
|
||||
else if (strcmp ("setLinkActive", request) == 0)
|
||||
{
|
||||
/* Can only set link status for active devices */
|
||||
if (nm_device_is_test_device (dev))
|
||||
{
|
||||
DBusError error;
|
||||
gboolean link;
|
||||
|
||||
dbus_error_init (&error);
|
||||
if (dbus_message_get_args (message, &error, DBUS_TYPE_BOOLEAN, &link, DBUS_TYPE_INVALID))
|
||||
{
|
||||
nm_device_set_link_active (dev, link);
|
||||
nm_data_mark_state_changed (data);
|
||||
}
|
||||
}
|
||||
else
|
||||
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NotTestDevice",
|
||||
"Only test devices can have their link status set manually.");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Must destroy the allocated message */
|
||||
@@ -1127,7 +1149,7 @@ static DBusHandlerResult nm_dbus_nm_message_handler (DBusConnection *connection,
|
||||
syslog (LOG_DEBUG, "Forcing AP '%s'", nm_ap_get_essid (ap));
|
||||
nm_device_freeze_best_ap (data->active_device);
|
||||
nm_device_set_best_ap (data->active_device, ap);
|
||||
nm_data_set_state_modified (data, TRUE);
|
||||
nm_data_mark_state_changed (data);
|
||||
}
|
||||
dbus_free (network);
|
||||
}
|
||||
@@ -1140,8 +1162,7 @@ static DBusHandlerResult nm_dbus_nm_message_handler (DBusConnection *connection,
|
||||
}
|
||||
else if (strcmp ("status", method) == 0)
|
||||
{
|
||||
reply_message = dbus_message_new_method_return (message);
|
||||
if (reply_message)
|
||||
if ((reply_message = dbus_message_new_method_return (message)))
|
||||
{
|
||||
if (data->active_device && nm_device_activating (data->active_device))
|
||||
dbus_message_append_args (reply_message, DBUS_TYPE_STRING, "connecting", DBUS_TYPE_INVALID);
|
||||
@@ -1151,6 +1172,64 @@ static DBusHandlerResult nm_dbus_nm_message_handler (DBusConnection *connection,
|
||||
dbus_message_append_args (reply_message, DBUS_TYPE_STRING, "disconnected", DBUS_TYPE_INVALID);
|
||||
}
|
||||
}
|
||||
else if (strcmp ("createTestDevice", method) == 0)
|
||||
{
|
||||
DBusError error;
|
||||
NMDeviceType type;
|
||||
|
||||
dbus_error_init (&error);
|
||||
if ( dbus_message_get_args (message, &error, DBUS_TYPE_INT32, &type, DBUS_TYPE_INVALID)
|
||||
&& ((type == DEVICE_TYPE_WIRED_ETHERNET) || (type == DEVICE_TYPE_WIRELESS_ETHERNET)))
|
||||
{
|
||||
char *interface = g_strdup_printf ("test%d", test_dev_num);
|
||||
char *udi = g_strdup_printf ("/test-devices/%s", interface);
|
||||
NMDevice *dev = NULL;
|
||||
|
||||
dev = nm_create_device_and_add_to_list (data, udi, interface, TRUE, type);
|
||||
test_dev_num++;
|
||||
if ((reply_message = dbus_message_new_method_return (message)))
|
||||
{
|
||||
char *dev_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev));
|
||||
dbus_message_append_args (reply_message, DBUS_TYPE_STRING, dev_path, DBUS_TYPE_INVALID);
|
||||
g_free (dev_path);
|
||||
}
|
||||
g_free (interface);
|
||||
g_free (udi);
|
||||
}
|
||||
else
|
||||
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "BadType",
|
||||
"The test device type was invalid.");
|
||||
}
|
||||
else if (strcmp ("removeTestDevice", method) == 0)
|
||||
{
|
||||
DBusError error;
|
||||
char *dev_path;
|
||||
|
||||
dbus_error_init (&error);
|
||||
if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev_path, DBUS_TYPE_INVALID))
|
||||
{
|
||||
NMDevice *dev;
|
||||
|
||||
if ((dev = nm_dbus_get_device_from_object_path (data, dev_path)))
|
||||
{
|
||||
if (nm_device_is_test_device (dev))
|
||||
nm_remove_device_from_list (data, nm_device_get_udi (dev));
|
||||
else
|
||||
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "NotTestDevice",
|
||||
"Only test devices can be removed via dbus calls.");
|
||||
}
|
||||
else
|
||||
{
|
||||
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound",
|
||||
"The requested network device does not exist.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceBad",
|
||||
"The device ID was bad.");
|
||||
}
|
||||
}
|
||||
else
|
||||
handled = FALSE;
|
||||
|
||||
|
@@ -94,6 +94,9 @@ struct NMDevice
|
||||
gboolean activating;
|
||||
gboolean just_activated;
|
||||
gboolean quit_activation;
|
||||
|
||||
gboolean test_device;
|
||||
gboolean test_device_up;
|
||||
};
|
||||
|
||||
/******************************************************/
|
||||
@@ -112,6 +115,12 @@ static gboolean nm_device_test_wireless_extensions (NMDevice *dev)
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
|
||||
/* We obviously cannot probe test devices (since they don't
|
||||
* actually exist in hardware).
|
||||
*/
|
||||
if (dev->test_device)
|
||||
return (FALSE);
|
||||
|
||||
iwlib_socket = iw_sockets_open ();
|
||||
error = iw_get_stats (iwlib_socket, nm_device_get_iface (dev), &stats, NULL, FALSE);
|
||||
close (iwlib_socket);
|
||||
@@ -133,6 +142,11 @@ static gboolean nm_device_supports_wireless_scan (NMDevice *dev)
|
||||
wireless_scan_head scan_data;
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
g_return_val_if_fail (dev->type == DEVICE_TYPE_WIRELESS_ETHERNET, FALSE);
|
||||
|
||||
/* A test wireless device can always scan (we generate fake scan data for it) */
|
||||
if (dev->test_device)
|
||||
return (TRUE);
|
||||
|
||||
iwlib_socket = iw_sockets_open ();
|
||||
error = iw_scan (iwlib_socket, nm_device_get_iface (dev), WIRELESS_EXT, &scan_data);
|
||||
@@ -223,16 +237,32 @@ NMDevice *nm_get_device_by_iface (NMData *data, const char *iface)
|
||||
/*
|
||||
* nm_device_new
|
||||
*
|
||||
* Creates and initializes the structure representation of an NM device.
|
||||
* Creates and initializes the structure representation of an NM device. For test
|
||||
* devices, a device type other than DEVICE_TYPE_DONT_KNOW must be specified, this
|
||||
* argument is ignored for real hardware devices since they are auto-probed.
|
||||
*
|
||||
*/
|
||||
NMDevice *nm_device_new (const char *iface, NMData *app_data)
|
||||
NMDevice *nm_device_new (const char *iface, gboolean test_dev, NMDeviceType test_dev_type, NMData *app_data)
|
||||
{
|
||||
NMDevice *dev;
|
||||
|
||||
g_return_val_if_fail (iface != NULL, NULL);
|
||||
g_return_val_if_fail (strlen (iface) > 0, NULL);
|
||||
|
||||
/* Test devices must have a valid type specified */
|
||||
if (test_dev && !(test_dev_type != DEVICE_TYPE_DONT_KNOW))
|
||||
return (NULL);
|
||||
|
||||
/* Another check to make sure we don't create a test device unless
|
||||
* test devices were enabled on the command line.
|
||||
*/
|
||||
if (app_data && !app_data->enable_test_devices && test_dev)
|
||||
{
|
||||
syslog (LOG_ERR, "nm_device_new(): attempt to create a test device, but test devices were not enabled"
|
||||
" on the command line. Will not create the device.\n");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
dev = g_new0 (NMDevice, 1);
|
||||
if (!dev)
|
||||
{
|
||||
@@ -243,6 +273,14 @@ NMDevice *nm_device_new (const char *iface, NMData *app_data)
|
||||
dev->refcount = 1;
|
||||
dev->app_data = app_data;
|
||||
dev->iface = g_strdup (iface);
|
||||
dev->test_device = test_dev;
|
||||
|
||||
/* Real hardware devices are probed for their type, test devices must have
|
||||
* their type specified.
|
||||
*/
|
||||
if (test_dev)
|
||||
dev->type = test_dev_type;
|
||||
else
|
||||
dev->type = nm_device_test_wireless_extensions (dev) ?
|
||||
DEVICE_TYPE_WIRELESS_ETHERNET : DEVICE_TYPE_WIRED_ETHERNET;
|
||||
|
||||
@@ -409,6 +447,86 @@ gboolean nm_device_get_supports_wireless_scan (NMDevice *dev)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_wireless_link_active
|
||||
*
|
||||
* Gets the link state of a wireless device
|
||||
*
|
||||
*/
|
||||
static gboolean nm_device_wireless_link_active (NMDevice *dev)
|
||||
{
|
||||
struct iwreq wrq;
|
||||
int iwlib_socket;
|
||||
gboolean link = FALSE;
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
g_return_val_if_fail (dev->app_data != NULL, FALSE);
|
||||
|
||||
/* Since non-active wireless cards are supposed to be powered off anyway,
|
||||
* only scan for active/pending device and clear ap_list and best_ap for
|
||||
* devices that aren't active/pending.
|
||||
*/
|
||||
if (dev != dev->app_data->active_device)
|
||||
{
|
||||
nm_ap_list_unref (dev->options.wireless.ap_list);
|
||||
dev->options.wireless.ap_list = NULL;
|
||||
if (dev->options.wireless.best_ap)
|
||||
nm_ap_unref (dev->options.wireless.best_ap);
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/* Test devices have their link state set through DBUS */
|
||||
if (dev->test_device)
|
||||
return (nm_device_get_link_active (dev));
|
||||
|
||||
/* FIXME
|
||||
* For wireless cards, the best indicator of a "link" at this time
|
||||
* seems to be whether the card has a valid access point MAC address.
|
||||
* Is there a better way?
|
||||
*/
|
||||
iwlib_socket = iw_sockets_open ();
|
||||
if (iw_get_ext (iwlib_socket, nm_device_get_iface (dev), SIOCGIWAP, &wrq) >= 0)
|
||||
{
|
||||
if ( nm_ethernet_address_is_valid ((struct ether_addr *)(&(wrq.u.ap_addr.sa_data)))
|
||||
&& (nm_device_get_best_ap (dev) && !nm_device_need_ap_switch (dev)))
|
||||
link = TRUE;
|
||||
}
|
||||
close (iwlib_socket);
|
||||
|
||||
return (link);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_wired_link_active
|
||||
*
|
||||
* Return the link state of a wired device. We usually just grab the HAL
|
||||
* net.ethernet.link property, but on card insertion we need to check the MII
|
||||
* registers of the card to get a more accurate response, since HAL may not
|
||||
* have received a netlink socket link event for the device yet, and therefore
|
||||
* will return FALSE when the device really does have a link.
|
||||
*
|
||||
*/
|
||||
static gboolean nm_device_wired_link_active (NMDevice *dev, gboolean check_mii)
|
||||
{
|
||||
gboolean link = FALSE;
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
g_return_val_if_fail (dev->app_data != NULL, FALSE);
|
||||
|
||||
/* Test devices have their link state set through DBUS */
|
||||
if (dev->test_device)
|
||||
return (nm_device_get_link_active (dev));
|
||||
|
||||
if (check_mii)
|
||||
link = mii_get_link (dev);
|
||||
else if (hal_device_property_exists (dev->app_data->hal_ctx, nm_device_get_udi (dev), "net.ethernet.link"))
|
||||
link = hal_device_get_property_bool (dev->app_data->hal_ctx, nm_device_get_udi (dev), "net.ethernet.link");
|
||||
|
||||
return (link);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_update_link_active
|
||||
*
|
||||
@@ -417,69 +535,30 @@ gboolean nm_device_get_supports_wireless_scan (NMDevice *dev)
|
||||
*/
|
||||
void nm_device_update_link_active (NMDevice *dev, gboolean check_mii)
|
||||
{
|
||||
gboolean link_active = FALSE;
|
||||
gboolean link = FALSE;
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
g_return_if_fail (dev->app_data != NULL);
|
||||
|
||||
/* FIXME
|
||||
* For wireless cards, the best indicator of a "link" at this time
|
||||
* seems to be whether the card has a valid access point MAC address.
|
||||
* Is there a better way?
|
||||
*/
|
||||
switch (nm_device_get_type (dev))
|
||||
{
|
||||
case DEVICE_TYPE_WIRELESS_ETHERNET:
|
||||
{
|
||||
struct iwreq wrq;
|
||||
int iwlib_socket;
|
||||
NMData *data = (NMData *)dev->app_data;
|
||||
|
||||
/* Since non-active wireless cards are supposed to be powered off anyway,
|
||||
* only scan for active/pending device and clear ap_list and best_ap for
|
||||
* devices that aren't active/pending.
|
||||
*/
|
||||
if (dev == data->active_device)
|
||||
{
|
||||
iwlib_socket = iw_sockets_open ();
|
||||
if (iw_get_ext (iwlib_socket, nm_device_get_iface (dev), SIOCGIWAP, &wrq) >= 0)
|
||||
{
|
||||
if (nm_ethernet_address_is_valid ((struct ether_addr *)(&(wrq.u.ap_addr.sa_data))))
|
||||
if (nm_device_get_best_ap (dev) && !nm_device_need_ap_switch (dev))
|
||||
link_active = TRUE;
|
||||
}
|
||||
close (iwlib_socket);
|
||||
}
|
||||
else
|
||||
{
|
||||
nm_ap_list_unref (dev->options.wireless.ap_list);
|
||||
dev->options.wireless.ap_list = NULL;
|
||||
if (dev->options.wireless.best_ap)
|
||||
nm_ap_unref (dev->options.wireless.best_ap);
|
||||
}
|
||||
link = nm_device_wireless_link_active (dev);
|
||||
break;
|
||||
}
|
||||
|
||||
case DEVICE_TYPE_WIRED_ETHERNET:
|
||||
{
|
||||
if (check_mii)
|
||||
link_active = mii_get_link (dev);
|
||||
else
|
||||
if (hal_device_property_exists (dev->app_data->hal_ctx, nm_device_get_udi (dev), "net.ethernet.link"))
|
||||
link_active = hal_device_get_property_bool (dev->app_data->hal_ctx, nm_device_get_udi (dev), "net.ethernet.link");
|
||||
break;
|
||||
}
|
||||
link = nm_device_wired_link_active (dev, check_mii);
|
||||
|
||||
default:
|
||||
link_active = nm_device_get_link_active (dev); /* Can't get link info for this device, so don't change link status */
|
||||
link = nm_device_get_link_active (dev); /* Can't get link info for this device, so don't change link status */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Update device link status and global state variable if the status changed */
|
||||
if (link_active != nm_device_get_link_active (dev))
|
||||
if (link != nm_device_get_link_active (dev))
|
||||
{
|
||||
nm_device_set_link_active (dev, link_active);
|
||||
nm_data_set_state_modified (dev->app_data, TRUE);
|
||||
nm_device_set_link_active (dev, link);
|
||||
nm_data_mark_state_changed (dev->app_data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -503,6 +582,17 @@ char * nm_device_get_essid (NMDevice *dev)
|
||||
g_return_val_if_fail (dev != NULL, NULL);
|
||||
g_return_val_if_fail (nm_device_is_wireless (dev), NULL);
|
||||
|
||||
/* Test devices return the essid of their "best" access point
|
||||
* or if there is none, the contents of the cur_essid field.
|
||||
*/
|
||||
if (dev->test_device)
|
||||
{
|
||||
if (nm_device_get_best_ap (dev))
|
||||
return (nm_ap_get_essid (nm_device_get_best_ap (dev)));
|
||||
else
|
||||
return (dev->options.wireless.cur_essid);
|
||||
}
|
||||
|
||||
iwlib_socket = iw_sockets_open ();
|
||||
if (iwlib_socket >= 0)
|
||||
{
|
||||
@@ -541,6 +631,15 @@ void nm_device_set_essid (NMDevice *dev, const char *essid)
|
||||
g_return_if_fail (dev != NULL);
|
||||
g_return_if_fail (nm_device_is_wireless (dev));
|
||||
|
||||
/* Test devices directly set cur_essid */
|
||||
if (dev->test_device)
|
||||
{
|
||||
if (dev->options.wireless.cur_essid)
|
||||
g_free (dev->options.wireless.cur_essid);
|
||||
dev->options.wireless.cur_essid = g_strdup (essid);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Make sure the essid we get passed is a valid size */
|
||||
if (!essid)
|
||||
safe_essid[0] = '\0';
|
||||
@@ -581,7 +680,19 @@ void nm_device_get_ap_address (NMDevice *dev, struct ether_addr *addr)
|
||||
g_return_if_fail (addr != NULL);
|
||||
g_return_if_fail (nm_device_is_wireless (dev));
|
||||
|
||||
/* Do we have a valid MAC address? */
|
||||
/* Test devices return an invalid address when there's no link,
|
||||
* and a made-up address when there is a link.
|
||||
*/
|
||||
if (dev->test_device)
|
||||
{
|
||||
struct ether_addr good_addr = { {0x70, 0x37, 0x03, 0x70, 0x37, 0x03} };
|
||||
struct ether_addr bad_addr = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
|
||||
gboolean link = nm_device_get_link_active (dev);
|
||||
|
||||
memcpy ((link ? &good_addr : &bad_addr), &(wrq.u.ap_addr.sa_data), sizeof (struct ether_addr));
|
||||
return;
|
||||
}
|
||||
|
||||
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));
|
||||
@@ -612,6 +723,10 @@ void nm_device_set_enc_key (NMDevice *dev, const char *key)
|
||||
g_return_if_fail (dev != NULL);
|
||||
g_return_if_fail (nm_device_is_wireless (dev));
|
||||
|
||||
/* Test devices just ignore encryption keys */
|
||||
if (dev->test_device)
|
||||
return;
|
||||
|
||||
/* Make sure the essid we get passed is a valid size */
|
||||
if (!key)
|
||||
safe_key[0] = '\0';
|
||||
@@ -625,12 +740,18 @@ void nm_device_set_enc_key (NMDevice *dev, const char *key)
|
||||
if (iwlib_socket >= 0)
|
||||
{
|
||||
wreq.u.data.pointer = (caddr_t) NULL;
|
||||
wreq.u.data.flags = IW_ENCODE_ENABLED;
|
||||
wreq.u.data.length = 0;
|
||||
wreq.u.data.flags = IW_ENCODE_ENABLED;
|
||||
|
||||
/* Unfortunately, some drivers (Cisco) don't make a distinction between
|
||||
* Open System authentication mode and whether or not to use WEP. You
|
||||
* DON'T have to use WEP when using Open System, but these cards force
|
||||
* it. Therefore, we have to set Open System mode when using WEP.
|
||||
*/
|
||||
|
||||
if (strlen (safe_key) == 0)
|
||||
{
|
||||
wreq.u.data.flags = IW_ENCODE_OPEN | IW_ENCODE_NOKEY; /* Disable WEP */
|
||||
wreq.u.data.flags |= IW_ENCODE_DISABLED | IW_ENCODE_NOKEY;
|
||||
set_key = TRUE;
|
||||
}
|
||||
else
|
||||
@@ -640,6 +761,7 @@ void nm_device_set_enc_key (NMDevice *dev, const char *key)
|
||||
keylen = iw_in_key_full(iwlib_socket, nm_device_get_iface (dev), safe_key, &parsed_key[0], &wreq.u.data.flags);
|
||||
if (keylen > 0)
|
||||
{
|
||||
wreq.u.data.flags |= IW_ENCODE_OPEN; // FIXME: what about restricted/Shared Key?
|
||||
wreq.u.data.pointer = (caddr_t) &parsed_key;
|
||||
wreq.u.data.length = keylen;
|
||||
set_key = TRUE;
|
||||
@@ -697,6 +819,13 @@ void nm_device_update_ip4_address (NMDevice *dev)
|
||||
g_return_if_fail (dev->app_data != NULL);
|
||||
g_return_if_fail (nm_device_get_iface (dev) != NULL);
|
||||
|
||||
/* Test devices get a nice, bogus IP address */
|
||||
if (dev->test_device)
|
||||
{
|
||||
dev->ip4_address = 0x07030703;
|
||||
return;
|
||||
}
|
||||
|
||||
socket = nm_get_network_control_socket ();
|
||||
if (socket < 0)
|
||||
return;
|
||||
@@ -747,6 +876,13 @@ static void nm_device_set_up_down (NMDevice *dev, gboolean up)
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* Test devices do whatever we tell them to do */
|
||||
if (dev->test_device)
|
||||
{
|
||||
dev->test_device_up = up;
|
||||
return;
|
||||
}
|
||||
|
||||
iface_fd = nm_get_network_control_socket ();
|
||||
if (iface_fd < 0)
|
||||
return;
|
||||
@@ -801,6 +937,9 @@ gboolean nm_device_is_up (NMDevice *dev)
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
|
||||
if (dev->test_device)
|
||||
return (dev->test_device_up);
|
||||
|
||||
iface_fd = nm_get_network_control_socket ();
|
||||
if (iface_fd < 0)
|
||||
return (FALSE);
|
||||
@@ -914,6 +1053,32 @@ static gboolean nm_device_activate_wireless (NMDevice *dev)
|
||||
return (success);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_activation_cancel_if_needed
|
||||
*
|
||||
* Check whether we should stop activation, and if so clean up flags
|
||||
* and other random things.
|
||||
*
|
||||
*/
|
||||
gboolean nm_device_activation_cancel_if_needed (NMDevice *dev)
|
||||
{
|
||||
g_return_val_if_fail (dev != NULL, TRUE);
|
||||
|
||||
/* If we were told to quit activation, stop the thread and return */
|
||||
if (dev->quit_activation)
|
||||
{
|
||||
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): activation canceled.", nm_device_get_iface (dev));
|
||||
dev->activating = FALSE;
|
||||
dev->just_activated = FALSE;
|
||||
nm_device_unref (dev);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_activation_worker
|
||||
*
|
||||
@@ -961,8 +1126,7 @@ fprintf( stderr, "(!switch (%d) || !enc_source (%d)) && is_enc (%d)\n",
|
||||
*/
|
||||
if (nm_ap_get_enc_key_source (best_ap) && !nm_ap_get_enc_method_good (best_ap))
|
||||
{
|
||||
fprintf (stderr, "trying encryption method\n");
|
||||
/* Try another method, since the one set before obviously didn't work */
|
||||
/* Try another method, since the one set in a previous iteration obviously didn't work */
|
||||
switch (nm_ap_get_enc_method (best_ap))
|
||||
{
|
||||
case (NM_AP_ENC_METHOD_UNKNOWN):
|
||||
@@ -984,27 +1148,21 @@ fprintf (stderr, "trying encryption method\n");
|
||||
|
||||
if (ask_for_key)
|
||||
{
|
||||
fprintf( stderr, "asking for key\n");
|
||||
dev->options.wireless.user_key_received = FALSE;
|
||||
nm_dbus_get_user_key_for_network (dev->app_data->dbus_connection, dev, best_ap);
|
||||
|
||||
/* Wait for the key to come back */
|
||||
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): asking for user key.", nm_device_get_iface (dev));
|
||||
while (!dev->options.wireless.user_key_received && !dev->quit_activation)
|
||||
g_usleep (G_USEC_PER_SEC / 2);
|
||||
|
||||
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): user key received!", nm_device_get_iface (dev));
|
||||
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): user key received.", nm_device_get_iface (dev));
|
||||
}
|
||||
|
||||
/* If we were told to quit activation, stop the thread and return */
|
||||
if (dev->quit_activation)
|
||||
{
|
||||
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): activation canceled 1", nm_device_get_iface (dev));
|
||||
dev->activating = FALSE;
|
||||
dev->just_activated = FALSE;
|
||||
nm_device_unref (dev);
|
||||
if (nm_device_activation_cancel_if_needed (dev))
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
nm_device_activate_wireless (dev);
|
||||
}
|
||||
@@ -1015,15 +1173,9 @@ fprintf (stderr, "sleeping due to no access point\n");
|
||||
}
|
||||
|
||||
/* If we were told to quit activation, stop the thread and return */
|
||||
if (dev->quit_activation)
|
||||
{
|
||||
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): activation canceled 1.5", nm_device_get_iface (dev));
|
||||
dev->activating = FALSE;
|
||||
dev->just_activated = FALSE;
|
||||
nm_device_unref (dev);
|
||||
if (nm_device_activation_cancel_if_needed (dev))
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* Since we've got a link, the encryption method must be good */
|
||||
nm_ap_set_enc_method_good (nm_device_get_best_ap (dev), TRUE);
|
||||
@@ -1070,28 +1222,16 @@ fprintf (stderr, "sleeping due to no access point\n");
|
||||
sethostname (hostname, strlen (hostname));
|
||||
|
||||
/* If we were told to quit activation, stop the thread and return */
|
||||
if (dev->quit_activation)
|
||||
{
|
||||
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): activation canceled 2", nm_device_get_iface (dev));
|
||||
dev->activating = FALSE;
|
||||
dev->just_activated = FALSE;
|
||||
nm_device_unref (dev);
|
||||
if (nm_device_activation_cancel_if_needed (dev))
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Make system aware of any new DNS settings from resolv.conf */
|
||||
nm_system_update_dns ();
|
||||
}
|
||||
|
||||
/* If we were told to quit activation, stop the thread and return */
|
||||
if (dev->quit_activation)
|
||||
{
|
||||
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): activation canceled 3", nm_device_get_iface (dev));
|
||||
dev->activating = FALSE;
|
||||
dev->just_activated = FALSE;
|
||||
nm_device_unref (dev);
|
||||
if (nm_device_activation_cancel_if_needed (dev))
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
dev->just_activated = TRUE;
|
||||
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): device activated", nm_device_get_iface (dev));
|
||||
@@ -1119,7 +1259,7 @@ gboolean nm_device_just_activated (NMDevice *dev)
|
||||
dev->just_activated = FALSE;
|
||||
return (TRUE);
|
||||
}
|
||||
else
|
||||
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
@@ -1139,17 +1279,20 @@ gboolean nm_device_activating (NMDevice *dev)
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_activation_cancel
|
||||
* nm_device_activation_signal_cancel
|
||||
*
|
||||
* Signal activation worker that it should stop and die.
|
||||
*
|
||||
*/
|
||||
void nm_device_activation_cancel (NMDevice *dev)
|
||||
void nm_device_activation_signal_cancel (NMDevice *dev)
|
||||
{
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
syslog (LOG_DEBUG, "nm_device_activation_cancel(%s): canceled", nm_device_get_iface (dev));
|
||||
if (dev->activating)
|
||||
{
|
||||
syslog (LOG_DEBUG, "nm_device_activation_signal_cancel(%s): canceled", nm_device_get_iface (dev));
|
||||
dev->quit_activation = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1164,7 +1307,7 @@ gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added)
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
g_return_val_if_fail (dev->app_data != NULL, FALSE);
|
||||
|
||||
nm_device_activation_cancel (dev);
|
||||
nm_device_activation_signal_cancel (dev);
|
||||
|
||||
/* Take out any entries in the routing table and any IP address the old device had. */
|
||||
nm_system_device_flush_routes (dev);
|
||||
@@ -1235,12 +1378,12 @@ fprintf( stderr, "Got user key\n");
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_ap_list_add
|
||||
* nm_device_ap_list_add_ap
|
||||
*
|
||||
* Add an access point to the devices internal AP list.
|
||||
*
|
||||
*/
|
||||
void nm_device_ap_list_add (NMDevice *dev, NMAccessPoint *ap)
|
||||
static void nm_device_ap_list_add_ap (NMDevice *dev, NMAccessPoint *ap)
|
||||
{
|
||||
g_return_if_fail (dev != NULL);
|
||||
g_return_if_fail (ap != NULL);
|
||||
@@ -1545,6 +1688,10 @@ static void nm_device_do_normal_scan (NMDevice *dev)
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
g_return_if_fail (dev->app_data != NULL);
|
||||
|
||||
/* Test devices shouldn't get here since we fake the AP list earlier */
|
||||
g_return_if_fail (!dev->test_device);
|
||||
|
||||
data = (NMData *)dev->app_data;
|
||||
|
||||
/* Device must be up before we can scan */
|
||||
@@ -1637,7 +1784,7 @@ static void nm_device_do_normal_scan (NMDevice *dev)
|
||||
}
|
||||
|
||||
/* Add the AP to the device's AP list */
|
||||
nm_device_ap_list_add (dev, nm_ap);
|
||||
nm_device_ap_list_add_ap (dev, nm_ap);
|
||||
}
|
||||
tmp_ap = tmp_ap->next;
|
||||
}
|
||||
@@ -1678,6 +1825,9 @@ static void nm_device_do_pseudo_scan (NMDevice *dev)
|
||||
g_return_if_fail (dev != NULL);
|
||||
g_return_if_fail (dev->app_data != NULL);
|
||||
|
||||
/* Test devices shouldn't get here since we fake the AP list earlier */
|
||||
g_return_if_fail (!dev->test_device);
|
||||
|
||||
nm_device_ref (dev);
|
||||
|
||||
if (!(list = nm_device_ap_list_get (dev)))
|
||||
@@ -1726,7 +1876,7 @@ static void nm_device_do_pseudo_scan (NMDevice *dev)
|
||||
syslog(LOG_INFO, "%s: setting AP '%s' best", nm_device_get_iface (dev), nm_ap_get_essid (ap));
|
||||
|
||||
nm_device_set_best_ap (dev, ap);
|
||||
nm_data_set_state_modified (dev->app_data, TRUE);
|
||||
nm_data_mark_state_changed (dev->app_data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1736,6 +1886,78 @@ static void nm_device_do_pseudo_scan (NMDevice *dev)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_fake_ap_list
|
||||
*
|
||||
* Fake the access point list, used for test devices.
|
||||
*
|
||||
*/
|
||||
static void nm_device_fake_ap_list (NMDevice *dev)
|
||||
{
|
||||
#define NUM_FAKE_APS 4
|
||||
|
||||
int i;
|
||||
NMAccessPointList *old_ap_list = nm_device_ap_list_get (dev);
|
||||
|
||||
char *fake_essids[NUM_FAKE_APS] = { "green", "bay", "packers", "rule" };
|
||||
struct ether_addr fake_addrs[NUM_FAKE_APS] = {{{0x70, 0x37, 0x03, 0x70, 0x37, 0x03}},
|
||||
{{0x12, 0x34, 0x56, 0x78, 0x90, 0xab}},
|
||||
{{0xcd, 0xef, 0x12, 0x34, 0x56, 0x78}},
|
||||
{{0x90, 0xab, 0xcd, 0xef, 0x12, 0x34}} };
|
||||
guint8 fake_qualities[NUM_FAKE_APS] = { 150, 26, 200, 100 };
|
||||
double fake_freqs[NUM_FAKE_APS] = { 3.1416, 4.1416, 5.1415, 6.1415 };
|
||||
gboolean fake_enc[NUM_FAKE_APS] = { FALSE, TRUE, FALSE, TRUE };
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
g_return_if_fail (dev->app_data != NULL);
|
||||
|
||||
dev->options.wireless.ap_list = nm_ap_list_new (NETWORK_TYPE_DEVICE);
|
||||
|
||||
for (i = 0; i < NUM_FAKE_APS; i++)
|
||||
{
|
||||
NMAccessPoint *nm_ap = nm_ap_new ();
|
||||
NMAccessPoint *list_ap;
|
||||
|
||||
/* Copy over info from scan to local structure */
|
||||
nm_ap_set_essid (nm_ap, fake_essids[i]);
|
||||
|
||||
if (fake_enc[i])
|
||||
{
|
||||
nm_ap_set_encrypted (nm_ap, FALSE);
|
||||
nm_ap_set_enc_method (nm_ap, NM_AP_ENC_METHOD_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
nm_ap_set_encrypted (nm_ap, TRUE);
|
||||
nm_ap_set_enc_method (nm_ap, NM_AP_ENC_METHOD_UNKNOWN);
|
||||
}
|
||||
|
||||
nm_ap_set_address (nm_ap, (const struct ether_addr *)(&fake_addrs[i]));
|
||||
nm_ap_set_quality (nm_ap, fake_qualities[i]);
|
||||
nm_ap_set_freq (nm_ap, fake_freqs[i]);
|
||||
|
||||
/* Merge settings from Preferred/Allowed networks, mainly Keys */
|
||||
list_ap = nm_ap_list_get_ap_by_essid (dev->app_data->trusted_ap_list, nm_ap_get_essid (nm_ap));
|
||||
if (!list_ap)
|
||||
list_ap = nm_ap_list_get_ap_by_essid (dev->app_data->preferred_ap_list, nm_ap_get_essid (nm_ap));
|
||||
if (list_ap)
|
||||
{
|
||||
nm_ap_set_timestamp (nm_ap, nm_ap_get_timestamp (list_ap));
|
||||
nm_ap_set_enc_key_source (nm_ap, nm_ap_get_enc_key_source (list_ap));
|
||||
}
|
||||
|
||||
/* Add the AP to the device's AP list */
|
||||
nm_device_ap_list_add_ap (dev, nm_ap);
|
||||
}
|
||||
|
||||
if (dev == dev->app_data->active_device)
|
||||
nm_ap_list_diff (dev->app_data, dev, old_ap_list, nm_device_ap_list_get (dev));
|
||||
if (old_ap_list)
|
||||
nm_ap_list_unref (old_ap_list);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_do_wireless_scan
|
||||
*
|
||||
@@ -1751,6 +1973,14 @@ void nm_device_do_wireless_scan (NMDevice *dev)
|
||||
if (!nm_try_acquire_mutex (dev->options.wireless.scan_mutex, __FUNCTION__))
|
||||
return;
|
||||
|
||||
/* Compose a fake list of access points */
|
||||
if (dev->test_device)
|
||||
{
|
||||
nm_device_fake_ap_list (dev);
|
||||
nm_unlock_mutex (dev->options.wireless.scan_mutex, __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nm_device_get_supports_wireless_scan (dev))
|
||||
nm_device_do_normal_scan (dev);
|
||||
else
|
||||
@@ -1859,3 +2089,19 @@ static gboolean mii_get_link (NMDevice *dev)
|
||||
/****************************************/
|
||||
/* End Code ripped from HAL */
|
||||
/****************************************/
|
||||
|
||||
|
||||
/****************************************/
|
||||
/* Test device routes */
|
||||
/****************************************/
|
||||
|
||||
/*
|
||||
* nm_device_is_test_device
|
||||
*
|
||||
*/
|
||||
gboolean nm_device_is_test_device (NMDevice *dev)
|
||||
{
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
|
||||
return (dev->test_device);
|
||||
}
|
||||
|
@@ -25,21 +25,10 @@
|
||||
#include <net/ethernet.h>
|
||||
#include "NetworkManager.h"
|
||||
|
||||
/*
|
||||
* Types of NetworkManager devices
|
||||
*/
|
||||
enum NMDeviceType
|
||||
{
|
||||
DEVICE_TYPE_DONT_KNOW = 0,
|
||||
DEVICE_TYPE_WIRED_ETHERNET,
|
||||
DEVICE_TYPE_WIRELESS_ETHERNET
|
||||
};
|
||||
|
||||
typedef struct NMDevice NMDevice;
|
||||
typedef enum NMDeviceType NMDeviceType;
|
||||
|
||||
|
||||
NMDevice * nm_device_new (const char *iface, NMData *app_data);
|
||||
NMDevice * nm_device_new (const char *iface, gboolean test_device,
|
||||
NMDeviceType test_dev_type, NMData *app_data);
|
||||
|
||||
void nm_device_ref (NMDevice *dev);
|
||||
void nm_device_unref (NMDevice *dev);
|
||||
@@ -86,7 +75,7 @@ char * nm_device_get_path_for_ap (NMDevice *dev, NMAccessPoint *ap);
|
||||
void nm_device_set_enc_key (NMDevice *dev, const char *key);
|
||||
|
||||
gboolean nm_device_activation_begin (NMDevice *dev);
|
||||
void nm_device_activation_cancel (NMDevice *dev);
|
||||
void nm_device_activation_signal_cancel (NMDevice *dev);
|
||||
gboolean nm_device_just_activated (NMDevice *dev);
|
||||
gboolean nm_device_activating (NMDevice *dev);
|
||||
gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added);
|
||||
@@ -98,7 +87,6 @@ void nm_device_bring_up (NMDevice *dev);
|
||||
void nm_device_bring_down (NMDevice *dev);
|
||||
gboolean nm_device_is_up (NMDevice *dev);
|
||||
|
||||
void nm_device_ap_list_add (NMDevice *dev, NMAccessPoint *ap);
|
||||
void nm_device_ap_list_clear (NMDevice *dev);
|
||||
struct NMAccessPointList *nm_device_ap_list_get (NMDevice *dev);
|
||||
NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *essid);
|
||||
@@ -106,4 +94,7 @@ NMAccessPoint *nm_device_ap_list_get_ap_by_essid (NMDevice *dev, const char *ess
|
||||
NMDevice * nm_get_device_by_udi (NMData *data, const char *udi);
|
||||
NMDevice * nm_get_device_by_iface (NMData *data, const char *iface);
|
||||
|
||||
/* Test device routines */
|
||||
gboolean nm_device_is_test_device (NMDevice *dev);
|
||||
|
||||
#endif
|
||||
|
@@ -36,7 +36,6 @@
|
||||
#include "NetworkManagerDbus.h"
|
||||
|
||||
gboolean allowed_ap_worker_exit = FALSE;
|
||||
extern gboolean debug;
|
||||
|
||||
|
||||
/*
|
||||
@@ -173,7 +172,9 @@ static NMDevice * nm_policy_get_best_device (NMData *data)
|
||||
nm_unlock_mutex (data->user_device_mutex, __FUNCTION__);
|
||||
}
|
||||
|
||||
/* Determine whether we need to clear the active device and unlock it. */
|
||||
/* Determine whether we need to clear the active device and unlock it.
|
||||
* This occurs if the best device is removed, for example.
|
||||
*/
|
||||
if (!best_dev && data->active_device_locked)
|
||||
{
|
||||
switch (nm_device_get_type (data->active_device))
|
||||
@@ -198,6 +199,22 @@ static NMDevice * nm_policy_get_best_device (NMData *data)
|
||||
}
|
||||
}
|
||||
|
||||
/* Or, if the current active device is wireless and its "best" access
|
||||
* point is locked, use that device still. This happens when the user
|
||||
* forces a specific wireless network choice. The "best" ap will have
|
||||
* already been set and locked by the dbus message handler, so we just
|
||||
* need to test for a locked "best" ap.
|
||||
*/
|
||||
if (data->active_device && nm_device_is_wireless (data->active_device))
|
||||
{
|
||||
/* Give ourselves a chance to clear the "best" access point if
|
||||
* its gone out of range and no longer in the device's ap list.
|
||||
*/
|
||||
nm_device_update_best_ap (data->active_device);
|
||||
if (nm_device_get_best_ap_frozen (data->active_device))
|
||||
best_dev = data->active_device;
|
||||
}
|
||||
|
||||
/* Fall back to automatic device picking */
|
||||
if (!best_dev)
|
||||
{
|
||||
@@ -276,8 +293,6 @@ gboolean nm_state_modification_monitor (gpointer user_data)
|
||||
|| ( best_dev && nm_device_is_wireless (best_dev) && !nm_device_activating (best_dev)
|
||||
&& (nm_device_need_ap_switch (best_dev) || (nm_device_get_ip4_address (best_dev) == 0))))
|
||||
{
|
||||
syslog (LOG_INFO, "nm_state_modification_monitor(): beginning activation for device '%s'", best_dev ? nm_device_get_iface (best_dev) : "(null)");
|
||||
|
||||
/* Deactivate the old device */
|
||||
if (data->active_device)
|
||||
{
|
||||
@@ -286,11 +301,15 @@ gboolean nm_state_modification_monitor (gpointer user_data)
|
||||
data->active_device = NULL;
|
||||
}
|
||||
|
||||
if (best_dev)
|
||||
{
|
||||
/* Begin activation on the new device */
|
||||
syslog (LOG_INFO, "nm_state_modification_monitor(): beginning activation for device '%s'", nm_device_get_iface (best_dev));
|
||||
nm_device_ref (best_dev);
|
||||
data->active_device = best_dev;
|
||||
nm_device_activation_begin (data->active_device);
|
||||
}
|
||||
}
|
||||
|
||||
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
||||
}
|
||||
|
@@ -28,8 +28,6 @@
|
||||
#include "NetworkManager.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
extern gboolean debug;
|
||||
|
||||
|
||||
/*#define LOCKING_DEBUG */
|
||||
|
||||
|
@@ -33,7 +33,6 @@
|
||||
#include "NetworkManagerPolicy.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
extern gboolean debug;
|
||||
|
||||
static char *
|
||||
nm_md5 (const char *buf, size_t len)
|
||||
|
@@ -47,6 +47,13 @@ gboolean nm_system_device_run_dhcp (NMDevice *dev)
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
|
||||
/* Fake it for a test device */
|
||||
if (nm_device_is_test_device (dev))
|
||||
{
|
||||
g_usleep (2000);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* Unfortunately, dhclient can take a long time to get a dhcp address
|
||||
* (for example, bad WEP key so it can't actually talk to the AP).
|
||||
*/
|
||||
@@ -74,6 +81,10 @@ void nm_system_device_stop_dhcp (NMDevice *dev)
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* Not really applicable for test devices */
|
||||
if (nm_device_is_test_device (dev))
|
||||
return;
|
||||
|
||||
/* Find and kill the previous dhclient process for this device */
|
||||
snprintf (buf, 500, "/var/run/dhclient-%s.pid", nm_device_get_iface (dev));
|
||||
pidfile = fopen (buf, "r");
|
||||
@@ -107,6 +118,10 @@ void nm_system_device_flush_routes (NMDevice *dev)
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* Not really applicable for test devices */
|
||||
if (nm_device_is_test_device (dev))
|
||||
return;
|
||||
|
||||
/* Remove routing table entries */
|
||||
snprintf (buf, 100, "/sbin/ip route flush dev %s", nm_device_get_iface (dev));
|
||||
nm_spawn_process (buf);
|
||||
@@ -125,7 +140,11 @@ void nm_system_device_flush_addresses (NMDevice *dev)
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* Remove routing table entries */
|
||||
/* Not really applicable for test devices */
|
||||
if (nm_device_is_test_device (dev))
|
||||
return;
|
||||
|
||||
/* Remove all IP addresses for a device */
|
||||
snprintf (buf, 100, "/sbin/ip address flush dev %s", nm_device_get_iface (dev));
|
||||
nm_spawn_process (buf);
|
||||
}
|
||||
|
@@ -64,6 +64,13 @@ gboolean nm_system_device_run_dhcp (NMDevice *dev)
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
|
||||
/* Fake it for a test device */
|
||||
if (nm_device_is_test_device (dev))
|
||||
{
|
||||
g_usleep (2000);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
iface = nm_device_get_iface (dev);
|
||||
snprintf (buf, 500, "/sbin/dhcpcd %s", iface);
|
||||
err = nm_spawn_process (buf);
|
||||
@@ -85,6 +92,10 @@ void nm_system_device_stop_dhcp (NMDevice *dev)
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* Not really applicable for test devices */
|
||||
if (nm_device_is_test_device (dev))
|
||||
return;
|
||||
|
||||
snprintf (buf, 500, "/var/run/dhcpcd-%s.pid", nm_device_get_iface(dev));
|
||||
pidfile = fopen (buf, "r");
|
||||
if (pidfile)
|
||||
@@ -116,11 +127,15 @@ void nm_system_device_flush_routes (NMDevice *dev)
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* Not really applicable for test devices */
|
||||
if (nm_device_is_test_device (dev))
|
||||
return;
|
||||
|
||||
if (nm_system_gentoo_conf_type == GENTOO_CONF_TYPE_IPROUTE) {
|
||||
snprintf (buf, 100, "/sbin/ip route flush dev %s", nm_device_get_iface (dev));
|
||||
} else if (nm_system_gentoo_conf_type == GENTOO_CONF_TYPE_IFCONFIG) {
|
||||
// FIXME: this command still isn't right
|
||||
snprintf (buf, 100, "/sbin/route del dev%s", nm_device_get_iface (dev));
|
||||
snprintf (buf, 100, "/sbin/route del dev %s", nm_device_get_iface (dev));
|
||||
} else {
|
||||
snprintf (buf, 100, "/bin/false");
|
||||
}
|
||||
@@ -139,6 +154,10 @@ void nm_system_device_flush_addresses (NMDevice *dev)
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* Not really applicable for test devices */
|
||||
if (nm_device_is_test_device (dev))
|
||||
return;
|
||||
|
||||
if (nm_system_gentoo_conf_type == GENTOO_CONF_TYPE_IPROUTE) {
|
||||
snprintf (buf, 100, "/sbin/ip address flush dev %s", nm_device_get_iface (dev));
|
||||
} else if (nm_system_gentoo_conf_type == GENTOO_CONF_TYPE_IFCONFIG) {
|
||||
|
@@ -54,6 +54,13 @@ gboolean nm_system_device_run_dhcp (NMDevice *dev)
|
||||
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
|
||||
/* Fake it for a test device */
|
||||
if (nm_device_is_test_device (dev))
|
||||
{
|
||||
g_usleep (2000);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* Unfortunately, dhclient can take a long time to get a dhcp address
|
||||
* (for example, bad WEP key so it can't actually talk to the AP).
|
||||
*/
|
||||
@@ -80,6 +87,10 @@ void nm_system_device_stop_dhcp (NMDevice *dev)
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* Not really applicable for test devices */
|
||||
if (nm_device_is_test_device (dev))
|
||||
return;
|
||||
|
||||
/* Find and kill the previous dhclient process for this device */
|
||||
snprintf (buf, 500, "/var/run/dhclient-%s.pid", nm_device_get_iface (dev));
|
||||
pidfile = fopen (buf, "r");
|
||||
@@ -113,6 +124,10 @@ void nm_system_device_flush_routes (NMDevice *dev)
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* Not really applicable for test devices */
|
||||
if (nm_device_is_test_device (dev))
|
||||
return;
|
||||
|
||||
/* Remove routing table entries */
|
||||
snprintf (buf, 100, "/sbin/ip route flush dev %s", nm_device_get_iface (dev));
|
||||
nm_spawn_process (buf);
|
||||
@@ -131,7 +146,11 @@ void nm_system_device_flush_addresses (NMDevice *dev)
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
/* Remove routing table entries */
|
||||
/* Not really applicable for test devices */
|
||||
if (nm_device_is_test_device (dev))
|
||||
return;
|
||||
|
||||
/* Remove all IP addresses for a device */
|
||||
snprintf (buf, 100, "/sbin/ip address flush dev %s", nm_device_get_iface (dev));
|
||||
nm_spawn_process (buf);
|
||||
}
|
||||
@@ -170,7 +189,7 @@ void nm_system_delete_default_route (void)
|
||||
*/
|
||||
void nm_system_kill_all_dhcp_daemons (void)
|
||||
{
|
||||
nm_spawn_process ("/usr/bin/killall dhclient");
|
||||
nm_spawn_process ("/usr/bin/killall -q dhclient");
|
||||
}
|
||||
|
||||
|
||||
@@ -183,7 +202,8 @@ void nm_system_kill_all_dhcp_daemons (void)
|
||||
*/
|
||||
void nm_system_update_dns (void)
|
||||
{
|
||||
nm_spawn_process ("/sbin/service nscd restart");
|
||||
if(nm_spawn_process ("/etc/init.d/nscd status"))
|
||||
nm_spawn_process ("/etc/init.d/nscd restart");
|
||||
}
|
||||
|
||||
|
||||
|
@@ -4,10 +4,13 @@ INCLUDES = \
|
||||
-DBINDIR=\"$(bindir)\" \
|
||||
-DDATADIR=\"$(datadir)\"
|
||||
|
||||
noinst_PROGRAMS = nmtest nminfotest
|
||||
noinst_PROGRAMS = nmtest nminfotest nmtestdevices
|
||||
|
||||
nmtest_SOURCES = nmclienttest.c
|
||||
nmtest_LDADD = $(NM_LIBS)
|
||||
|
||||
nminfotest_SOURCES = nminfotest.c
|
||||
nminfotest_LDADD = $(NM_LIBS)
|
||||
|
||||
nmtestdevices_SOURCES = nmtestdevices.c
|
||||
nmtestdevices_LDADD = $(NM_LIBS)
|
||||
|
297
test/nmtestdevices.c
Normal file
297
test/nmtestdevices.c
Normal file
@@ -0,0 +1,297 @@
|
||||
/* nmtestdevices - Tool to create/delete/modify test devices for NetworkManager
|
||||
* (use when you are on a plane, don't have a wireless card, etc)
|
||||
*
|
||||
* 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.h>
|
||||
#include <dbus/dbus-glib.h>
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
|
||||
/* These MUST correspond to NetworkManager device types */
|
||||
typedef enum NMDeviceType
|
||||
{
|
||||
DEVICE_TYPE_DONT_KNOW = 0,
|
||||
DEVICE_TYPE_WIRED_ETHERNET,
|
||||
DEVICE_TYPE_WIRELESS_ETHERNET
|
||||
} NMDeviceType;
|
||||
|
||||
|
||||
#define NM_DBUS_SERVICE "org.freedesktop.NetworkManager"
|
||||
#define NM_DBUS_PATH "/org/freedesktop/NetworkManager"
|
||||
#define NM_DBUS_INTERFACE "org.freedesktop.NetworkManager"
|
||||
#define NM_DBUS_INTERFACE_DEVICES "org.freedesktop.NetworkManager.Devices"
|
||||
|
||||
|
||||
void create_device (DBusConnection *connection, NMDeviceType type)
|
||||
{
|
||||
DBusMessage *message;
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusError error;
|
||||
|
||||
g_return_if_fail (connection != NULL);
|
||||
g_return_if_fail (((type == DEVICE_TYPE_WIRED_ETHERNET) || (type == DEVICE_TYPE_WIRELESS_ETHERNET)));
|
||||
|
||||
message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, "createTestDevice");
|
||||
if (message == NULL)
|
||||
{
|
||||
fprintf (stderr, "Couldn't allocate the dbus message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_error_init (&error);
|
||||
dbus_message_append_args (message, DBUS_TYPE_INT32, type, DBUS_TYPE_INVALID);
|
||||
reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
|
||||
if (dbus_error_is_set (&error))
|
||||
{
|
||||
fprintf (stderr, "%s raised:\n %s\n\n", error.name, error.message);
|
||||
dbus_error_free (&error);
|
||||
dbus_message_unref (message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (reply == NULL)
|
||||
{
|
||||
fprintf( stderr, "dbus reply message was NULL\n" );
|
||||
dbus_message_unref (message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* now analyze reply */
|
||||
dbus_message_iter_init (reply, &iter);
|
||||
char *string;
|
||||
string = dbus_message_iter_get_string (&iter);
|
||||
if (!string)
|
||||
{
|
||||
fprintf (stderr, "NetworkManager returned a NULL test device ID, test device could not be created." );
|
||||
return;
|
||||
}
|
||||
|
||||
fprintf (stderr, "New test device ID: '%s'\n", string );
|
||||
|
||||
dbus_free (string);
|
||||
dbus_message_unref (reply);
|
||||
dbus_message_unref (message);
|
||||
}
|
||||
|
||||
|
||||
void remove_device (DBusConnection *connection, char *dev)
|
||||
{
|
||||
DBusMessage *message;
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusError error;
|
||||
|
||||
g_return_if_fail (connection != NULL);
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, "removeTestDevice");
|
||||
if (message == NULL)
|
||||
{
|
||||
fprintf (stderr, "Couldn't allocate the dbus message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_error_init (&error);
|
||||
dbus_message_append_args (message, DBUS_TYPE_STRING, dev, DBUS_TYPE_INVALID);
|
||||
reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
|
||||
if (dbus_error_is_set (&error))
|
||||
{
|
||||
fprintf (stderr, "%s raised:\n %s\n\n", error.name, error.message);
|
||||
dbus_error_free (&error);
|
||||
dbus_message_unref (message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (reply == NULL)
|
||||
{
|
||||
fprintf( stderr, "dbus reply message was NULL\n" );
|
||||
dbus_message_unref (message);
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_message_unref (message);
|
||||
dbus_message_unref (reply);
|
||||
}
|
||||
|
||||
|
||||
void set_link_active (DBusConnection *connection, char *dev, gboolean active)
|
||||
{
|
||||
DBusMessage *message;
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusError error;
|
||||
|
||||
g_return_if_fail (connection != NULL);
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
message = dbus_message_new_method_call (NM_DBUS_SERVICE, dev, NM_DBUS_INTERFACE_DEVICES, "setLinkActive");
|
||||
if (message == NULL)
|
||||
{
|
||||
fprintf (stderr, "Couldn't allocate the dbus message\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_message_append_args (message, DBUS_TYPE_BOOLEAN, active, DBUS_TYPE_INVALID);
|
||||
|
||||
dbus_error_init (&error);
|
||||
reply = dbus_connection_send_with_reply_and_block (connection, message, -1, &error);
|
||||
if (dbus_error_is_set (&error))
|
||||
{
|
||||
fprintf (stderr, "%s raised:\n %s\n\n", error.name, error.message);
|
||||
dbus_error_free (&error);
|
||||
dbus_message_unref (message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (reply == NULL)
|
||||
{
|
||||
fprintf( stderr, "dbus reply message was NULL\n" );
|
||||
dbus_message_unref (message);
|
||||
return;
|
||||
}
|
||||
|
||||
dbus_message_unref (message);
|
||||
dbus_message_unref (reply);
|
||||
}
|
||||
|
||||
|
||||
static void print_usage (void)
|
||||
{
|
||||
fprintf (stderr, "\n" "usage : nmtestdevices [options] [--help]\n");
|
||||
fprintf (stderr,
|
||||
"\n"
|
||||
" --create-device <wired | wireless> Creates a test device, returns the new device ID\n"
|
||||
" --remove-device <ID> Remove a test device (cannot remove real devices)\n"
|
||||
" --make-link-active <ID> Switch a test device's link ON\n"
|
||||
" --make-link-inactive <ID> Switch a test device's link OFF\n"
|
||||
" --help Show this information and exit\n"
|
||||
"\n"
|
||||
"This tool allows you to tell NetworkManager to create and manipulate fake 'test' devices. This\n"
|
||||
"is useful in sitation where you may not have a particular device but still want to test\n"
|
||||
"NetworkManager out with it (For example, you forgot your wireless card at home and now you're\n"
|
||||
"taking a trip and want to hack on NM, and you're on a plane so you could use the wireless\n"
|
||||
"card anyway).\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
DBusConnection *connection;
|
||||
DBusError error;
|
||||
char *dev = NULL;
|
||||
gboolean create = FALSE;
|
||||
gboolean remove = FALSE;
|
||||
gboolean make_link_active = FALSE;
|
||||
gboolean make_link_inactive = FALSE;
|
||||
NMDeviceType dev_type = DEVICE_TYPE_DONT_KNOW;
|
||||
|
||||
/* Parse options */
|
||||
while (1)
|
||||
{
|
||||
int c;
|
||||
int option_index = 0;
|
||||
const char *opt;
|
||||
|
||||
static struct option options[] = {
|
||||
{"create-device", 1, NULL, 0},
|
||||
{"remove-device", 1, NULL, 0},
|
||||
{"make-link-active", 1, NULL, 0},
|
||||
{"make-link-inactive", 1, NULL, 0},
|
||||
{"help", 0, NULL, 0},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
c = getopt_long (argc, argv, "", options, &option_index);
|
||||
if (c == -1)
|
||||
break;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
opt = options[option_index].name;
|
||||
if (strcmp (opt, "help") == 0)
|
||||
{
|
||||
print_usage ();
|
||||
exit (0);
|
||||
}
|
||||
else if (strcmp (opt, "create-device") == 0)
|
||||
{
|
||||
create = TRUE;
|
||||
if (optarg)
|
||||
{
|
||||
if (strcmp (optarg, "wired") == 0)
|
||||
dev_type = DEVICE_TYPE_WIRED_ETHERNET;
|
||||
else if (strcmp (optarg, "wireless") == 0)
|
||||
dev_type = DEVICE_TYPE_WIRELESS_ETHERNET;
|
||||
}
|
||||
}
|
||||
else if (strcmp (opt, "remove-device") == 0)
|
||||
{
|
||||
remove = TRUE;
|
||||
if (optarg)
|
||||
dev = g_strdup (optarg);
|
||||
}
|
||||
else if (strcmp (opt, "make-link-active") == 0)
|
||||
{
|
||||
make_link_active = TRUE;
|
||||
if (optarg)
|
||||
dev = g_strdup (optarg);
|
||||
}
|
||||
else if (strcmp (opt, "make-link-inactive") == 0)
|
||||
{
|
||||
make_link_inactive = TRUE;
|
||||
if (optarg)
|
||||
dev = g_strdup (optarg);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
print_usage ();
|
||||
exit (1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_type_init ();
|
||||
|
||||
dbus_error_init (&error);
|
||||
connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error);
|
||||
if (connection == NULL)
|
||||
{
|
||||
fprintf (stderr, "Error connecting to system bus: %s\n", error.message);
|
||||
dbus_error_free (&error);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (create)
|
||||
create_device (connection, dev_type);
|
||||
else if (remove)
|
||||
remove_device (connection, dev);
|
||||
else if (make_link_active)
|
||||
set_link_active (connection, dev, TRUE);
|
||||
else if (make_link_inactive)
|
||||
set_link_active (connection, dev, FALSE);
|
||||
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user