2004-12-15 Dan Williams <dcbw@redhat.com>
Patch from Tom Parker * Add autoip/Link Local Addressing support when we fail to get a DHCP address * Longer pause after setting ESSID on cards that support a larger number of channels to give the card time to find the right channel * Add system hook to restart mDNSResponder (or whatever the local implementation of Multicast DNS is) when we activate interfaces git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@341 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
12
ChangeLog
12
ChangeLog
@@ -1,3 +1,15 @@
|
|||||||
|
2004-12-15 Dan Williams <dcbw@redhat.com>
|
||||||
|
|
||||||
|
Patch from Tom Parker
|
||||||
|
* Add autoip/Link Local Addressing support when we fail to get a DHCP
|
||||||
|
address
|
||||||
|
|
||||||
|
* Longer pause after setting ESSID on cards that support a larger number
|
||||||
|
of channels to give the card time to find the right channel
|
||||||
|
|
||||||
|
* Add system hook to restart mDNSResponder (or whatever the local implementation
|
||||||
|
of Multicast DNS is) when we activate interfaces
|
||||||
|
|
||||||
2004-12-15 Dan Williams <dcbw@redhat.com>
|
2004-12-15 Dan Williams <dcbw@redhat.com>
|
||||||
|
|
||||||
* Rework the DHCP code again to revert to sending full ethernet frames
|
* Rework the DHCP code again to revert to sending full ethernet frames
|
||||||
|
@@ -59,7 +59,7 @@ typedef enum NMDeviceType
|
|||||||
/*
|
/*
|
||||||
* Wireless network types
|
* Wireless network types
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum NMNetworkType
|
||||||
{
|
{
|
||||||
NETWORK_TYPE_UNKNOWN = 0,
|
NETWORK_TYPE_UNKNOWN = 0,
|
||||||
NETWORK_TYPE_ALLOWED,
|
NETWORK_TYPE_ALLOWED,
|
||||||
@@ -93,6 +93,17 @@ typedef enum NMDriverSupportLevel
|
|||||||
} NMDriverSupportLevel;
|
} NMDriverSupportLevel;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wireless network modes
|
||||||
|
*/
|
||||||
|
typedef enum NMNetworkMode
|
||||||
|
{
|
||||||
|
NETWORK_MODE_UNKNOWN = 0,
|
||||||
|
NETWORK_MODE_INFRA,
|
||||||
|
NETWORK_MODE_ADHOC
|
||||||
|
} NMNetworkMode;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Info-daemon specific preference locations
|
* Info-daemon specific preference locations
|
||||||
*/
|
*/
|
||||||
|
@@ -1,9 +1,11 @@
|
|||||||
INCLUDES = -I${top_srcdir} -I${top_srcdir}/src
|
INCLUDES = -I${top_srcdir} -I${top_srcdir}/src
|
||||||
|
|
||||||
AM_CPPFLAGS = \
|
AM_CPPFLAGS = \
|
||||||
$(NM_CFLAGS) \
|
$(NM_CFLAGS) \
|
||||||
-DBINDIR=\"$(bindir)\" \
|
-DBINDIR=\"$(bindir)\" \
|
||||||
-DDATADIR=\"$(datadir)\"
|
-DDATADIR=\"$(datadir)\" \
|
||||||
|
-DARP_DEBUG \
|
||||||
|
-DDEBUG
|
||||||
|
|
||||||
noinst_LIBRARIES = libdhcpc.a
|
noinst_LIBRARIES = libdhcpc.a
|
||||||
|
|
||||||
|
15
dhcpcd/arp.c
15
dhcpcd/arp.c
@@ -28,21 +28,6 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "arp.h"
|
#include "arp.h"
|
||||||
|
|
||||||
typedef struct arpMessage
|
|
||||||
{
|
|
||||||
struct packed_ether_header ethhdr;
|
|
||||||
u_short htype; /* hardware type (must be ARPHRD_ETHER) */
|
|
||||||
u_short ptype; /* protocol type (must be ETHERTYPE_IP) */
|
|
||||||
u_char hlen; /* hardware address length (must be 6) */
|
|
||||||
u_char plen; /* protocol address length (must be 4) */
|
|
||||||
u_short operation; /* ARP opcode */
|
|
||||||
u_char sHaddr[ETH_ALEN]; /* sender's hardware address */
|
|
||||||
u_char sInaddr[4]; /* sender's IP address */
|
|
||||||
u_char tHaddr[ETH_ALEN]; /* target's hardware address */
|
|
||||||
u_char tInaddr[4]; /* target's IP address */
|
|
||||||
u_char pad[18]; /* pad for min. Ethernet payload (60 bytes) */
|
|
||||||
} __attribute__((packed)) arpMessage;
|
|
||||||
|
|
||||||
#define BasicArpLen(A) (sizeof(A) - (sizeof(A.ethhdr) + sizeof(A.pad)))
|
#define BasicArpLen(A) (sizeof(A) - (sizeof(A.ethhdr) + sizeof(A.pad)))
|
||||||
|
|
||||||
extern int DebugFlag;
|
extern int DebugFlag;
|
||||||
|
18
dhcpcd/arp.h
18
dhcpcd/arp.h
@@ -23,6 +23,24 @@
|
|||||||
#ifndef ARP_H
|
#ifndef ARP_H
|
||||||
#define ARP_H
|
#define ARP_H
|
||||||
|
|
||||||
|
#include "client.h"
|
||||||
|
|
||||||
|
typedef struct arpMessage
|
||||||
|
{
|
||||||
|
struct packed_ether_header ethhdr;
|
||||||
|
u_short htype; /* hardware type (must be ARPHRD_ETHER) */
|
||||||
|
u_short ptype; /* protocol type (must be ETHERTYPE_IP) */
|
||||||
|
u_char hlen; /* hardware address length (must be 6) */
|
||||||
|
u_char plen; /* protocol address length (must be 4) */
|
||||||
|
u_short operation; /* ARP opcode */
|
||||||
|
u_char sHaddr[ETH_ALEN]; /* sender's hardware address */
|
||||||
|
u_char sInaddr[4]; /* sender's IP address */
|
||||||
|
u_char tHaddr[ETH_ALEN]; /* target's hardware address */
|
||||||
|
u_char tInaddr[4]; /* target's IP address */
|
||||||
|
u_char pad[18]; /* pad for min. Ethernet payload (60 bytes) */
|
||||||
|
} __attribute__((packed)) arpMessage;
|
||||||
|
|
||||||
|
|
||||||
#ifdef ARPCHECK
|
#ifdef ARPCHECK
|
||||||
int arpCheck(const dhcp_interface *iface);
|
int arpCheck(const dhcp_interface *iface);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -48,8 +48,11 @@
|
|||||||
#include "arp.h"
|
#include "arp.h"
|
||||||
#include "udpipgen.h"
|
#include "udpipgen.h"
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
int DebugFlag = 1;
|
int DebugFlag = 1;
|
||||||
#define DEBUG
|
#else
|
||||||
|
int DebugFlag = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef struct dhcp_response_return
|
typedef struct dhcp_response_return
|
||||||
{
|
{
|
||||||
@@ -984,6 +987,8 @@ int dhcp_inform(dhcp_interface *iface)
|
|||||||
return RET_DHCP_SUCCESS;
|
return RET_DHCP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
char *get_dhcp_option_name (int i)
|
char *get_dhcp_option_name (int i)
|
||||||
{
|
{
|
||||||
@@ -1080,3 +1085,4 @@ void debug_dump_dhcp_options (struct sockaddr_ll *saddr, dhcpMessage *dhcp_msg,
|
|||||||
saddr->sll_addr[4], saddr->sll_addr[5]);
|
saddr->sll_addr[4], saddr->sll_addr[5]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@@ -7,7 +7,8 @@ AM_CPPFLAGS = \
|
|||||||
-DDBUS_API_SUBJECT_TO_CHANGE \
|
-DDBUS_API_SUBJECT_TO_CHANGE \
|
||||||
-DG_DISABLE_DEPRECATED \
|
-DG_DISABLE_DEPRECATED \
|
||||||
-DBINDIR=\"$(bindir)\" \
|
-DBINDIR=\"$(bindir)\" \
|
||||||
-DDATADIR=\"$(datadir)\"
|
-DDATADIR=\"$(datadir)\" \
|
||||||
|
-DARP_DEBUG
|
||||||
|
|
||||||
bin_PROGRAMS = NetworkManager
|
bin_PROGRAMS = NetworkManager
|
||||||
|
|
||||||
@@ -34,7 +35,8 @@ NetworkManager_SOURCES = \
|
|||||||
NetworkManagerWireless.c \
|
NetworkManagerWireless.c \
|
||||||
NetworkManagerWireless.h \
|
NetworkManagerWireless.h \
|
||||||
NetworkManagerSystem.c \
|
NetworkManagerSystem.c \
|
||||||
NetworkManagerSystem.h
|
NetworkManagerSystem.h \
|
||||||
|
autoip.c
|
||||||
|
|
||||||
if !WITH_GCRYPT
|
if !WITH_GCRYPT
|
||||||
NetworkManager_SOURCES += gnome-keyring-md5.c gnome-keyring-md5.h
|
NetworkManager_SOURCES += gnome-keyring-md5.c gnome-keyring-md5.h
|
||||||
|
@@ -32,6 +32,7 @@ struct NMAccessPoint
|
|||||||
guint refcount;
|
guint refcount;
|
||||||
char *essid;
|
char *essid;
|
||||||
struct ether_addr *address;
|
struct ether_addr *address;
|
||||||
|
NMNetworkMode mode;
|
||||||
gint8 strength;
|
gint8 strength;
|
||||||
double freq;
|
double freq;
|
||||||
guint16 rate;
|
guint16 rate;
|
||||||
@@ -66,6 +67,7 @@ NMAccessPoint * nm_ap_new (void)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ap->mode = NETWORK_MODE_INFRA;
|
||||||
ap->refcount = 1;
|
ap->refcount = 1;
|
||||||
|
|
||||||
return (ap);
|
return (ap);
|
||||||
@@ -102,6 +104,7 @@ NMAccessPoint * nm_ap_new_from_ap (NMAccessPoint *src_ap)
|
|||||||
memcpy (new_addr, src_ap->address, sizeof (struct ether_addr));
|
memcpy (new_addr, src_ap->address, sizeof (struct ether_addr));
|
||||||
new_ap->address = new_addr;
|
new_ap->address = new_addr;
|
||||||
}
|
}
|
||||||
|
new_ap->mode = NETWORK_MODE_INFRA;
|
||||||
new_ap->strength = src_ap->strength;
|
new_ap->strength = src_ap->strength;
|
||||||
new_ap->freq = src_ap->freq;
|
new_ap->freq = src_ap->freq;
|
||||||
new_ap->rate = src_ap->rate;
|
new_ap->rate = src_ap->rate;
|
||||||
@@ -295,6 +298,25 @@ void nm_ap_set_address (NMAccessPoint *ap, const struct ether_addr * addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get/set functions for mode (ie Ad-Hoc, Infrastructure, etc)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
NMNetworkMode nm_ap_get_mode (NMAccessPoint *ap)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (ap != NULL, NETWORK_MODE_UNKNOWN);
|
||||||
|
|
||||||
|
return (ap->mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void nm_ap_set_mode (NMAccessPoint *ap, const NMNetworkMode mode)
|
||||||
|
{
|
||||||
|
g_return_if_fail (ap != NULL);
|
||||||
|
|
||||||
|
ap->mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get/set functions for strength
|
* Get/set functions for strength
|
||||||
*
|
*
|
||||||
@@ -306,7 +328,7 @@ gint8 nm_ap_get_strength (NMAccessPoint *ap)
|
|||||||
return (ap->strength);
|
return (ap->strength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nm_ap_set_strength (NMAccessPoint *ap, gint8 strength)
|
void nm_ap_set_strength (NMAccessPoint *ap, const gint8 strength)
|
||||||
{
|
{
|
||||||
g_return_if_fail (ap != NULL);
|
g_return_if_fail (ap != NULL);
|
||||||
|
|
||||||
@@ -325,7 +347,7 @@ double nm_ap_get_freq (NMAccessPoint *ap)
|
|||||||
return (ap->freq);
|
return (ap->freq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void nm_ap_set_freq (NMAccessPoint *ap, double freq)
|
void nm_ap_set_freq (NMAccessPoint *ap, const double freq)
|
||||||
{
|
{
|
||||||
g_return_if_fail (ap != NULL);
|
g_return_if_fail (ap != NULL);
|
||||||
|
|
||||||
|
@@ -50,6 +50,9 @@ void nm_ap_set_encrypted (NMAccessPoint *ap, gboolean encrypted);
|
|||||||
struct ether_addr * nm_ap_get_address (NMAccessPoint *ap);
|
struct ether_addr * nm_ap_get_address (NMAccessPoint *ap);
|
||||||
void nm_ap_set_address (NMAccessPoint *ap, const struct ether_addr *addr);
|
void nm_ap_set_address (NMAccessPoint *ap, const struct ether_addr *addr);
|
||||||
|
|
||||||
|
NMNetworkMode nm_ap_get_mode (NMAccessPoint *ap);
|
||||||
|
void nm_ap_set_mode (NMAccessPoint *ap, const NMNetworkMode mode);
|
||||||
|
|
||||||
gint8 nm_ap_get_strength (NMAccessPoint *ap);
|
gint8 nm_ap_get_strength (NMAccessPoint *ap);
|
||||||
void nm_ap_set_strength (NMAccessPoint *ap, gint8 strength);
|
void nm_ap_set_strength (NMAccessPoint *ap, gint8 strength);
|
||||||
|
|
||||||
|
@@ -32,6 +32,8 @@
|
|||||||
#include "NetworkManagerSystem.h"
|
#include "NetworkManagerSystem.h"
|
||||||
#include "../dhcpcd/client.h"
|
#include "../dhcpcd/client.h"
|
||||||
|
|
||||||
|
extern gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_device_dhcp_configure
|
* nm_device_dhcp_configure
|
||||||
@@ -55,7 +57,7 @@ static void nm_device_dhcp_configure (NMDevice *dev)
|
|||||||
nm_system_device_set_ip4_netmask (dev, temp);
|
nm_system_device_set_ip4_netmask (dev, temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, subnetMask))
|
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, broadcastAddr))
|
||||||
{
|
{
|
||||||
memcpy (&temp, dhcp_interface_get_dhcp_field (dev->dhcp_iface, broadcastAddr), dhcp_individual_value_len (broadcastAddr));
|
memcpy (&temp, dhcp_interface_get_dhcp_field (dev->dhcp_iface, broadcastAddr), dhcp_individual_value_len (broadcastAddr));
|
||||||
nm_system_device_set_ip4_broadcast (dev, temp);
|
nm_system_device_set_ip4_broadcast (dev, temp);
|
||||||
@@ -85,8 +87,9 @@ static void nm_device_dhcp_configure (NMDevice *dev)
|
|||||||
*/
|
*/
|
||||||
int nm_device_dhcp_request (NMDevice *dev)
|
int nm_device_dhcp_request (NMDevice *dev)
|
||||||
{
|
{
|
||||||
dhcp_client_options opts;
|
dhcp_client_options opts;
|
||||||
int err;
|
int err;
|
||||||
|
struct in_addr ip;
|
||||||
|
|
||||||
g_return_val_if_fail (dev != NULL, RET_DHCP_ERROR);
|
g_return_val_if_fail (dev != NULL, RET_DHCP_ERROR);
|
||||||
|
|
||||||
@@ -104,16 +107,32 @@ int nm_device_dhcp_request (NMDevice *dev)
|
|||||||
/* Start off in DHCP INIT state, get a completely new IP address
|
/* Start off in DHCP INIT state, get a completely new IP address
|
||||||
* and settings.
|
* and settings.
|
||||||
*/
|
*/
|
||||||
if ((err = dhcp_init (dev->dhcp_iface)) == RET_DHCP_BOUND)
|
err = dhcp_init (dev->dhcp_iface);
|
||||||
|
switch (err)
|
||||||
{
|
{
|
||||||
nm_device_dhcp_configure (dev);
|
case RET_DHCP_BOUND:
|
||||||
nm_device_update_ip4_address (dev);
|
nm_device_dhcp_configure (dev);
|
||||||
nm_device_dhcp_setup_timeouts (dev);
|
nm_device_update_ip4_address (dev);
|
||||||
}
|
nm_device_dhcp_setup_timeouts (dev);
|
||||||
else
|
break;
|
||||||
{
|
|
||||||
dhcp_interface_free (dev->dhcp_iface);
|
default:
|
||||||
dev->dhcp_iface = NULL;
|
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (err);
|
return (err);
|
||||||
|
@@ -238,9 +238,15 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
|
|||||||
dev->type = nm_device_test_wireless_extensions (dev) ?
|
dev->type = nm_device_test_wireless_extensions (dev) ?
|
||||||
DEVICE_TYPE_WIRELESS_ETHERNET : DEVICE_TYPE_WIRED_ETHERNET;
|
DEVICE_TYPE_WIRELESS_ETHERNET : DEVICE_TYPE_WIRED_ETHERNET;
|
||||||
|
|
||||||
|
/* Have to bring the device up before checking link status and other stuff */
|
||||||
|
nm_device_bring_up (dev);
|
||||||
|
|
||||||
/* Initialize wireless-specific options */
|
/* Initialize wireless-specific options */
|
||||||
if (nm_device_is_wireless (dev))
|
if (nm_device_is_wireless (dev))
|
||||||
{
|
{
|
||||||
|
iwrange range;
|
||||||
|
int sk;
|
||||||
|
|
||||||
if (!(dev->options.wireless.scan_mutex = g_mutex_new ()))
|
if (!(dev->options.wireless.scan_mutex = g_mutex_new ()))
|
||||||
{
|
{
|
||||||
g_free (dev->iface);
|
g_free (dev->iface);
|
||||||
@@ -266,17 +272,23 @@ NMDevice *nm_device_new (const char *iface, const char *udi, gboolean test_dev,
|
|||||||
dev->options.wireless.supports_wireless_scan = nm_device_supports_wireless_scan (dev);
|
dev->options.wireless.supports_wireless_scan = nm_device_supports_wireless_scan (dev);
|
||||||
|
|
||||||
/* Perform an initial wireless scan */
|
/* Perform an initial wireless scan */
|
||||||
nm_device_set_mode_managed (dev);
|
nm_device_set_mode (dev, NETWORK_MODE_INFRA);
|
||||||
nm_device_do_wireless_scan (dev);
|
nm_device_do_wireless_scan (dev);
|
||||||
nm_device_update_best_ap (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;
|
||||||
|
close (sk);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->driver_support_level = nm_get_driver_support_level (dev->app_data->hal_ctx, dev);
|
dev->driver_support_level = nm_get_driver_support_level (dev->app_data->hal_ctx, dev);
|
||||||
|
|
||||||
if (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED)
|
if (nm_device_get_driver_support_level (dev) != NM_DRIVER_UNSUPPORTED)
|
||||||
{
|
{
|
||||||
/* Have to bring the device up before checking link status. */
|
|
||||||
nm_device_bring_up (dev);
|
|
||||||
nm_device_update_link_active (dev, TRUE);
|
nm_device_update_link_active (dev, TRUE);
|
||||||
|
|
||||||
nm_device_update_ip4_address (dev);
|
nm_device_update_ip4_address (dev);
|
||||||
@@ -360,6 +372,28 @@ int nm_device_open_sock (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the amount of time we should wait for the device
|
||||||
|
* to get a link, based on the # of frequencies it has to
|
||||||
|
* scan.
|
||||||
|
*/
|
||||||
|
int nm_device_get_association_pause_value (NMDevice *dev)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (dev != NULL, 5);
|
||||||
|
g_return_val_if_fail (nm_device_is_wireless (dev), -1);
|
||||||
|
|
||||||
|
/* If the card supports more than 14 channels, we should probably wait
|
||||||
|
* around 10s so it can scan them all. 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).
|
||||||
|
*/
|
||||||
|
if (dev->options.wireless.num_freqs > 14)
|
||||||
|
return 10;
|
||||||
|
else
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get/set functions for UDI
|
* Get/set functions for UDI
|
||||||
*/
|
*/
|
||||||
@@ -485,7 +519,9 @@ static gboolean nm_device_wireless_link_active (NMDevice *dev)
|
|||||||
* seems to be whether the card has a valid access point MAC address.
|
* seems to be whether the card has a valid access point MAC address.
|
||||||
* Is there a better way?
|
* Is there a better way?
|
||||||
*/
|
*/
|
||||||
iwlib_socket = iw_sockets_open ();
|
if ((iwlib_socket = iw_sockets_open ()) < 0)
|
||||||
|
return (FALSE);
|
||||||
|
|
||||||
if (iw_get_ext (iwlib_socket, nm_device_get_iface (dev), SIOCGIWAP, &wrq) >= 0)
|
if (iw_get_ext (iwlib_socket, nm_device_get_iface (dev), SIOCGIWAP, &wrq) >= 0)
|
||||||
{
|
{
|
||||||
NMAccessPoint *best_ap;
|
NMAccessPoint *best_ap;
|
||||||
@@ -1152,58 +1188,54 @@ gboolean nm_device_is_up (NMDevice *dev)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_device_set_mode_managed
|
* nm_device_set_mode
|
||||||
*
|
*
|
||||||
* Set managed/infrastructure mode on a device (currently wireless only)
|
* Set managed/infrastructure/adhoc mode on a device (currently wireless only)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void nm_device_set_mode_managed (NMDevice *dev)
|
gboolean nm_device_set_mode (NMDevice *dev, const NMNetworkMode mode)
|
||||||
{
|
{
|
||||||
int sk;
|
int sk;
|
||||||
struct iwreq wreq;
|
gboolean success = FALSE;
|
||||||
|
|
||||||
g_return_if_fail (dev != NULL);
|
g_return_val_if_fail (dev != NULL, FALSE);
|
||||||
g_return_if_fail (nm_device_is_wireless (dev));
|
g_return_val_if_fail (nm_device_is_wireless (dev), FALSE);
|
||||||
|
g_return_val_if_fail ((mode == NETWORK_MODE_INFRA) || (mode == NETWORK_MODE_ADHOC), FALSE);
|
||||||
|
|
||||||
/* Force the card into Managed/Infrastructure mode */
|
/* Force the card into Managed/Infrastructure mode */
|
||||||
sk = iw_sockets_open ();
|
sk = iw_sockets_open ();
|
||||||
if (sk >= 0)
|
if (sk >= 0)
|
||||||
{
|
{
|
||||||
int err;
|
struct iwreq wreq;
|
||||||
wreq.u.mode = IW_MODE_INFRA;
|
int err;
|
||||||
err = iw_set_ext (sk, nm_device_get_iface (dev), SIOCSIWMODE, &wreq);
|
gboolean mode_good = FALSE;
|
||||||
if (err == -1)
|
|
||||||
syslog (LOG_ERR, "nm_device_set_mode_managed (%s): error setting card to Infrastructure mode. errno = %d", nm_device_get_iface (dev), errno);
|
switch (mode)
|
||||||
|
{
|
||||||
|
case NETWORK_MODE_INFRA:
|
||||||
|
wreq.u.mode = IW_MODE_INFRA;
|
||||||
|
mode_good = TRUE;
|
||||||
|
break;
|
||||||
|
case NETWORK_MODE_ADHOC:
|
||||||
|
wreq.u.mode = IW_MODE_ADHOC;
|
||||||
|
mode_good = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mode_good = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (mode_good)
|
||||||
|
{
|
||||||
|
err = iw_set_ext (sk, nm_device_get_iface (dev), SIOCSIWMODE, &wreq);
|
||||||
|
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);
|
||||||
|
}
|
||||||
close (sk);
|
close (sk);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
return (success);
|
||||||
/*
|
|
||||||
* nm_device_set_mode_adhoc
|
|
||||||
*
|
|
||||||
* Set Ad Hoc mode on a device (currently wireless only)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void nm_device_set_mode_adhoc (NMDevice *dev)
|
|
||||||
{
|
|
||||||
int sk;
|
|
||||||
struct iwreq wreq;
|
|
||||||
|
|
||||||
g_return_if_fail (dev != NULL);
|
|
||||||
g_return_if_fail (nm_device_is_wireless (dev));
|
|
||||||
|
|
||||||
/* Force the card into Adhoc mode */
|
|
||||||
sk = iw_sockets_open ();
|
|
||||||
if (sk >= 0)
|
|
||||||
{
|
|
||||||
int err;
|
|
||||||
wreq.u.mode = IW_MODE_ADHOC;
|
|
||||||
err = iw_set_ext (sk, nm_device_get_iface (dev), SIOCSIWMODE, &wreq);
|
|
||||||
if (err == -1)
|
|
||||||
syslog (LOG_ERR, "nm_device_set_mode_adhoc (%s): error setting card to Ad Hoc mode. errno = %d", nm_device_get_iface (dev), errno);
|
|
||||||
close (sk);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1273,13 +1305,13 @@ gboolean nm_device_activation_begin (NMDevice *dev)
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_device_activation_should_cancel
|
* nm_device_activation_handle_cancel
|
||||||
*
|
*
|
||||||
* Check whether we should stop activation, and if so clean up flags
|
* Check whether we should stop activation, and if so clean up flags
|
||||||
* and other random things.
|
* and other random things.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static gboolean nm_device_activation_should_cancel (NMDevice *dev)
|
static gboolean nm_device_activation_handle_cancel (NMDevice *dev)
|
||||||
{
|
{
|
||||||
g_return_val_if_fail (dev != NULL, TRUE);
|
g_return_val_if_fail (dev != NULL, TRUE);
|
||||||
|
|
||||||
@@ -1322,13 +1354,14 @@ static gboolean nm_device_set_wireless_config (NMDevice *dev, NMAccessPoint *ap,
|
|||||||
g_usleep (G_USEC_PER_SEC * 4);
|
g_usleep (G_USEC_PER_SEC * 4);
|
||||||
nm_device_bring_up (dev);
|
nm_device_bring_up (dev);
|
||||||
g_usleep (G_USEC_PER_SEC * 2);
|
g_usleep (G_USEC_PER_SEC * 2);
|
||||||
nm_device_set_mode_managed (dev);
|
nm_device_set_mode (dev, NETWORK_MODE_INFRA);
|
||||||
nm_device_set_essid (dev, " ");
|
nm_device_set_essid (dev, " ");
|
||||||
|
|
||||||
/* Disable encryption, then re-enable and set correct key on the card
|
/* Disable encryption, then re-enable and set correct key on the card
|
||||||
* if we are going to encrypt traffic.
|
* if we are going to encrypt traffic.
|
||||||
*/
|
*/
|
||||||
essid = nm_ap_get_essid (ap);
|
essid = nm_ap_get_essid (ap);
|
||||||
|
nm_device_set_mode (dev, nm_ap_get_mode (ap));
|
||||||
nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE);
|
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))
|
if (nm_ap_get_encrypted (ap) && nm_ap_get_enc_key_source (ap))
|
||||||
{
|
{
|
||||||
@@ -1344,8 +1377,11 @@ static gboolean nm_device_set_wireless_config (NMDevice *dev, NMAccessPoint *ap,
|
|||||||
((auth == NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM) ? "Open System" :
|
((auth == NM_DEVICE_AUTH_METHOD_OPEN_SYSTEM) ? "Open System" :
|
||||||
((auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY) ? "Shared Key" : "unknown")));
|
((auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY) ? "Shared Key" : "unknown")));
|
||||||
|
|
||||||
/* Bring the device up and pause to allow card to associate */
|
/* Bring the device up and pause to allow card to associate. After we set the ESSID
|
||||||
g_usleep (G_USEC_PER_SEC * 5);
|
* 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).
|
||||||
|
*/
|
||||||
|
g_usleep (G_USEC_PER_SEC * nm_device_get_association_pause_value (dev));
|
||||||
|
|
||||||
nm_device_update_link_active (dev, FALSE);
|
nm_device_update_link_active (dev, FALSE);
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
@@ -1403,7 +1439,7 @@ static gboolean nm_device_activate_wireless (NMDevice *dev)
|
|||||||
|
|
||||||
get_ap:
|
get_ap:
|
||||||
/* If we were told to quit activation, stop the thread and return */
|
/* If we were told to quit activation, stop the thread and return */
|
||||||
if (nm_device_activation_should_cancel (dev))
|
if (nm_device_activation_handle_cancel (dev))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Get a valid "best" access point we should connect to */
|
/* Get a valid "best" access point we should connect to */
|
||||||
@@ -1414,7 +1450,7 @@ get_ap:
|
|||||||
g_usleep (G_USEC_PER_SEC * 2);
|
g_usleep (G_USEC_PER_SEC * 2);
|
||||||
|
|
||||||
/* If we were told to quit activation, stop the thread and return */
|
/* If we were told to quit activation, stop the thread and return */
|
||||||
if (nm_device_activation_should_cancel (dev))
|
if (nm_device_activation_handle_cancel (dev))
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1465,7 +1501,7 @@ get_ap:
|
|||||||
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): user key received.", nm_device_get_iface (dev));
|
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): user key received.", nm_device_get_iface (dev));
|
||||||
|
|
||||||
/* If we were told to quit activation, stop the thread and return */
|
/* If we were told to quit activation, stop the thread and return */
|
||||||
if (nm_device_activation_should_cancel (dev))
|
if (nm_device_activation_handle_cancel (dev))
|
||||||
{
|
{
|
||||||
nm_ap_unref (best_ap);
|
nm_ap_unref (best_ap);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1484,7 +1520,7 @@ get_ap:
|
|||||||
int ip_success = FALSE;
|
int ip_success = FALSE;
|
||||||
|
|
||||||
/* If we were told to quit activation, stop the thread and return */
|
/* If we were told to quit activation, stop the thread and return */
|
||||||
if (nm_device_activation_should_cancel (dev))
|
if (nm_device_activation_handle_cancel (dev))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
nm_device_set_wireless_config (dev, best_ap, auth);
|
nm_device_set_wireless_config (dev, best_ap, auth);
|
||||||
@@ -1587,6 +1623,9 @@ static gboolean nm_device_activation_configure_ip (NMDevice *dev)
|
|||||||
success = nm_system_device_setup_static_ip4_config (dev);
|
success = nm_system_device_setup_static_ip4_config (dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
nm_system_restart_mdns_responder ();
|
||||||
|
|
||||||
return (success);
|
return (success);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1620,7 +1659,7 @@ static gpointer nm_device_activation_worker (gpointer user_data)
|
|||||||
syslog (LOG_DEBUG, "Activation (%s) IP configuration/DHCP returned = %d\n", nm_device_get_iface (dev), success);
|
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 */
|
/* If we were told to quit activation, stop the thread and return */
|
||||||
if (nm_device_activation_should_cancel (dev))
|
if (nm_device_activation_handle_cancel (dev))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
if (!success)
|
if (!success)
|
||||||
@@ -1640,7 +1679,7 @@ static gpointer nm_device_activation_worker (gpointer user_data)
|
|||||||
syslog (LOG_DEBUG, "Activation (%s) IP configuration/DHCP successful!\n", nm_device_get_iface (dev));
|
syslog (LOG_DEBUG, "Activation (%s) IP configuration/DHCP successful!\n", nm_device_get_iface (dev));
|
||||||
|
|
||||||
/* If we were told to quit activation, stop the thread and return */
|
/* If we were told to quit activation, stop the thread and return */
|
||||||
if (nm_device_activation_should_cancel (dev))
|
if (nm_device_activation_handle_cancel (dev))
|
||||||
{
|
{
|
||||||
syslog (LOG_DEBUG, "Activation (%s) told to cancel. Ending activation...\n", nm_device_get_iface (dev));
|
syslog (LOG_DEBUG, "Activation (%s) told to cancel. Ending activation...\n", nm_device_get_iface (dev));
|
||||||
goto out;
|
goto out;
|
||||||
@@ -1714,6 +1753,20 @@ gboolean nm_device_is_activating (NMDevice *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nm_device_activation_should_cancel
|
||||||
|
*
|
||||||
|
* Return whether or not we've been told to cancel activation
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
gboolean nm_device_activation_should_cancel (NMDevice *dev)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (dev != NULL, FALSE);
|
||||||
|
|
||||||
|
return (dev->quit_activation);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_device_did_activation_fail
|
* nm_device_did_activation_fail
|
||||||
*
|
*
|
||||||
@@ -2243,7 +2296,7 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
|
|||||||
g_usleep (G_USEC_PER_SEC * 4);
|
g_usleep (G_USEC_PER_SEC * 4);
|
||||||
|
|
||||||
/* Force the card into Managed/Infrastructure mode */
|
/* Force the card into Managed/Infrastructure mode */
|
||||||
nm_device_set_mode_managed (dev);
|
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)) && !nm_ap_get_encrypted (ap))
|
||||||
{
|
{
|
||||||
@@ -2296,9 +2349,12 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bring the device up and pause to allow card to associate */
|
/* 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);
|
nm_device_set_essid (dev, network);
|
||||||
g_usleep (G_USEC_PER_SEC * 3);
|
g_usleep (G_USEC_PER_SEC * nm_device_get_association_pause_value (dev));
|
||||||
|
|
||||||
nm_device_update_link_active (dev, FALSE);
|
nm_device_update_link_active (dev, FALSE);
|
||||||
nm_device_get_ap_address (dev, &addr);
|
nm_device_get_ap_address (dev, &addr);
|
||||||
@@ -2445,9 +2501,10 @@ static void nm_device_do_normal_scan (NMDevice *dev)
|
|||||||
{
|
{
|
||||||
/* Card hasn't had time yet to compile full access point list.
|
/* 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 it some more time and scan again. If that doesn't work
|
||||||
* give up.
|
* give up. Cards that need to scan more channels (Atheros 5212
|
||||||
|
* based cards, for example) need more time here.
|
||||||
*/
|
*/
|
||||||
g_usleep (G_USEC_PER_SEC / 2);
|
g_usleep ((G_USEC_PER_SEC * nm_device_get_association_pause_value (dev)) / 2);
|
||||||
err = iw_scan (iwlib_socket, (char *)nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
|
err = iw_scan (iwlib_socket, (char *)nm_device_get_iface (dev), WIRELESS_EXT, &scan_results);
|
||||||
if (err == -1)
|
if (err == -1)
|
||||||
{
|
{
|
||||||
@@ -2481,7 +2538,13 @@ static void nm_device_do_normal_scan (NMDevice *dev)
|
|||||||
NMAccessPoint *nm_ap = nm_ap_new ();
|
NMAccessPoint *nm_ap = nm_ap_new ();
|
||||||
|
|
||||||
/* Copy over info from scan to local structure */
|
/* Copy over info from scan to local structure */
|
||||||
if (!tmp_ap->b.has_essid || (tmp_ap->b.essid && !strlen (tmp_ap->b.essid)))
|
|
||||||
|
/* NOTE: some Cisco products actually broadcast "<hidden>" as their ESSID when they
|
||||||
|
* are set to not broadcast it, rather than just broadcasting a blank ESSID.
|
||||||
|
*/
|
||||||
|
if ( !tmp_ap->b.has_essid
|
||||||
|
|| (tmp_ap->b.essid && !strlen (tmp_ap->b.essid))
|
||||||
|
|| (tmp_ap->b.essid && !strcmp (tmp_ap->b.essid, "<hidden>")))
|
||||||
{
|
{
|
||||||
nm_ap_set_essid (nm_ap, NULL);
|
nm_ap_set_essid (nm_ap, NULL);
|
||||||
have_blank_essids = TRUE;
|
have_blank_essids = TRUE;
|
||||||
@@ -2497,6 +2560,26 @@ static void nm_device_do_normal_scan (NMDevice *dev)
|
|||||||
if (tmp_ap->has_ap_addr)
|
if (tmp_ap->has_ap_addr)
|
||||||
nm_ap_set_address (nm_ap, (const struct ether_addr *)(tmp_ap->ap_addr.sa_data));
|
nm_ap_set_address (nm_ap, (const struct ether_addr *)(tmp_ap->ap_addr.sa_data));
|
||||||
|
|
||||||
|
if (tmp_ap->b.has_mode)
|
||||||
|
{
|
||||||
|
NMNetworkMode mode = NETWORK_MODE_INFRA;
|
||||||
|
switch (tmp_ap->b.mode)
|
||||||
|
{
|
||||||
|
case IW_MODE_INFRA:
|
||||||
|
mode = NETWORK_MODE_INFRA;
|
||||||
|
break;
|
||||||
|
case IW_MODE_ADHOC:
|
||||||
|
mode = NETWORK_MODE_ADHOC;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mode = NETWORK_MODE_INFRA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nm_ap_set_mode (nm_ap, mode);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nm_ap_set_mode (nm_ap, NETWORK_MODE_INFRA);
|
||||||
|
|
||||||
nm_ap_set_strength (nm_ap, nm_wireless_qual_to_percent (dev, &(tmp_ap->stats.qual)));
|
nm_ap_set_strength (nm_ap, nm_wireless_qual_to_percent (dev, &(tmp_ap->stats.qual)));
|
||||||
|
|
||||||
if (tmp_ap->b.has_freq)
|
if (tmp_ap->b.has_freq)
|
||||||
@@ -2615,7 +2698,6 @@ static void nm_device_do_pseudo_scan (NMDevice *dev)
|
|||||||
/* Save the MAC address */
|
/* Save the MAC address */
|
||||||
nm_device_get_ap_address (dev, &save_ap_addr);
|
nm_device_get_ap_address (dev, &save_ap_addr);
|
||||||
|
|
||||||
nm_device_set_essid (dev, nm_ap_get_essid (ap));
|
|
||||||
if (nm_ap_get_enc_key_source (ap))
|
if (nm_ap_get_enc_key_source (ap))
|
||||||
{
|
{
|
||||||
char *hashed_key = nm_ap_get_enc_key_hashed (ap);
|
char *hashed_key = nm_ap_get_enc_key_hashed (ap);
|
||||||
@@ -2624,9 +2706,10 @@ static void nm_device_do_pseudo_scan (NMDevice *dev)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE);
|
nm_device_set_enc_key (dev, NULL, NM_DEVICE_AUTH_METHOD_NONE);
|
||||||
|
nm_device_set_essid (dev, nm_ap_get_essid (ap));
|
||||||
|
|
||||||
/* Wait a bit for association */
|
/* Wait a bit for association */
|
||||||
g_usleep (G_USEC_PER_SEC);
|
g_usleep (G_USEC_PER_SEC * nm_device_get_association_pause_value (dev));
|
||||||
|
|
||||||
/* Do we have a valid MAC address? */
|
/* Do we have a valid MAC address? */
|
||||||
nm_device_get_ap_address (dev, &cur_ap_addr);
|
nm_device_get_ap_address (dev, &cur_ap_addr);
|
||||||
|
@@ -79,8 +79,7 @@ void nm_device_do_wireless_scan (NMDevice *dev);
|
|||||||
gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network, const char *key, NMEncKeyType key_type,
|
gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network, const char *key, NMEncKeyType key_type,
|
||||||
struct ether_addr *addr, gboolean *encrypted);
|
struct ether_addr *addr, gboolean *encrypted);
|
||||||
|
|
||||||
void nm_device_set_mode_managed (NMDevice *dev);
|
gboolean nm_device_set_mode (NMDevice *dev, const NMNetworkMode mode);
|
||||||
void nm_device_set_mode_adhoc (NMDevice *dev);
|
|
||||||
|
|
||||||
gint8 nm_device_get_signal_strength (NMDevice *dev);
|
gint8 nm_device_get_signal_strength (NMDevice *dev);
|
||||||
void nm_device_update_signal_strength (NMDevice *dev);
|
void nm_device_update_signal_strength (NMDevice *dev);
|
||||||
@@ -104,6 +103,7 @@ void nm_device_set_enc_key (NMDevice *dev, const char *key, NMDeviceAuthMeth
|
|||||||
|
|
||||||
gboolean nm_device_activation_begin (NMDevice *dev);
|
gboolean nm_device_activation_begin (NMDevice *dev);
|
||||||
void nm_device_activation_cancel (NMDevice *dev);
|
void nm_device_activation_cancel (NMDevice *dev);
|
||||||
|
gboolean nm_device_activation_should_cancel (NMDevice *dev);
|
||||||
gboolean nm_device_is_just_activated (NMDevice *dev);
|
gboolean nm_device_is_just_activated (NMDevice *dev);
|
||||||
gboolean nm_device_is_activating (NMDevice *dev);
|
gboolean nm_device_is_activating (NMDevice *dev);
|
||||||
gboolean nm_device_did_activation_fail (NMDevice *dev);
|
gboolean nm_device_did_activation_fail (NMDevice *dev);
|
||||||
|
@@ -42,6 +42,7 @@ typedef struct NMDeviceWirelessOptions
|
|||||||
guint8 noise;
|
guint8 noise;
|
||||||
gint8 strength;
|
gint8 strength;
|
||||||
gint8 invalid_strength_counter;
|
gint8 invalid_strength_counter;
|
||||||
|
gint8 num_freqs;
|
||||||
|
|
||||||
GMutex *scan_mutex;
|
GMutex *scan_mutex;
|
||||||
/* We keep a couple lists around since wireless cards
|
/* We keep a couple lists around since wireless cards
|
||||||
|
@@ -112,7 +112,7 @@ gboolean nm_system_device_set_ip4_netmask (NMDevice *dev, int ip4_netmask)
|
|||||||
p->sin_family = AF_INET;
|
p->sin_family = AF_INET;
|
||||||
p->sin_addr.s_addr = ip4_netmask;
|
p->sin_addr.s_addr = ip4_netmask;
|
||||||
if (ioctl (sk, SIOCSIFNETMASK, &ifr) == -1)
|
if (ioctl (sk, SIOCSIFNETMASK, &ifr) == -1)
|
||||||
syslog (LOG_ERR,"nm_system_device_set_ip4_netmask (%s): failed to set IPv4 netmask!", iface);
|
syslog (LOG_ERR,"nm_system_device_set_ip4_netmask (%s): failed to set IPv4 netmask! errno = %s", iface, strerror (errno));
|
||||||
else
|
else
|
||||||
success = TRUE;
|
success = TRUE;
|
||||||
|
|
||||||
|
@@ -43,6 +43,7 @@ void nm_system_delete_default_route (void);
|
|||||||
void nm_system_kill_all_dhcp_daemons (void);
|
void nm_system_kill_all_dhcp_daemons (void);
|
||||||
void nm_system_update_dns (void);
|
void nm_system_update_dns (void);
|
||||||
void nm_system_load_device_modules (void);
|
void nm_system_load_device_modules (void);
|
||||||
|
void nm_system_restart_mdns_responder (void);
|
||||||
|
|
||||||
/* Prototyps for system-layer network functions (ie setting IP address, etc) */
|
/* Prototyps for system-layer network functions (ie setting IP address, etc) */
|
||||||
gboolean nm_system_device_set_ip4_address (NMDevice *dev, int ip4_address);
|
gboolean nm_system_device_set_ip4_address (NMDevice *dev, int ip4_address);
|
||||||
|
303
src/autoip.c
Normal file
303
src/autoip.c
Normal file
@@ -0,0 +1,303 @@
|
|||||||
|
// Based upon http://www.zeroconf.org/AVH-IPv4LL.c
|
||||||
|
// Merged into NetworkManager by Tom Parker <palfrey@tevp.net>
|
||||||
|
// Original copyright continues below
|
||||||
|
//
|
||||||
|
// ----------------------------------
|
||||||
|
// Simple IPv4 Link-Local addressing (see <http://www.zeroconf.org/>)
|
||||||
|
// @(#)llip.c, 1.5, Copyright 2003 by Arthur van Hoff (avh@strangeberry.com)
|
||||||
|
//
|
||||||
|
// This library is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU Lesser General Public
|
||||||
|
// License as published by the Free Software Foundation; either
|
||||||
|
// version 2.1 of the License, or (at your option) any later version.
|
||||||
|
// See <http://www.gnu.org/copyleft/lesser.html>
|
||||||
|
//
|
||||||
|
// This library 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
|
||||||
|
// Lesser General Public License for more details.
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netinet/ether.h>
|
||||||
|
#include <net/if.h>
|
||||||
|
#include <linux/sockios.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <glib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "../dhcpcd/arp.h"
|
||||||
|
#include "NetworkManager.h"
|
||||||
|
#include "NetworkManagerDevice.h"
|
||||||
|
#include "NetworkManagerMain.h"
|
||||||
|
|
||||||
|
// Times here are in seconds
|
||||||
|
#define LINKLOCAL_ADDR 0xa9fe0000
|
||||||
|
#define LINKLOCAL_BCAST 0xa9feffff
|
||||||
|
#define PROBE_NUM 3
|
||||||
|
#define PROBE_MIN 1
|
||||||
|
#define PROBE_MAX 2
|
||||||
|
#define ANNOUNCE_NUM 3
|
||||||
|
#define ANNOUNCE_INTERVAL 2
|
||||||
|
#define ANNOUNCE_WAIT 2
|
||||||
|
|
||||||
|
#define FAILURE_TIMEOUT 14
|
||||||
|
|
||||||
|
// Times here are in seconds
|
||||||
|
#define ARP_DEFAULT_LEASETIME 100
|
||||||
|
|
||||||
|
static struct in_addr null_ip = {0};
|
||||||
|
static struct ether_addr null_addr = {{0, 0, 0, 0, 0, 0}};
|
||||||
|
static struct ether_addr broadcast_addr = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pick a random link local IP address.
|
||||||
|
*/
|
||||||
|
static void pick(struct in_addr *ip)
|
||||||
|
{
|
||||||
|
ip->s_addr = htonl (LINKLOCAL_ADDR | ((abs(random()) % 0xFD00) + 0x0100));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send out an ARP packet.
|
||||||
|
*/
|
||||||
|
static gboolean arp(int fd, struct sockaddr *saddr, int op,
|
||||||
|
struct ether_addr *source_addr, struct in_addr source_ip,
|
||||||
|
struct ether_addr *target_addr, struct in_addr target_ip)
|
||||||
|
{
|
||||||
|
struct arpMessage p;
|
||||||
|
gboolean success = FALSE;
|
||||||
|
|
||||||
|
memset (&p, 0, sizeof (p));
|
||||||
|
|
||||||
|
/* ether header */
|
||||||
|
p.ethhdr.ether_type = htons (ETHERTYPE_ARP);
|
||||||
|
memcpy (p.ethhdr.ether_shost, source_addr, ETH_ALEN);
|
||||||
|
memcpy (p.ethhdr.ether_dhost, &broadcast_addr, ETH_ALEN);
|
||||||
|
|
||||||
|
/* arp request */
|
||||||
|
p.htype = htons (ARPHRD_ETHER);
|
||||||
|
p.ptype = htons (ETHERTYPE_IP);
|
||||||
|
p.hlen = ETH_ALEN;
|
||||||
|
p.plen = 4;
|
||||||
|
p.operation = htons (op);
|
||||||
|
memcpy (&p.sHaddr, source_addr, ETH_ALEN);
|
||||||
|
memcpy (&p.sInaddr, &source_ip, sizeof (p.sInaddr));
|
||||||
|
memcpy (&p.tHaddr, target_addr, ETH_ALEN);
|
||||||
|
memcpy (&p.tInaddr, &target_ip, sizeof (p.tInaddr));
|
||||||
|
|
||||||
|
/* send it */
|
||||||
|
if (sendto (fd, &p, sizeof (p), 0, saddr, sizeof (*saddr)) < 0)
|
||||||
|
syslog (LOG_ERR, "autoip ARP sendto() failed.");
|
||||||
|
else
|
||||||
|
success = TRUE;
|
||||||
|
|
||||||
|
return (success);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* Subtract the `struct timeval' values X and Y,
|
||||||
|
storing the result in RESULT.
|
||||||
|
Return 1 if the difference is negative, otherwise 0. */
|
||||||
|
static int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y)
|
||||||
|
{
|
||||||
|
/* Perform the carry for the later subtraction by updating Y. */
|
||||||
|
if (x->tv_usec < y->tv_usec)
|
||||||
|
{
|
||||||
|
int nsec = (y->tv_usec - x->tv_usec) / 1000000 + 1;
|
||||||
|
y->tv_usec -= 1000000 * nsec;
|
||||||
|
y->tv_sec += nsec;
|
||||||
|
}
|
||||||
|
if (x->tv_usec - y->tv_usec > 1000000)
|
||||||
|
{
|
||||||
|
int nsec = (x->tv_usec - y->tv_usec) / 1000000;
|
||||||
|
y->tv_usec += 1000000 * nsec;
|
||||||
|
y->tv_sec -= nsec;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compute the time remaining to wait.
|
||||||
|
`tv_usec' is certainly positive. */
|
||||||
|
result->tv_sec = x->tv_sec - y->tv_sec;
|
||||||
|
result->tv_usec = x->tv_usec - y->tv_usec;
|
||||||
|
|
||||||
|
/* Return 1 if result is negative. */
|
||||||
|
return x->tv_sec < y->tv_sec;
|
||||||
|
}
|
||||||
|
/*****************************************************************************/
|
||||||
|
/* "timeout" should be the future point in time when we wish to stop
|
||||||
|
* checking for data on the socket.
|
||||||
|
*/
|
||||||
|
static int peekfd (NMDevice *dev, int sk, struct timeval *timeout)
|
||||||
|
{
|
||||||
|
struct timeval diff;
|
||||||
|
struct timeval now;
|
||||||
|
|
||||||
|
/* Wake up each second to check whether or not we've been told
|
||||||
|
* to stop with iface->cease and check our timeout.
|
||||||
|
*/
|
||||||
|
gettimeofday (&now, NULL);
|
||||||
|
// syslog (LOG_INFO, "autoip waiting for data, overall timeout = {%ds, %dus}\n", (int)timeout->tv_sec, (int)timeout->tv_usec);
|
||||||
|
while (timeval_subtract (&diff, timeout, &now) == 0)
|
||||||
|
{
|
||||||
|
fd_set fs;
|
||||||
|
struct timeval wait = {1, 0};
|
||||||
|
// syslog (LOG_INFO, "autoip waiting for data, remaining timeout = {%ds, %dus}\n", (int)diff.tv_sec, (int)diff.tv_usec);
|
||||||
|
|
||||||
|
FD_ZERO (&fs);
|
||||||
|
FD_SET (sk, &fs);
|
||||||
|
|
||||||
|
if (select (sk+1, &fs, NULL, NULL, &wait) == -1)
|
||||||
|
return RET_DHCP_ERROR;
|
||||||
|
if (FD_ISSET(sk, &fs))
|
||||||
|
return RET_DHCP_SUCCESS;
|
||||||
|
if (nm_device_activation_should_cancel (dev))
|
||||||
|
return RET_DHCP_CEASED;
|
||||||
|
gettimeofday (&now, NULL);
|
||||||
|
};
|
||||||
|
return RET_DHCP_TIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip)
|
||||||
|
{
|
||||||
|
struct sockaddr saddr;
|
||||||
|
arpMessage p;
|
||||||
|
struct ifreq ifr;
|
||||||
|
struct ether_addr addr;
|
||||||
|
struct in_addr ip = {0};
|
||||||
|
int fd;
|
||||||
|
int timeout = 0;
|
||||||
|
int nprobes = 0;
|
||||||
|
int nannounce = 0;
|
||||||
|
gboolean success = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (dev != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (out_ip != NULL, FALSE);
|
||||||
|
|
||||||
|
out_ip->s_addr = 0;
|
||||||
|
|
||||||
|
/* initialize saddr */
|
||||||
|
memset (&saddr, 0, sizeof (saddr));
|
||||||
|
strncpy (saddr.sa_data, nm_device_get_iface (dev), sizeof (saddr.sa_data));
|
||||||
|
|
||||||
|
/* open an ARP socket */
|
||||||
|
if ((fd = socket (PF_PACKET, SOCK_PACKET, htons (ETH_P_ARP))) < 0)
|
||||||
|
{
|
||||||
|
syslog (LOG_ERR, "%s: Couldn't open network control socket.", nm_device_get_iface (dev));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bind to the ARP socket */
|
||||||
|
if (bind (fd, &saddr, sizeof (saddr)) < 0)
|
||||||
|
{
|
||||||
|
syslog (LOG_ERR, "%s: Couldn't bind to the device.", nm_device_get_iface (dev));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
nm_device_get_hw_address (dev, addr.ether_addr_octet);
|
||||||
|
|
||||||
|
/* initialize pseudo random selection of IP addresses */
|
||||||
|
srandom ( (addr.ether_addr_octet[ETHER_ADDR_LEN-4] << 24) |
|
||||||
|
(addr.ether_addr_octet[ETHER_ADDR_LEN-3] << 16) |
|
||||||
|
(addr.ether_addr_octet[ETHER_ADDR_LEN-2] << 8) |
|
||||||
|
(addr.ether_addr_octet[ETHER_ADDR_LEN-1] << 0));
|
||||||
|
|
||||||
|
/* pick an ip address */
|
||||||
|
if (ip.s_addr == 0)
|
||||||
|
pick (&ip);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
struct timeval timeout;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* Make sure we haven't been told to quit */
|
||||||
|
if (nm_device_activation_should_cancel (dev))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (nprobes < PROBE_NUM)
|
||||||
|
{
|
||||||
|
syslog (LOG_INFO, "autoip: Sending probe #%d for IP address %s.", nprobes, inet_ntoa (ip));
|
||||||
|
arp (fd, &saddr, ARPOP_REQUEST, &addr, null_ip, &null_addr, ip);
|
||||||
|
nprobes++;
|
||||||
|
gettimeofday (&timeout, NULL);
|
||||||
|
if (nprobes == PROBE_NUM)
|
||||||
|
{
|
||||||
|
/* Link local specifies a different interval between
|
||||||
|
* the end of probe requests and announce packets.
|
||||||
|
*/
|
||||||
|
timeout.tv_sec += ANNOUNCE_WAIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME: we need to randomize the timeout _between_ MIN and MAX */
|
||||||
|
timeout.tv_sec += PROBE_MIN;
|
||||||
|
timeout.tv_usec += (random () % 200000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (nannounce < ANNOUNCE_NUM)
|
||||||
|
{
|
||||||
|
syslog (LOG_INFO, "autoip: Sending announce #%d for IP address %s.", nannounce, inet_ntoa (ip));
|
||||||
|
arp (fd, &saddr, ARPOP_REQUEST, &addr, ip, &addr, ip);
|
||||||
|
nannounce++;
|
||||||
|
gettimeofday (&timeout, NULL);
|
||||||
|
timeout.tv_sec += ANNOUNCE_INTERVAL;
|
||||||
|
timeout.tv_usec += (random () % 200000);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Use our address! */
|
||||||
|
memcpy (out_ip, &ip, sizeof (ip));
|
||||||
|
success = TRUE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
syslog (LOG_INFO, "autoip: Waiting for reply...");
|
||||||
|
err = peekfd (dev, fd, &timeout);
|
||||||
|
if ((err == RET_DHCP_ERROR) || (err == RET_DHCP_CEASED))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* There's some data waiting for us */
|
||||||
|
if (err == RET_DHCP_SUCCESS)
|
||||||
|
{
|
||||||
|
syslog (LOG_INFO, "autoip: Got some data to check for reply packet.");
|
||||||
|
|
||||||
|
/* read ARP packet */
|
||||||
|
if (recv (fd, &p, sizeof (p), 0) < 0)
|
||||||
|
{
|
||||||
|
syslog (LOG_ERR, "autoip: packet receive failure, ignoring it.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ( (ntohs (p.ethhdr.ether_type) == ETHERTYPE_ARP)
|
||||||
|
&& (ntohs (p.operation) == ARPOP_REPLY)
|
||||||
|
&& ((uint32_t)(*p.tInaddr) == ip.s_addr)
|
||||||
|
&& (memcmp (&addr, &p.tHaddr, ETH_ALEN) != 0))
|
||||||
|
{
|
||||||
|
#ifdef ARP_DEBUG
|
||||||
|
syslog(LOG_ERR, "autoip: (%s) ARP conflict for IP address %s.\n", nm_device_get_iface (dev), inet_ntoa(ip));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Ok, start all over again */
|
||||||
|
pick (&ip);
|
||||||
|
nprobes = 0;
|
||||||
|
nannounce = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (fd >= 0)
|
||||||
|
close (fd);
|
||||||
|
return (success);
|
||||||
|
}
|
@@ -442,3 +442,14 @@ void nm_system_load_device_modules (void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nm_system_restart_mdns_responder
|
||||||
|
*
|
||||||
|
* Restart the multicast DNS responder so that it knows about new
|
||||||
|
* network interfaces and IP addresses.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void nm_system_restart_mdns_responder (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
@@ -25,8 +25,13 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
/* get strnlen */
|
||||||
|
#define __USE_GNU
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "NetworkManagerSystem.h"
|
#include "NetworkManagerSystem.h"
|
||||||
#include "NetworkManagerUtils.h"
|
#include "NetworkManagerUtils.h"
|
||||||
|
|
||||||
@@ -56,7 +61,7 @@ void nm_system_init (void)
|
|||||||
gboolean nm_system_device_run_dhcp (NMDevice *dev)
|
gboolean nm_system_device_run_dhcp (NMDevice *dev)
|
||||||
{
|
{
|
||||||
char buf [500];
|
char buf [500];
|
||||||
char *iface;
|
const char *iface;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
g_return_val_if_fail (dev != NULL, FALSE);
|
g_return_val_if_fail (dev != NULL, FALSE);
|
||||||
@@ -168,7 +173,7 @@ gboolean nm_system_device_setup_static_ip4_config (NMDevice *dev)
|
|||||||
struct in_addr ip_addr, net_addr, broad_addr, gate_addr;
|
struct in_addr ip_addr, net_addr, broad_addr, gate_addr;
|
||||||
int i, err;
|
int i, err;
|
||||||
guint32 prefix = IPBITS;
|
guint32 prefix = IPBITS;
|
||||||
char *iface;
|
const char *iface;
|
||||||
char *buf;
|
char *buf;
|
||||||
char *addr, *netmask, *broadcast, *gateway;
|
char *addr, *netmask, *broadcast, *gateway;
|
||||||
|
|
||||||
@@ -269,6 +274,20 @@ void nm_system_load_device_modules (void)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nm_system_restart_mdns_responder
|
||||||
|
*
|
||||||
|
* Restart the multicast DNS responder so that it knows about new
|
||||||
|
* network interfaces and IP addresses.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void nm_system_restart_mdns_responder (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_system_device_update_config_info
|
* nm_system_device_update_config_info
|
||||||
*
|
*
|
||||||
|
@@ -328,6 +328,31 @@ void nm_system_load_device_modules (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nm_system_restart_mdns_responder
|
||||||
|
*
|
||||||
|
* Restart the multicast DNS responder so that it knows about new
|
||||||
|
* network interfaces and IP addresses.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void nm_system_restart_mdns_responder (void)
|
||||||
|
{
|
||||||
|
FILE *fp = NULL;
|
||||||
|
|
||||||
|
if ((fp = fopen ("/var/run/mDNSResponder.pid", "rt")))
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
int res = fscanf (fp, "%d", &pid);
|
||||||
|
fclose (fp);
|
||||||
|
if (res == 1)
|
||||||
|
{
|
||||||
|
syslog (LOG_INFO, "Restarting mDNSResponder.\n");
|
||||||
|
kill (pid, SIGUSR1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* nm_system_device_update_config_info
|
* nm_system_device_update_config_info
|
||||||
*
|
*
|
||||||
|
@@ -243,4 +243,14 @@ void nm_system_load_device_modules (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nm_system_restart_mdns_responder
|
||||||
|
*
|
||||||
|
* Restart the multicast DNS responder so that it knows about new
|
||||||
|
* network interfaces and IP addresses.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void nm_system_restart_mdns_responder (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user