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>
|
||||
|
||||
* Rework the DHCP code again to revert to sending full ethernet frames
|
||||
|
@@ -59,7 +59,7 @@ typedef enum NMDeviceType
|
||||
/*
|
||||
* Wireless network types
|
||||
*/
|
||||
typedef enum
|
||||
typedef enum NMNetworkType
|
||||
{
|
||||
NETWORK_TYPE_UNKNOWN = 0,
|
||||
NETWORK_TYPE_ALLOWED,
|
||||
@@ -93,6 +93,17 @@ typedef enum NMDriverSupportLevel
|
||||
} NMDriverSupportLevel;
|
||||
|
||||
|
||||
/*
|
||||
* Wireless network modes
|
||||
*/
|
||||
typedef enum NMNetworkMode
|
||||
{
|
||||
NETWORK_MODE_UNKNOWN = 0,
|
||||
NETWORK_MODE_INFRA,
|
||||
NETWORK_MODE_ADHOC
|
||||
} NMNetworkMode;
|
||||
|
||||
|
||||
/*
|
||||
* Info-daemon specific preference locations
|
||||
*/
|
||||
|
@@ -3,7 +3,9 @@ INCLUDES = -I${top_srcdir} -I${top_srcdir}/src
|
||||
AM_CPPFLAGS = \
|
||||
$(NM_CFLAGS) \
|
||||
-DBINDIR=\"$(bindir)\" \
|
||||
-DDATADIR=\"$(datadir)\"
|
||||
-DDATADIR=\"$(datadir)\" \
|
||||
-DARP_DEBUG \
|
||||
-DDEBUG
|
||||
|
||||
noinst_LIBRARIES = libdhcpc.a
|
||||
|
||||
|
15
dhcpcd/arp.c
15
dhcpcd/arp.c
@@ -28,21 +28,6 @@
|
||||
#include "client.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)))
|
||||
|
||||
extern int DebugFlag;
|
||||
|
18
dhcpcd/arp.h
18
dhcpcd/arp.h
@@ -23,6 +23,24 @@
|
||||
#ifndef 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
|
||||
int arpCheck(const dhcp_interface *iface);
|
||||
#endif
|
||||
|
@@ -48,8 +48,11 @@
|
||||
#include "arp.h"
|
||||
#include "udpipgen.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
int DebugFlag = 1;
|
||||
#define DEBUG
|
||||
#else
|
||||
int DebugFlag = 0;
|
||||
#endif
|
||||
|
||||
typedef struct dhcp_response_return
|
||||
{
|
||||
@@ -984,6 +987,8 @@ int dhcp_inform(dhcp_interface *iface)
|
||||
return RET_DHCP_SUCCESS;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
/*****************************************************************************/
|
||||
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]);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@@ -7,7 +7,8 @@ AM_CPPFLAGS = \
|
||||
-DDBUS_API_SUBJECT_TO_CHANGE \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
-DBINDIR=\"$(bindir)\" \
|
||||
-DDATADIR=\"$(datadir)\"
|
||||
-DDATADIR=\"$(datadir)\" \
|
||||
-DARP_DEBUG
|
||||
|
||||
bin_PROGRAMS = NetworkManager
|
||||
|
||||
@@ -34,7 +35,8 @@ NetworkManager_SOURCES = \
|
||||
NetworkManagerWireless.c \
|
||||
NetworkManagerWireless.h \
|
||||
NetworkManagerSystem.c \
|
||||
NetworkManagerSystem.h
|
||||
NetworkManagerSystem.h \
|
||||
autoip.c
|
||||
|
||||
if !WITH_GCRYPT
|
||||
NetworkManager_SOURCES += gnome-keyring-md5.c gnome-keyring-md5.h
|
||||
|
@@ -32,6 +32,7 @@ struct NMAccessPoint
|
||||
guint refcount;
|
||||
char *essid;
|
||||
struct ether_addr *address;
|
||||
NMNetworkMode mode;
|
||||
gint8 strength;
|
||||
double freq;
|
||||
guint16 rate;
|
||||
@@ -66,6 +67,7 @@ NMAccessPoint * nm_ap_new (void)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ap->mode = NETWORK_MODE_INFRA;
|
||||
ap->refcount = 1;
|
||||
|
||||
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));
|
||||
new_ap->address = new_addr;
|
||||
}
|
||||
new_ap->mode = NETWORK_MODE_INFRA;
|
||||
new_ap->strength = src_ap->strength;
|
||||
new_ap->freq = src_ap->freq;
|
||||
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
|
||||
*
|
||||
@@ -306,7 +328,7 @@ gint8 nm_ap_get_strength (NMAccessPoint *ap)
|
||||
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);
|
||||
|
||||
@@ -325,7 +347,7 @@ double nm_ap_get_freq (NMAccessPoint *ap)
|
||||
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);
|
||||
|
||||
|
@@ -50,6 +50,9 @@ void nm_ap_set_encrypted (NMAccessPoint *ap, gboolean encrypted);
|
||||
struct ether_addr * nm_ap_get_address (NMAccessPoint *ap);
|
||||
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);
|
||||
void nm_ap_set_strength (NMAccessPoint *ap, gint8 strength);
|
||||
|
||||
|
@@ -32,6 +32,8 @@
|
||||
#include "NetworkManagerSystem.h"
|
||||
#include "../dhcpcd/client.h"
|
||||
|
||||
extern gboolean get_autoip (NMDevice *dev, struct in_addr *out_ip);
|
||||
|
||||
|
||||
/*
|
||||
* nm_device_dhcp_configure
|
||||
@@ -55,7 +57,7 @@ static void nm_device_dhcp_configure (NMDevice *dev)
|
||||
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));
|
||||
nm_system_device_set_ip4_broadcast (dev, temp);
|
||||
@@ -87,6 +89,7 @@ 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);
|
||||
|
||||
@@ -104,16 +107,32 @@ int nm_device_dhcp_request (NMDevice *dev)
|
||||
/* Start off in DHCP INIT state, get a completely new IP address
|
||||
* and settings.
|
||||
*/
|
||||
if ((err = dhcp_init (dev->dhcp_iface)) == RET_DHCP_BOUND)
|
||||
err = dhcp_init (dev->dhcp_iface);
|
||||
switch (err)
|
||||
{
|
||||
case RET_DHCP_BOUND:
|
||||
nm_device_dhcp_configure (dev);
|
||||
nm_device_update_ip4_address (dev);
|
||||
nm_device_dhcp_setup_timeouts (dev);
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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) ?
|
||||
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 */
|
||||
if (nm_device_is_wireless (dev))
|
||||
{
|
||||
iwrange range;
|
||||
int sk;
|
||||
|
||||
if (!(dev->options.wireless.scan_mutex = g_mutex_new ()))
|
||||
{
|
||||
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);
|
||||
|
||||
/* 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_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);
|
||||
|
||||
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_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
|
||||
*/
|
||||
@@ -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.
|
||||
* 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)
|
||||
{
|
||||
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;
|
||||
struct iwreq wreq;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
g_return_if_fail (nm_device_is_wireless (dev));
|
||||
g_return_val_if_fail (dev != NULL, FALSE);
|
||||
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 */
|
||||
sk = iw_sockets_open ();
|
||||
if (sk >= 0)
|
||||
{
|
||||
int err;
|
||||
wreq.u.mode = IW_MODE_INFRA;
|
||||
err = iw_set_ext (sk, nm_device_get_iface (dev), SIOCSIWMODE, &wreq);
|
||||
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);
|
||||
close (sk);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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;
|
||||
gboolean mode_good = FALSE;
|
||||
|
||||
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 == -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);
|
||||
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);
|
||||
}
|
||||
|
||||
return (success);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
* 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);
|
||||
|
||||
@@ -1322,13 +1354,14 @@ static gboolean nm_device_set_wireless_config (NMDevice *dev, NMAccessPoint *ap,
|
||||
g_usleep (G_USEC_PER_SEC * 4);
|
||||
nm_device_bring_up (dev);
|
||||
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, " ");
|
||||
|
||||
/* Disable encryption, then re-enable and set correct key on the card
|
||||
* if we are going to encrypt traffic.
|
||||
*/
|
||||
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);
|
||||
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_SHARED_KEY) ? "Shared Key" : "unknown")));
|
||||
|
||||
/* Bring the device up and pause to allow card to associate */
|
||||
g_usleep (G_USEC_PER_SEC * 5);
|
||||
/* Bring the device up and 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).
|
||||
*/
|
||||
g_usleep (G_USEC_PER_SEC * nm_device_get_association_pause_value (dev));
|
||||
|
||||
nm_device_update_link_active (dev, FALSE);
|
||||
success = TRUE;
|
||||
@@ -1403,7 +1439,7 @@ static gboolean nm_device_activate_wireless (NMDevice *dev)
|
||||
|
||||
get_ap:
|
||||
/* 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;
|
||||
|
||||
/* Get a valid "best" access point we should connect to */
|
||||
@@ -1414,7 +1450,7 @@ get_ap:
|
||||
g_usleep (G_USEC_PER_SEC * 2);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -1465,7 +1501,7 @@ get_ap:
|
||||
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 (nm_device_activation_should_cancel (dev))
|
||||
if (nm_device_activation_handle_cancel (dev))
|
||||
{
|
||||
nm_ap_unref (best_ap);
|
||||
goto out;
|
||||
@@ -1484,7 +1520,7 @@ get_ap:
|
||||
int ip_success = FALSE;
|
||||
|
||||
/* 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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (success)
|
||||
nm_system_restart_mdns_responder ();
|
||||
|
||||
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);
|
||||
|
||||
/* 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;
|
||||
|
||||
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));
|
||||
|
||||
/* 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));
|
||||
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
|
||||
*
|
||||
@@ -2243,7 +2296,7 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
|
||||
g_usleep (G_USEC_PER_SEC * 4);
|
||||
|
||||
/* 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))
|
||||
{
|
||||
@@ -2296,9 +2349,12 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
|
||||
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);
|
||||
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_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.
|
||||
* 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);
|
||||
if (err == -1)
|
||||
{
|
||||
@@ -2481,7 +2538,13 @@ static void nm_device_do_normal_scan (NMDevice *dev)
|
||||
NMAccessPoint *nm_ap = nm_ap_new ();
|
||||
|
||||
/* 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);
|
||||
have_blank_essids = TRUE;
|
||||
@@ -2497,6 +2560,26 @@ static void nm_device_do_normal_scan (NMDevice *dev)
|
||||
if (tmp_ap->has_ap_addr)
|
||||
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)));
|
||||
|
||||
if (tmp_ap->b.has_freq)
|
||||
@@ -2615,7 +2698,6 @@ static void nm_device_do_pseudo_scan (NMDevice *dev)
|
||||
/* Save the MAC address */
|
||||
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))
|
||||
{
|
||||
char *hashed_key = nm_ap_get_enc_key_hashed (ap);
|
||||
@@ -2624,9 +2706,10 @@ static void nm_device_do_pseudo_scan (NMDevice *dev)
|
||||
}
|
||||
else
|
||||
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 */
|
||||
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? */
|
||||
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,
|
||||
struct ether_addr *addr, gboolean *encrypted);
|
||||
|
||||
void nm_device_set_mode_managed (NMDevice *dev);
|
||||
void nm_device_set_mode_adhoc (NMDevice *dev);
|
||||
gboolean nm_device_set_mode (NMDevice *dev, const NMNetworkMode mode);
|
||||
|
||||
gint8 nm_device_get_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);
|
||||
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_activating (NMDevice *dev);
|
||||
gboolean nm_device_did_activation_fail (NMDevice *dev);
|
||||
|
@@ -42,6 +42,7 @@ typedef struct NMDeviceWirelessOptions
|
||||
guint8 noise;
|
||||
gint8 strength;
|
||||
gint8 invalid_strength_counter;
|
||||
gint8 num_freqs;
|
||||
|
||||
GMutex *scan_mutex;
|
||||
/* 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_addr.s_addr = ip4_netmask;
|
||||
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
|
||||
success = TRUE;
|
||||
|
||||
|
@@ -43,6 +43,7 @@ void nm_system_delete_default_route (void);
|
||||
void nm_system_kill_all_dhcp_daemons (void);
|
||||
void nm_system_update_dns (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) */
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* get strnlen */
|
||||
#define __USE_GNU
|
||||
#include <string.h>
|
||||
|
||||
#include "NetworkManagerSystem.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
||||
@@ -56,7 +61,7 @@ void nm_system_init (void)
|
||||
gboolean nm_system_device_run_dhcp (NMDevice *dev)
|
||||
{
|
||||
char buf [500];
|
||||
char *iface;
|
||||
const char *iface;
|
||||
int err;
|
||||
|
||||
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;
|
||||
int i, err;
|
||||
guint32 prefix = IPBITS;
|
||||
char *iface;
|
||||
const char *iface;
|
||||
char *buf;
|
||||
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
|
||||
*
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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