2005-03-11 Ray Strode <rstrode@redhat.com>
Third (unfinished, partially working) cut at porting to dbus 0.30 api and new hal. * info-daemon/NetworkManagerInfoDbus.c: don't free null arrays. * panel-applet/NMWirelessAppletDbus.c: * src/nm-dbus-device.c: * src/nm-dbus-net.c: * src/NetworkManagerDbus.c: more STRING -> OBJECT_PATH fun * src/NetworkManagerDevice.c: * src/NetworkManagerDevice.h: (rename nm_device_get_link_active): rename to nm_device_has_active_link (nm_device_wireless_link_active): rename to nm_device_probe_wireless_link_state (nm_device_wired_link_active): rename to nm_device_probe_wired_link_state. Rewrite to use carrier file since hal doesn't maintain link state anymore. (nm_device_update_link_active): rename to nm_device_update_link_state * src/NetworkManagerPolicy.c (nm_policy_activation_finish): check for NULL MAC address. * src/Makefile.am: * src/NetworkManagerMain.h: * src/NetworkManager.c: * src/nm-netlink-monitor.c: * src/nm-netlink-monitor.h: New class to support monitoring wired ethernet link status, since HAL doesn't export that information anymore. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@495 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
39
ChangeLog
39
ChangeLog
@@ -1,9 +1,46 @@
|
|||||||
|
2005-03-11 Ray Strode <rstrode@redhat.com>
|
||||||
|
|
||||||
|
Third (unfinished, partially working) cut at porting to
|
||||||
|
dbus 0.30 api and new hal.
|
||||||
|
|
||||||
|
* info-daemon/NetworkManagerInfoDbus.c:
|
||||||
|
don't free null arrays.
|
||||||
|
|
||||||
|
* panel-applet/NMWirelessAppletDbus.c:
|
||||||
|
* src/nm-dbus-device.c:
|
||||||
|
* src/nm-dbus-net.c:
|
||||||
|
* src/NetworkManagerDbus.c: more
|
||||||
|
STRING -> OBJECT_PATH fun
|
||||||
|
* src/NetworkManagerDevice.c:
|
||||||
|
* src/NetworkManagerDevice.h:
|
||||||
|
(rename nm_device_get_link_active): rename to
|
||||||
|
nm_device_has_active_link
|
||||||
|
(nm_device_wireless_link_active): rename to
|
||||||
|
nm_device_probe_wireless_link_state
|
||||||
|
(nm_device_wired_link_active): rename to
|
||||||
|
nm_device_probe_wired_link_state. Rewrite to
|
||||||
|
use carrier file since hal doesn't maintain
|
||||||
|
link state anymore.
|
||||||
|
(nm_device_update_link_active): rename to
|
||||||
|
nm_device_update_link_state
|
||||||
|
* src/NetworkManagerPolicy.c
|
||||||
|
(nm_policy_activation_finish): check for NULL
|
||||||
|
MAC address.
|
||||||
|
|
||||||
|
* src/Makefile.am:
|
||||||
|
* src/NetworkManagerMain.h:
|
||||||
|
* src/NetworkManager.c:
|
||||||
|
* src/nm-netlink-monitor.c:
|
||||||
|
* src/nm-netlink-monitor.h: New class to support
|
||||||
|
monitoring wired ethernet link status, since HAL
|
||||||
|
doesn't export that information anymore.
|
||||||
|
|
||||||
2005-03-09 Ray Strode <rstrode@redhat.com>
|
2005-03-09 Ray Strode <rstrode@redhat.com>
|
||||||
|
|
||||||
Second (unfinished, unworking) cut at porting to
|
Second (unfinished, unworking) cut at porting to
|
||||||
dbus 0.30 api.
|
dbus 0.30 api.
|
||||||
|
|
||||||
* dispatcher-daemon/NetworkManagerDispatcher.c
|
* dispatcher-daemon/NetworkManagerDispatcher.c:
|
||||||
* info-daemon/NetworkManagerInfoDbus.c:
|
* info-daemon/NetworkManagerInfoDbus.c:
|
||||||
* panel-applet/NMWirelessAppletDbus.c:
|
* panel-applet/NMWirelessAppletDbus.c:
|
||||||
* src/NetworkManagerDbusUtils.c:
|
* src/NetworkManagerDbusUtils.c:
|
||||||
|
@@ -482,7 +482,9 @@ static DBusMessage *nmi_dbus_get_network_properties (NMIAppInfo *info, DBusMessa
|
|||||||
|
|
||||||
dbus_message_iter_close_container (&iter, &array_iter);
|
dbus_message_iter_close_container (&iter, &array_iter);
|
||||||
}
|
}
|
||||||
gconf_value_free (ap_addrs_value);
|
|
||||||
|
if (ap_addrs_value != NULL)
|
||||||
|
gconf_value_free (ap_addrs_value);
|
||||||
|
|
||||||
g_free (essid);
|
g_free (essid);
|
||||||
g_free (key);
|
g_free (key);
|
||||||
|
@@ -72,7 +72,7 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons
|
|||||||
g_return_val_if_fail (*arg == NULL, RETURN_FAILURE);
|
g_return_val_if_fail (*arg == NULL, RETURN_FAILURE);
|
||||||
|
|
||||||
if ((arg_type == NM_DBUS_TYPE_STRING_ARRAY) ||
|
if ((arg_type == NM_DBUS_TYPE_STRING_ARRAY) ||
|
||||||
(arg_type == NM_DBUS_TYPE_OBJECT_PATH_ARRAY))
|
(arg_type == NM_DBUS_TYPE_OBJECT_PATH_ARRAY))
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (item_count != NULL, RETURN_FAILURE);
|
g_return_val_if_fail (item_count != NULL, RETURN_FAILURE);
|
||||||
*item_count = 0;
|
*item_count = 0;
|
||||||
@@ -102,7 +102,7 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons
|
|||||||
ret = RETURN_SUCCESS;
|
ret = RETURN_SUCCESS;
|
||||||
|
|
||||||
if ((ret != RETURN_SUCCESS) && (ret != RETURN_NO_NM))
|
if ((ret != RETURN_SUCCESS) && (ret != RETURN_NO_NM))
|
||||||
fprintf (stderr, "nmwa_dbus_call_nm_method(): %s raised:\n %s\n\n", error.name, error.message);
|
fprintf (stderr, "nmwa_dbus_call_nm_method(): %s raised on method '%s':\n %s\n\n", error.name, method, error.message);
|
||||||
|
|
||||||
dbus_error_free (&error);
|
dbus_error_free (&error);
|
||||||
return (ret);
|
return (ret);
|
||||||
@@ -155,6 +155,7 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons
|
|||||||
|
|
||||||
switch (arg_type)
|
switch (arg_type)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
case DBUS_TYPE_OBJECT_PATH:
|
case DBUS_TYPE_OBJECT_PATH:
|
||||||
*((char **)(arg)) = nm_dbus_unescape_object_path (dbus_string);
|
*((char **)(arg)) = nm_dbus_unescape_object_path (dbus_string);
|
||||||
break;
|
break;
|
||||||
@@ -170,9 +171,12 @@ static int nmwa_dbus_call_nm_method (DBusConnection *con, const char *path, cons
|
|||||||
*item_count = num_items;
|
*item_count = num_items;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
case DBUS_TYPE_OBJECT_PATH:
|
||||||
case DBUS_TYPE_STRING:
|
case DBUS_TYPE_STRING:
|
||||||
*((char **)(arg)) = g_strdup (dbus_string);
|
*((char **)(arg)) = g_strdup (dbus_string);
|
||||||
break;
|
break;
|
||||||
|
case NM_DBUS_TYPE_OBJECT_PATH_ARRAY:
|
||||||
case NM_DBUS_TYPE_STRING_ARRAY:
|
case NM_DBUS_TYPE_STRING_ARRAY:
|
||||||
*((char ***)(arg)) = g_strdupv (dbus_array);
|
*((char ***)(arg)) = g_strdupv (dbus_array);
|
||||||
*item_count = num_items;
|
*item_count = num_items;
|
||||||
@@ -234,7 +238,7 @@ static char * nmwa_dbus_get_active_network (NMWirelessApplet *applet, char *dev_
|
|||||||
{
|
{
|
||||||
char *network = NULL;
|
char *network = NULL;
|
||||||
|
|
||||||
switch (nmwa_dbus_call_nm_method (applet->connection, dev_path, "getActiveNetwork", DBUS_TYPE_STRING, (void **)(&network), NULL))
|
switch (nmwa_dbus_call_nm_method (applet->connection, dev_path, "getActiveNetwork", DBUS_TYPE_OBJECT_PATH, (void **)(&network), NULL))
|
||||||
{
|
{
|
||||||
case (RETURN_NO_NM):
|
case (RETURN_NO_NM):
|
||||||
applet->applet_state = APPLET_STATE_NO_NM;
|
applet->applet_state = APPLET_STATE_NO_NM;
|
||||||
@@ -685,7 +689,7 @@ void nmwa_dbus_set_device (DBusConnection *connection, const NetworkDevice *dev,
|
|||||||
if (passphrase == NULL)
|
if (passphrase == NULL)
|
||||||
passphrase = "";
|
passphrase = "";
|
||||||
|
|
||||||
dbus_message_append_args (message, DBUS_TYPE_STRING, &dev->nm_device,
|
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev->nm_device,
|
||||||
DBUS_TYPE_STRING, &network->essid,
|
DBUS_TYPE_STRING, &network->essid,
|
||||||
DBUS_TYPE_STRING, &passphrase,
|
DBUS_TYPE_STRING, &passphrase,
|
||||||
DBUS_TYPE_INT32, &key_type,
|
DBUS_TYPE_INT32, &key_type,
|
||||||
@@ -1261,8 +1265,8 @@ static void nmwa_dbus_device_update_one_network (NMWirelessApplet *applet, DBusM
|
|||||||
dbus_error_init (&error);
|
dbus_error_init (&error);
|
||||||
/* Try first time with strength, which is only passed for NETWORK_STATUS_STRENGTH_CHANGED */
|
/* Try first time with strength, which is only passed for NETWORK_STATUS_STRENGTH_CHANGED */
|
||||||
if (!dbus_message_get_args (message, &error,
|
if (!dbus_message_get_args (message, &error,
|
||||||
DBUS_TYPE_STRING, &dev_path,
|
DBUS_TYPE_OBJECT_PATH, &dev_path,
|
||||||
DBUS_TYPE_STRING, &net_path,
|
DBUS_TYPE_OBJECT_PATH, &net_path,
|
||||||
DBUS_TYPE_UINT32, &status,
|
DBUS_TYPE_UINT32, &status,
|
||||||
DBUS_TYPE_INT32, &strength,
|
DBUS_TYPE_INT32, &strength,
|
||||||
DBUS_TYPE_INVALID))
|
DBUS_TYPE_INVALID))
|
||||||
@@ -1273,8 +1277,8 @@ static void nmwa_dbus_device_update_one_network (NMWirelessApplet *applet, DBusM
|
|||||||
|
|
||||||
/* Try without strength */
|
/* Try without strength */
|
||||||
if (!dbus_message_get_args (message, &error,
|
if (!dbus_message_get_args (message, &error,
|
||||||
DBUS_TYPE_STRING, &dev_path,
|
DBUS_TYPE_OBJECT_PATH, &dev_path,
|
||||||
DBUS_TYPE_STRING, &net_path,
|
DBUS_TYPE_OBJECT_PATH, &net_path,
|
||||||
DBUS_TYPE_UINT32, &status,
|
DBUS_TYPE_UINT32, &status,
|
||||||
DBUS_TYPE_INVALID))
|
DBUS_TYPE_INVALID))
|
||||||
{
|
{
|
||||||
|
@@ -38,6 +38,8 @@ NetworkManager_SOURCES = \
|
|||||||
NetworkManagerWireless.h \
|
NetworkManagerWireless.h \
|
||||||
NetworkManagerSystem.c \
|
NetworkManagerSystem.c \
|
||||||
NetworkManagerSystem.h \
|
NetworkManagerSystem.h \
|
||||||
|
nm-netlink-monitor.c \
|
||||||
|
nm-netlink-monitor.h \
|
||||||
autoip.c
|
autoip.c
|
||||||
|
|
||||||
NetworkManager_CPPFLAGS = \
|
NetworkManager_CPPFLAGS = \
|
||||||
|
@@ -43,7 +43,9 @@
|
|||||||
#include "NetworkManagerAPList.h"
|
#include "NetworkManagerAPList.h"
|
||||||
#include "NetworkManagerSystem.h"
|
#include "NetworkManagerSystem.h"
|
||||||
#include "nm-named-manager.h"
|
#include "nm-named-manager.h"
|
||||||
|
#include "nm-netlink-monitor.h"
|
||||||
|
|
||||||
|
#define NM_WIRELESS_LINK_STATE_POLL_INTERVAL (5 * 1000)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Globals
|
* Globals
|
||||||
@@ -54,13 +56,9 @@ static gboolean sigterm_pipe_handler (GIOChannel *src, GIOCondition condition, g
|
|||||||
static void sigterm_handler (int signum);
|
static void sigterm_handler (int signum);
|
||||||
static void nm_data_free (NMData *data);
|
static void nm_data_free (NMData *data);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_get_device_interface_from_hal
|
* 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)
|
static char *nm_get_device_interface_from_hal (LibHalContext *ctx, const char *udi)
|
||||||
{
|
{
|
||||||
@@ -95,7 +93,7 @@ static char *nm_get_device_interface_from_hal (LibHalContext *ctx, const char *u
|
|||||||
* NULL on failure
|
* NULL on failure
|
||||||
*/
|
*/
|
||||||
NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, const char *iface,
|
NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, const char *iface,
|
||||||
gboolean test_device, NMDeviceType test_device_type)
|
gboolean test_device, NMDeviceType test_device_type)
|
||||||
{
|
{
|
||||||
NMDevice *dev = NULL;
|
NMDevice *dev = NULL;
|
||||||
|
|
||||||
@@ -110,7 +108,7 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, cons
|
|||||||
if (!data->enable_test_devices && test_device)
|
if (!data->enable_test_devices && test_device)
|
||||||
{
|
{
|
||||||
syslog (LOG_ERR, "nm_create_device_and_add_to_list(): attempt to create a test device,"
|
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");
|
" but test devices were not enabled on the command line. Will not create the device.\n");
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,6 +129,8 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, cons
|
|||||||
data->dev_list = g_slist_append (data->dev_list, dev);
|
data->dev_list = g_slist_append (data->dev_list, dev);
|
||||||
nm_device_deactivate (dev, TRUE);
|
nm_device_deactivate (dev, TRUE);
|
||||||
|
|
||||||
|
nm_device_update_link_state (dev);
|
||||||
|
|
||||||
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
||||||
|
|
||||||
nm_policy_schedule_state_update (data);
|
nm_policy_schedule_state_update (data);
|
||||||
@@ -139,11 +139,11 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi, cons
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* If we couldn't add the device to our list, free its data. */
|
/* 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." );
|
syslog ( LOG_ERR, "nm_create_device_and_add_to_list() could not acquire device list mutex." );
|
||||||
nm_device_unref (dev);
|
nm_device_unref (dev);
|
||||||
dev = NULL;
|
dev = NULL;
|
||||||
}
|
}
|
||||||
} else syslog( LOG_ERR, "nm_create_device_and_add_to_list() could not allocate device data." );
|
} else syslog ( LOG_ERR, "nm_create_device_and_add_to_list() could not allocate device data." );
|
||||||
|
|
||||||
return (dev);
|
return (dev);
|
||||||
}
|
}
|
||||||
@@ -194,7 +194,7 @@ void nm_remove_device_from_list (NMData *data, const char *udi)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
||||||
} else syslog( LOG_ERR, "nm_remove_device_from_list() could not acquire device list mutex." );
|
} else syslog ( LOG_ERR, "nm_remove_device_from_list() could not acquire device list mutex." );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hal doesn't really give us any way to pass a GMainContext to our
|
/* Hal doesn't really give us any way to pass a GMainContext to our
|
||||||
@@ -212,7 +212,6 @@ static void nm_hal_mainloop_integration (LibHalContext *ctx, DBusConnection * db
|
|||||||
dbus_connection_setup_with_g_main (dbus_connection, main_context);
|
dbus_connection_setup_with_g_main (dbus_connection, main_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_hal_device_added
|
* nm_hal_device_added
|
||||||
*
|
*
|
||||||
@@ -224,7 +223,7 @@ static void nm_hal_device_added (LibHalContext *ctx, const char *udi)
|
|||||||
|
|
||||||
g_return_if_fail (data != NULL);
|
g_return_if_fail (data != NULL);
|
||||||
|
|
||||||
syslog( LOG_DEBUG, "New device added (hal udi is '%s').", udi );
|
syslog ( LOG_DEBUG, "New device added (hal udi is '%s').", udi );
|
||||||
|
|
||||||
/* Sometimes the device's properties (like net.interface) are not set up yet,
|
/* Sometimes the device's properties (like net.interface) are not set up yet,
|
||||||
* so this call will fail, and it will actually be added when hal sets the device's
|
* so this call will fail, and it will actually be added when hal sets the device's
|
||||||
@@ -248,7 +247,7 @@ static void nm_hal_device_removed (LibHalContext *ctx, const char *udi)
|
|||||||
|
|
||||||
g_return_if_fail (data != NULL);
|
g_return_if_fail (data != NULL);
|
||||||
|
|
||||||
syslog( LOG_DEBUG, "Device removed (hal udi is '%s').", udi );
|
syslog ( LOG_DEBUG, "Device removed (hal udi is '%s').", udi );
|
||||||
|
|
||||||
nm_remove_device_from_list (data, udi);
|
nm_remove_device_from_list (data, udi);
|
||||||
}
|
}
|
||||||
@@ -264,7 +263,7 @@ static void nm_hal_device_new_capability (LibHalContext *ctx, const char *udi, c
|
|||||||
|
|
||||||
g_return_if_fail (data != NULL);
|
g_return_if_fail (data != NULL);
|
||||||
|
|
||||||
/*syslog( LOG_DEBUG, "nm_hal_device_new_capability() called with udi = %s, capability = %s", udi, capability );*/
|
/*syslog ( LOG_DEBUG, "nm_hal_device_new_capability() called with udi = %s, capability = %s", udi, capability );*/
|
||||||
|
|
||||||
if (capability && ((strcmp (capability, "net.80203") == 0) || (strcmp (capability, "net.80211") == 0)))
|
if (capability && ((strcmp (capability, "net.80203") == 0) || (strcmp (capability, "net.80211") == 0)))
|
||||||
{
|
{
|
||||||
@@ -285,67 +284,9 @@ static void nm_hal_device_new_capability (LibHalContext *ctx, const char *udi, c
|
|||||||
*/
|
*/
|
||||||
static void nm_hal_device_lost_capability (LibHalContext *ctx, const char *udi, const char *capability)
|
static void nm_hal_device_lost_capability (LibHalContext *ctx, const char *udi, const char *capability)
|
||||||
{
|
{
|
||||||
/* syslog( LOG_DEBUG, "nm_hal_device_lost_capability() called with udi = %s, capability = %s", udi, capability );*/
|
/* syslog ( LOG_DEBUG, "nm_hal_device_lost_capability() called with udi = %s, capability = %s", udi, capability );*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* nm_hal_device_property_modified
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
static void nm_hal_device_property_modified (LibHalContext *ctx, const char *udi, const char *key, dbus_bool_t is_removed, dbus_bool_t is_added)
|
|
||||||
{
|
|
||||||
NMData *data = (NMData *)libhal_ctx_get_user_data (ctx);
|
|
||||||
gboolean link = FALSE;
|
|
||||||
|
|
||||||
g_return_if_fail (data != NULL);
|
|
||||||
g_return_if_fail (udi != NULL);
|
|
||||||
g_return_if_fail (key != NULL);
|
|
||||||
|
|
||||||
/*syslog (LOG_DEBUG, "nm_hal_device_property_modified() called with udi = %s, key = %s, is_removed = %d, is_added = %d", udi, key, is_removed, is_added);*/
|
|
||||||
|
|
||||||
/* Only accept wired ethernet link changes for now */
|
|
||||||
if (is_removed || (strcmp (key, "net.80203.link") != 0))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!libhal_device_property_exists (ctx, udi, "net.80203.link", NULL))
|
|
||||||
return;
|
|
||||||
|
|
||||||
link = libhal_device_get_property_bool (ctx, udi, "net.80203.link", NULL);
|
|
||||||
|
|
||||||
/* Attempt to acquire mutex for device link updating. If acquire fails ignore the event. */
|
|
||||||
if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
|
|
||||||
{
|
|
||||||
NMDevice *dev = NULL;
|
|
||||||
if ((dev = nm_get_device_by_udi (data, udi)) && nm_device_is_wired (dev))
|
|
||||||
{
|
|
||||||
syslog (LOG_DEBUG, "HAL signaled link state change for device %s.", nm_device_get_iface (dev));
|
|
||||||
nm_device_update_link_active (dev);
|
|
||||||
|
|
||||||
/* If the currently active device is locked and wireless, and the wired
|
|
||||||
* device we just received this property change event for now has a link
|
|
||||||
* state of TRUE, we want to clear the active device lock so that we switch
|
|
||||||
* from wireless to wired on the next state update.
|
|
||||||
*
|
|
||||||
* This happens when the user has explicitly chosen a wireless network at
|
|
||||||
* some point, and then comes back and plugs the wired cable in. Due to the
|
|
||||||
* active device lock we wouldn't switch back to wired automatically, but
|
|
||||||
* this fixes that behavior.
|
|
||||||
*/
|
|
||||||
if ( nm_device_get_link_active (dev)
|
|
||||||
&& data->active_device
|
|
||||||
&& data->active_device_locked
|
|
||||||
&& nm_device_is_wireless (data->active_device))
|
|
||||||
{
|
|
||||||
data->active_device_locked = FALSE;
|
|
||||||
nm_policy_schedule_state_update (data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
|
||||||
} else syslog( LOG_ERR, "nm_hal_device_property_modified() could not acquire device list mutex." );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_add_initial_devices
|
* nm_add_initial_devices
|
||||||
*
|
*
|
||||||
@@ -424,16 +365,14 @@ void nm_schedule_status_signal_broadcast (NMData *data)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_link_state_monitor
|
* nm_poll_and_update_wireless_link_state
|
||||||
*
|
*
|
||||||
* Called every 2s to poll cards and determine if they have a link
|
* Called every 2s to poll wireless cards and determine if they have a link
|
||||||
* or not.
|
* or not.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
gboolean nm_link_state_monitor (gpointer user_data)
|
gboolean nm_poll_and_update_wireless_link_state (NMData *data)
|
||||||
{
|
{
|
||||||
NMData *data = (NMData *)user_data;
|
|
||||||
|
|
||||||
g_return_val_if_fail (data != NULL, TRUE);
|
g_return_val_if_fail (data != NULL, TRUE);
|
||||||
|
|
||||||
/* Attempt to acquire mutex for device list iteration.
|
/* Attempt to acquire mutex for device list iteration.
|
||||||
@@ -446,39 +385,26 @@ gboolean nm_link_state_monitor (gpointer user_data)
|
|||||||
{
|
{
|
||||||
NMDevice *dev = (NMDevice *)(elt->data);
|
NMDevice *dev = (NMDevice *)(elt->data);
|
||||||
|
|
||||||
if (dev)
|
if (dev && nm_device_is_wireless (dev))
|
||||||
{
|
{
|
||||||
if (!nm_device_is_up (dev))
|
if (!nm_device_is_up (dev))
|
||||||
nm_device_bring_up (dev);
|
nm_device_bring_up (dev);
|
||||||
nm_device_update_link_active (dev);
|
|
||||||
|
|
||||||
if (dev == data->active_device)
|
nm_device_update_link_state (dev);
|
||||||
{
|
|
||||||
if (nm_device_is_wireless (dev) && !nm_device_get_link_active (dev))
|
/* Is this the currently selected device?
|
||||||
{
|
* If so, let's make sure it's still has
|
||||||
/* If we loose a link to the access point, then
|
* an active link. If it lost the link,
|
||||||
* look for another access point to connect to.
|
* find a better access point.
|
||||||
*/
|
*/
|
||||||
nm_device_update_best_ap (dev);
|
if ((dev == data->active_device) &&
|
||||||
}
|
!nm_device_has_active_link (dev))
|
||||||
}
|
nm_device_update_best_ap (dev);
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Ensure that the device has no IP address or routes. This will
|
|
||||||
* sometimes occur when a card gets inserted, and the system
|
|
||||||
* initscripts will run to bring the card up, but they get around to
|
|
||||||
* running _after_ we've been notified of insertion and cleared out
|
|
||||||
* card info already.
|
|
||||||
*/
|
|
||||||
nm_system_device_flush_routes (dev);
|
|
||||||
if (nm_device_get_ip4_address (dev) != 0)
|
|
||||||
nm_system_device_flush_addresses (dev);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
||||||
} else syslog( LOG_ERR, "nm_link_state_monitor() could not acquire device list mutex." );
|
} else syslog ( LOG_ERR, "nm_poll_and_update_wireless_link_state() could not acquire device list mutex." );
|
||||||
|
|
||||||
return (TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
@@ -623,6 +549,114 @@ static void nm_print_usage (void)
|
|||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_monitor_wireless_link_state (NMData *data)
|
||||||
|
{
|
||||||
|
GSource *link_source;
|
||||||
|
link_source = g_timeout_source_new (NM_WIRELESS_LINK_STATE_POLL_INTERVAL);
|
||||||
|
g_source_set_callback (link_source,
|
||||||
|
(GSourceFunc) nm_poll_and_update_wireless_link_state,
|
||||||
|
nm_data, NULL);
|
||||||
|
g_source_attach (link_source, nm_data->main_context);
|
||||||
|
g_source_unref (link_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_wired_link_activated (NmNetlinkMonitor *monitor,
|
||||||
|
const gchar *interface_name,
|
||||||
|
NMData *data)
|
||||||
|
{
|
||||||
|
NMDevice *device;
|
||||||
|
|
||||||
|
if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
|
||||||
|
{
|
||||||
|
device = nm_get_device_by_iface (data, interface_name);
|
||||||
|
|
||||||
|
if (device != NULL)
|
||||||
|
{
|
||||||
|
nm_device_set_link_active (device, TRUE);
|
||||||
|
|
||||||
|
if (nm_device_has_active_link (device)
|
||||||
|
&& data->active_device
|
||||||
|
&& data->active_device_locked
|
||||||
|
&& nm_device_is_wireless (data->active_device))
|
||||||
|
{
|
||||||
|
data->active_device_locked = FALSE;
|
||||||
|
nm_policy_schedule_state_update (data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
syslog (LOG_ERR, "unknown wired ethernet interface '%s' activated\n",
|
||||||
|
interface_name);
|
||||||
|
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_wired_link_deactivated (NmNetlinkMonitor *monitor,
|
||||||
|
const gchar *interface_name,
|
||||||
|
NMData *data)
|
||||||
|
{
|
||||||
|
NMDevice *device;
|
||||||
|
|
||||||
|
if (nm_try_acquire_mutex (data->dev_list_mutex, __FUNCTION__))
|
||||||
|
{
|
||||||
|
device = nm_get_device_by_iface (data, interface_name);
|
||||||
|
|
||||||
|
if (device != NULL)
|
||||||
|
nm_device_set_link_active (device, FALSE);
|
||||||
|
else
|
||||||
|
syslog (LOG_ERR, "unknown wired ethernet interface '%s' "
|
||||||
|
"deactivated\n", interface_name);
|
||||||
|
nm_unlock_mutex (data->dev_list_mutex, __FUNCTION__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_error_monitoring_wired_link_state (NmNetlinkMonitor *monitor,
|
||||||
|
GError *error,
|
||||||
|
NMData *data)
|
||||||
|
{
|
||||||
|
/* FIXME: Try to handle the error instead of just printing it.
|
||||||
|
*/
|
||||||
|
syslog (LOG_ERR, "error monitoring wired ethernet link state: %s\n",
|
||||||
|
error->message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_monitor_wired_link_state (NMData *data)
|
||||||
|
{
|
||||||
|
GError *error;
|
||||||
|
NmNetlinkMonitor *monitor;
|
||||||
|
|
||||||
|
monitor = nm_netlink_monitor_new ();
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
nm_netlink_monitor_open_connection (monitor, &error);
|
||||||
|
|
||||||
|
if (error != NULL)
|
||||||
|
{
|
||||||
|
syslog (LOG_ERR, "could not monitor wired ethernet devices: %s",
|
||||||
|
error->message);
|
||||||
|
g_error_free (error);
|
||||||
|
g_object_unref (monitor);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (monitor), "interface-connected",
|
||||||
|
G_CALLBACK (nm_wired_link_activated), data);
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (monitor), "interface-disconnected",
|
||||||
|
G_CALLBACK (nm_wired_link_deactivated), data);
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (monitor), "error",
|
||||||
|
G_CALLBACK (nm_error_monitoring_wired_link_state),
|
||||||
|
data);
|
||||||
|
|
||||||
|
nm_netlink_monitor_attach (monitor, data->main_context);
|
||||||
|
|
||||||
|
data->netlink_monitor = monitor;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* main
|
* main
|
||||||
@@ -766,8 +800,6 @@ int main( int argc, char *argv[] )
|
|||||||
nm_hal_device_new_capability);
|
nm_hal_device_new_capability);
|
||||||
libhal_ctx_set_device_lost_capability (ctx,
|
libhal_ctx_set_device_lost_capability (ctx,
|
||||||
nm_hal_device_lost_capability);
|
nm_hal_device_lost_capability);
|
||||||
libhal_ctx_set_device_property_modified (ctx,
|
|
||||||
nm_hal_device_property_modified);
|
|
||||||
|
|
||||||
libhal_device_property_watch_all (nm_data->hal_ctx, &dbus_error);
|
libhal_device_property_watch_all (nm_data->hal_ctx, &dbus_error);
|
||||||
|
|
||||||
@@ -789,10 +821,9 @@ int main( int argc, char *argv[] )
|
|||||||
/* Bring up the loopback interface. */
|
/* Bring up the loopback interface. */
|
||||||
nm_system_enable_loopback ();
|
nm_system_enable_loopback ();
|
||||||
|
|
||||||
/* Create a watch function that monitors cards for link status. */
|
/* Create watch functions that monitor cards for link status. */
|
||||||
link_source = g_timeout_source_new (5000);
|
nm_monitor_wireless_link_state (nm_data);
|
||||||
g_source_set_callback (link_source, nm_link_state_monitor, nm_data, NULL);
|
nm_monitor_wired_link_state (nm_data);
|
||||||
link_source_id = g_source_attach (link_source, nm_data->main_context);
|
|
||||||
|
|
||||||
if (!nm_named_manager_start (nm_data->named, &error))
|
if (!nm_named_manager_start (nm_data->named, &error))
|
||||||
{
|
{
|
||||||
@@ -803,9 +834,6 @@ int main( int argc, char *argv[] )
|
|||||||
/* Wheeee!!! */
|
/* Wheeee!!! */
|
||||||
g_main_loop_run (nm_data->main_loop);
|
g_main_loop_run (nm_data->main_loop);
|
||||||
|
|
||||||
/* Kill the watch functions */
|
|
||||||
g_source_remove (link_source_id);
|
|
||||||
|
|
||||||
/* Cleanup */
|
/* Cleanup */
|
||||||
if (libhal_ctx_shutdown (nm_data->hal_ctx, &dbus_error) != 0) {
|
if (libhal_ctx_shutdown (nm_data->hal_ctx, &dbus_error) != 0) {
|
||||||
syslog (LOG_NOTICE, "Error: libhal shutdown failed - %s", dbus_error.message);
|
syslog (LOG_NOTICE, "Error: libhal shutdown failed - %s", dbus_error.message);
|
||||||
|
@@ -39,6 +39,7 @@
|
|||||||
#include "nm-dbus-device.h"
|
#include "nm-dbus-device.h"
|
||||||
#include "nm-dbus-net.h"
|
#include "nm-dbus-net.h"
|
||||||
#include "nm-dbus-dhcp.h"
|
#include "nm-dbus-dhcp.h"
|
||||||
|
#include "nm-utils.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -75,9 +76,15 @@ DBusMessage *nm_dbus_create_error_message (DBusMessage *message, const char *exc
|
|||||||
*/
|
*/
|
||||||
static unsigned char * nm_dbus_get_object_path_from_device (NMDevice *dev)
|
static unsigned char * nm_dbus_get_object_path_from_device (NMDevice *dev)
|
||||||
{
|
{
|
||||||
|
char *object_path, *escaped_object_path;
|
||||||
|
|
||||||
g_return_val_if_fail (dev != NULL, NULL);
|
g_return_val_if_fail (dev != NULL, NULL);
|
||||||
|
|
||||||
return (g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev)));
|
object_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev));
|
||||||
|
escaped_object_path = nm_dbus_escape_object_path (object_path);
|
||||||
|
g_free (object_path);
|
||||||
|
|
||||||
|
return escaped_object_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -106,15 +113,21 @@ NMDevice *nm_dbus_get_device_from_object_path (NMData *data, const char *path)
|
|||||||
{
|
{
|
||||||
GSList *elt;
|
GSList *elt;
|
||||||
char compare_path[100];
|
char compare_path[100];
|
||||||
|
char *escaped_compare_path;
|
||||||
|
|
||||||
for (elt = data->dev_list; elt; elt = g_slist_next (elt))
|
for (elt = data->dev_list; elt; elt = g_slist_next (elt))
|
||||||
{
|
{
|
||||||
if ((dev = (NMDevice *)(elt->data)))
|
if ((dev = (NMDevice *)(elt->data)))
|
||||||
{
|
{
|
||||||
snprintf (compare_path, 100, "%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev));
|
snprintf (compare_path, 100, "%s/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev));
|
||||||
|
escaped_compare_path = nm_dbus_escape_object_path (compare_path);
|
||||||
/* Compare against our constructed path, but ignore any trailing elements */
|
/* Compare against our constructed path, but ignore any trailing elements */
|
||||||
if (strncmp (path, compare_path, strlen (compare_path)) == 0)
|
if (strncmp (path, compare_path, strlen (escaped_compare_path)) == 0)
|
||||||
|
{
|
||||||
|
g_free (escaped_compare_path);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
g_free (escaped_compare_path);
|
||||||
dev = NULL;
|
dev = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -298,11 +311,11 @@ void nm_dbus_signal_device_status_change (DBusConnection *connection, NMDevice *
|
|||||||
if (ap && nm_ap_get_essid (ap)) {
|
if (ap && nm_ap_get_essid (ap)) {
|
||||||
const char *essid;
|
const char *essid;
|
||||||
essid = nm_ap_get_essid (ap);
|
essid = nm_ap_get_essid (ap);
|
||||||
dbus_message_append_args (message, DBUS_TYPE_STRING, &dev_path,
|
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path,
|
||||||
DBUS_TYPE_STRING, &essid,
|
DBUS_TYPE_STRING, &essid,
|
||||||
DBUS_TYPE_INVALID);
|
DBUS_TYPE_INVALID);
|
||||||
} else
|
} else
|
||||||
dbus_message_append_args (message, DBUS_TYPE_STRING, &dev_path, DBUS_TYPE_INVALID);
|
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_INVALID);
|
||||||
|
|
||||||
if (ap)
|
if (ap)
|
||||||
nm_ap_unref (ap);
|
nm_ap_unref (ap);
|
||||||
@@ -405,7 +418,7 @@ void nm_dbus_signal_device_ip4_address_change (DBusConnection *connection, NMDev
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dbus_message_append_args (message, DBUS_TYPE_STRING, &dev_path, DBUS_TYPE_INVALID);
|
dbus_message_append_args (message, DBUS_TYPE_OBJECT_PATH, &dev_path, DBUS_TYPE_INVALID);
|
||||||
g_free (dev_path);
|
g_free (dev_path);
|
||||||
|
|
||||||
if (!dbus_connection_send (connection, message, NULL))
|
if (!dbus_connection_send (connection, message, NULL))
|
||||||
@@ -451,8 +464,8 @@ void nm_dbus_signal_wireless_network_change (DBusConnection *connection, NMDevic
|
|||||||
}
|
}
|
||||||
|
|
||||||
dbus_message_append_args (message,
|
dbus_message_append_args (message,
|
||||||
DBUS_TYPE_STRING, &dev_path,
|
DBUS_TYPE_OBJECT_PATH, &dev_path,
|
||||||
DBUS_TYPE_STRING, &ap_path,
|
DBUS_TYPE_OBJECT_PATH, &ap_path,
|
||||||
DBUS_TYPE_UINT32, &status,
|
DBUS_TYPE_UINT32, &status,
|
||||||
DBUS_TYPE_INVALID);
|
DBUS_TYPE_INVALID);
|
||||||
g_free (ap_path);
|
g_free (ap_path);
|
||||||
@@ -548,9 +561,9 @@ NMAccessPoint *nm_dbus_get_network_object (DBusConnection *connection, NMNetwork
|
|||||||
DBusMessage *reply;
|
DBusMessage *reply;
|
||||||
NMAccessPoint *ap = NULL;
|
NMAccessPoint *ap = NULL;
|
||||||
|
|
||||||
char *essid = NULL;
|
const char *essid = NULL;
|
||||||
gint timestamp_secs = -1;
|
gint timestamp_secs = -1;
|
||||||
char *key = NULL;
|
const char *key = NULL;
|
||||||
NMEncKeyType key_type = -1;
|
NMEncKeyType key_type = -1;
|
||||||
gboolean trusted = FALSE;
|
gboolean trusted = FALSE;
|
||||||
NMDeviceAuthMethod auth_method = NM_DEVICE_AUTH_METHOD_UNKNOWN;
|
NMDeviceAuthMethod auth_method = NM_DEVICE_AUTH_METHOD_UNKNOWN;
|
||||||
@@ -589,6 +602,9 @@ NMAccessPoint *nm_dbus_get_network_object (DBusConnection *connection, NMNetwork
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: These argument types need to be validated
|
||||||
|
*/
|
||||||
|
|
||||||
dbus_message_iter_init (reply, &iter);
|
dbus_message_iter_init (reply, &iter);
|
||||||
dbus_message_iter_get_basic (&iter, &essid);
|
dbus_message_iter_get_basic (&iter, &essid);
|
||||||
dbus_message_iter_get_basic (&iter, ×tamp_secs);
|
dbus_message_iter_get_basic (&iter, ×tamp_secs);
|
||||||
@@ -618,6 +634,7 @@ NMAccessPoint *nm_dbus_get_network_object (DBusConnection *connection, NMNetwork
|
|||||||
nm_ap_set_auth_method (ap, auth_method);
|
nm_ap_set_auth_method (ap, auth_method);
|
||||||
|
|
||||||
/* Get user addresses, form into a GSList, and stuff into the AP */
|
/* Get user addresses, form into a GSList, and stuff into the AP */
|
||||||
|
if (dbus_message_iter_get_arg_type (&iter) == DBUS_TYPE_ARRAY)
|
||||||
{
|
{
|
||||||
GSList *addr_list = NULL;
|
GSList *addr_list = NULL;
|
||||||
DBusMessageIter array_iter;
|
DBusMessageIter array_iter;
|
||||||
@@ -673,7 +690,7 @@ gboolean nm_dbus_update_network_auth_method (DBusConnection *connection, const c
|
|||||||
}
|
}
|
||||||
|
|
||||||
auth_method_as_int32 = (dbus_int32_t) auth_method;
|
auth_method_as_int32 = (dbus_int32_t) auth_method;
|
||||||
dbus_message_append_args (message, DBUS_TYPE_STRING, network,
|
dbus_message_append_args (message, DBUS_TYPE_STRING, &network,
|
||||||
DBUS_TYPE_INT32, &auth_method,
|
DBUS_TYPE_INT32, &auth_method,
|
||||||
DBUS_TYPE_INVALID);
|
DBUS_TYPE_INVALID);
|
||||||
|
|
||||||
@@ -706,7 +723,7 @@ gboolean nm_dbus_add_network_address (DBusConnection *connection, NMNetworkType
|
|||||||
DBusMessage *message;
|
DBusMessage *message;
|
||||||
DBusError error;
|
DBusError error;
|
||||||
gboolean success = FALSE;
|
gboolean success = FALSE;
|
||||||
char char_addr[20];
|
gchar *char_addr;
|
||||||
dbus_int32_t type_as_int32;
|
dbus_int32_t type_as_int32;
|
||||||
|
|
||||||
g_return_val_if_fail (connection != NULL, FALSE);
|
g_return_val_if_fail (connection != NULL, FALSE);
|
||||||
@@ -722,14 +739,15 @@ gboolean nm_dbus_add_network_address (DBusConnection *connection, NMNetworkType
|
|||||||
return (FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (char_addr, 0, 20);
|
char_addr = g_new0 (gchar, 20);
|
||||||
ether_ntoa_r (addr, &char_addr[0]);
|
ether_ntoa_r (addr, char_addr);
|
||||||
|
|
||||||
type_as_int32 = (dbus_int32_t) type;
|
type_as_int32 = (dbus_int32_t) type;
|
||||||
dbus_message_append_args (message, DBUS_TYPE_STRING, network,
|
dbus_message_append_args (message, DBUS_TYPE_STRING, &network,
|
||||||
DBUS_TYPE_INT32, &type_as_int32,
|
DBUS_TYPE_INT32, &type_as_int32,
|
||||||
DBUS_TYPE_STRING, &char_addr,
|
DBUS_TYPE_STRING, &char_addr,
|
||||||
DBUS_TYPE_INVALID);
|
DBUS_TYPE_INVALID);
|
||||||
|
g_free (char_addr);
|
||||||
|
|
||||||
/* Send message and get trusted status back from NetworkManagerInfo */
|
/* Send message and get trusted status back from NetworkManagerInfo */
|
||||||
dbus_error_init (&error);
|
dbus_error_init (&error);
|
||||||
@@ -813,6 +831,8 @@ char ** nm_dbus_get_networks (DBusConnection *connection, NMNetworkType type, in
|
|||||||
dbus_message_iter_next(&array_iter);
|
dbus_message_iter_next(&array_iter);
|
||||||
}
|
}
|
||||||
networks = (gchar **)(buffer->data);
|
networks = (gchar **)(buffer->data);
|
||||||
|
if (num_networks != NULL)
|
||||||
|
*num_networks = buffer->len;
|
||||||
g_array_free (buffer, FALSE);
|
g_array_free (buffer, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -969,7 +989,7 @@ static DBusHandlerResult nm_dbus_devices_message_handler (DBusConnection *connec
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *object_path;
|
char *object_path, *escaped_object_path;
|
||||||
NMDbusCBData cb_data;
|
NMDbusCBData cb_data;
|
||||||
|
|
||||||
cb_data.data = data;
|
cb_data.data = data;
|
||||||
@@ -977,10 +997,13 @@ static DBusHandlerResult nm_dbus_devices_message_handler (DBusConnection *connec
|
|||||||
|
|
||||||
/* Test whether or not the _networks_ of a device were queried instead of the device itself */
|
/* Test whether or not the _networks_ of a device were queried instead of the device itself */
|
||||||
object_path = g_strdup_printf ("%s/%s/Networks/", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev));
|
object_path = g_strdup_printf ("%s/%s/Networks/", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev));
|
||||||
if (strncmp (path, object_path, strlen (object_path)) == 0)
|
escaped_object_path = nm_dbus_escape_object_path (object_path);
|
||||||
|
g_free (object_path);
|
||||||
|
if (strncmp (path, escaped_object_path, strlen (escaped_object_path)) == 0)
|
||||||
handled = nm_dbus_method_dispatch (data->net_methods, connection, message, &cb_data, &reply);
|
handled = nm_dbus_method_dispatch (data->net_methods, connection, message, &cb_data, &reply);
|
||||||
else
|
else
|
||||||
handled = nm_dbus_method_dispatch (data->device_methods, connection, message, &cb_data, &reply);
|
handled = nm_dbus_method_dispatch (data->device_methods, connection, message, &cb_data, &reply);
|
||||||
|
g_free (escaped_object_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reply)
|
if (reply)
|
||||||
|
@@ -39,6 +39,8 @@
|
|||||||
#include "NetworkManagerSystem.h"
|
#include "NetworkManagerSystem.h"
|
||||||
#include "NetworkManagerDHCP.h"
|
#include "NetworkManagerDHCP.h"
|
||||||
|
|
||||||
|
#include "nm-utils.h"
|
||||||
|
|
||||||
/* Local static prototypes */
|
/* Local static prototypes */
|
||||||
static gpointer nm_device_worker (gpointer user_data);
|
static gpointer nm_device_worker (gpointer user_data);
|
||||||
static gboolean nm_device_activate (gpointer user_data);
|
static gboolean nm_device_activate (gpointer user_data);
|
||||||
@@ -307,7 +309,11 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
|
|||||||
|
|
||||||
if (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED)
|
if (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED)
|
||||||
{
|
{
|
||||||
nm_device_update_link_active (dev);
|
if (nm_device_is_wireless (dev))
|
||||||
|
{
|
||||||
|
nm_device_update_link_state (dev);
|
||||||
|
nm_device_update_signal_strength (dev);
|
||||||
|
}
|
||||||
|
|
||||||
nm_device_update_ip4_address (dev);
|
nm_device_update_ip4_address (dev);
|
||||||
nm_device_update_hw_address (dev);
|
nm_device_update_hw_address (dev);
|
||||||
@@ -610,7 +616,7 @@ NMDriverSupportLevel nm_device_get_driver_support_level (NMDevice *dev)
|
|||||||
/*
|
/*
|
||||||
* Get/set functions for link_active
|
* Get/set functions for link_active
|
||||||
*/
|
*/
|
||||||
gboolean nm_device_get_link_active (NMDevice *dev)
|
gboolean nm_device_has_active_link (NMDevice *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (dev != NULL, FALSE);
|
g_return_val_if_fail (dev != NULL, FALSE);
|
||||||
|
|
||||||
@@ -621,7 +627,13 @@ void nm_device_set_link_active (NMDevice *dev, const gboolean link_active)
|
|||||||
{
|
{
|
||||||
g_return_if_fail (dev != NULL);
|
g_return_if_fail (dev != NULL);
|
||||||
|
|
||||||
dev->link_active = link_active;
|
if (dev->link_active != link_active)
|
||||||
|
{
|
||||||
|
dev->link_active = link_active;
|
||||||
|
|
||||||
|
nm_dbus_schedule_device_status_change (dev, DEVICE_STATUS_CHANGE);
|
||||||
|
nm_policy_schedule_state_update (dev->app_data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -693,7 +705,7 @@ static gboolean nm_device_wireless_is_associated (NMDevice *dev)
|
|||||||
|
|
||||||
/* Test devices have their link state set through DBUS */
|
/* Test devices have their link state set through DBUS */
|
||||||
if (dev->test_device)
|
if (dev->test_device)
|
||||||
return (nm_device_get_link_active (dev));
|
return (nm_device_has_active_link (dev));
|
||||||
|
|
||||||
if ((sk = iw_sockets_open ()) < 0)
|
if ((sk = iw_sockets_open ()) < 0)
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
@@ -730,12 +742,12 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_device_wireless_link_active
|
* nm_device_probe_wireless_link_state
|
||||||
*
|
*
|
||||||
* Gets the link state of a wireless device
|
* Gets the link state of a wireless device
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static gboolean nm_device_wireless_link_active (NMDevice *dev)
|
static gboolean nm_device_probe_wireless_link_state (NMDevice *dev)
|
||||||
{
|
{
|
||||||
gboolean link = FALSE;
|
gboolean link = FALSE;
|
||||||
NMAccessPoint *best_ap;
|
NMAccessPoint *best_ap;
|
||||||
@@ -745,7 +757,7 @@ static gboolean nm_device_wireless_link_active (NMDevice *dev)
|
|||||||
|
|
||||||
/* Test devices have their link state set through DBUS */
|
/* Test devices have their link state set through DBUS */
|
||||||
if (dev->test_device)
|
if (dev->test_device)
|
||||||
return (nm_device_get_link_active (dev));
|
return (nm_device_has_active_link (dev));
|
||||||
|
|
||||||
if (!nm_device_wireless_is_associated (dev))
|
if (!nm_device_wireless_is_associated (dev))
|
||||||
return (FALSE);
|
return (FALSE);
|
||||||
@@ -765,14 +777,16 @@ static gboolean nm_device_wireless_link_active (NMDevice *dev)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_device_wired_link_active
|
* nm_device_probe_wired_link_state
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static gboolean nm_device_wired_link_active (NMDevice *dev)
|
static gboolean nm_device_probe_wired_link_state (NMDevice *dev)
|
||||||
{
|
{
|
||||||
gboolean link = FALSE;
|
gboolean link = FALSE;
|
||||||
|
gchar *contents, *carrier_path;
|
||||||
|
gsize length;
|
||||||
|
|
||||||
g_return_val_if_fail (dev != NULL, FALSE);
|
g_return_val_if_fail (dev != NULL, FALSE);
|
||||||
g_return_val_if_fail (nm_device_is_wired (dev) == TRUE, FALSE);
|
g_return_val_if_fail (nm_device_is_wired (dev) == TRUE, FALSE);
|
||||||
@@ -780,32 +794,36 @@ static gboolean nm_device_wired_link_active (NMDevice *dev)
|
|||||||
|
|
||||||
/* Test devices have their link state set through DBUS */
|
/* Test devices have their link state set through DBUS */
|
||||||
if (dev->test_device)
|
if (dev->test_device)
|
||||||
return (nm_device_get_link_active (dev));
|
return (nm_device_has_active_link (dev));
|
||||||
|
|
||||||
|
if (dev->removed)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
carrier_path = g_strdup_printf ("/sys/sys/class/net/%s/carrier", dev->iface);
|
||||||
|
if (g_file_get_contents (carrier_path, &contents, &length, NULL)) {
|
||||||
|
link = (gboolean) atoi (contents);
|
||||||
|
g_free (contents);
|
||||||
|
} else {
|
||||||
|
contents = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* We say that non-carrier-detect devices always have a link, because
|
/* We say that non-carrier-detect devices always have a link, because
|
||||||
* they never get auto-selected by NM. User has to force them on us,
|
* they never get auto-selected by NM. User has to force them on us,
|
||||||
* so we just hope the user knows whether or not the cable's plugged in.
|
* so we just hope the user knows whether or not the cable's plugged in.
|
||||||
*/
|
*/
|
||||||
if (dev->options.wired.has_carrier_detect != TRUE)
|
if ((dev->options.wired.has_carrier_detect != TRUE) || (contents == NULL))
|
||||||
link = TRUE;
|
link = TRUE;
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Device has carrier detect, yay! */
|
|
||||||
if (libhal_device_property_exists (dev->app_data->hal_ctx, nm_device_get_udi (dev), "net.80203.link", NULL))
|
|
||||||
link = libhal_device_get_property_bool (dev->app_data->hal_ctx, nm_device_get_udi (dev), "net.80203.link", NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (link);
|
return (link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_device_update_link_active
|
* nm_device_update_link_state
|
||||||
*
|
*
|
||||||
* Updates the link state for a particular device.
|
* Updates the link state for a particular device.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void nm_device_update_link_active (NMDevice *dev)
|
void nm_device_update_link_state (NMDevice *dev)
|
||||||
{
|
{
|
||||||
gboolean link = FALSE;
|
gboolean link = FALSE;
|
||||||
|
|
||||||
@@ -815,27 +833,16 @@ void nm_device_update_link_active (NMDevice *dev)
|
|||||||
switch (nm_device_get_type (dev))
|
switch (nm_device_get_type (dev))
|
||||||
{
|
{
|
||||||
case DEVICE_TYPE_WIRELESS_ETHERNET:
|
case DEVICE_TYPE_WIRELESS_ETHERNET:
|
||||||
link = nm_device_wireless_link_active (dev);
|
nm_device_set_link_active (dev, nm_device_probe_wireless_link_state (dev));
|
||||||
/* Update our current signal strength too */
|
|
||||||
nm_device_update_signal_strength (dev);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DEVICE_TYPE_WIRED_ETHERNET:
|
case DEVICE_TYPE_WIRED_ETHERNET:
|
||||||
link = nm_device_wired_link_active (dev);
|
nm_device_set_link_active (dev, nm_device_probe_wired_link_state (dev));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
link = nm_device_get_link_active (dev); /* Can't get link info for this device, so don't change link status */
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update device link status and global state variable if the status changed */
|
|
||||||
if (link != nm_device_get_link_active (dev))
|
|
||||||
{
|
|
||||||
nm_device_set_link_active (dev, link);
|
|
||||||
nm_dbus_schedule_device_status_change (dev, DEVICE_STATUS_CHANGE);
|
|
||||||
nm_policy_schedule_state_update (dev->app_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1155,7 +1162,7 @@ void nm_device_get_ap_address (NMDevice *dev, struct ether_addr *addr)
|
|||||||
{
|
{
|
||||||
struct ether_addr good_addr = { {0x70, 0x37, 0x03, 0x70, 0x37, 0x03} };
|
struct ether_addr good_addr = { {0x70, 0x37, 0x03, 0x70, 0x37, 0x03} };
|
||||||
struct ether_addr bad_addr = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
|
struct ether_addr bad_addr = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} };
|
||||||
gboolean link = nm_device_get_link_active (dev);
|
gboolean link = nm_device_has_active_link (dev);
|
||||||
|
|
||||||
memcpy ((link ? &good_addr : &bad_addr), &(wrq.u.ap_addr.sa_data), sizeof (struct ether_addr));
|
memcpy ((link ? &good_addr : &bad_addr), &(wrq.u.ap_addr.sa_data), sizeof (struct ether_addr));
|
||||||
return;
|
return;
|
||||||
@@ -2790,8 +2797,15 @@ char * nm_device_get_path_for_ap (NMDevice *dev, NMAccessPoint *ap)
|
|||||||
g_return_val_if_fail (ap != NULL, NULL);
|
g_return_val_if_fail (ap != NULL, NULL);
|
||||||
|
|
||||||
if (nm_ap_get_essid (ap))
|
if (nm_ap_get_essid (ap))
|
||||||
return (g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev), nm_ap_get_essid (ap)));
|
{
|
||||||
else
|
char *path, *escaped_path;
|
||||||
|
|
||||||
|
path = g_strdup_printf ("%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev), nm_ap_get_essid (ap));
|
||||||
|
escaped_path = nm_dbus_escape_object_path (path);
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
return (escaped_path);
|
||||||
|
} else
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -56,9 +56,9 @@ NMData * nm_device_get_app_data (const NMDevice *dev);
|
|||||||
gboolean nm_device_get_removed (const NMDevice *dev);
|
gboolean nm_device_get_removed (const NMDevice *dev);
|
||||||
void nm_device_set_removed (NMDevice *dev, const gboolean removed);
|
void nm_device_set_removed (NMDevice *dev, const gboolean removed);
|
||||||
|
|
||||||
gboolean nm_device_get_link_active (NMDevice *dev);
|
gboolean nm_device_has_active_link (NMDevice *dev);
|
||||||
void nm_device_set_link_active (NMDevice *dev, const gboolean active);
|
void nm_device_set_link_active (NMDevice *dev, const gboolean active);
|
||||||
void nm_device_update_link_active (NMDevice *dev);
|
void nm_device_update_link_state (NMDevice *dev);
|
||||||
|
|
||||||
char * nm_device_get_essid (NMDevice *dev);
|
char * nm_device_get_essid (NMDevice *dev);
|
||||||
void nm_device_set_essid (NMDevice *dev, const char *essid);
|
void nm_device_set_essid (NMDevice *dev, const char *essid);
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include <libhal.h>
|
#include <libhal.h>
|
||||||
#include "NetworkManager.h"
|
#include "NetworkManager.h"
|
||||||
#include "NetworkManagerAP.h"
|
#include "NetworkManagerAP.h"
|
||||||
|
#include "nm-netlink-monitor.h"
|
||||||
#include "nm-named-manager.h"
|
#include "nm-named-manager.h"
|
||||||
|
|
||||||
typedef struct NMDbusMethodList NMDbusMethodList;
|
typedef struct NMDbusMethodList NMDbusMethodList;
|
||||||
@@ -36,10 +37,12 @@ typedef struct NMDbusMethodList NMDbusMethodList;
|
|||||||
typedef struct NMData
|
typedef struct NMData
|
||||||
{
|
{
|
||||||
GIOChannel *sigterm_iochannel;
|
GIOChannel *sigterm_iochannel;
|
||||||
int sigterm_pipe[2];
|
int sigterm_pipe[2];
|
||||||
|
|
||||||
LibHalContext *hal_ctx;
|
LibHalContext *hal_ctx;
|
||||||
|
|
||||||
|
NmNetlinkMonitor *netlink_monitor;
|
||||||
|
|
||||||
NMNamedManager *named;
|
NMNamedManager *named;
|
||||||
GList *nameserver_ids; /* For now these are global instead of per-device */
|
GList *nameserver_ids; /* For now these are global instead of per-device */
|
||||||
GList *domain_search_ids;
|
GList *domain_search_ids;
|
||||||
|
@@ -65,7 +65,7 @@ static NMDevice * nm_policy_auto_get_best_device (NMData *data)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
dev_type = nm_device_get_type (dev);
|
dev_type = nm_device_get_type (dev);
|
||||||
link_active = nm_device_get_link_active (dev);
|
link_active = nm_device_has_active_link (dev);
|
||||||
|
|
||||||
if (dev_type == DEVICE_TYPE_WIRED_ETHERNET)
|
if (dev_type == DEVICE_TYPE_WIRED_ETHERNET)
|
||||||
{
|
{
|
||||||
@@ -181,7 +181,7 @@ static NMDevice * nm_policy_get_best_device (NMDevice *switch_to_dev, NMData *da
|
|||||||
{
|
{
|
||||||
/* Wired devices get unlocked only if they have lost their link */
|
/* Wired devices get unlocked only if they have lost their link */
|
||||||
case (DEVICE_TYPE_WIRED_ETHERNET):
|
case (DEVICE_TYPE_WIRED_ETHERNET):
|
||||||
if (nm_device_get_link_active (data->active_device))
|
if (nm_device_has_active_link (data->active_device))
|
||||||
best_dev = data->active_device;
|
best_dev = data->active_device;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -251,7 +251,7 @@ gboolean nm_policy_activation_finish (gpointer user_data)
|
|||||||
struct ether_addr addr;
|
struct ether_addr addr;
|
||||||
|
|
||||||
nm_device_get_ap_address (dev, &addr);
|
nm_device_get_ap_address (dev, &addr);
|
||||||
if (!nm_ethernet_address_is_valid (nm_ap_get_address (ap)))
|
if (!nm_ap_get_address (ap) || !nm_ethernet_address_is_valid (nm_ap_get_address (ap)))
|
||||||
nm_ap_set_address (ap, &addr);
|
nm_ap_set_address (ap, &addr);
|
||||||
|
|
||||||
/* Don't store MAC addresses for non-infrastructure networks */
|
/* Don't store MAC addresses for non-infrastructure networks */
|
||||||
|
@@ -124,7 +124,7 @@ static int timeval_subtract (struct timeval *result, struct timeval *x, struct t
|
|||||||
y->tv_usec += 1000000 * nsec;
|
y->tv_usec += 1000000 * nsec;
|
||||||
y->tv_sec -= nsec;
|
y->tv_sec -= nsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compute the time remaining to wait.
|
/* Compute the time remaining to wait.
|
||||||
`tv_usec' is certainly positive. */
|
`tv_usec' is certainly positive. */
|
||||||
result->tv_sec = x->tv_sec - y->tv_sec;
|
result->tv_sec = x->tv_sec - y->tv_sec;
|
||||||
|
@@ -130,7 +130,7 @@ static DBusMessage *nm_dbus_device_get_link_active (DBusConnection *connection,
|
|||||||
if ((reply = dbus_message_new_method_return (message))) {
|
if ((reply = dbus_message_new_method_return (message))) {
|
||||||
dbus_bool_t is_active;
|
dbus_bool_t is_active;
|
||||||
|
|
||||||
is_active = nm_device_get_link_active (dev);
|
is_active = nm_device_has_active_link (dev);
|
||||||
dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &is_active, DBUS_TYPE_INVALID);
|
dbus_message_append_args (reply, DBUS_TYPE_BOOLEAN, &is_active, DBUS_TYPE_INVALID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,16 +186,24 @@ static DBusMessage *nm_dbus_device_get_active_network (DBusConnection *connectio
|
|||||||
if ((best_ap = nm_device_get_best_ap (dev)))
|
if ((best_ap = nm_device_get_best_ap (dev)))
|
||||||
{
|
{
|
||||||
NMAccessPoint *tmp_ap;
|
NMAccessPoint *tmp_ap;
|
||||||
char *object_path = g_strdup_printf ("%s/%s/Networks/", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev));
|
char *object_path, *escaped_object_path;
|
||||||
|
|
||||||
|
object_path = g_strdup_printf ("%s/%s/Networks/", NM_DBUS_PATH_DEVICES, nm_device_get_iface (dev));
|
||||||
|
escaped_object_path = nm_dbus_escape_object_path (object_path);
|
||||||
|
g_free (object_path);
|
||||||
|
|
||||||
if ( (tmp_ap = nm_device_ap_list_get_ap_by_essid (dev, nm_ap_get_essid (best_ap)))
|
if ( (tmp_ap = nm_device_ap_list_get_ap_by_essid (dev, nm_ap_get_essid (best_ap)))
|
||||||
&& (object_path = nm_device_get_path_for_ap (dev, tmp_ap)))
|
&& (object_path = nm_device_get_path_for_ap (dev, tmp_ap)))
|
||||||
{
|
{
|
||||||
dbus_message_append_args (reply, DBUS_TYPE_STRING, &object_path, DBUS_TYPE_INVALID);
|
|
||||||
|
escaped_object_path = nm_dbus_escape_object_path (object_path);
|
||||||
|
g_free (object_path);
|
||||||
|
|
||||||
|
dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &escaped_object_path, DBUS_TYPE_INVALID);
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
}
|
}
|
||||||
nm_ap_unref (best_ap);
|
nm_ap_unref (best_ap);
|
||||||
g_free (object_path);
|
g_free (escaped_object_path);
|
||||||
}
|
}
|
||||||
if (!success)
|
if (!success)
|
||||||
{
|
{
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include "NetworkManagerAPList.h"
|
#include "NetworkManagerAPList.h"
|
||||||
#include "NetworkManagerUtils.h"
|
#include "NetworkManagerUtils.h"
|
||||||
#include "nm-dbus-net.h"
|
#include "nm-dbus-net.h"
|
||||||
|
#include "nm-utils.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_dbus_get_ap_from_object_path
|
* nm_dbus_get_ap_from_object_path
|
||||||
@@ -37,7 +38,7 @@ static NMAccessPoint *nm_dbus_get_ap_from_object_path (const char *path, NMDevic
|
|||||||
NMAccessPoint *ap = NULL;
|
NMAccessPoint *ap = NULL;
|
||||||
NMAccessPointList *ap_list;
|
NMAccessPointList *ap_list;
|
||||||
NMAPListIter *iter;
|
NMAPListIter *iter;
|
||||||
char compare_path[100];
|
char compare_path[100], *escaped_compare_path;
|
||||||
|
|
||||||
g_return_val_if_fail (path != NULL, NULL);
|
g_return_val_if_fail (path != NULL, NULL);
|
||||||
g_return_val_if_fail (dev != NULL, NULL);
|
g_return_val_if_fail (dev != NULL, NULL);
|
||||||
@@ -53,8 +54,14 @@ static NMAccessPoint *nm_dbus_get_ap_from_object_path (const char *path, NMDevic
|
|||||||
{
|
{
|
||||||
snprintf (compare_path, 100, "%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES,
|
snprintf (compare_path, 100, "%s/%s/Networks/%s", NM_DBUS_PATH_DEVICES,
|
||||||
nm_device_get_iface (dev), nm_ap_get_essid (ap));
|
nm_device_get_iface (dev), nm_ap_get_essid (ap));
|
||||||
if (strncmp (path, compare_path, strlen (compare_path)) == 0)
|
escaped_compare_path = nm_dbus_escape_object_path (compare_path);
|
||||||
|
if (strncmp (path, escaped_compare_path,
|
||||||
|
strlen (escaped_compare_path)) == 0)
|
||||||
|
{
|
||||||
|
g_free (escaped_compare_path);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
g_free (escaped_compare_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
nm_ap_list_iter_free (iter);
|
nm_ap_list_iter_free (iter);
|
||||||
|
635
src/nm-netlink-monitor.c
Normal file
635
src/nm-netlink-monitor.c
Normal file
@@ -0,0 +1,635 @@
|
|||||||
|
/* nm-netlink-monitor.c - Monitor netlink socket for interface change
|
||||||
|
* events
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 Ray Strode
|
||||||
|
*
|
||||||
|
* Some code borrowed from HAL:
|
||||||
|
|
||||||
|
* Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
|
||||||
|
* Copyright (C) 2004 Novell, Inc.
|
||||||
|
*
|
||||||
|
* 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, 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.
|
||||||
|
*/
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/netlink.h>
|
||||||
|
#include <linux/rtnetlink.h>
|
||||||
|
#include <linux/if.h>
|
||||||
|
#include <linux/unistd.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
|
#include "nm-netlink-monitor.h"
|
||||||
|
|
||||||
|
#define NM_NETLINK_MONITOR_EVENT_CONDITIONS \
|
||||||
|
((GIOCondition) (G_IO_IN | G_IO_PRI))
|
||||||
|
|
||||||
|
#define NM_NETLINK_MONITOR_ERROR_CONDITIONS \
|
||||||
|
((GIOCondition) (G_IO_ERR | G_IO_NVAL))
|
||||||
|
|
||||||
|
#define NM_NETLINK_MONITOR_DISCONNECT_CONDITIONS \
|
||||||
|
((GIOCondition) (G_IO_HUP))
|
||||||
|
|
||||||
|
struct _NmNetlinkMonitorPrivate
|
||||||
|
{
|
||||||
|
GMainContext *context;
|
||||||
|
GIOChannel *io_channel;
|
||||||
|
GSource *event_source;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void nm_netlink_monitor_finalize (GObject *object);
|
||||||
|
static void nm_netlink_monitor_class_install_signals (NmNetlinkMonitorClass *service_class);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nm_netlink_monitor_event_handler (GIOChannel *channel,
|
||||||
|
GIOCondition io_condition,
|
||||||
|
NmNetlinkMonitor *monitor);
|
||||||
|
static gboolean
|
||||||
|
nm_netlink_monitor_error_handler (GIOChannel *channel,
|
||||||
|
GIOCondition io_condition,
|
||||||
|
NmNetlinkMonitor *monitor);
|
||||||
|
static gboolean
|
||||||
|
nm_netlink_monitor_disconnect_handler (GIOChannel *channel,
|
||||||
|
GIOCondition io_condition,
|
||||||
|
NmNetlinkMonitor *monitor);
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
INTERFACE_CONNECTED = 0,
|
||||||
|
INTERFACE_DISCONNECTED,
|
||||||
|
ERROR,
|
||||||
|
NUMBER_OF_SIGNALS
|
||||||
|
};
|
||||||
|
|
||||||
|
static guint nm_netlink_monitor_signals[NUMBER_OF_SIGNALS];
|
||||||
|
|
||||||
|
G_DEFINE_TYPE (NmNetlinkMonitor, nm_netlink_monitor, G_TYPE_OBJECT);
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_netlink_monitor_class_init (NmNetlinkMonitorClass *monitor_class)
|
||||||
|
{
|
||||||
|
GObjectClass *gobject_class;
|
||||||
|
|
||||||
|
gobject_class = G_OBJECT_CLASS (monitor_class);
|
||||||
|
|
||||||
|
gobject_class->finalize = nm_netlink_monitor_finalize;
|
||||||
|
|
||||||
|
nm_netlink_monitor_class_install_signals (monitor_class);
|
||||||
|
|
||||||
|
g_type_class_add_private (monitor_class, sizeof (NmNetlinkMonitorPrivate));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_netlink_monitor_class_install_signals (NmNetlinkMonitorClass *monitor_class)
|
||||||
|
{
|
||||||
|
GObjectClass *object_class;
|
||||||
|
|
||||||
|
object_class = G_OBJECT_CLASS (monitor_class);
|
||||||
|
|
||||||
|
nm_netlink_monitor_signals[INTERFACE_CONNECTED] =
|
||||||
|
g_signal_new ("interface-connected",
|
||||||
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (NmNetlinkMonitorClass, interface_connected),
|
||||||
|
NULL, NULL, g_cclosure_marshal_VOID__STRING,
|
||||||
|
G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||||
|
monitor_class->interface_connected = NULL;
|
||||||
|
|
||||||
|
nm_netlink_monitor_signals[INTERFACE_DISCONNECTED] =
|
||||||
|
g_signal_new ("interface-disconnected",
|
||||||
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (NmNetlinkMonitorClass, interface_disconnected),
|
||||||
|
NULL, NULL, g_cclosure_marshal_VOID__STRING,
|
||||||
|
G_TYPE_NONE, 1, G_TYPE_STRING);
|
||||||
|
monitor_class->interface_disconnected = NULL;
|
||||||
|
|
||||||
|
nm_netlink_monitor_signals[ERROR] =
|
||||||
|
g_signal_new ("error",
|
||||||
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
|
G_SIGNAL_RUN_LAST,
|
||||||
|
G_STRUCT_OFFSET (NmNetlinkMonitorClass, error),
|
||||||
|
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
||||||
|
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||||
|
monitor_class->error = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_netlink_monitor_open_connection (NmNetlinkMonitor *monitor,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
struct sockaddr_nl monitor_address = { 0 };
|
||||||
|
int fd, saved_errno;
|
||||||
|
GError *channel_error;
|
||||||
|
GIOFlags channel_flags;
|
||||||
|
|
||||||
|
g_return_val_if_fail (monitor->priv->io_channel == NULL, FALSE);
|
||||||
|
|
||||||
|
fd = socket (PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
|
||||||
|
|
||||||
|
if (fd < 0)
|
||||||
|
{
|
||||||
|
saved_errno = errno;
|
||||||
|
|
||||||
|
g_set_error (error, NM_NETLINK_MONITOR_ERROR,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_OPENING_SOCKET,
|
||||||
|
_("unable to create netlink socket for monitoring "
|
||||||
|
"wired ethernet devices - %s"),
|
||||||
|
g_strerror (saved_errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor_address.nl_family = AF_NETLINK;
|
||||||
|
monitor_address.nl_pid = getpid ();
|
||||||
|
monitor_address.nl_groups = RTMGRP_LINK;
|
||||||
|
|
||||||
|
if (bind (fd,
|
||||||
|
(struct sockaddr *) &monitor_address,
|
||||||
|
sizeof (monitor_address)) < 0) {
|
||||||
|
|
||||||
|
saved_errno = errno;
|
||||||
|
|
||||||
|
g_set_error (error, NM_NETLINK_MONITOR_ERROR,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_BINDING_TO_SOCKET,
|
||||||
|
_("unable to bind to netlink socket for monitoring "
|
||||||
|
"wired ethernet devices - %s"),
|
||||||
|
g_strerror (saved_errno));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor->priv->io_channel = g_io_channel_unix_new (fd);
|
||||||
|
|
||||||
|
channel_error = NULL;
|
||||||
|
g_io_channel_set_encoding (monitor->priv->io_channel,
|
||||||
|
NULL /* encoding */,
|
||||||
|
&channel_error);
|
||||||
|
|
||||||
|
/* Encoding is NULL, so no conversion error can possibly
|
||||||
|
* occur
|
||||||
|
*/
|
||||||
|
g_assert (channel_error == NULL);
|
||||||
|
|
||||||
|
g_io_channel_set_close_on_unref (monitor->priv->io_channel,
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
channel_flags = g_io_channel_get_flags (monitor->priv->io_channel);
|
||||||
|
channel_error = NULL;
|
||||||
|
g_io_channel_set_flags (monitor->priv->io_channel,
|
||||||
|
channel_flags | G_IO_FLAG_NONBLOCK,
|
||||||
|
&channel_error);
|
||||||
|
|
||||||
|
if (channel_error != NULL)
|
||||||
|
{
|
||||||
|
g_propagate_error (error, channel_error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nm_netlink_monitor_close_connection (NmNetlinkMonitor *monitor)
|
||||||
|
{
|
||||||
|
g_return_if_fail (monitor->priv->io_channel != NULL);
|
||||||
|
|
||||||
|
if (monitor->priv->event_source != NULL)
|
||||||
|
nm_netlink_monitor_detach (monitor);
|
||||||
|
|
||||||
|
g_io_channel_shutdown (monitor->priv->io_channel,
|
||||||
|
TRUE /* flush pending data */,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
g_io_channel_unref (monitor->priv->io_channel);
|
||||||
|
monitor->priv->io_channel = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_netlink_monitor_init (NmNetlinkMonitor *monitor)
|
||||||
|
{
|
||||||
|
monitor->priv = G_TYPE_INSTANCE_GET_PRIVATE (monitor,
|
||||||
|
NM_TYPE_NETLINK_MONITOR,
|
||||||
|
NmNetlinkMonitorPrivate);
|
||||||
|
|
||||||
|
monitor->priv->context = NULL;
|
||||||
|
monitor->priv->io_channel = NULL;
|
||||||
|
monitor->priv->event_source = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_netlink_monitor_finalize (GObject *object)
|
||||||
|
{
|
||||||
|
NmNetlinkMonitor *monitor;
|
||||||
|
GObjectClass *gobject_class;
|
||||||
|
|
||||||
|
monitor = NM_NETLINK_MONITOR (object);
|
||||||
|
gobject_class = G_OBJECT_CLASS (nm_netlink_monitor_parent_class);
|
||||||
|
|
||||||
|
if (monitor->priv->io_channel != NULL)
|
||||||
|
nm_netlink_monitor_close_connection (monitor);
|
||||||
|
|
||||||
|
gobject_class->finalize (object);
|
||||||
|
}
|
||||||
|
|
||||||
|
GQuark
|
||||||
|
nm_netlink_monitor_error_quark (void)
|
||||||
|
{
|
||||||
|
static GQuark error_quark = 0;
|
||||||
|
|
||||||
|
if (error_quark == 0)
|
||||||
|
error_quark = g_quark_from_static_string ("nm-netlink-monitor-error-quark");
|
||||||
|
|
||||||
|
return error_quark;
|
||||||
|
}
|
||||||
|
|
||||||
|
NmNetlinkMonitor *
|
||||||
|
nm_netlink_monitor_new (void)
|
||||||
|
{
|
||||||
|
GObject *instance;
|
||||||
|
|
||||||
|
instance = g_object_new (NM_TYPE_NETLINK_MONITOR, NULL);
|
||||||
|
|
||||||
|
return NM_NETLINK_MONITOR (instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nm_netlink_monitor_clear_event_source (NmNetlinkMonitor *monitor)
|
||||||
|
{
|
||||||
|
monitor->priv->event_source = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nm_netlink_monitor_attach (NmNetlinkMonitor *monitor,
|
||||||
|
GMainContext *context)
|
||||||
|
{
|
||||||
|
GSource *event_source;
|
||||||
|
|
||||||
|
g_return_if_fail (NM_IS_NETLINK_MONITOR (monitor));
|
||||||
|
g_return_if_fail (monitor->priv->context == NULL);
|
||||||
|
|
||||||
|
if (context == NULL)
|
||||||
|
context = g_main_context_default ();
|
||||||
|
|
||||||
|
monitor->priv->context = g_main_context_ref (context);
|
||||||
|
|
||||||
|
event_source = g_io_create_watch (monitor->priv->io_channel,
|
||||||
|
NM_NETLINK_MONITOR_EVENT_CONDITIONS |
|
||||||
|
NM_NETLINK_MONITOR_ERROR_CONDITIONS |
|
||||||
|
NM_NETLINK_MONITOR_DISCONNECT_CONDITIONS);
|
||||||
|
g_source_set_callback (event_source,
|
||||||
|
(GSourceFunc) nm_netlink_monitor_event_handler,
|
||||||
|
monitor,
|
||||||
|
(GDestroyNotify)
|
||||||
|
nm_netlink_monitor_clear_event_source);
|
||||||
|
g_source_attach (event_source, context);
|
||||||
|
monitor->priv->event_source = event_source;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nm_netlink_monitor_detach (NmNetlinkMonitor *monitor)
|
||||||
|
{
|
||||||
|
g_return_if_fail (NM_IS_NETLINK_MONITOR (monitor));
|
||||||
|
g_return_if_fail (monitor->priv->context != NULL);
|
||||||
|
|
||||||
|
g_source_destroy (monitor->priv->event_source);
|
||||||
|
monitor->priv->event_source = NULL;
|
||||||
|
|
||||||
|
g_main_context_unref (monitor->priv->context);
|
||||||
|
monitor->priv->context = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nm_netlink_monitor_request_status (NmNetlinkMonitor *monitor)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
receive_pending_bytes (GIOChannel *channel,
|
||||||
|
gchar **str_return,
|
||||||
|
gsize *length,
|
||||||
|
GError **error)
|
||||||
|
{
|
||||||
|
GString *pending_bytes;
|
||||||
|
ssize_t num_bytes_read;
|
||||||
|
gboolean succeeded;
|
||||||
|
struct sockaddr_nl sender = { 0 };
|
||||||
|
gchar buffer[4096];
|
||||||
|
static const size_t buffer_capacity = (size_t) sizeof (buffer);
|
||||||
|
socklen_t sender_size;
|
||||||
|
int fd, saved_errno;
|
||||||
|
|
||||||
|
fd = g_io_channel_unix_get_fd (channel);
|
||||||
|
|
||||||
|
pending_bytes = g_string_sized_new (4096);
|
||||||
|
|
||||||
|
sender_size = (socklen_t) sizeof (sender);
|
||||||
|
saved_errno = 0;
|
||||||
|
succeeded = TRUE;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
num_bytes_read = recvfrom (fd, buffer, buffer_capacity,
|
||||||
|
MSG_DONTWAIT,
|
||||||
|
(struct sockaddr *) &sender,
|
||||||
|
&sender_size);
|
||||||
|
|
||||||
|
if (num_bytes_read < 0)
|
||||||
|
{
|
||||||
|
saved_errno = errno;
|
||||||
|
|
||||||
|
/* the kernel doesn't send EOF when it's done,
|
||||||
|
* so we just have to wait until it wants to
|
||||||
|
* block and assume that means it's done.
|
||||||
|
*/
|
||||||
|
if (saved_errno == EAGAIN)
|
||||||
|
{
|
||||||
|
saved_errno = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (saved_errno == EINTR)
|
||||||
|
saved_errno = 0;
|
||||||
|
|
||||||
|
/* First let's make sure that the sender is actually
|
||||||
|
* someone legitimate.
|
||||||
|
*
|
||||||
|
* There are a few possibilities:
|
||||||
|
* 1) The size of the sender is less than the
|
||||||
|
* size of a generic sockaddr structure.
|
||||||
|
* This means we got sent completely bogus
|
||||||
|
* data.
|
||||||
|
* 2) The size of the sender is greater than or
|
||||||
|
* equal to the size of a generic sockaddr
|
||||||
|
* structure, but the address family the sender
|
||||||
|
* belongs to is not AF_NETLINK. In this case
|
||||||
|
* we were sent some spurious packets that we
|
||||||
|
* don't care about.
|
||||||
|
* 3) The address family is AF_NETLINK but the
|
||||||
|
* the size of the sender is not equal to the
|
||||||
|
* size of a sockaddr_nl structure. This means
|
||||||
|
* we can't treat the received data as an
|
||||||
|
* instance of sockaddr_nl structure.
|
||||||
|
*
|
||||||
|
* In any of the above cases, we should discard the data.
|
||||||
|
*/
|
||||||
|
if ((sender_size != (socklen_t) sizeof (sender)) ||
|
||||||
|
((sender_size == (socklen_t) sizeof (sender)) &&
|
||||||
|
sender.nl_family != AF_NETLINK))
|
||||||
|
{
|
||||||
|
g_set_error (error, NM_NETLINK_MONITOR_ERROR,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_BAD_SENDER,
|
||||||
|
_("received data from wrong type of sender"));
|
||||||
|
succeeded = FALSE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We only care about messages from the kernel,
|
||||||
|
* not anywhere else. Only the kernel can have
|
||||||
|
* nl_pid == 0.
|
||||||
|
*/
|
||||||
|
if (sender.nl_pid != 0)
|
||||||
|
{
|
||||||
|
g_set_error (error, NM_NETLINK_MONITOR_ERROR,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_BAD_SENDER,
|
||||||
|
_("received data from unexpected sender"));
|
||||||
|
succeeded = FALSE;
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Okay, the data has passed basic sanity checks,
|
||||||
|
* let's store it.
|
||||||
|
*/
|
||||||
|
if (num_bytes_read > 0)
|
||||||
|
{
|
||||||
|
g_string_append_len (pending_bytes,
|
||||||
|
buffer, (gssize) num_bytes_read);
|
||||||
|
memset (buffer, 0, num_bytes_read);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while ((num_bytes_read > 0) || (saved_errno == EINTR));
|
||||||
|
|
||||||
|
if (saved_errno != 0)
|
||||||
|
{
|
||||||
|
g_set_error (error, NM_NETLINK_MONITOR_ERROR,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_READING_SOCKET,
|
||||||
|
_("%s"), g_strerror (saved_errno));
|
||||||
|
succeeded = FALSE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pending_bytes->len > 0)
|
||||||
|
{
|
||||||
|
if (str_return)
|
||||||
|
*str_return = pending_bytes->str;
|
||||||
|
|
||||||
|
if (length)
|
||||||
|
*length = pending_bytes->len;
|
||||||
|
|
||||||
|
g_string_free (pending_bytes, FALSE);
|
||||||
|
pending_bytes = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (str_return)
|
||||||
|
*str_return = NULL;
|
||||||
|
|
||||||
|
if (length)
|
||||||
|
*length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (pending_bytes != NULL)
|
||||||
|
g_string_free (pending_bytes, TRUE);
|
||||||
|
return succeeded;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nm_netlink_monitor_event_handler (GIOChannel *channel,
|
||||||
|
GIOCondition io_condition,
|
||||||
|
NmNetlinkMonitor *monitor)
|
||||||
|
{
|
||||||
|
GError *error;
|
||||||
|
gchar *received_bytes;
|
||||||
|
gboolean processing_is_done;
|
||||||
|
gsize num_received_bytes;
|
||||||
|
guint num_bytes_to_process;
|
||||||
|
struct nlmsghdr *header;
|
||||||
|
|
||||||
|
if (io_condition == NM_NETLINK_MONITOR_ERROR_CONDITIONS)
|
||||||
|
return nm_netlink_monitor_error_handler (channel, io_condition, monitor);
|
||||||
|
else if (io_condition == NM_NETLINK_MONITOR_DISCONNECT_CONDITIONS)
|
||||||
|
return nm_netlink_monitor_disconnect_handler (channel, io_condition, monitor);
|
||||||
|
|
||||||
|
g_return_val_if_fail (!(io_condition &
|
||||||
|
~(NM_NETLINK_MONITOR_EVENT_CONDITIONS)),
|
||||||
|
TRUE);
|
||||||
|
|
||||||
|
error = NULL;
|
||||||
|
|
||||||
|
/* Unfortunately, the kernel doesn't return EOF when it's
|
||||||
|
* done sending packets, so read_to_end () gets confused.
|
||||||
|
*
|
||||||
|
* This let's us do sockaddr_nl specific sanity checks anyway.
|
||||||
|
*/
|
||||||
|
//status = g_io_channel_read_to_end (channel, &received_bytes,
|
||||||
|
// &num_received_bytes,
|
||||||
|
// &error);
|
||||||
|
receive_pending_bytes (channel, &received_bytes,
|
||||||
|
&num_received_bytes,
|
||||||
|
&error);
|
||||||
|
if (error != NULL)
|
||||||
|
{
|
||||||
|
g_signal_emit (G_OBJECT (monitor),
|
||||||
|
nm_netlink_monitor_signals[ERROR],
|
||||||
|
0, error);
|
||||||
|
g_error_free (error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Why does NLMSG_* use unsigned ints instead of unsigned longs
|
||||||
|
* or size_t?
|
||||||
|
*/
|
||||||
|
num_bytes_to_process = (guint) num_received_bytes;
|
||||||
|
|
||||||
|
if (num_bytes_to_process < 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
processing_is_done = FALSE;
|
||||||
|
for (header = (struct nlmsghdr *) received_bytes;
|
||||||
|
!processing_is_done &&
|
||||||
|
NLMSG_OK (header, (gint) num_bytes_to_process);
|
||||||
|
header = NLMSG_NEXT (header, num_bytes_to_process))
|
||||||
|
{
|
||||||
|
struct ifinfomsg *interface_info;
|
||||||
|
struct rtattr *attribute;
|
||||||
|
int num_attribute_bytes_to_process;
|
||||||
|
gboolean is_connected;
|
||||||
|
gchar *interface_name;
|
||||||
|
|
||||||
|
g_assert (num_bytes_to_process <= num_received_bytes);
|
||||||
|
|
||||||
|
switch (header->nlmsg_type)
|
||||||
|
{
|
||||||
|
case NLMSG_DONE:
|
||||||
|
processing_is_done = TRUE;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case NLMSG_NOOP:
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case NLMSG_OVERRUN:
|
||||||
|
{
|
||||||
|
error = g_error_new (NM_NETLINK_MONITOR_ERROR,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_BAD_SOCKET_DATA,
|
||||||
|
_("too much data was sent "
|
||||||
|
"over socket and some of "
|
||||||
|
"it was lost"));
|
||||||
|
|
||||||
|
g_signal_emit (G_OBJECT (monitor),
|
||||||
|
nm_netlink_monitor_signals[ERROR],
|
||||||
|
0, error);
|
||||||
|
g_error_free (error);
|
||||||
|
error = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
case NLMSG_ERROR:
|
||||||
|
{
|
||||||
|
struct nlmsgerr *error_message;
|
||||||
|
|
||||||
|
error_message =
|
||||||
|
(struct nlmsgerr *) NLMSG_DATA (header);
|
||||||
|
|
||||||
|
error = g_error_new (NM_NETLINK_MONITOR_ERROR,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_BAD_SOCKET_DATA,
|
||||||
|
"%s", g_strerror (error_message->error));
|
||||||
|
|
||||||
|
g_signal_emit (G_OBJECT (monitor),
|
||||||
|
nm_netlink_monitor_signals[ERROR],
|
||||||
|
0, error);
|
||||||
|
g_error_free (error);
|
||||||
|
error = NULL;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
/* we continue above, so we don't have to stuff
|
||||||
|
* everything below here in here */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface_name = NULL;
|
||||||
|
interface_info = (struct ifinfomsg *) NLMSG_DATA (header);
|
||||||
|
|
||||||
|
/* The !! weirdness is to cannonicalize the value to 0 or 1.
|
||||||
|
*/
|
||||||
|
is_connected = !!((gboolean) (interface_info->ifi_flags & IFF_RUNNING));
|
||||||
|
|
||||||
|
num_attribute_bytes_to_process = IFLA_PAYLOAD (header);
|
||||||
|
|
||||||
|
for (attribute = IFLA_RTA (interface_info);
|
||||||
|
RTA_OK (attribute, num_attribute_bytes_to_process);
|
||||||
|
attribute = RTA_NEXT (attribute, num_attribute_bytes_to_process))
|
||||||
|
{
|
||||||
|
if (attribute->rta_type == IFLA_IFNAME) {
|
||||||
|
interface_name =
|
||||||
|
(gchar *) g_strdup (RTA_DATA (attribute));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interface_name != NULL)
|
||||||
|
{
|
||||||
|
if (is_connected)
|
||||||
|
g_signal_emit (G_OBJECT (monitor),
|
||||||
|
nm_netlink_monitor_signals[INTERFACE_CONNECTED],
|
||||||
|
0, interface_name);
|
||||||
|
else
|
||||||
|
g_signal_emit (G_OBJECT (monitor),
|
||||||
|
nm_netlink_monitor_signals[INTERFACE_DISCONNECTED],
|
||||||
|
0, interface_name);
|
||||||
|
|
||||||
|
g_free (interface_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nm_netlink_monitor_error_handler (GIOChannel *channel,
|
||||||
|
GIOCondition io_condition,
|
||||||
|
NmNetlinkMonitor *monitor)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (!(io_condition &
|
||||||
|
~(NM_NETLINK_MONITOR_ERROR_CONDITIONS)),
|
||||||
|
TRUE);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
nm_netlink_monitor_disconnect_handler (GIOChannel *channel,
|
||||||
|
GIOCondition io_condition,
|
||||||
|
NmNetlinkMonitor *monitor)
|
||||||
|
{
|
||||||
|
|
||||||
|
g_return_val_if_fail (!(io_condition &
|
||||||
|
~(NM_NETLINK_MONITOR_DISCONNECT_CONDITIONS)),
|
||||||
|
TRUE);
|
||||||
|
return FALSE;
|
||||||
|
}
|
89
src/nm-netlink-monitor.h
Normal file
89
src/nm-netlink-monitor.h
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
/* nm-netlink-monitor.h - monitor netlink socket for network
|
||||||
|
* interface eventss
|
||||||
|
*
|
||||||
|
* Copyright (C) 2005 Ray Strode
|
||||||
|
*
|
||||||
|
* 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, 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.
|
||||||
|
*/
|
||||||
|
#ifndef NM_NETLINK_MONITOR_H
|
||||||
|
#define NM_NETLINK_MONITOR_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
#include <glib-object.h>
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
#define NM_TYPE_NETLINK_MONITOR (nm_netlink_monitor_get_type ())
|
||||||
|
#define NM_NETLINK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_NETLINK_MONITOR, NmNetlinkMonitor))
|
||||||
|
#define NM_NETLINK_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_NETLINK_MONITOR, NmNetlinkMonitorClass))
|
||||||
|
#define NM_IS_NETLINK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_NETLINK_MONITOR))
|
||||||
|
#define NM_IS_NETLINK_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_NETLINK_MONITOR))
|
||||||
|
#define NM_NETLINK_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_NETLINK_MONITOR, NmNetlinkMonitorClass))
|
||||||
|
#define NM_NETLINK_MONITOR_ERROR (nm_netlink_monitor_error_quark ())
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct _NmNetlinkMonitor NmNetlinkMonitor;
|
||||||
|
typedef struct _NmNetlinkMonitorClass NmNetlinkMonitorClass;
|
||||||
|
typedef struct _NmNetlinkMonitorPrivate NmNetlinkMonitorPrivate;
|
||||||
|
typedef enum _NmNetlinkMonitorError NmNetlinkMonitorError;
|
||||||
|
|
||||||
|
struct _NmNetlinkMonitor
|
||||||
|
{
|
||||||
|
GObject parent;
|
||||||
|
|
||||||
|
/*< private >*/
|
||||||
|
NmNetlinkMonitorPrivate *priv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _NmNetlinkMonitorClass
|
||||||
|
{
|
||||||
|
GObjectClass parent_class;
|
||||||
|
|
||||||
|
/* Signals */
|
||||||
|
void (* interface_connected) (NmNetlinkMonitor *monitor,
|
||||||
|
const gchar *interface);
|
||||||
|
void (* interface_disconnected) (NmNetlinkMonitor *monitor,
|
||||||
|
const gchar *interface);
|
||||||
|
void (* error) (NmNetlinkMonitor *monitor,
|
||||||
|
GError *error);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum _NmNetlinkMonitorError
|
||||||
|
{
|
||||||
|
NM_NETLINK_MONITOR_ERROR_GENERIC = 0,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_OPENING_SOCKET,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_BINDING_TO_SOCKET,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_BAD_SENDER,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_BAD_SOCKET_DATA,
|
||||||
|
NM_NETLINK_MONITOR_ERROR_READING_SOCKET
|
||||||
|
};
|
||||||
|
|
||||||
|
GType nm_netlink_monitor_get_type (void) G_GNUC_CONST;
|
||||||
|
GQuark nm_netlink_monitor_error_quark (void) G_GNUC_CONST;
|
||||||
|
|
||||||
|
NmNetlinkMonitor *nm_netlink_monitor_new (void);
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_netlink_monitor_open_connection (NmNetlinkMonitor *monitor,
|
||||||
|
GError **error);
|
||||||
|
|
||||||
|
void nm_netlink_monitor_attach (NmNetlinkMonitor *monitor,
|
||||||
|
GMainContext *context);
|
||||||
|
void nm_netlink_monitor_detach (NmNetlinkMonitor *monitor);
|
||||||
|
|
||||||
|
void nm_netlink_monitor_request_status (NmNetlinkMonitor *monitor);
|
||||||
|
G_END_DECLS
|
||||||
|
#endif /* NM_NETLINK_MONITOR_H */
|
Reference in New Issue
Block a user