2004-12-17 Dan Williams <dcbw@redhat.com>

* Ad Ad-Hoc networking mode support.  In Ad-Hoc mode, we only try to get
		link-local addresses instead of doing DHCP.

	* In the panel applet, there's a new "Create new Wireless Network..." item

	* The panel applet also sticks around now even if NetworkManager dies, but
		it doesn't hide its icon when NM isn't around.  Not hiding the icon is
		a bug, I'll fix that later.

	* We also don't use 'nscd' anymore in the RH backend, it was impeding name
		lookups after a switch rather than actually doing them.

	* Clean up some of those warnings in nm_ap_list_* functions

	* Delay between scans changed to 15s instead of 10s


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@342 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2004-12-17 17:16:22 +00:00
parent cd475e6d0c
commit e96c5c2967
24 changed files with 982 additions and 227 deletions

View file

@ -1,3 +1,21 @@
2004-12-17 Dan Williams <dcbw@redhat.com>
* Ad Ad-Hoc networking mode support. In Ad-Hoc mode, we only try to get
link-local addresses instead of doing DHCP.
* In the panel applet, there's a new "Create new Wireless Network..." item
* The panel applet also sticks around now even if NetworkManager dies, but
it doesn't hide its icon when NM isn't around. Not hiding the icon is
a bug, I'll fix that later.
* We also don't use 'nscd' anymore in the RH backend, it was impeding name
lookups after a switch rather than actually doing them.
* Clean up some of those warnings in nm_ap_list_* functions
* Delay between scans changed to 15s instead of 10s
2004-12-15 Dan Williams <dcbw@redhat.com>
Patch from Tom Parker

View file

@ -822,6 +822,35 @@ static DBusHandlerResult nmi_dbus_filter (DBusConnection *connection, DBusMessag
appeared = TRUE;
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "WirelessNetworkDisappeared"))
disappeared = TRUE;
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceActivationFailed"))
{
char *dev = NULL;
char *net = NULL;
DBusError error;
dbus_error_init (&error);
if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev, DBUS_TYPE_STRING, &net, DBUS_TYPE_INVALID))
{
if (dbus_error_is_set (&error))
dbus_error_free (&error);
dbus_error_init (&error);
dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev, DBUS_TYPE_INVALID);
}
if (dbus_error_is_set (&error))
dbus_error_free (&error);
if (dev && net)
{
char *string = g_strdup_printf ("Connection to the wireless network '%s' failed.\n", net);
nmi_show_warning_dialog (TRUE, string);
g_free (string);
}
else if (dev)
nmi_show_warning_dialog (TRUE, "Connection to the wired network failed.\n");
dbus_free (dev);
dbus_free (net);
}
#if 0
else if (dbus_message_is_signal (message, DBUS_INTERFACE_ORG_FREEDESKTOP_DBUS, "ServiceDeleted"))
{
char *service;
@ -870,56 +899,8 @@ static DBusHandlerResult nmi_dbus_filter (DBusConnection *connection, DBusMessag
if (dbus_error_is_set (&error))
dbus_error_free (&error);
}
else if (dbus_message_is_signal (message, NM_DBUS_INTERFACE, "DeviceActivationFailed"))
{
char *dev = NULL;
char *net = NULL;
DBusError error;
dbus_error_init (&error);
if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev, DBUS_TYPE_STRING, &net, DBUS_TYPE_INVALID))
{
if (dbus_error_is_set (&error))
dbus_error_free (&error);
dbus_error_init (&error);
dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev, DBUS_TYPE_INVALID);
}
if (dbus_error_is_set (&error))
dbus_error_free (&error);
if (dev && net)
{
char *string = g_strdup_printf ("Connection to the wireless network '%s' failed.\n", net);
nmi_show_warning_dialog (TRUE, string);
g_free (string);
}
else if (dev)
nmi_show_warning_dialog (TRUE, "Connection to the wired network failed.\n");
dbus_free (dev);
dbus_free (net);
}
if (appeared || disappeared)
{
dbus_error_init (&error);
if (dbus_message_get_args (message, &error,
DBUS_TYPE_STRING, &dev_path,
DBUS_TYPE_STRING, &ap_path,
DBUS_TYPE_INVALID))
{
#if 0
if (appeared)
nmi_new_networks_dialog_add_network (ap_path, info);
else if (disappeared)
nmi_new_networks_dialog_add_network (ap_path, info);
#endif
dbus_free (dev_path);
dbus_free (ap_path);
handled = TRUE;
}
}
return (handled ? DBUS_HANDLER_RESULT_HANDLED : DBUS_HANDLER_RESULT_NOT_YET_HANDLED);
}
@ -969,8 +950,10 @@ int nmi_dbus_service_init (DBusConnection *dbus_connection, NMIAppInfo *info)
exit (0);
}
#if 0
if (!nmi_dbus_nm_is_running (dbus_connection))
return (-1);
#endif
if (!dbus_connection_register_object_path (dbus_connection, NMI_DBUS_PATH, &nmi_vtable, info))
{

View file

@ -640,14 +640,12 @@ static void nmwa_menu_add_device_item (GtkWidget *menu, NetworkDevice *device, g
}
/* FIXME: We really should break this dialog into its own file. This function is too long.
*/
static void
custom_essid_item_selected (GtkWidget *menu_item, NMWirelessApplet *applet)
static void custom_essid_item_selected (GtkWidget *menu_item, NMWirelessApplet *applet)
{
nmwa_other_network_dialog_run (applet);
nmwa_other_network_dialog_run (applet, FALSE);
}
static void nmwa_menu_add_custom_essid_item (GtkWidget *menu, NMWirelessApplet *applet)
{
GtkWidget *menu_item;
@ -663,6 +661,26 @@ static void nmwa_menu_add_custom_essid_item (GtkWidget *menu, NMWirelessApplet *
}
static void new_network_item_selected (GtkWidget *menu_item, NMWirelessApplet *applet)
{
nmwa_other_network_dialog_run (applet, TRUE);
}
static void nmwa_menu_add_create_network_item (GtkWidget *menu, NMWirelessApplet *applet)
{
GtkWidget *menu_item;
GtkWidget *label;
menu_item = gtk_menu_item_new ();
label = gtk_label_new (_("Create new Wireless Network..."));
gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
gtk_container_add (GTK_CONTAINER (menu_item), label);
gtk_widget_show_all (menu_item);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
g_signal_connect (menu_item, "activate", G_CALLBACK (new_network_item_selected), applet);
}
/*
* nmwa_menu_device_add_networks
*
@ -813,9 +831,10 @@ static void nmwa_menu_add_devices (GtkWidget *menu, NMWirelessApplet *applet)
if (n_wireless_interfaces > 0)
{
/* Add the 'Select a custom esssid entry */
/* Add the "Other wireless network..." entry */
nmwa_menu_add_separator_item (menu);
nmwa_menu_add_custom_essid_item (menu, applet);
nmwa_menu_add_create_network_item (menu, applet);
}
g_mutex_unlock (applet->data_mutex);

View file

@ -548,6 +548,39 @@ void nmwa_dbus_set_device (DBusConnection *connection, const NetworkDevice *dev,
}
/*
* nmwa_dbus_create_network
*
* Tell NetworkManager to create an Ad-Hoc wireless network
*
*/
void nmwa_dbus_create_network (DBusConnection *connection, const NetworkDevice *dev, const WirelessNetwork *network,
NMEncKeyType key_type, const char *passphrase)
{
DBusMessage *message;
g_return_if_fail (connection != NULL);
g_return_if_fail (dev != NULL);
g_return_if_fail (dev->type == DEVICE_TYPE_WIRELESS_ETHERNET);
if ((message = dbus_message_new_method_call (NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, "createWirelessNetwork")))
{
if (network && network->essid)
{
fprintf (stderr, "Creating network '%s' %s passphrase on device '%s'.\n", network->essid, passphrase ? "with" : "without", dev->nm_device);
dbus_message_append_args (message, DBUS_TYPE_STRING, dev->nm_device,
DBUS_TYPE_STRING, network->essid,
DBUS_TYPE_STRING, (passphrase ? passphrase : ""),
DBUS_TYPE_INT32, key_type,
DBUS_TYPE_INVALID);
}
dbus_connection_send (connection, message, NULL);
}
else
fprintf (stderr, "nm_dbus_set_device(): Couldn't allocate the dbus message\n");
}
/*
* wireless_network_ref
*

View file

@ -42,6 +42,10 @@ void nmwa_dbus_set_device (DBusConnection *connection, const NetworkDevice
const WirelessNetwork *network, NMEncKeyType key_type,
const char *passphrase);
void nmwa_dbus_create_network (DBusConnection *connection, const NetworkDevice *dev,
const WirelessNetwork *network, NMEncKeyType key_type,
const char *passphrase);
WirelessNetwork * wireless_network_new_with_essid (const char *essid);
void wireless_network_unref (WirelessNetwork *net);

View file

@ -193,7 +193,7 @@ void nmwa_other_network_dialog_enc_check_toggled (GtkWidget *enc_check_button, g
}
static GtkDialog *nmwa_other_network_dialog_init (GladeXML *xml, NMWirelessApplet *applet, NetworkDevice **def_dev)
static GtkDialog *nmwa_other_network_dialog_init (GladeXML *xml, NMWirelessApplet *applet, NetworkDevice **def_dev, gboolean create_network)
{
GtkDialog *dialog = NULL;
GtkWidget *essid_entry;
@ -220,9 +220,18 @@ static GtkDialog *nmwa_other_network_dialog_init (GladeXML *xml, NMWirelessApple
gtk_widget_set_sensitive (button, FALSE);
g_signal_connect (essid_entry, "changed", G_CALLBACK (update_button_cb), xml);
label = g_strdup_printf ("<span size=\"larger\" weight=\"bold\">%s</span>\n\n%s",
if (create_network)
{
label = g_strdup_printf ("<span size=\"larger\" weight=\"bold\">%s</span>\n\n%s",
_("Create new wireless network"),
_("Enter the ESSID and security settings of the wireless network you wish to create."));
}
else
{
label = g_strdup_printf ("<span size=\"larger\" weight=\"bold\">%s</span>\n\n%s",
_("Custom wireless network"),
_("Enter the ESSID of the wireless network to which you wish to connect."));
}
gtk_label_set_markup (GTK_LABEL (glade_xml_get_widget (xml, "essid_label")), label);
/* Do we have multiple Network cards? */
@ -287,7 +296,7 @@ static GtkDialog *nmwa_other_network_dialog_init (GladeXML *xml, NMWirelessApple
}
void nmwa_other_network_dialog_run (NMWirelessApplet *applet)
void nmwa_other_network_dialog_run (NMWirelessApplet *applet, gboolean create_network)
{
gchar *glade_file;
GtkDialog *dialog;
@ -315,7 +324,7 @@ void nmwa_other_network_dialog_run (NMWirelessApplet *applet)
return;
}
if (!(dialog = nmwa_other_network_dialog_init (xml, applet, &def_dev)))
if (!(dialog = nmwa_other_network_dialog_init (xml, applet, &def_dev, create_network)))
return;
/* Run the dialog */
@ -375,7 +384,10 @@ void nmwa_other_network_dialog_run (NMWirelessApplet *applet)
}
applet->applet_state = APPLET_STATE_WIRELESS_CONNECTING;
applet->forcing_device = TRUE;
nmwa_dbus_set_device (applet->connection, def_dev, net, nm_key_type, passphrase);
if (create_network)
nmwa_dbus_create_network (applet->connection, def_dev, net, nm_key_type, passphrase);
else
nmwa_dbus_set_device (applet->connection, def_dev, net, nm_key_type, passphrase);
network_device_unref (def_dev);
wireless_network_unref (net);
}

View file

@ -26,6 +26,6 @@
#ifndef NM_WIRELESS_APPLET_OTHER_NETWORK_DIALOG_H
#define NM_WIRELESS_APPLET_OTHER_NETWORK_DIALOG_H
void nmwa_other_network_dialog_run (NMWirelessApplet *applet);
void nmwa_other_network_dialog_run (NMWirelessApplet *applet, gboolean create_network);
#endif

View file

@ -727,7 +727,7 @@ int main( int argc, char *argv[] )
policy_source_id = g_source_attach (policy_source, nm_data->main_context);
/* Keep a current list of access points */
wscan_source = g_timeout_source_new (10000);
wscan_source = g_timeout_source_new (15000);
g_source_set_callback (wscan_source, nm_wireless_scan_monitor, nm_data, NULL);
wscan_source_id = g_source_attach (wscan_source, nm_data->main_context);

View file

@ -41,6 +41,7 @@ struct NMAccessPoint
gboolean matched; /* used in ap list diffing */
gboolean trusted;
gboolean artificial; /* Whether or not the AP is from a scan */
gboolean user_created; /* Whether or not the AP was created by the user with "Create network..." */
/* Things from user prefs */
char *enc_key;
@ -104,7 +105,7 @@ NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *src_ap)
memcpy (new_addr, src_ap->address, sizeof (struct ether_addr));
new_ap->address = new_addr;
}
new_ap->mode = NETWORK_MODE_INFRA;
new_ap->mode = src_ap->mode;
new_ap->strength = src_ap->strength;
new_ap->freq = src_ap->freq;
new_ap->rate = src_ap->rate;
@ -456,6 +457,28 @@ void nm_ap_set_artificial (NMAccessPoint *ap, gboolean artificial)
}
/*
* Get/Set functions to indicate that an access point is
* user-created, ie whether or not its a network filled with
* information from the user and intended to create a new Ad-Hoc
* wireless network.
*
*/
gboolean nm_ap_get_user_created (NMAccessPoint *ap)
{
g_return_val_if_fail (ap != NULL, FALSE);
return (ap->user_created);
}
void nm_ap_set_user_created (NMAccessPoint *ap, gboolean user_created)
{
g_return_if_fail (ap != NULL);
ap->user_created = user_created;
}
/*
* Return the encryption method the user specified for this access point.
*

View file

@ -74,6 +74,9 @@ void nm_ap_set_trusted (NMAccessPoint *ap, gboolean trusted);
gboolean nm_ap_get_artificial (NMAccessPoint *ap);
void nm_ap_set_artificial (NMAccessPoint *ap, gboolean artificial);
gboolean nm_ap_get_user_created (NMAccessPoint *ap);
void nm_ap_set_user_created (NMAccessPoint *ap, gboolean user_created);
const NMEncKeyType nm_ap_get_enc_method (NMAccessPoint *ap);
GSList * nm_ap_get_user_addresses (NMAccessPoint *ap);

View file

@ -477,8 +477,8 @@ void nm_ap_list_copy_properties (NMAccessPointList *dest, NMAccessPointList *sou
NMAPListIter *iter;
NMAccessPoint *dest_ap;
g_return_if_fail (dest != NULL);
g_return_if_fail (source != NULL);
if (!dest || !source)
return;
if ((iter = nm_ap_list_iter_new (dest)))
{
@ -511,8 +511,8 @@ void nm_ap_list_copy_essids_by_address (NMAccessPointList *dest, NMAccessPointLi
NMAPListIter *iter;
NMAccessPoint *dest_ap;
g_return_if_fail (dest != NULL);
g_return_if_fail (source != NULL);
if (!dest || !source)
return;
if ((iter = nm_ap_list_iter_new (dest)))
{

View file

@ -79,6 +79,39 @@ static void nm_device_dhcp_configure (NMDevice *dev)
}
/*
* nm_device_do_autoip
*
* Get and assign a Link Local Address.
*
*/
gboolean nm_device_do_autoip (NMDevice *dev)
{
struct in_addr ip;
gboolean success = FALSE;
g_return_val_if_fail (dev != NULL, FALSE);
if ((success = get_autoip (dev, &ip)))
{
#define LINKLOCAL_BCAST 0xa9feffff
int temp = ip.s_addr;
nm_system_device_set_ip4_address (dev, temp);
temp = ntohl (0xFFFF0000);
nm_system_device_set_ip4_netmask (dev, temp);
temp = ntohl (LINKLOCAL_BCAST);
nm_system_device_set_ip4_broadcast (dev, temp);
/* Set all traffic to go through the device */
nm_system_flush_loopback_routes ();
nm_system_device_add_default_route_via_device (dev);
}
return (success);
}
/*
* nm_device_dhcp_request
*
@ -89,7 +122,6 @@ int nm_device_dhcp_request (NMDevice *dev)
{
dhcp_client_options opts;
int err;
struct in_addr ip;
g_return_val_if_fail (dev != NULL, RET_DHCP_ERROR);
@ -107,32 +139,16 @@ int nm_device_dhcp_request (NMDevice *dev)
/* Start off in DHCP INIT state, get a completely new IP address
* and settings.
*/
err = dhcp_init (dev->dhcp_iface);
switch (err)
if ((err = dhcp_init (dev->dhcp_iface)) == RET_DHCP_BOUND)
{
case RET_DHCP_BOUND:
nm_device_dhcp_configure (dev);
nm_device_update_ip4_address (dev);
nm_device_dhcp_setup_timeouts (dev);
break;
default:
/* DHCP didn't work, so use Link Local addressing */
dhcp_interface_free (dev->dhcp_iface);
dev->dhcp_iface = NULL;
if (get_autoip (dev, &ip))
{
#define LINKLOCAL_BCAST 0xa9feffff
int temp = ip.s_addr;
nm_system_device_set_ip4_address (dev, temp);
temp = ntohl (0xFFFF0000);
nm_system_device_set_ip4_netmask (dev, temp);
temp = ntohl (LINKLOCAL_BCAST);
nm_system_device_set_ip4_broadcast (dev, temp);
err = RET_DHCP_BOUND;
}
break;
nm_device_dhcp_configure (dev);
nm_device_update_ip4_address (dev);
nm_device_dhcp_setup_timeouts (dev);
}
else
{
dhcp_interface_free (dev->dhcp_iface);
dev->dhcp_iface = NULL;
}
return (err);

View file

@ -29,5 +29,6 @@ void nm_device_dhcp_cease (NMDevice *dev);
gboolean nm_device_dhcp_setup_timeouts (NMDevice *dev);
gboolean nm_device_dhcp_renew (gpointer user_data);
gboolean nm_device_dhcp_rebind (gpointer user_data);
gboolean nm_device_do_autoip (NMDevice *dev);
#endif

View file

@ -298,7 +298,9 @@ static DBusMessage *nm_dbus_nm_set_active_device (DBusConnection *connection, DB
/* If the user specificed a wireless network too, force that as well */
if (nm_device_is_wireless (dev) && !nm_device_find_and_use_essid (dev, network, key, key_type))
{
nm_dbus_send_network_not_found (data->dbus_connection, network);
}
else
{
if (nm_try_acquire_mutex (data->user_device_mutex, __FUNCTION__))
@ -326,6 +328,98 @@ out:
}
/*
* nm_dbus_nm_create_wireless_network
*
* Create a new wireless network and
*
*/
static DBusMessage *nm_dbus_nm_create_wireless_network (DBusConnection *connection, DBusMessage *message, NMData *data)
{
NMDevice *dev = NULL;
DBusMessage *reply_message = NULL;
char *dev_path = NULL;
char *network = NULL;
char *key = NULL;
int key_type = -1;
DBusError error;
g_return_val_if_fail (connection != NULL, NULL);
g_return_val_if_fail (message != NULL, NULL);
g_return_val_if_fail (data != NULL, NULL);
/* Try to grab both device _and_ network first, and if that fails then just the device. */
dbus_error_init (&error);
if (!dbus_message_get_args (message, &error, DBUS_TYPE_STRING, &dev_path,
DBUS_TYPE_STRING, &network, DBUS_TYPE_STRING, &key,
DBUS_TYPE_INT32, &key_type, DBUS_TYPE_INVALID))
{
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "InvalidArguments",
"NetworkManager::createWirelessNetwork called with invalid arguments.");
return (reply_message);
} else syslog (LOG_INFO, "Creating network '%s' on device '%s'.", network, dev_path);
dev = nm_dbus_get_device_from_object_path (data, dev_path);
dbus_free (dev_path);
if (!dev || (nm_device_get_driver_support_level (dev) == NM_DRIVER_UNSUPPORTED))
{
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "DeviceNotFound",
"The requested network device does not exist.");
return (reply_message);
}
nm_device_ref (dev);
/* Make sure network is valid and device is wireless */
if (!nm_device_is_wireless (dev) || !network)
{
reply_message = nm_dbus_create_error_message (message, NM_DBUS_INTERFACE, "InvalidArguments",
"NetworkManager::createWirelessNetwork called with invalid arguments.");
goto out;
}
if (!(reply_message = dbus_message_new_method_return (message)))
goto out;
/* If the user specificed a wireless network too, force that as well */
if (nm_try_acquire_mutex (data->user_device_mutex, __FUNCTION__))
{
NMAccessPoint *ap = nm_ap_new ();
/* Fill in the description of the network to create */
nm_ap_set_essid (ap, network);
if (key && strlen (key))
{
nm_ap_set_encrypted (ap, TRUE);
nm_ap_set_enc_key_source (ap, key, key_type);
}
nm_ap_set_mode (ap, NETWORK_MODE_ADHOC);
nm_ap_set_user_created (ap, TRUE);
nm_device_set_best_ap (dev, ap);
nm_device_freeze_best_ap (dev);
nm_device_activation_cancel (dev);
if (data->user_device)
nm_device_unref (data->user_device);
data->user_device = dev;
nm_device_ref (data->user_device);
nm_unlock_mutex (data->user_device_mutex, __FUNCTION__);
}
/* Have to mark our state changed since we blew away our connection trying out
* the user-requested network.
*/
nm_data_mark_state_changed (data);
out:
dbus_free (network);
dbus_free (key);
nm_device_unref (dev);
return (reply_message);
}
/*
* nm_dbus_nm_get_devices
*
@ -1467,6 +1561,8 @@ static DBusHandlerResult nm_dbus_nm_message_handler (DBusConnection *connection,
reply_message = nm_dbus_nm_get_devices (connection, message, data);
else if (strcmp ("setActiveDevice", method) == 0)
nm_dbus_nm_set_active_device (connection, message, data);
else if (strcmp ("createWirelessNetwork", method) == 0)
nm_dbus_nm_create_wireless_network (connection, message, data);
else if (strcmp ("setKeyForNetwork", method) == 0)
nm_dbus_set_user_key_for_network (connection, message, data);
else if (strcmp ("status", method) == 0)

View file

@ -42,7 +42,7 @@
/* Local static prototypes */
static gboolean mii_get_link (NMDevice *dev);
static gpointer nm_device_activation_worker (gpointer user_data);
static gboolean nm_device_activation_configure_ip (NMDevice *dev);
static gboolean nm_device_activation_configure_ip (NMDevice *dev, gboolean do_only_autoip);
/******************************************************/
@ -276,11 +276,10 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
nm_device_do_wireless_scan (dev);
nm_device_update_best_ap (dev);
dev->options.wireless.num_freqs = 14; /* Default, fake something like 802.11b */
if ((sk = iw_sockets_open ()) >= 0)
{
if (iw_get_range_info (sk, nm_device_get_iface (dev), &range) >= 0)
dev->options.wireless.num_freqs = range.num_frequency;
if (iw_get_range_info (sk, nm_device_get_iface (dev), &(dev->options.wireless.range_info)) == -1)
memset (&(dev->options.wireless.range_info), 0, sizeof (struct iw_range));
close (sk);
}
}
@ -387,7 +386,7 @@ int nm_device_get_association_pause_value (NMDevice *dev)
* has to scan all channels to find our requested AP (which can take a long time
* if it is an A/B/G chipset like the Atheros 5212, for example).
*/
if (dev->options.wireless.num_freqs > 14)
if (dev->options.wireless.range_info.num_frequency > 14)
return 10;
else
return 5;
@ -714,6 +713,150 @@ void nm_device_set_essid (NMDevice *dev, const char *essid)
}
/*
* nm_device_get_frequency
*
* For wireless devices, get the frequency we broadcast/receive on.
*
*/
double nm_device_get_frequency (NMDevice *dev)
{
int sk;
int err;
double freq = 0;
g_return_val_if_fail (dev != NULL, 0);
g_return_val_if_fail (nm_device_is_wireless (dev), 0);
/* Test devices don't really have a frequency, they always succeed */
if (dev->test_device)
return 703000000;
sk = iw_sockets_open ();
if (sk >= 0)
{
struct iwreq wrq;
err = iw_set_ext (sk, nm_device_get_iface (dev), SIOCGIWFREQ, &wrq);
if (err >= 0)
freq = iw_freq2float (&wrq.u.freq);
if (err == -1)
syslog (LOG_ERR, "nm_device_get_frequency(): error getting frequency for device %s. errno = %d", nm_device_get_iface (dev), errno);
close (sk);
}
return (freq);
}
/*
* nm_device_set_frequency
*
* For wireless devices, set the frequency to broadcast/receive on.
*
*/
void nm_device_set_frequency (NMDevice *dev, const double freq)
{
int sk;
int err;
g_return_if_fail (dev != NULL);
g_return_if_fail (nm_device_is_wireless (dev));
/* Test devices don't really have a frequency, they always succeed */
if (dev->test_device)
return;
sk = iw_sockets_open ();
if (sk >= 0)
{
struct iwreq wrq;
wrq.u.freq.flags = IW_FREQ_FIXED;
iw_float2freq (freq, &wrq.u.freq);
err = iw_set_ext (sk, nm_device_get_iface (dev), SIOCSIWFREQ, &wrq);
if (err == -1)
syslog (LOG_ERR, "nm_device_set_frequency(): error setting frequency %f for device %s. errno = %d", freq, nm_device_get_iface (dev), errno);
close (sk);
}
}
/*
* nm_device_get_bitrate
*
* For wireless devices, get the bitrate to broadcast/receive at.
* Returned value is rate in KHz.
*
*/
int nm_device_get_bitrate (NMDevice *dev)
{
int sk;
int err = -1;
struct iwreq wrq;
g_return_val_if_fail (dev != NULL, 0);
g_return_val_if_fail (nm_device_is_wireless (dev), 0);
/* Test devices don't really have a frequency, they always succeed */
if (dev->test_device)
return 11;
sk = iw_sockets_open ();
if (sk >= 0)
{
err = iw_set_ext (sk, nm_device_get_iface (dev), SIOCGIWRATE, &wrq);
close (sk);
}
return ((err >= 0) ? wrq.u.bitrate.value / 1000 : 0);
}
/*
* nm_device_set_bitrate
*
* For wireless devices, set the bitrate to broadcast/receive at.
* Rate argument should be in KHz, or 0 for automatic.
*
*/
void nm_device_set_bitrate (NMDevice *dev, const int KHz)
{
int sk;
int err;
g_return_if_fail (dev != NULL);
g_return_if_fail (nm_device_is_wireless (dev));
/* Test devices don't really have a frequency, they always succeed */
if (dev->test_device)
return;
sk = iw_sockets_open ();
if (sk >= 0)
{
struct iwreq wrq;
if (KHz != 0)
{
wrq.u.bitrate.value = KHz * 1000;
wrq.u.bitrate.fixed = 1;
}
else
{
wrq.u.bitrate.value = -1;
wrq.u.bitrate.fixed = 0;
}
err = iw_set_ext (sk, nm_device_get_iface (dev), SIOCSIWRATE, &wrq);
if (err == -1)
syslog (LOG_ERR, "nm_device_set_bitrate(): error setting bitrate %d KHz for device %s. errno = %d", KHz, nm_device_get_iface (dev), errno);
close (sk);
}
}
/*
* nm_device_get_ap_address
*
@ -1187,6 +1330,51 @@ gboolean nm_device_is_up (NMDevice *dev)
}
/*
* nm_device_get_mode
*
* Get managed/infrastructure/adhoc mode on a device (currently wireless only)
*
*/
NMNetworkMode nm_device_get_mode (NMDevice *dev)
{
int sk;
NMNetworkMode mode = NETWORK_MODE_UNKNOWN;
g_return_val_if_fail (dev != NULL, NETWORK_MODE_UNKNOWN);
g_return_val_if_fail (nm_device_is_wireless (dev), NETWORK_MODE_UNKNOWN);
/* Force the card into Managed/Infrastructure mode */
sk = iw_sockets_open ();
if (sk >= 0)
{
struct iwreq wrq;
int err;
err = iw_set_ext (sk, nm_device_get_iface (dev), SIOCGIWMODE, &wrq);
if (err == 0)
{
switch (wrq.u.mode)
{
case IW_MODE_INFRA:
mode = NETWORK_MODE_INFRA;
break;
case IW_MODE_ADHOC:
mode = NETWORK_MODE_ADHOC;
break;
default:
break;
}
}
else
syslog (LOG_ERR, "nm_device_get_mode (%s): error setting card to Infrastructure mode. errno = %d", nm_device_get_iface (dev), errno);
close (sk);
}
return (mode);
}
/*
* nm_device_set_mode
*
@ -1230,7 +1418,7 @@ gboolean nm_device_set_mode (NMDevice *dev, const NMNetworkMode mode)
if (err == 0)
success = TRUE;
else
syslog (LOG_ERR, "nm_device_set_mode_managed (%s): error setting card to Infrastructure mode. errno = %d", nm_device_get_iface (dev), errno);
syslog (LOG_ERR, "nm_device_set_mode (%s): error setting card to Infrastructure mode. errno = %d", nm_device_get_iface (dev), errno);
}
close (sk);
}
@ -1362,6 +1550,11 @@ static gboolean nm_device_set_wireless_config (NMDevice *dev, NMAccessPoint *ap,
*/
essid = nm_ap_get_essid (ap);
nm_device_set_mode (dev, nm_ap_get_mode (ap));
nm_device_set_bitrate (dev, 0);
if (nm_ap_get_user_created (ap) || (nm_ap_get_freq (ap) && (nm_ap_get_mode (ap) == NETWORK_MODE_ADHOC)))
{
nm_device_set_frequency (dev, nm_ap_get_freq (ap));
}
nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE);
if (nm_ap_get_encrypted (ap) && nm_ap_get_enc_key_source (ap))
{
@ -1383,6 +1576,13 @@ static gboolean nm_device_set_wireless_config (NMDevice *dev, NMAccessPoint *ap,
*/
g_usleep (G_USEC_PER_SEC * nm_device_get_association_pause_value (dev));
/* Some cards don't really work well in ad-hoc mode unless you explicitly set the bitrate
* on them. (Netgear WG511T/Atheros 5212 with madwifi drivers). Until we can get rate information
* from scanned access points out of iwlib, clamp bitrate for these cards at 11Mbps.
*/
if ((nm_ap_get_mode (ap) == NETWORK_MODE_ADHOC) && (nm_device_get_bitrate (dev) <= 0))
nm_device_set_bitrate (dev, 11000); /* In Kbps */
nm_device_update_link_active (dev, FALSE);
success = TRUE;
@ -1390,7 +1590,89 @@ static gboolean nm_device_set_wireless_config (NMDevice *dev, NMAccessPoint *ap,
}
gboolean AP_NEED_KEY (NMAccessPoint *ap)
/*
* nm_device_activate_wireless_adhoc
*
* Create an ad-hoc network (rather than associating with one).
*
*/
static gboolean nm_device_activate_wireless_adhoc (NMDevice *dev, NMAccessPoint *ap)
{
gboolean success = FALSE;
NMDeviceAuthMethod auth = NM_DEVICE_AUTH_METHOD_NONE;
NMAPListIter *iter;
NMAccessPoint *tmp_ap;
double card_freqs[IW_MAX_FREQUENCIES];
int num_freqs = 0, i;
double freq_to_use = 0;
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (ap != NULL, FALSE);
if (nm_ap_get_encrypted (ap))
auth = NM_DEVICE_AUTH_METHOD_SHARED_KEY;
/* Build our local list of frequencies to whittle down until we find a free one */
memset (&card_freqs, 0, sizeof (card_freqs));
num_freqs = MIN (dev->options.wireless.range_info.num_frequency, IW_MAX_FREQUENCIES);
for (i = 0; i < num_freqs; i++)
card_freqs[i] = iw_freq2float (&(dev->options.wireless.range_info.freq[i]));
/* We need to find a clear wireless channel to use. We will
* only use 802.11b channels for now.
*/
iter = nm_ap_list_iter_new (nm_device_ap_list_get (dev));
while ((tmp_ap = nm_ap_list_iter_next (iter)))
{
double ap_freq = nm_ap_get_freq (tmp_ap);
for (i = 0; i < num_freqs && ap_freq; i++)
{
if (card_freqs[i] == ap_freq)
card_freqs[i] = 0;
}
}
nm_ap_list_iter_free (iter);
/* Ok, find the first non-zero freq in our table and use it.
* For now we only try to use a channel in the 802.11b channel
* space so that most everyone can see it.
*/
for (i = 0; i < num_freqs; i++)
{
int channel = iw_freq_to_channel (card_freqs[i], &(dev->options.wireless.range_info));
if (card_freqs[i] && (channel > 0) && (channel < 15))
{
freq_to_use = card_freqs[i];
break;
}
}
/* Hmm, no free channels in 802.11b space. Pick one more or less randomly */
if (!freq_to_use)
{
double pfreq;
int channel = (int)(random () % 14);
int err;
err = iw_channel_to_freq (channel, &pfreq, &(dev->options.wireless.range_info));
if (err == channel)
freq_to_use = pfreq;
}
if (freq_to_use)
{
nm_ap_set_freq (ap, freq_to_use);
syslog (LOG_INFO, "Will create network '%s' with frequency %f.\n", nm_ap_get_essid (ap), nm_ap_get_freq (ap));
if ((success = nm_device_set_wireless_config (dev, ap, auth)))
success = nm_device_activation_configure_ip (dev, TRUE);
}
return (success);
}
static gboolean AP_NEED_KEY (NMAccessPoint *ap)
{
char *s;
int len = 0;
@ -1407,7 +1689,7 @@ gboolean AP_NEED_KEY (NMAccessPoint *ap)
return (FALSE);
}
gboolean HAVE_LINK (NMDevice *dev)
static gboolean HAVE_LINK (NMDevice *dev)
{
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (nm_device_is_wireless (dev), FALSE);
@ -1462,7 +1744,7 @@ get_ap:
/* If its unencrypted and we don't have a link, we can't use this AP.
* If we can't get an IP address off this AP, we can't use it either.
*/
if (!HAVE_LINK (dev) || !nm_device_activation_configure_ip (dev))
if (!HAVE_LINK (dev) || !nm_device_activation_configure_ip (dev, FALSE))
{
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): no link to '%s', or couldn't get configure interface for IP. Trying another access point.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
@ -1524,42 +1806,56 @@ get_ap:
goto out;
nm_device_set_wireless_config (dev, best_ap, auth);
if (!HAVE_LINK (dev) && (auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY))
/* Link checking and all this fallback doesn't really make sense in ad-hoc mode,
* so only do it for infrastructure mode.
*/
if (nm_ap_get_mode (best_ap) == NETWORK_MODE_ADHOC)
{
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): no hardware link to '%s' in Shared Key mode, trying Open System.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
/* Back down to Open System mode */
auth--;
continue;
/* Only do auto-ip on Ad-Hoc connections for now. We technically
* could do DHCP on them though.
*/
success = nm_device_activation_configure_ip (dev, TRUE);
}
else if (!HAVE_LINK (dev))
else if (nm_ap_get_mode (best_ap) == NETWORK_MODE_INFRA)
{
/* Must be in Open System mode and it still didn't work, so
* we'll invalidate the current "best" ap and get another one */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): no hardware link to '%s' in Open System mode, trying another access point.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
nm_ap_set_invalid (best_ap, TRUE);
nm_ap_list_append_ap (dev->app_data->invalid_ap_list, best_ap);
nm_ap_unref (best_ap);
nm_device_update_best_ap (dev);
goto get_ap;
}
ip_success = nm_device_activation_configure_ip (dev);
if (!ip_success && (auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY))
{
/* Back down to Open System mode */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): could not get IP configuration info for '%s' in Shared Key mode, trying Open System.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
auth--;
continue;
}
else if (!ip_success)
{
/* Open System mode failed, we must have bad WEP key */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): could not get IP configuration info for '%s' in Open System mode, asking for new key.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
need_key = TRUE;
goto need_key;
if (!HAVE_LINK (dev) && (auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY))
{
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): no hardware link to '%s' in Shared Key mode, trying Open System.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
/* Back down to Open System mode */
auth--;
continue;
}
else if (!HAVE_LINK (dev))
{
/* Must be in Open System mode and it still didn't work, so
* we'll invalidate the current "best" ap and get another one */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): no hardware link to '%s' in Open System mode, trying another access point.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
nm_ap_set_invalid (best_ap, TRUE);
nm_ap_list_append_ap (dev->app_data->invalid_ap_list, best_ap);
nm_ap_unref (best_ap);
nm_device_update_best_ap (dev);
goto get_ap;
}
ip_success = nm_device_activation_configure_ip (dev, FALSE);
if (!ip_success && (auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY))
{
/* Back down to Open System mode */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): could not get IP configuration info for '%s' in Shared Key mode, trying Open System.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
auth--;
continue;
}
else if (!ip_success)
{
/* Open System mode failed, we must have bad WEP key */
syslog (LOG_DEBUG, "nm_device_activate_wireless(%s): could not get IP configuration info for '%s' in Open System mode, asking for new key.",
nm_device_get_iface (dev), nm_ap_get_essid (best_ap) ? nm_ap_get_essid (best_ap) : "(none)");
need_key = TRUE;
goto need_key;
}
}
/* OK, we have a link and we have IP address info, we're good */
@ -1588,14 +1884,18 @@ out:
* or manually setting up the IP address, gateway, and default route.
*
*/
static gboolean nm_device_activation_configure_ip (NMDevice *dev)
static gboolean nm_device_activation_configure_ip (NMDevice *dev, gboolean do_only_autoip)
{
gboolean success = FALSE;
g_return_val_if_fail (dev != NULL, FALSE);
nm_system_delete_default_route ();
if (nm_device_config_get_use_dhcp (dev))
if (do_only_autoip)
{
success = nm_device_do_autoip (dev);
}
else if (nm_device_config_get_use_dhcp (dev))
{
int err;
@ -1624,7 +1924,10 @@ static gboolean nm_device_activation_configure_ip (NMDevice *dev)
}
if (success)
{
nm_system_flush_arp_cache ();
nm_system_restart_mdns_responder ();
}
return (success);
}
@ -1653,9 +1956,27 @@ static gpointer nm_device_activation_worker (gpointer user_data)
nm_device_bring_up (dev);
if (nm_device_is_wireless (dev))
success = nm_device_activate_wireless (dev);
{
gboolean create_network = FALSE;
NMAccessPoint *best_ap = nm_device_get_best_ap (dev);
if (best_ap)
{
if (nm_ap_get_user_created (best_ap))
{
create_network = TRUE;
syslog (LOG_INFO, "Creating wireless network '%s'.\n", nm_ap_get_essid (best_ap));
success = nm_device_activate_wireless_adhoc (dev, best_ap);
syslog (LOG_INFO, "Wireless network creation for '%s' was %s.\n", nm_ap_get_essid (best_ap), success ? "successful" : "unsuccessful");
}
nm_ap_unref (best_ap);
}
if (!create_network)
success = nm_device_activate_wireless (dev);
}
else if (nm_device_is_wired (dev))
success = nm_device_activation_configure_ip (dev);
success = nm_device_activation_configure_ip (dev, FALSE);
syslog (LOG_DEBUG, "Activation (%s) IP configuration/DHCP returned = %d\n", nm_device_get_iface (dev), success);
/* If we were told to quit activation, stop the thread and return */
@ -1813,6 +2134,7 @@ void nm_device_activation_cancel (NMDevice *dev)
*/
while (nm_device_is_activating (dev))
g_usleep (G_USEC_PER_SEC / 2);
syslog (LOG_DEBUG, "nm_device_activation_cancel(%s): cancelled.", nm_device_get_iface (dev));
}
}
@ -1849,6 +2171,7 @@ gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added)
{
nm_device_set_essid (dev, "");
nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE);
nm_device_set_mode (dev, NETWORK_MODE_INFRA);
}
return (TRUE);
@ -2201,8 +2524,13 @@ void nm_device_update_best_ap (NMDevice *dev)
if (best_ap)
{
char *essid = nm_ap_get_essid (best_ap);
if ( !nm_ap_list_get_ap_by_essid (dev->app_data->invalid_ap_list, essid)
&& nm_device_ap_list_get_ap_by_essid (dev, essid))
/* Two reasons to keep the current best_ap:
* 1) Its still valid and we see it in our scan data
* 2) Its an ad-hoc network that we've created (and therefore its not in our scan data)
*/
if ( ( !nm_ap_list_get_ap_by_essid (dev->app_data->invalid_ap_list, essid)
&& nm_device_ap_list_get_ap_by_essid (dev, essid))
|| nm_ap_get_user_created (best_ap))
{
nm_ap_unref (best_ap);
g_mutex_unlock (dev->options.wireless.best_ap_mutex);
@ -2281,6 +2609,7 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
NMAccessPoint *ap = NULL;
NMDeviceAuthMethod auths[3] = { NM_DEVICE_AUTH_METHOD_SHARED_KEY, NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM, NM_DEVICE_AUTH_METHOD_NONE };
int i;
NMNetworkMode mode = NETWORK_MODE_INFRA;
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (network != NULL, FALSE);
@ -2295,74 +2624,95 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
nm_device_bring_up (dev);
g_usleep (G_USEC_PER_SEC * 4);
/* Force the card into Managed/Infrastructure mode */
nm_device_set_mode (dev, NETWORK_MODE_INFRA);
if ((ap = nm_ap_list_get_ap_by_essid (nm_device_ap_list_get (dev), network)) && !nm_ap_get_encrypted (ap))
if ((ap = nm_ap_list_get_ap_by_essid (nm_device_ap_list_get (dev), network)))
{
auths[0] = NM_DEVICE_AUTH_METHOD_NONE;
auths[1] = NM_DEVICE_AUTH_METHOD_SHARED_KEY;
auths[2] = NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM;
mode = nm_ap_get_mode (ap);
/* If the access point we're looking for is in our list and we know its
* not encrypted, short-cut our connection fallbacks here and don't even
* try enabling encryption to see if we can connect.
*/
if (!nm_ap_get_encrypted (ap))
{
auths[0] = NM_DEVICE_AUTH_METHOD_NONE;
auths[1] = NM_DEVICE_AUTH_METHOD_SHARED_KEY;
auths[2] = NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM;
}
}
/* Loop through the auth modes */
for (i = 0; i < 3; i++)
/* Two cases here. Ad-Hoc networks don't have an access point that authenticates or
* that you associate with, we just have to see if we know about the network and then
* set up the card. So if we know about it, we can use it. I guess if you don't have
* the right WEP key, you're kind of screwed.
*/
if (mode == NETWORK_MODE_ADHOC)
{
switch (auths[i])
{
case NM_DEVICE_AUTH_METHOD_SHARED_KEY:
case NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM:
{
temp_enc = TRUE;
if ((key_type != NM_ENC_TYPE_UNKNOWN) && key)
{
char *hashed_key = NULL;
switch (key_type)
{
case (NM_ENC_TYPE_128_BIT_PASSPHRASE):
hashed_key = nm_wireless_128bit_key_from_passphrase (key);
break;
case (NM_ENC_TYPE_ASCII_KEY):
if (strlen (key) <= 5)
hashed_key = nm_wireless_64bit_ascii_to_hex (key);
else
hashed_key = nm_wireless_128bit_ascii_to_hex (key);
break;
case (NM_ENC_TYPE_HEX_KEY):
case (NM_ENC_TYPE_UNKNOWN):
hashed_key = g_strdup (key);
break;
default:
break;
}
nm_device_set_enc_key (dev, hashed_key, auths[i]);
g_free (hashed_key);
}
else
nm_device_set_enc_key (dev, "11111111111111111111111111", auths[i]);
break;
}
case NM_DEVICE_AUTH_METHOD_NONE:
default:
temp_enc = FALSE;
nm_device_set_enc_key (dev, NULL, auths[i]);
break;
}
/* Pause to allow card to associate. After we set the ESSID on the card, the card
* has to scan all channels to find our requested AP (which can take a long time
* if it is an A/B/G chipset like the Atheros 5212, for example).
*/
nm_device_set_essid (dev, network);
g_usleep (G_USEC_PER_SEC * nm_device_get_association_pause_value (dev));
nm_device_update_link_active (dev, FALSE);
nm_device_get_ap_address (dev, &addr);
if (nm_ethernet_address_is_valid (&addr) && nm_device_get_essid (dev))
{
nm_device_get_ap_address (dev, ap_addr);
if (ap)
success = TRUE;
*encrypted = temp_enc;
}
else if (mode == NETWORK_MODE_INFRA)
{
nm_device_set_mode (dev, mode);
/* Loop through the auth modes */
for (i = 0; i < 3; i++)
{
switch (auths[i])
{
case NM_DEVICE_AUTH_METHOD_SHARED_KEY:
case NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM:
{
temp_enc = TRUE;
if ((key_type != NM_ENC_TYPE_UNKNOWN) && key)
{
char *hashed_key = NULL;
switch (key_type)
{
case (NM_ENC_TYPE_128_BIT_PASSPHRASE):
hashed_key = nm_wireless_128bit_key_from_passphrase (key);
break;
case (NM_ENC_TYPE_ASCII_KEY):
if (strlen (key) <= 5)
hashed_key = nm_wireless_64bit_ascii_to_hex (key);
else
hashed_key = nm_wireless_128bit_ascii_to_hex (key);
break;
case (NM_ENC_TYPE_HEX_KEY):
case (NM_ENC_TYPE_UNKNOWN):
hashed_key = g_strdup (key);
break;
default:
break;
}
nm_device_set_enc_key (dev, hashed_key, auths[i]);
g_free (hashed_key);
}
else
nm_device_set_enc_key (dev, "11111111111111111111111111", auths[i]);
break;
}
case NM_DEVICE_AUTH_METHOD_NONE:
default:
temp_enc = FALSE;
nm_device_set_enc_key (dev, NULL, auths[i]);
break;
}
/* Pause to allow card to associate. After we set the ESSID on the card, the card
* has to scan all channels to find our requested AP (which can take a long time
* if it is an A/B/G chipset like the Atheros 5212, for example).
*/
nm_device_set_essid (dev, network);
g_usleep (G_USEC_PER_SEC * nm_device_get_association_pause_value (dev));
nm_device_update_link_active (dev, FALSE);
nm_device_get_ap_address (dev, &addr);
if (nm_ethernet_address_is_valid (&addr) && nm_device_get_essid (dev))
{
nm_device_get_ap_address (dev, ap_addr);
success = TRUE;
*encrypted = temp_enc;
}
}
}
@ -2467,8 +2817,8 @@ gboolean nm_device_find_and_use_essid (NMDevice *dev, const char *essid, const c
*/
static void nm_device_do_normal_scan (NMDevice *dev)
{
int iwlib_socket;
NMData *data;
int iwlib_socket;
NMData *data;
g_return_if_fail (dev != NULL);
g_return_if_fail (dev->app_data != NULL);
@ -2495,6 +2845,14 @@ static void nm_device_do_normal_scan (NMDevice *dev)
gboolean have_blank_essids = FALSE;
NMAPListIter *iter;
NMAccessPoint *artificial_ap;
NMNetworkMode orig_mode = NETWORK_MODE_INFRA;
double orig_freq;
int orig_rate;
orig_mode = nm_device_get_mode (dev);
orig_freq = nm_device_get_frequency (dev);
orig_rate = nm_device_get_bitrate (dev);
nm_device_set_mode (dev, NETWORK_MODE_INFRA);
err = iw_scan (iwlib_socket, (char *)nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
if ((err == -1) && (errno == ENODATA))
@ -2508,10 +2866,16 @@ static void nm_device_do_normal_scan (NMDevice *dev)
err = iw_scan (iwlib_socket, (char *)nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
if (err == -1)
{
nm_device_set_mode (dev, orig_mode);
nm_device_set_frequency (dev, orig_freq);
nm_device_set_bitrate (dev, orig_rate);
close (iwlib_socket);
return;
}
}
nm_device_set_mode (dev, orig_mode);
nm_device_set_frequency (dev, orig_freq);
nm_device_set_bitrate (dev, orig_rate);
/* New list for current scan data */
new_scan_list = nm_ap_list_new (NETWORK_TYPE_DEVICE);
@ -2810,6 +3174,9 @@ static void nm_device_fake_ap_list (NMDevice *dev)
*/
void nm_device_do_wireless_scan (NMDevice *dev)
{
NMAccessPoint *best_ap = NULL;
gboolean do_scan = TRUE;
g_return_if_fail (dev != NULL);
g_return_if_fail (dev->app_data != NULL);
g_return_if_fail (nm_device_is_wireless (dev));
@ -2825,23 +3192,31 @@ void nm_device_do_wireless_scan (NMDevice *dev)
return;
}
if (nm_device_get_supports_wireless_scan (dev))
nm_device_do_normal_scan (dev);
else
if ((best_ap = nm_device_get_best_ap (dev)))
{
struct ether_addr ap_addr;
/* We can't pseudo-scan without switching APs, therefore
* if the card has a valid access point and its an allowed
* access point, don't pseudo-scan for others.
*/
nm_device_get_ap_address (dev, &ap_addr);
if ( !nm_ethernet_address_is_valid (&ap_addr)
|| !nm_ap_list_get_ap_by_essid (dev->app_data->allowed_ap_list, nm_device_get_essid (dev))
|| !nm_device_get_best_ap (dev))
/* Don't pseudo-scan when we already have a connection. */
if (!nm_device_get_supports_wireless_scan (dev))
{
struct ether_addr ap_addr;
/* We can't pseudo-scan without switching APs, therefore
* if the card has a valid access point and its an allowed
* access point, don't pseudo-scan for others.
*/
nm_device_get_ap_address (dev, &ap_addr);
if ( nm_ethernet_address_is_valid (&ap_addr)
&& nm_ap_list_get_ap_by_essid (dev->app_data->allowed_ap_list, nm_device_get_essid (dev)))
do_scan = FALSE;
}
nm_ap_unref (best_ap);
}
if (do_scan)
{
if (nm_device_get_supports_wireless_scan (dev))
nm_device_do_normal_scan (dev);
else
nm_device_do_pseudo_scan (dev);
}
}
nm_unlock_mutex (dev->options.wireless.scan_mutex, __FUNCTION__);

View file

@ -42,7 +42,7 @@ typedef struct NMDeviceWirelessOptions
guint8 noise;
gint8 strength;
gint8 invalid_strength_counter;
gint8 num_freqs;
struct iw_range range_info;
GMutex *scan_mutex;
/* We keep a couple lists around since wireless cards

View file

@ -293,12 +293,12 @@ gboolean nm_state_modification_monitor (gpointer user_data)
{
if (nm_device_is_wireless (best_dev) && !nm_device_is_activating (best_dev) && nm_device_need_ap_switch (best_dev))
{
syslog (LOG_INFO, " SWITCH: need to associate with new access point");
syslog (LOG_INFO, " SWITCH: need to associate with new access point or create a wireless network.");
do_switch = TRUE;
}
else if (!nm_device_is_activating (best_dev) && !nm_device_get_ip4_address (best_dev))
{
syslog (LOG_INFO, " SWITCH: need to get an IP address");
syslog (LOG_INFO, " SWITCH: need to get an IP address.");
do_switch = TRUE;
}
}

View file

@ -180,9 +180,9 @@ gboolean nm_system_device_set_ip4_default_route (NMDevice *dev, int ip4_def_rout
rtent.rt_window = 0;
rtent.rt_flags = RTF_UP | RTF_GATEWAY | ( rtent.rt_window ? RTF_WINDOW : 0);
if ( ioctl (sk, SIOCADDRT, &rtent) == -1 )
if (ioctl (sk, SIOCADDRT, &rtent) == -1)
{
if ( errno == ENETUNREACH ) /* possibly gateway is over the bridge */
if (errno == ENETUNREACH) /* possibly gateway is over the bridge */
{ /* try adding a route to gateway first */
struct rtentry rtent2;

View file

@ -35,11 +35,14 @@ gboolean nm_system_device_run_dhcp (NMDevice *dev);
void nm_system_device_stop_dhcp (NMDevice *dev);
gboolean nm_system_device_has_active_routes (NMDevice *dev);
void nm_system_device_flush_routes (NMDevice *dev);
void nm_system_device_add_default_route_via_device(NMDevice *dev);
void nm_system_device_flush_addresses (NMDevice *dev);
void nm_system_device_update_config_info (NMDevice *dev);
gboolean nm_system_device_setup_static_ip4_config (NMDevice *dev);
void nm_system_enable_loopback (void);
void nm_system_flush_loopback_routes (void);
void nm_system_delete_default_route (void);
void nm_system_flush_arp_cache (void);
void nm_system_kill_all_dhcp_daemons (void);
void nm_system_update_dns (void);
void nm_system_load_device_modules (void);

View file

@ -59,7 +59,14 @@ static struct ether_addr broadcast_addr = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}
*/
static void pick(struct in_addr *ip)
{
ip->s_addr = htonl (LINKLOCAL_ADDR | ((abs(random()) % 0xFD00) + 0x0100));
ip->s_addr = htonl (LINKLOCAL_ADDR | ((abs(random()) % 0xFD00) + (abs(random()) % 0x0100)));
/* Make sure we don't use 0xFF or 0x00 anywhere */
while (((ip->s_addr & 0x0000FF00) == 0xFF00) || ((ip->s_addr & 0x0000FF00) == 0x0000))
ip->s_addr = (ip->s_addr & 0xFFFF00FF) + (abs(random()) && 0xFFFF);
while (((ip->s_addr & 0x000000FF) == 0xFF) || ((ip->s_addr & 0x000000FF) == 0x00))
ip->s_addr = (ip->s_addr & 0xFFFFFF00) + (abs(random()) && 0xFF);
}
/**
@ -275,8 +282,15 @@ gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip)
#ifdef ARP_DEBUG
syslog (LOG_ERR, "autoip: (%s) recv arp type=%d, op=%d, ", nm_device_get_iface (dev), ntohs(p.ethhdr.ether_type), ntohs(p.operation));
syslog (LOG_ERR, "source=%s %s,", (char *)(p.sHaddr), p.sInaddr);
syslog (LOG_ERR, "target=%s %s\n", (char *)(p.tHaddr), p.tInaddr);
{
struct in_addr a;
memcpy (&(a.s_addr), &(p.sInaddr), sizeof (a.s_addr));
syslog (LOG_ERR, " source = %s %02X:%02X:%02X:%02X:%02X:%02X, ", inet_ntoa (a),
p.sHaddr[0], p.sHaddr[1], p.sHaddr[2], p.sHaddr[3], p.sHaddr[4], p.sHaddr[5]);
memcpy (&(a.s_addr), &(p.tInaddr), sizeof (a.s_addr));
syslog (LOG_ERR, " target = %s %02X:%02X:%02X:%02X:%02X:%02X\n", inet_ntoa (a),
p.tHaddr[0], p.tHaddr[1], p.tHaddr[2], p.tHaddr[3], p.tHaddr[4], p.tHaddr[5]);
}
#endif
if ( (ntohs (p.ethhdr.ether_type) == ETHERTYPE_ARP)

View file

@ -453,3 +453,37 @@ void nm_system_load_device_modules (void)
void nm_system_restart_mdns_responder (void)
{
}
/*
* nm_system_device_add_default_route_via_device
*
* Flush all routes associated with a network device
*
*/
void nm_system_device_add_default_route_via_device (NMDevice *dev)
{
}
/*
* nm_system_flush_loopback_routes
*
* Flush all routes associated with the loopback device, because it
* sometimes gets the first route for ZeroConf/Link-Local traffic.
*
*/
void nm_system_flush_loopback_routes (void)
{
}
/*
* nm_system_flush_arp_cache
*
* Flush all entries in the arp cache.
*
*/
void nm_system_flush_arp_cache (void)
{
}

View file

@ -421,3 +421,37 @@ void nm_system_device_update_config_info (NMDevice *dev)
nm_device_config_set_ip4_broadcast (dev, ip4_broadcast);
}
}
/*
* nm_system_device_add_default_route_via_device
*
* Flush all routes associated with a network device
*
*/
void nm_system_device_add_default_route_via_device (NMDevice *dev)
{
}
/*
* nm_system_flush_loopback_routes
*
* Flush all routes associated with the loopback device, because it
* sometimes gets the first route for ZeroConf/Link-Local traffic.
*
*/
void nm_system_flush_loopback_routes (void)
{
}
/*
* nm_system_flush_arp_cache
*
* Flush all entries in the arp cache.
*
*/
void nm_system_flush_arp_cache (void)
{
}

View file

@ -138,6 +138,29 @@ void nm_system_device_flush_routes (NMDevice *dev)
}
/*
* nm_system_device_add_default_route_via_device
*
* Flush all routes associated with a network device
*
*/
void nm_system_device_add_default_route_via_device (NMDevice *dev)
{
char *buf;
g_return_if_fail (dev != NULL);
/* Not really applicable for test devices */
if (nm_device_is_test_device (dev))
return;
/* Remove routing table entries */
buf = g_strdup_printf ("/sbin/ip route add default dev %s", nm_device_get_iface (dev));
nm_spawn_process (buf);
g_free (buf);
}
/*
* nm_system_device_has_active_routes
*
@ -277,6 +300,20 @@ void nm_system_enable_loopback (void)
}
/*
* nm_system_flush_loopback_routes
*
* Flush all routes associated with the loopback device, because it
* sometimes gets the first route for ZeroConf/Link-Local traffic.
*
*/
void nm_system_flush_loopback_routes (void)
{
/* Remove routing table entries for lo */
nm_spawn_process ("/sbin/ip route flush dev lo");
}
/*
* nm_system_delete_default_route
*
@ -289,6 +326,18 @@ void nm_system_delete_default_route (void)
}
/*
* nm_system_flush_arp_cache
*
* Flush all entries in the arp cache.
*
*/
void nm_system_flush_arp_cache (void)
{
nm_spawn_process ("/sbin/ip neigh flush all");
}
/*
* nm_system_kill_all_dhcp_daemons
*
@ -310,8 +359,12 @@ void nm_system_kill_all_dhcp_daemons (void)
*/
void nm_system_update_dns (void)
{
#if 0
/* This doesn't acutally seem to work very well... */
if(nm_spawn_process ("/etc/init.d/nscd status"))
nm_spawn_process ("nscd -i hosts");
#endif
nm_spawn_process ("/usr/bin/killall -q nscd");
}

View file

@ -254,3 +254,37 @@ void nm_system_restart_mdns_responder (void)
{
}
/*
* nm_system_device_add_default_route_via_device
*
* Flush all routes associated with a network device
*
*/
void nm_system_device_add_default_route_via_device (NMDevice *dev)
{
}
/*
* nm_system_flush_loopback_routes
*
* Flush all routes associated with the loopback device, because it
* sometimes gets the first route for ZeroConf/Link-Local traffic.
*
*/
void nm_system_flush_loopback_routes (void)
{
}
/*
* nm_system_flush_arp_cache
*
* Flush all entries in the arp cache.
*
*/
void nm_system_flush_arp_cache (void)
{
}