2004-07-06 Dan Williams <dcbw@redhat.com>

* src/NetworkManager.c
		- Add IPv4 address update for active device during link state check
		- Don't allow wireless cards to be powered up when they are not the
			active device

	* src/NetworkManagerDbus.c
	  src/NetworkManagerDbus.h
		- Add DBUS IPv4 address change signal
		- Add DBUS IPv4 address get method for devices

	* src/NetworkManagerDevice.c
		- Make setting the WEP key actually work
		- Move IP address get/set/update stuff here, per-device
		- Power down/bring down wireless device when deactivated
		- For scanning wireless devices, if first scan returned ENODATA, try again

	* src/NetworkManagerPolicy.c
		- Only set the WEP key for an allowed access point if there is one.
			We were setting it to be blank if one wasn't specified.

	* src/NetworkManagerUtils.h
	  src/NetworkManagerUtils.c
		- Move the IP address stuff to NetworkManagerDevice.c

	* dispatcher-daemon/NetworkManagerDispatcher.c
		- Add device IPv4 address change notification stuff


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@13 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2004-07-06 04:45:00 +00:00
parent 019e2337bf
commit 0073d4dd55
9 changed files with 224 additions and 74 deletions

View file

@ -1,3 +1,32 @@
2004-07-06 Dan Williams <dcbw@redhat.com>
* src/NetworkManager.c
- Add IPv4 address update for active device during link state check
- Don't allow wireless cards to be powered up when they are not the
active device
* src/NetworkManagerDbus.c
src/NetworkManagerDbus.h
- Add DBUS IPv4 address change signal
- Add DBUS IPv4 address get method for devices
* src/NetworkManagerDevice.c
- Make setting the WEP key actually work
- Move IP address get/set/update stuff here, per-device
- Power down/bring down wireless device when deactivated
- For scanning wireless devices, if first scan returned ENODATA, try again
* src/NetworkManagerPolicy.c
- Only set the WEP key for an allowed access point if there is one.
We were setting it to be blank if one wasn't specified.
* src/NetworkManagerUtils.h
src/NetworkManagerUtils.c
- Move the IP address stuff to NetworkManagerDevice.c
* dispatcher-daemon/NetworkManagerDispatcher.c
- Add device IPv4 address change notification stuff
2004-07-05 Dan Williams <dcbw@redhat.com>
* dispatcher-daemon/NetworkManagerDispatcher.c

View file

@ -36,10 +36,15 @@ enum NMDAction
{
NMD_DEVICE_DONT_KNOW,
NMD_DEVICE_NOW_INACTIVE,
NMD_DEVICE_NOW_ACTIVE
NMD_DEVICE_NOW_ACTIVE,
NMD_DEVICE_IP4_ADDRESS_CHANGE
};
typedef enum NMDAction NMDAction;
#define NIPQUAD(addr) ((unsigned char)(addr)), \
((unsigned char)(addr>>8)), \
((unsigned char)(addr>>16)), \
((unsigned char)(addr>>24))
/*
* nmd_execute_scripts
@ -47,7 +52,7 @@ typedef enum NMDAction NMDAction;
* Call scripts in /etc/NetworkManager.d when devices go down or up
*
*/
void nmd_execute_scripts (NMDAction action, char *iface_name)
void nmd_execute_scripts (NMDAction action, char *iface_name, guint32 new_ip4_address)
{
DIR *dir = opendir ("/etc/NetworkManager.d");
struct dirent *ent;
@ -77,9 +82,16 @@ void nmd_execute_scripts (NMDAction action, char *iface_name)
{
char cmd[500];
snprintf (cmd, 499, "%s %s %s", path, iface_name,
(action == NMD_DEVICE_NOW_INACTIVE ? "down" :
(action == NMD_DEVICE_NOW_ACTIVE ? "up" : "error")));
if ((action == NMD_DEVICE_NOW_INACTIVE) || (action == NMD_DEVICE_NOW_ACTIVE))
{
snprintf (cmd, 499, "%s %s %s", path, iface_name,
(action == NMD_DEVICE_NOW_INACTIVE ? "down" :
(action == NMD_DEVICE_NOW_ACTIVE ? "up" : "error")));
}
else if (action == NMD_DEVICE_IP4_ADDRESS_CHANGE)
{
snprintf (cmd, 499, "%s %s %u.%u.%u.%u", path, iface_name, NIPQUAD (new_ip4_address));
}
system (cmd);
}
}
@ -145,6 +157,55 @@ char * nmd_get_device_name (DBusConnection *connection, char *path)
}
/*
* nmd_get_device_ip4_address
*
* Queries NetworkManager for the IPv4 address of a device, specified by a device path
*/
guint32 nmd_get_device_ip4_address (DBusConnection *connection, char *path)
{
DBusMessage *message;
DBusMessage *reply;
DBusMessageIter iter;
DBusError error;
guint32 ret_address;
message = dbus_message_new_method_call ("org.freedesktop.NetworkManager",
path,
"org.freedesktop.NetworkManager",
"getIP4Address");
if (message == NULL)
{
fprintf (stderr, "Couldn't allocate the dbus message\n");
return (0);
}
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_message_unref (message);
return (0);
}
if (reply == NULL)
{
fprintf( stderr, "dbus reply message was NULL\n" );
dbus_message_unref (message);
return (0);
}
/* now analyze reply */
dbus_message_iter_init (reply, &iter);
ret_address = dbus_message_iter_get_uint32 (&iter);
dbus_message_unref (reply);
dbus_message_unref (message);
return (ret_address);
}
/*
* nmd_dbus_filter
*
@ -161,7 +222,9 @@ static DBusHandlerResult nmd_dbus_filter (DBusConnection *connection, DBusMessag
dbus_error_init (&error);
object_path = dbus_message_get_path (message);
if (dbus_message_is_signal (message, "org.freedesktop.NetworkManager", "DeviceNoLongerActive"))
if (dbus_message_is_signal (message, "org.freedesktop.NetworkManager", "DeviceIP4AddressChange"))
action = NMD_DEVICE_IP4_ADDRESS_CHANGE;
else if (dbus_message_is_signal (message, "org.freedesktop.NetworkManager", "DeviceNoLongerActive"))
action = NMD_DEVICE_NOW_INACTIVE;
else if (dbus_message_is_signal (message, "org.freedesktop.NetworkManager", "DeviceNowActive"))
action = NMD_DEVICE_NOW_ACTIVE;
@ -171,12 +234,21 @@ static DBusHandlerResult nmd_dbus_filter (DBusConnection *connection, DBusMessag
if (dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev_object_path, DBUS_TYPE_INVALID))
{
char *dev_iface_name = nmd_get_device_name (connection, dev_object_path);
guint32 dev_ip4_address = nmd_get_device_ip4_address (connection, dev_object_path);
fprintf (stderr, "Device %s (%s) is now %s.\n", dev_object_path, dev_iface_name,
if (action == NMD_DEVICE_NOW_ACTIVE || action == NMD_DEVICE_NOW_INACTIVE)
{
fprintf (stderr, "Device %s (%s) is now %s.\n", dev_object_path, dev_iface_name,
(action == NMD_DEVICE_NOW_INACTIVE ? "down" :
(action == NMD_DEVICE_NOW_ACTIVE ? "up" : "error")));
}
else if (action == NMD_DEVICE_IP4_ADDRESS_CHANGE)
{
fprintf (stderr, "Device %s (%s) now has address %u.%u.%u.%u\n", dev_object_path, dev_iface_name,
NIPQUAD(dev_ip4_address));
}
nmd_execute_scripts (action, dev_iface_name);
nmd_execute_scripts (action, dev_iface_name, dev_ip4_address);
free (dev_iface_name);
dbus_free (dev_object_path);

View file

@ -100,11 +100,10 @@ NMDevice * nm_create_device_and_add_to_list (NMData *data, const char *udi)
/* Initialize and bring up all new devices */
if (nm_device_get_iface_type (dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET)
{
/* Disable WEP */
/* Disable WEP, take device down */
nm_device_bring_down (dev);
nm_device_set_wep_key (dev, NULL);
nm_device_set_essid (dev, NULL);
nm_device_bring_up (dev);
}
else
{
@ -334,19 +333,31 @@ gboolean nm_link_state_monitor (gpointer user_data)
if (dev)
{
/* Make sure the device is up first. It doesn't have to have
* an IP address or anything, but most devices cannot do link
* detection when they are down.
*/
if (!nm_device_is_up (dev))
nm_device_bring_up (dev);
if ( dev != data->active_device
&& (nm_device_get_iface_type (dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET))
{
/* If its a wireless card, make sure its down. Saves power. */
if (nm_device_is_up (dev))
nm_device_bring_down (dev);
}
nm_device_update_link_active (dev, FALSE);
if ((nm_device_get_iface_type (dev) == NM_IFACE_TYPE_WIRED_ETHERNET))
{
/* Make sure the device is up first. It doesn't have to have
* an IP address or anything, but most wired devices cannot do link
* detection when they are down.
*/
if (!nm_device_is_up (dev))
nm_device_bring_up (dev);
nm_device_update_link_active (dev, FALSE);
}
/* Check if the device's IP address has changed
* (ie dhcp lease renew/address change)
*/
/* Implement me */
if (dev == data->active_device)
nm_device_update_ip4_address (dev);
}
element = g_slist_next (element);

View file

@ -413,6 +413,35 @@ void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev
}
/*
* nm_dbus_signal_device_ip4_address_change
*
* Notifies the bus that a particular device's IPv4 address changed.
*
*/
void nm_dbus_signal_device_ip4_address_change (DBusConnection *connection, NMDevice *dev)
{
DBusMessage *message;
unsigned char *object_path = g_new0 (unsigned char, 100);
message = dbus_message_new_signal (NM_DBUS_NM_OBJECT_PATH_PREFIX, NM_DBUS_NM_NAMESPACE, "DeviceIP4AddressChange");
if (!message)
{
NM_DEBUG_PRINT ("nm_dbus_signal_device_ip4_address_change(): Not enough memory for new dbus message!\n");
return;
}
nm_dbus_get_object_path_from_device (dev, object_path, 100, FALSE);
dbus_message_append_args (message, DBUS_TYPE_STRING, object_path, DBUS_TYPE_INVALID);
g_free (object_path);
if (!dbus_connection_send (connection, message, NULL))
NM_DEBUG_PRINT ("nm_dbus_signal_device_ip4_address_change(): Could not raise the IP4AddressChange signal!\n");
dbus_message_unref (message);
}
/*
* nm_dbus_devices_handle_networks_request
*
@ -502,6 +531,8 @@ static DBusMessage *nm_dbus_devices_handle_request (DBusConnection *connection,
dbus_message_iter_append_string (&iter, nm_device_get_iface (dev));
else if (strcmp ("getType", request) == 0)
dbus_message_iter_append_int32 (&iter, nm_device_get_iface_type (dev));
else if (strcmp ("getIP4Address", request) == 0)
dbus_message_iter_append_uint32 (&iter, nm_device_get_ip4_address (dev));
else if (strcmp ("getActiveNetwork", request) == 0)
{
NMAccessPoint *ap = NULL;

View file

@ -38,4 +38,6 @@ void nm_dbus_signal_device_no_longer_active (DBusConnection *connection, NMDe
void nm_dbus_signal_device_now_active (DBusConnection *connection, NMDevice *dev);
void nm_dbus_signal_device_ip4_address_change(DBusConnection *connection, NMDevice *dev);
#endif

View file

@ -187,7 +187,7 @@ struct NMDevice
gchar *iface;
NMIfaceType iface_type;
gboolean link_active;
guint32 ip_address;
guint32 ip4_address;
/* FIXME: ipv6 address too */
NMDeviceOptions dev_options;
};
@ -373,7 +373,7 @@ void nm_device_update_link_active (NMDevice *dev, gboolean check_mii)
iwlib_socket = iw_sockets_open ();
if (iw_get_ext (iwlib_socket, nm_device_get_iface (dev), SIOCGIWAP, &wrq) >= 0)
link_active = nm_ethernet_address_is_valid (&(wrq.u.ap_addr.sa_data));
link_active = nm_ethernet_address_is_valid ((struct ether_addr *)(&(wrq.u.ap_addr.sa_data)));
close (iwlib_socket);
break;
}
@ -521,7 +521,7 @@ void nm_device_set_wep_key (NMDevice *dev, const char *wep_key)
int err;
struct iwreq wreq;
int keylen;
unsigned char safe_key[IW_ENCODING_TOKEN_MAX];
unsigned char safe_key[IW_ENCODING_TOKEN_MAX + 1];
gboolean set_key = FALSE;
char *it = NULL;
@ -552,10 +552,12 @@ void nm_device_set_wep_key (NMDevice *dev, const char *wep_key)
}
else
{
keylen = iw_in_key_full(iwlib_socket, nm_device_get_iface (dev), "", safe_key, &wreq.u.data.flags);
unsigned char parsed_key[IW_ENCODING_TOKEN_MAX + 1];
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.pointer = (caddr_t) safe_key;
wreq.u.data.pointer = (caddr_t) &parsed_key;
wreq.u.data.length = keylen;
set_key = TRUE;
}
@ -569,7 +571,7 @@ void nm_device_set_wep_key (NMDevice *dev, const char *wep_key)
}
close (iwlib_socket);
}
} else NM_DEBUG_PRINT ("nm_device_set_wep_key(): could not get wireless control socket.\n");
}
@ -585,17 +587,37 @@ guint32 nm_device_get_ip4_address(NMDevice *dev)
int socket;
g_return_val_if_fail (dev != NULL, 0);
g_return_val_if_fail (nm_device_get_iface (dev) != NULL, 0);
return (dev->ip4_address);
}
void nm_device_update_ip4_address (NMDevice *dev)
{
NMData *data = nm_get_global_data ();
guint32 new_address;
struct ifreq req;
int socket;
g_return_if_fail (data != NULL);
g_return_if_fail (dev != NULL);
g_return_if_fail (nm_device_get_iface (dev) != NULL);
socket = nm_get_network_control_socket ();
if (socket < 0)
return (0);
return;
strncpy ((char *)(&req.ifr_name), nm_device_get_iface (dev), 16); // 16 == IF_NAMESIZE
if (ioctl (socket, SIOCGIFADDR, &req) != 0)
return (0);
return;
return (((struct sockaddr_in *)(&req.ifr_addr))->sin_addr.s_addr);
new_address = ((struct sockaddr_in *)(&req.ifr_addr))->sin_addr.s_addr;
/* If the new address is different, send an IP4AddressChanged signal on the bus */
if (new_address != nm_device_get_ip4_address (dev))
{
nm_dbus_signal_device_ip4_address_change (data->dbus_connection, dev);
dev->ip4_address = new_address;
}
}
@ -734,7 +756,7 @@ gboolean nm_device_activate (NMDevice *dev)
}
/* If there is a desired AP to connect to, use that essid and possible WEP key */
if (nm_ap_get_essid (ap) != NULL)
if (ap && nm_ap_get_essid (ap) != NULL)
{
nm_device_bring_down (dev);
@ -744,7 +766,8 @@ gboolean nm_device_activate (NMDevice *dev)
nm_device_set_wep_key (dev, NULL);
if (nm_ap_get_wep_key (ap))
nm_device_set_wep_key (dev, nm_ap_get_wep_key (ap));
}
} else NM_DEBUG_PRINT_1 ("nm_device_activate(%s) could not get best ap even after scan\n", nm_device_get_iface (dev));
NM_DEBUG_PRINT_2 ("nm_device_activate(%s) using essid '%s'\n", nm_device_get_iface (dev), nm_ap_get_essid (ap));
}
@ -848,6 +871,15 @@ gboolean nm_device_deactivate (NMDevice *dev)
nm_dbus_signal_device_no_longer_active (data->dbus_connection, dev);
/* Clean up stuff, don't leave the card associated or up */
if (nm_device_get_iface_type (dev) == NM_IFACE_TYPE_WIRELESS_ETHERNET)
{
nm_device_set_essid (dev, "");
nm_device_set_wep_key (dev, NULL);
nm_device_bring_down (dev);
}
return (success);
}
@ -1007,6 +1039,20 @@ static void nm_device_do_normal_scan (NMDevice *dev)
nm_device_ap_list_clear (dev);
err = iw_scan (iwlib_socket, nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
if ((err == -1) && (errno == ENODATA))
{
/* Card hasn't had time yet to compile full access point list.
* Give it some more time and scan again. If that doesn't work
* give up.
*/
g_usleep (G_USEC_PER_SEC / 2);
err = iw_scan (iwlib_socket, nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
if (err == -1)
{
close (iwlib_socket);
return;
}
}
/* Iterate over scan results and pick a "most" preferred access point. */
tmp_ap = scan_results.result;
@ -1128,7 +1174,7 @@ fprintf( stderr, "Looking at AP %s\n", nm_ap_get_essid (ap) );
nm_device_set_wep_key (dev, NULL);
/* Wait a bit for association */
g_usleep (G_USEC_PER_SEC * 2);
g_usleep (G_USEC_PER_SEC);
/* Do we have a valid MAC address? */
nm_device_get_ap_address (dev, &cur_ap_addr);

View file

@ -324,7 +324,8 @@ void nm_policy_update_allowed_access_points (NMData *data)
ap = nm_ap_new ();
nm_ap_set_priority (ap, prio_num);
nm_ap_set_essid (ap, essid);
nm_ap_set_wep_key (ap, wep_key);
if (strlen (wep_key) > 0)
nm_ap_set_wep_key (ap, wep_key);
data->allowed_ap_list = g_slist_append (data->allowed_ap_list, ap);
/*

View file

@ -171,42 +171,3 @@ void nm_dispose_scan_results (wireless_scan *result_list)
}
}
/*
* nm_get_ip4_address_for_device
*
* Get a device's IPv4 address
*
*/
guint32 nm_get_ip4_address_for_device(NMDevice *dev)
{
struct ifreq req;
int socket;
g_return_val_if_fail (dev != NULL, 0);
g_return_val_if_fail (nm_device_get_iface (dev) != NULL, 0);
socket = nm_get_network_control_socket ();
if (socket < 0)
return (0);
strncpy ((char *)(&req.ifr_name), nm_device_get_iface (dev), 16); // 16 == IF_NAMESIZE
if (ioctl (socket, SIOCGIFADDR, &req) != 0)
return (0);
return (((struct sockaddr_in *)(&req.ifr_addr))->sin_addr.s_addr);
}
/*
* nm_get_ip6_address_for_device
*
* Get a device's IPv6 address
*
*/
void nm_get_ip6_address_for_device(NMDevice *dev)
{
/* FIXME
* Implement
*/
}

View file

@ -48,7 +48,4 @@ gboolean nm_ethernet_address_is_valid (struct ether_addr *test_addr);
void nm_dispose_scan_results (wireless_scan *result_list);
guint32 nm_get_ipv4_address_for_device (NMDevice *dev);
void nm_get_ipv6_address_for_device (NMDevice *dev);
#endif