2004-11-22 Dan Williams <dcbw@redhat.com>

* src/NetworkManagerDevicePrivate.h
		- Split out the NMDevice struct to a different file so that stuff like
			NetworkManagerDHCP.c and NetworkManagerSystem.c can use it

	* dhcpcd/client.c
		- fprintf->syslog
		- (dhcpSendAndRecv): do non-blocking sends and receives, and check to see if we
			need to cancel the dhcp request during the send and recv

	* dhcpcd/client.h
		- Move the DHCP option enum to dhcpcd.h

	* src/NetworkManagerDHCP.c
		- Split out the actual IP/netmask/etc setting code
		- New Renew/Rebind functions
		- New timer setup function for renew/rebind operations

	* src/NetworkManagerDevice.c
		- For device activation, if we are using DHCP then keep the activation thread
			alive until device deactivation.  We need to renew/rebind the DHCP address
			after the T1 (renew) and T2 (rebind) times have expired.
		- Increase some timeouts after bringing wireless cards up/down


git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@320 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams 2004-11-22 14:42:34 +00:00
parent 498d3f8773
commit 86ac9e930d
11 changed files with 504 additions and 251 deletions

View file

@ -1,3 +1,28 @@
2004-11-22 Dan Williams <dcbw@redhat.com>
* src/NetworkManagerDevicePrivate.h
- Split out the NMDevice struct to a different file so that stuff like
NetworkManagerDHCP.c and NetworkManagerSystem.c can use it
* dhcpcd/client.c
- fprintf->syslog
- (dhcpSendAndRecv): do non-blocking sends and receives, and check to see if we
need to cancel the dhcp request during the send and recv
* dhcpcd/client.h
- Move the DHCP option enum to dhcpcd.h
* src/NetworkManagerDHCP.c
- Split out the actual IP/netmask/etc setting code
- New Renew/Rebind functions
- New timer setup function for renew/rebind operations
* src/NetworkManagerDevice.c
- For device activation, if we are using DHCP then keep the activation thread
alive until device deactivation. We need to renew/rebind the DHCP address
after the T1 (renew) and T2 (rebind) times have expired.
- Increase some timeouts after bringing wireless cards up/down
2004-11-17 Dan Williams <dcbw@redhat.com>
* Cache access point MAC addresses in NetworkManagerInfo after you've explicitly

View file

@ -295,7 +295,7 @@ void classIDsetup(dhcp_interface *iface, const char *g_cls_id)
{
struct utsname sname;
if ( uname(&sname) )
syslog(LOG_ERR,"classIDsetup: uname: %m\n");
syslog (LOG_ERR,"classIDsetup: uname: %m\n");
snprintf (iface->cls_id, DHCP_CLASS_ID_MAX_LEN, "%s %s %s",
sname.sysname, sname.release, sname.machine);
}
@ -506,7 +506,7 @@ int dhcpSendAndRecv (dhcp_interface *iface, unsigned int expected_reply_type,
{
udpipMessage *udp_msg_recv = NULL;
struct sockaddr addr;
int len, err, local_timeout = 0;
int len, err = RET_DHCP_TIMEOUT, local_timeout = 0;
int j = DHCP_INITIAL_RTO / 2;
struct timeval local_begin, current, diff;
struct timeval overall_end;
@ -519,6 +519,7 @@ int dhcpSendAndRecv (dhcp_interface *iface, unsigned int expected_reply_type,
do
{
udpipMessage *udp_msg_send = buildUdpIpMsg (iface);
int send_err = 0;
if (!udp_msg_send)
return RET_DHCP_ERROR;
@ -546,12 +547,16 @@ int dhcpSendAndRecv (dhcp_interface *iface, unsigned int expected_reply_type,
memset (&addr, 0, sizeof(struct sockaddr));
memcpy (addr.sa_data, iface->iface, strlen (iface->iface));
if (sendto (iface->sk, udp_msg_send, len, 0, &addr, sizeof(struct sockaddr)) == -1)
do
{
syslog (LOG_ERR,"sendto: %m\n");
free (udp_msg_send);
return RET_DHCP_ERROR;
}
send_err = sendto (iface->sk, udp_msg_send, len, MSG_DONTWAIT, &addr, sizeof(struct sockaddr));
if (iface->cease || ((send_err == -1) && (errno != EAGAIN)))
{
free (udp_msg_send);
return iface->cease ? RET_DHCP_CEASED : RET_DHCP_ERROR;
}
} while ((send_err == -1) && (errno == EAGAIN));
free (udp_msg_send);
gettimeofday (&local_begin, NULL);
err = peekfd (iface, (j + random () % 200000));
@ -571,13 +576,15 @@ int dhcpSendAndRecv (dhcp_interface *iface, unsigned int expected_reply_type,
udp_msg_recv = calloc (1, sizeof (udpipMessage));
o = sizeof (struct sockaddr);
len = recvfrom (iface->sk, udp_msg_recv, sizeof(udpipMessage), 0, (struct sockaddr *)&addr, &o);
if (len == -1)
do
{
syslog(LOG_ERR,"recvfrom: %m\n");
free (udp_msg_recv);
return RET_DHCP_ERROR;
}
len = recvfrom (iface->sk, udp_msg_recv, sizeof(udpipMessage), MSG_DONTWAIT, (struct sockaddr *)&addr, &o);
if (iface->cease || ((len == -1) && (errno != EAGAIN)))
{
free (udp_msg_recv);
return iface->cease ? RET_DHCP_CEASED : RET_DHCP_ERROR;
}
} while ((len == -1) && (errno == EAGAIN));
if (iface->bTokenRing)
{ /* Here we convert a TR frame into an Eth frame */
@ -752,7 +759,7 @@ int dhcp_init (dhcp_interface *iface)
releaseDhcpOptions (iface);
#ifdef DEBUG
fprintf(stderr,"ClassID = \"%s\"\n"
syslog (LOG_DEBUG, "ClassID = \"%s\"\n"
"ClientID = \"%u.%u.%u.%02X.%02X.%02X.%02X.%02X.%02X\"\n", iface->cls_id,
iface->cli_id[0], iface->cli_id[1], iface->cli_id[2],
iface->cli_id[3], iface->cli_id[4], iface->cli_id[5],
@ -760,7 +767,7 @@ int dhcp_init (dhcp_interface *iface)
#endif
if ( DebugFlag )
syslog (LOG_DEBUG,"broadcasting DHCP_DISCOVER\n");
syslog (LOG_INFO, "Broadcasting DHCP_DISCOVER\n");
iface->xid = random ();
err = dhcpSendAndRecv (iface, DHCP_OFFER, &buildDhcpDiscover, &msg);
if (err != RET_DHCP_SUCCESS)
@ -772,7 +779,7 @@ int dhcp_init (dhcp_interface *iface)
udpipMessage *msg2 = NULL;
if (DebugFlag)
syslog (LOG_DEBUG,"broadcasting second DHCP_DISCOVER\n");
syslog (LOG_INFO, "Broadcasting second DHCP_DISCOVER\n");
iface->xid = dhcp_msg->xid;
err = dhcpSendAndRecv (iface, DHCP_OFFER, &buildDhcpDiscover, &msg2);
@ -792,7 +799,7 @@ int dhcp_init (dhcp_interface *iface)
/* DHCP_OFFER received */
if ( DebugFlag )
{
syslog(LOG_DEBUG,"DHCP_OFFER received from %s (%u.%u.%u.%u)\n", dhcp_msg->sname,
syslog (LOG_INFO, "DHCP_OFFER received from %s (%u.%u.%u.%u)\n", dhcp_msg->sname,
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[0],
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[1],
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[2],
@ -814,7 +821,7 @@ int dhcp_request(dhcp_interface *iface, dhcp_msg_build_proc buildDhcpMsg)
if ( DebugFlag )
{
syslog(LOG_DEBUG,"broadcasting DHCP_REQUEST for %u.%u.%u.%u\n",
syslog (LOG_INFO, "Broadcasting DHCP_REQUEST for %u.%u.%u.%u\n",
((unsigned char *)&(iface->ciaddr))[0], ((unsigned char *)&(iface->ciaddr))[1],
((unsigned char *)&(iface->ciaddr))[2], ((unsigned char *)&(iface->ciaddr))[3]);
}
@ -826,7 +833,7 @@ int dhcp_request(dhcp_interface *iface, dhcp_msg_build_proc buildDhcpMsg)
if ( DebugFlag )
{
dhcpMessage *dhcp_msg = (dhcpMessage *)&(msg->udpipmsg[sizeof(udpiphdr)]);
syslog(LOG_DEBUG, "DHCP_ACK received from %s (%u.%u.%u.%u)\n", dhcp_msg->sname,
syslog (LOG_INFO, "DHCP_ACK received from %s (%u.%u.%u.%u)\n", dhcp_msg->sname,
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[0],
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[1],
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[2],
@ -840,7 +847,7 @@ int dhcp_request(dhcp_interface *iface, dhcp_msg_build_proc buildDhcpMsg)
if ( arpCheck(iface) )
{
if ( DebugFlag )
syslog(LOG_DEBUG, "requested %u.%u.%u.%u address is in use\n",
syslog (LOG_INFO, "requested %u.%u.%u.%u address is in use\n",
((unsigned char *)&(iface->ciaddr))[0], ((unsigned char *)&(iface->ciaddr))[1],
((unsigned char *)&(iface->ciaddr))[2], ((unsigned char *)&(iface->ciaddr))[3]);
dhcpDecline();
@ -850,7 +857,7 @@ int dhcp_request(dhcp_interface *iface, dhcp_msg_build_proc buildDhcpMsg)
if ( DebugFlag )
{
syslog(LOG_DEBUG, "verified %u.%u.%u.%u address is not in use\n",
syslog (LOG_INFO, "verified %u.%u.%u.%u address is not in use\n",
((unsigned char *)&(iface->ciaddr))[0], ((unsigned char *)&(iface->ciaddr))[1],
((unsigned char *)&(iface->ciaddr))[2], ((unsigned char *)&(iface->ciaddr))[3]);
}
@ -895,7 +902,7 @@ int dhcp_renew(dhcp_interface *iface)
if ( DebugFlag )
{
syslog(LOG_DEBUG,"sending DHCP_REQUEST for %u.%u.%u.%u to %u.%u.%u.%u\n",
syslog (LOG_INFO,"Sending DHCP_REQUEST for %u.%u.%u.%u to %u.%u.%u.%u\n",
((unsigned char *)&(iface->ciaddr))[0], ((unsigned char *)&(iface->ciaddr))[1],
((unsigned char *)&(iface->ciaddr))[2], ((unsigned char *)&(iface->ciaddr))[3],
((unsigned char *)&(iface->siaddr))[0], ((unsigned char *)&(iface->siaddr))[1],
@ -912,7 +919,7 @@ int dhcp_renew(dhcp_interface *iface)
if ( DebugFlag )
{
dhcpMessage *dhcp_msg = (dhcpMessage *)&(msg->udpipmsg[sizeof(udpiphdr)]);
syslog(LOG_DEBUG, "DHCP_ACK received from %s (%u.%u.%u.%u)\n", dhcp_msg->sname,
syslog (LOG_INFO, "DHCP_ACK received from %s (%u.%u.%u.%u)\n", dhcp_msg->sname,
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[0],
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[1],
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[2],
@ -938,7 +945,7 @@ int dhcp_rebind(dhcp_interface *iface)
if ( DebugFlag )
{
syslog(LOG_DEBUG,"broadcasting DHCP_REQUEST for %u.%u.%u.%u\n",
syslog (LOG_INFO,"Broadcasting DHCP_REQUEST for %u.%u.%u.%u\n",
((unsigned char *)&(iface->ciaddr))[0],
((unsigned char *)&(iface->ciaddr))[1],
((unsigned char *)&(iface->ciaddr))[2],
@ -955,7 +962,7 @@ int dhcp_rebind(dhcp_interface *iface)
if ( DebugFlag )
{
dhcpMessage *dhcp_msg = (dhcpMessage *)&(msg->udpipmsg[sizeof(udpiphdr)]);
syslog(LOG_DEBUG, "DHCP_ACK received from %s (%u.%u.%u.%u)\n", dhcp_msg->sname,
syslog (LOG_INFO, "DHCP_ACK received from %s (%u.%u.%u.%u)\n", dhcp_msg->sname,
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[0],
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[1],
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[2],
@ -984,7 +991,7 @@ int dhcp_release(dhcp_interface *iface)
if (DebugFlag)
{
syslog(LOG_DEBUG,"sending DHCP_RELEASE for %u.%u.%u.%u to %u.%u.%u.%u\n",
syslog (LOG_INFO, "Sending DHCP_RELEASE for %u.%u.%u.%u to %u.%u.%u.%u\n",
((unsigned char *)&(iface->ciaddr))[0], ((unsigned char *)&(iface->ciaddr))[1],
((unsigned char *)&(iface->ciaddr))[2], ((unsigned char *)&(iface->ciaddr))[3],
((unsigned char *)&(iface->siaddr))[0], ((unsigned char *)&(iface->siaddr))[1],
@ -994,7 +1001,7 @@ int dhcp_release(dhcp_interface *iface)
memset (&addr, 0, sizeof(struct sockaddr));
memcpy (addr.sa_data, iface->iface, strlen (iface->iface));
if ( sendto (iface->sk, msg, sizeof(struct packed_ether_header) + sizeof(udpiphdr) + sizeof(dhcpMessage), 0, &addr, sizeof(struct sockaddr)) == -1 )
syslog(LOG_ERR,"dhcpRelease: sendto: %m\n");
syslog (LOG_ERR, "dhcpRelease: sendto: %m\n");
free (msg);
arpRelease (iface); /* clear ARP cache entries for client IP addr */
@ -1016,7 +1023,7 @@ int dhcp_decline(dhcp_interface *iface)
memset (&addr, 0, sizeof(struct sockaddr));
memcpy (addr.sa_data, iface->iface, strlen (iface->iface));
if ( DebugFlag )
syslog (LOG_DEBUG,"broadcasting DHCP_DECLINE\n");
syslog (LOG_INFO, "Broadcasting DHCP_DECLINE\n");
if ( sendto (iface->sk, msg, sizeof(struct packed_ether_header) + sizeof(udpiphdr)+sizeof(dhcpMessage), 0, &addr, sizeof(struct sockaddr)) == -1 )
syslog (LOG_ERR,"dhcpDecline: sendto: %m\n");
@ -1033,7 +1040,7 @@ int dhcp_inform(dhcp_interface *iface)
if ( DebugFlag )
{
syslog(LOG_DEBUG, "broadcasting DHCP_INFORM for %u.%u.%u.%u\n",
syslog (LOG_INFO, "Broadcasting DHCP_INFORM for %u.%u.%u.%u\n",
((unsigned char *)&(iface->ciaddr))[0],
((unsigned char *)&(iface->ciaddr))[1],
((unsigned char *)&(iface->ciaddr))[2],
@ -1048,7 +1055,7 @@ int dhcp_inform(dhcp_interface *iface)
if ( DebugFlag )
{
dhcpMessage *dhcp_msg = (dhcpMessage *)&(msg->udpipmsg[sizeof(udpiphdr)]);
syslog(LOG_DEBUG, "DHCP_ACK received from %s (%u.%u.%u.%u)\n", dhcp_msg->sname,
syslog (LOG_INFO, "DHCP_ACK received from %s (%u.%u.%u.%u)\n", dhcp_msg->sname,
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[0],
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[1],
((unsigned char *)(iface->dhcp_options.val[dhcpServerIdentifier]))[2],
@ -1061,7 +1068,7 @@ int dhcp_inform(dhcp_interface *iface)
if ( arpCheck(iface) )
{
if ( DebugFlag )
syslog(LOG_DEBUG, "requested %u.%u.%u.%u address is in use\n",
syslog (LOG_INFO, "Requested %u.%u.%u.%u address is in use\n",
((unsigned char *)&(iface->ciaddr))[0], ((unsigned char *)&(iface->ciaddr))[1],
((unsigned char *)&(iface->ciaddr))[2], ((unsigned char *)&(iface->ciaddr))[3]);
dhcpDecline (iface);
@ -1069,7 +1076,7 @@ int dhcp_inform(dhcp_interface *iface)
}
if ( DebugFlag )
{
syslog(LOG_DEBUG, "verified %u.%u.%u.%u address is not in use\n",
syslog (LOG_INFO, "Verified %u.%u.%u.%u address is not in use\n",
((unsigned char *)&(iface->ciaddr))[0], ((unsigned char *)&(iface->ciaddr))[1],
((unsigned char *)&(iface->ciaddr))[2], ((unsigned char *)&(iface->ciaddr))[3]);
}
@ -1095,7 +1102,7 @@ void debug_dump_dhcp_options (udpipMessage *udp_msg, dhcpOptions *options)
int i,j;
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
fprintf (stderr,"parseDhcpMsgRecv: %d options received:\n", options->num);
syslog (LOG_INFO, "parseDhcpMsgRecv: %d options received:\n", options->num);
for (i = 1; i < 255; i++)
{
if ( options->val[i] )
@ -1116,7 +1123,7 @@ void debug_dump_dhcp_options (udpipMessage *udp_msg, dhcpOptions *options)
for (j = 0; j < options->len[i]; j += 4)
{
char *opt_name = get_dhcp_option_name (i);
fprintf (stderr,"i=%-2d (%s) len=%-2d option = %u.%u.%u.%u\n",
syslog (LOG_INFO, "i=%-2d (%s) len=%-2d option = %u.%u.%u.%u\n",
i, opt_name, options->len[i],
((unsigned char *)options->val[i])[0+j],
((unsigned char *)options->val[i])[1+j],
@ -1132,7 +1139,7 @@ void debug_dump_dhcp_options (udpipMessage *udp_msg, dhcpOptions *options)
case 59:/* dhcpT2value */
{
char *opt_name = get_dhcp_option_name (i);
fprintf (stderr,"i=%-2d (%s) len=%-2d option = %d\n", i, opt_name,
syslog (LOG_INFO, "i=%-2d (%s) len=%-2d option = %d\n", i, opt_name,
options->len[i], ntohl(*(int *)options->val[i]));
free (opt_name);
}
@ -1143,7 +1150,7 @@ void debug_dump_dhcp_options (udpipMessage *udp_msg, dhcpOptions *options)
case 53:/* dhcpMessageType */
{
char *opt_name = get_dhcp_option_name (i);
fprintf(stderr,"i=%-2d (%s) len=%-2d option = %u\n", i, opt_name,
syslog (LOG_INFO, "i=%-2d (%s) len=%-2d option = %u\n", i, opt_name,
options->len[i],*(unsigned char *)options->val[i]);
free (opt_name);
}
@ -1151,7 +1158,7 @@ void debug_dump_dhcp_options (udpipMessage *udp_msg, dhcpOptions *options)
default:
{
char *opt_name = get_dhcp_option_name (i);
fprintf(stderr,"i=%-2d (%s) len=%-2d option = \"%s\"\n",
syslog (LOG_INFO, "i=%-2d (%s) len=%-2d option = \"%s\"\n",
i, opt_name, options->len[i], (char *)options->val[i]);
free (opt_name);
}
@ -1160,7 +1167,7 @@ void debug_dump_dhcp_options (udpipMessage *udp_msg, dhcpOptions *options)
}
}
fprintf(stderr,"dhcp_msg->yiaddr = %u.%u.%u.%u\n"
syslog (LOG_INFO, "dhcp_msg->yiaddr = %u.%u.%u.%u\n"
"dhcp_msg->siaddr = %u.%u.%u.%u\n"
"dhcp_msg->giaddr = %u.%u.%u.%u\n"
"dhcp_msg->sname = \"%s\"\n"

View file

@ -40,7 +40,7 @@
#define HWADDR_TRIES 3
/* UDP port numbers for DHCP */
#define DHCP_SERVER_PORT 67 /* from client to server */
#define DHCP_SERVER_PORT 67 /* from client to server */
#define DHCP_CLIENT_PORT 68 /* from server to client */
/* DHCP message OP code */
@ -48,86 +48,18 @@
#define DHCP_BOOTREPLY 2
/* DHCP message type */
#define DHCP_DISCOVER 1
#define DHCP_DISCOVER 1
#define DHCP_OFFER 2
#define DHCP_REQUEST 3
#define DHCP_DECLINE 4
#define DHCP_ACK 5
#define DHCP_REQUEST 3
#define DHCP_DECLINE 4
#define DHCP_ACK 5
#define DHCP_NAK 6
#define DHCP_RELEASE 7
#define DHCP_RELEASE 7
#define DHCP_INFORM 8
/* DHCP RETRANSMISSION TIMEOUT (microseconds) */
#define DHCP_INITIAL_RTO (4*1000000)
#define DHCP_MAX_RTO (64*1000000)
/* DHCP option and value (cf. RFC1533) */
enum
{
padOption = 0,
subnetMask = 1,
timerOffset = 2,
routersOnSubnet = 3,
timeServer = 4,
nameServer = 5,
dns = 6,
logServer = 7,
cookieServer = 8,
lprServer = 9,
impressServer = 10,
resourceLocationServer = 11,
hostName = 12,
bootFileSize = 13,
meritDumpFile = 14,
domainName = 15,
swapServer = 16,
rootPath = 17,
extentionsPath = 18,
IPforwarding = 19,
nonLocalSourceRouting = 20,
policyFilter = 21,
maxDgramReasmSize = 22,
defaultIPTTL = 23,
pathMTUagingTimeout = 24,
pathMTUplateauTable = 25,
ifMTU = 26,
allSubnetsLocal = 27,
broadcastAddr = 28,
performMaskDiscovery = 29,
maskSupplier = 30,
performRouterDiscovery = 31,
routerSolicitationAddr = 32,
staticRoute = 33,
trailerEncapsulation = 34,
arpCacheTimeout = 35,
ethernetEncapsulation = 36,
tcpDefaultTTL = 37,
tcpKeepaliveInterval = 38,
tcpKeepaliveGarbage = 39,
nisDomainName = 40,
nisServers = 41,
ntpServers = 42,
vendorSpecificInfo = 43,
netBIOSnameServer = 44,
netBIOSdgramDistServer = 45,
netBIOSnodeType = 46,
netBIOSscope = 47,
xFontServer = 48,
xDisplayManager = 49,
dhcpRequestedIPaddr = 50,
dhcpIPaddrLeaseTime = 51,
dhcpOptionOverload = 52,
dhcpMessageType = 53,
dhcpServerIdentifier = 54,
dhcpParamRequest = 55,
dhcpMsg = 56,
dhcpMaxMsgSize = 57,
dhcpT1value = 58,
dhcpT2value = 59,
dhcpClassIdentifier = 60,
dhcpClientIdentifier = 61,
endOption = 255
};
typedef struct dhcpMessage
{
u_char op; /* message type */

View file

@ -119,7 +119,7 @@ dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *i
memcpy (sap.spkt_device, iface->iface, strlen (iface->iface));
sap.spkt_family = AF_PACKET;
if ( bind (iface->sk, (void*)&sap, sizeof(struct sockaddr)) == -1 )
syslog (LOG_ERR,"dhcp_interface_init: bind: %m\n");
syslog (LOG_ERR,"dhcp_interface_init: bind: %m\n");
memcpy (iface->chaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
fprintf(stdout,"dhcpcd: MAC address = %02x:%02x:%02x:%02x:%02x:%02x\n",
@ -168,6 +168,9 @@ void dhcp_interface_free (dhcp_interface *iface)
struct ifreq ifr;
struct sockaddr_in *p = (struct sockaddr_in *)&(ifr.ifr_addr);
if (!iface)
return;
releaseDhcpOptions (iface);
if (iface->foo_sk >= 0)

View file

@ -31,6 +31,73 @@
#define DHCP_CLIENT_ID_MAX_LEN 48
#define DHCP_HOSTNAME_MAX_LEN 64
/* DHCP option and value (cf. RFC1533) */
enum
{
padOption = 0,
subnetMask = 1,
timerOffset = 2,
routersOnSubnet = 3,
timeServer = 4,
nameServer = 5,
dns = 6,
logServer = 7,
cookieServer = 8,
lprServer = 9,
impressServer = 10,
resourceLocationServer = 11,
hostName = 12,
bootFileSize = 13,
meritDumpFile = 14,
domainName = 15,
swapServer = 16,
rootPath = 17,
extentionsPath = 18,
IPforwarding = 19,
nonLocalSourceRouting = 20,
policyFilter = 21,
maxDgramReasmSize = 22,
defaultIPTTL = 23,
pathMTUagingTimeout = 24,
pathMTUplateauTable = 25,
ifMTU = 26,
allSubnetsLocal = 27,
broadcastAddr = 28,
performMaskDiscovery = 29,
maskSupplier = 30,
performRouterDiscovery = 31,
routerSolicitationAddr = 32,
staticRoute = 33,
trailerEncapsulation = 34,
arpCacheTimeout = 35,
ethernetEncapsulation = 36,
tcpDefaultTTL = 37,
tcpKeepaliveInterval = 38,
tcpKeepaliveGarbage = 39,
nisDomainName = 40,
nisServers = 41,
ntpServers = 42,
vendorSpecificInfo = 43,
netBIOSnameServer = 44,
netBIOSdgramDistServer = 45,
netBIOSnodeType = 46,
netBIOSscope = 47,
xFontServer = 48,
xDisplayManager = 49,
dhcpRequestedIPaddr = 50,
dhcpIPaddrLeaseTime = 51,
dhcpOptionOverload = 52,
dhcpMessageType = 53,
dhcpServerIdentifier = 54,
dhcpParamRequest = 55,
dhcpMsg = 56,
dhcpMaxMsgSize = 57,
dhcpT1value = 58,
dhcpT2value = 59,
dhcpClassIdentifier = 60,
dhcpClientIdentifier = 61,
endOption = 255
};
/* Return codes */
#define RET_DHCP_ERROR 0

View file

@ -23,81 +23,98 @@
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <syslog.h>
#include "NetworkManager.h"
#include "NetworkManagerMain.h"
#include "NetworkManagerDevice.h"
#include "NetworkManagerDevicePrivate.h"
#include "NetworkManagerDHCP.h"
#include "NetworkManagerSystem.h"
#include "../dhcpcd/client.h"
/* Accessors to device data that only this file should need */
dhcp_interface *nm_device_get_dhcp_iface (NMDevice *dev);
void nm_device_set_dhcp_iface (NMDevice *dev, dhcp_interface *dhcp_iface);
/*
* nm_device_dhcp_configure
*
* Using the results of a DHCP request, configure the device.
*
*/
static void nm_device_dhcp_configure (NMDevice *dev)
{
int temp;
g_return_if_fail (dev != NULL);
g_return_if_fail (dev->dhcp_iface != NULL);
/* Replace basic info */
nm_system_device_set_ip4_address (dev, dev->dhcp_iface->ciaddr);
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, subnetMask))
{
memcpy (&temp, dhcp_interface_get_dhcp_field (dev->dhcp_iface, subnetMask), dhcp_individual_value_len (subnetMask));
nm_system_device_set_ip4_netmask (dev, temp);
}
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, subnetMask))
{
memcpy (&temp, dhcp_interface_get_dhcp_field (dev->dhcp_iface, broadcastAddr), dhcp_individual_value_len (broadcastAddr));
nm_system_device_set_ip4_broadcast (dev, temp);
}
/* Default route */
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, routersOnSubnet))
{
memcpy (&temp, dhcp_interface_get_dhcp_field (dev->dhcp_iface, routersOnSubnet), dhcp_individual_value_len (routersOnSubnet));
nm_system_device_set_ip4_default_route (dev, temp);
}
/* Update /etc/resolv.conf */
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, dns))
{
nm_system_device_update_resolv_conf (dhcp_interface_get_dhcp_field (dev->dhcp_iface, dns),
dhcp_interface_get_dhcp_field_len (dev->dhcp_iface, dns), dhcp_interface_get_dhcp_field (dev->dhcp_iface, domainName));
}
}
/*
* nm_device_dhcp_run
* nm_device_dhcp_request
*
* Start a DHCP transaction on particular device.
*
*/
int nm_device_dhcp_run (NMDevice *dev)
int nm_device_dhcp_request (NMDevice *dev)
{
dhcp_interface *dhcp_iface;
dhcp_client_options opts;
int err;
const char *iface;
g_return_val_if_fail (dev != NULL, RET_DHCP_ERROR);
if (dev->dhcp_iface)
{
syslog (LOG_ERR, "nm_device_dhcp_request(): device DHCP info exists, but it should have been cleared already.\n");
dhcp_interface_free (dev->dhcp_iface);
}
memset (&opts, 0, sizeof (dhcp_client_options));
opts.base_timeout = 30;
iface = nm_device_get_iface (dev);
if (!(dhcp_iface = dhcp_interface_init (iface, &opts)))
if (!(dev->dhcp_iface = dhcp_interface_init (nm_device_get_iface (dev), &opts)))
return RET_DHCP_ERROR;
nm_device_set_dhcp_iface (dev, dhcp_iface);
/* Start off in DHCP INIT state, get a completely new IP address
* and settings.
*/
err = dhcp_init (dhcp_iface);
if (err == RET_DHCP_BOUND)
if ((err = dhcp_init (dev->dhcp_iface)) == RET_DHCP_BOUND)
{
int temp;
/* Replace basic info */
nm_system_device_set_ip4_address (dev, dhcp_iface->ciaddr);
if (dhcp_interface_dhcp_field_exists (dhcp_iface, subnetMask))
{
memcpy (&temp, dhcp_interface_get_dhcp_field (dhcp_iface, subnetMask), dhcp_individual_value_len (subnetMask));
nm_system_device_set_ip4_netmask (dev, temp);
}
if (dhcp_interface_dhcp_field_exists (dhcp_iface, subnetMask))
{
memcpy (&temp, dhcp_interface_get_dhcp_field (dhcp_iface, broadcastAddr), dhcp_individual_value_len (broadcastAddr));
nm_system_device_set_ip4_broadcast (dev, temp);
}
/* Default route */
if (dhcp_interface_dhcp_field_exists (dhcp_iface, routersOnSubnet))
{
memcpy (&temp, dhcp_interface_get_dhcp_field (dhcp_iface, routersOnSubnet), dhcp_individual_value_len (routersOnSubnet));
nm_system_device_set_ip4_default_route (dev, temp);
}
/* Update /etc/resolv.conf */
if (dhcp_interface_dhcp_field_exists (dhcp_iface, dns))
{
nm_system_device_update_resolv_conf (dhcp_interface_get_dhcp_field (dhcp_iface, dns),
dhcp_interface_get_dhcp_field_len (dhcp_iface, dns), dhcp_interface_get_dhcp_field (dhcp_iface, domainName));
}
nm_device_dhcp_configure (dev);
nm_device_update_ip4_address (dev);
nm_device_dhcp_setup_timeouts (dev);
}
else
{
dhcp_interface_free (dev->dhcp_iface);
dev->dhcp_iface = NULL;
}
dhcp_interface_free (dhcp_iface);
nm_device_set_dhcp_iface (dev, NULL);
return (err);
}
@ -112,8 +129,129 @@ int nm_device_dhcp_run (NMDevice *dev)
void nm_device_dhcp_cease (NMDevice *dev)
{
g_return_if_fail (dev != NULL);
g_return_if_fail (nm_device_get_dhcp_iface (dev) != NULL);
g_return_if_fail (dev->dhcp_iface != NULL);
dhcp_interface_cease (nm_device_get_dhcp_iface (dev));
dhcp_interface_cease (dev->dhcp_iface);
}
/*
* nm_device_dhcp_setup_timeouts
*
* Set up the DHCP renew and rebind timeouts for a device.
*
* Returns: FALSE on error
* TRUE on success
*
*/
gboolean nm_device_dhcp_setup_timeouts (NMDevice *dev)
{
int t1 = 0, t2 = 0;
GSource *t1_source, *t2_source;
g_return_val_if_fail (dev != NULL, FALSE);
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, dhcpT1value))
{
memcpy (&t1, dhcp_interface_get_dhcp_field (dev->dhcp_iface, dhcpT1value), sizeof (int));
t1 = ntohl (t1);
}
if (dhcp_interface_dhcp_field_exists (dev->dhcp_iface, dhcpT2value))
{
memcpy (&t2, dhcp_interface_get_dhcp_field (dev->dhcp_iface, dhcpT2value), sizeof (int));
t2 = ntohl (t2);
}
if (!t1 || !t2)
{
syslog (LOG_ERR, "DHCP renew/rebind values were 0! Won't renew lease.");
return (FALSE);
}
t1_source = g_timeout_source_new (t1 * 1000);
t2_source = g_timeout_source_new (t2 * 1000);
g_source_set_callback (t1_source, nm_device_dhcp_renew, dev, NULL);
g_source_set_callback (t2_source, nm_device_dhcp_rebind, dev, NULL);
dev->renew_timeout = g_source_attach (t1_source, dev->context);
dev->rebind_timeout = g_source_attach (t2_source, dev->context);
return (TRUE);
}
/*
* nm_device_dhcp_renew
*
* Renew a DHCP address.
*
*/
gboolean nm_device_dhcp_renew (gpointer user_data)
{
NMDevice *dev = (NMDevice *)user_data;
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (dev->app_data != NULL, FALSE);
g_return_val_if_fail (dev->dhcp_iface, FALSE);
if (dhcp_renew (dev->dhcp_iface) != RET_DHCP_BOUND)
{
/* If the T1 renewal fails, then we wait around until T2
* for rebind.
*/
return (FALSE);
}
else
{
/* Lease renewed, start timers again from 0 */
nm_device_dhcp_setup_timeouts (dev);
}
/* Always return false to remove ourselves, since we just
* set up another timeout above.
*/
return (FALSE);
}
/*
* nm_device_dhcp_renew
*
* Renew a DHCP address.
*
*/
gboolean nm_device_dhcp_rebind (gpointer user_data)
{
NMDevice *dev = (NMDevice *)user_data;
g_return_val_if_fail (dev != NULL, FALSE);
g_return_val_if_fail (dev->app_data != NULL, FALSE);
g_return_val_if_fail (dev->dhcp_iface, FALSE);
if (dhcp_rebind (dev->dhcp_iface) != RET_DHCP_BOUND)
{
/* T2 rebind failed, so flush the device's address and signal
* that we should find another device to use.
*/
/* FIXME: technically we should run out the entire lease time before
* flushing the address and getting a new device. We'll leave that for
* a bit later (do a new timer for entire lease time, blah, blah).
*/
nm_system_device_flush_addresses (dev);
nm_device_update_ip4_address (dev);
nm_data_mark_state_changed (dev->app_data);
return (FALSE);
}
else
{
/* Lease renewed, start timers again from 0 */
nm_device_dhcp_setup_timeouts (dev);
}
dhcp_interface_free (dev->dhcp_iface);
dev->dhcp_iface = NULL;
/* Always return false to remove ourselves, since we just
* set up another timeout above.
*/
return (FALSE);
}

View file

@ -24,8 +24,10 @@
#include "../dhcpcd/dhcpcd.h"
int nm_device_dhcp_run (NMDevice *dev);
int nm_device_dhcp_request (NMDevice *dev);
void nm_device_dhcp_cease (NMDevice *dev);
gboolean nm_device_dhcp_setup_timeouts (NMDevice *dev);
gboolean nm_device_dhcp_renew (gpointer user_data);
gboolean nm_device_dhcp_rebind (gpointer user_data);
#endif

View file

@ -30,6 +30,7 @@
#include "NetworkManager.h"
#include "NetworkManagerMain.h"
#include "NetworkManagerDevice.h"
#include "NetworkManagerDevicePrivate.h"
#include "NetworkManagerUtils.h"
#include "NetworkManagerDbus.h"
#include "NetworkManagerWireless.h"
@ -46,88 +47,6 @@ static gboolean nm_device_activation_configure_ip (NMDevice *dev);
/******************************************************/
/* Wireless device specific options */
typedef struct NMDeviceWirelessOptions
{
char *cur_essid;
gboolean supports_wireless_scan;
guint8 max_quality;
guint8 noise;
gint8 strength;
gint8 invalid_strength_counter;
GMutex *scan_mutex;
/* We keep a couple lists around since wireless cards
* are a bit flakey and don't report the same access
* points every time. The lists get merged and diffed
* to figure out the "real" list, but the latest_ap_list
* is always the most-current scan.
*/
NMAccessPointList *ap_list;
NMAccessPointList *cached_ap_list1;
NMAccessPointList *cached_ap_list2;
NMAccessPointList *cached_ap_list3;
NMAccessPoint *best_ap;
GMutex *best_ap_mutex;
gboolean freeze_best_ap;
gboolean user_key_received;
gboolean now_scanning;
} NMDeviceWirelessOptions;
/* Wired device specific options */
typedef struct NMDeviceWiredOptions
{
int foo;
} NMDeviceWiredOptions;
typedef union NMDeviceOptions
{
NMDeviceWirelessOptions wireless;
NMDeviceWiredOptions wired;
} NMDeviceOptions;
typedef struct NMDeviceConfigInfo
{
gboolean use_dhcp;
guint32 ip4_gateway;
guint32 ip4_address;
guint32 ip4_netmask;
guint32 ip4_broadcast;
/* FIXME: ip6 stuff */
} NMDeviceConfigInfo;
/*
* NetworkManager device structure
*/
struct NMDevice
{
guint refcount;
char *udi;
char *iface;
NMDeviceType type;
NMDriverSupportLevel driver_support_level;
gboolean link_active;
guint32 ip4_address;
/* FIXME: ipv6 address too */
unsigned char hw_addr[ETH_ALEN];
NMData *app_data;
NMDeviceOptions options;
NMDeviceConfigInfo config_info;
struct dhcp_interface *dhcp_iface;
gboolean activating; /* Set by main thread before beginning activation */
gboolean just_activated; /* Set by activation thread after successful activation */
gboolean quit_activation; /* Flag to signal activation thread to stop activating */
gboolean activation_failed; /* Did the activation fail? */
gboolean test_device;
gboolean test_device_up;
};
/******************************************************/
@ -1564,6 +1483,10 @@ 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))
goto out;
nm_device_set_wireless_config (dev, best_ap, auth);
if (!HAVE_LINK (dev) && (auth == NM_DEVICE_AUTH_METHOD_SHARED_KEY))
{
@ -1640,7 +1563,7 @@ static gboolean nm_device_activation_configure_ip (NMDevice *dev)
{
int err;
err = nm_device_dhcp_run (dev);
err = nm_device_dhcp_request (dev);
if (err == RET_DHCP_BOUND)
success = TRUE;
else
@ -1679,6 +1602,7 @@ static gpointer nm_device_activation_worker (gpointer user_data)
{
NMDevice *dev = (NMDevice *)user_data;
gboolean success = FALSE;
GMainContext *context = NULL;
g_return_val_if_fail (dev != NULL, NULL);
g_return_val_if_fail (dev->app_data != NULL, NULL);
@ -1712,10 +1636,31 @@ static gpointer nm_device_activation_worker (gpointer user_data)
dev->activation_failed = FALSE;
dev->quit_activation = FALSE;
/* If we were told to quit activation, stop the thread and return */
if (nm_device_activation_should_cancel (dev))
goto out;
nm_device_update_ip4_address (dev);
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): device activated", nm_device_get_iface (dev));
if (!nm_device_config_get_use_dhcp (dev) || !dev->dhcp_iface)
goto out;
/* We stick around if we need to renew the address with DHCP or something. */
dev->context = g_main_context_new ();
dev->loop = g_main_loop_new (context, FALSE);
nm_device_dhcp_setup_timeouts (dev);
g_main_loop_run (dev->loop);
g_source_remove (dev->renew_timeout);
g_source_remove (dev->rebind_timeout);
g_main_loop_unref (dev->loop);
g_main_context_unref (dev->context);
dev->context = NULL;
dev->loop = NULL;
out:
nm_device_unref (dev);
return (NULL);
@ -1820,6 +1765,9 @@ gboolean nm_device_deactivate (NMDevice *dev, gboolean just_added)
nm_device_activation_cancel (dev);
if (dev->loop)
g_main_loop_quit (dev->loop);
if (nm_device_get_driver_support_level (dev) == NM_DRIVER_UNSUPPORTED)
return (TRUE);
@ -2279,9 +2227,10 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
*encrypted = FALSE;
/* Force the card into Managed/Infrastructure mode */
nm_device_bring_up (dev);
g_usleep (G_USEC_PER_SEC);
g_usleep (G_USEC_PER_SEC * 4);
/* Force the card into Managed/Infrastructure mode */
nm_device_set_mode_managed (dev);
if ((ap = nm_ap_list_get_ap_by_essid (nm_device_ap_list_get (dev), network)) && !nm_ap_get_encrypted (ap))
@ -2337,7 +2286,7 @@ gboolean nm_device_wireless_network_exists (NMDevice *dev, const char *network,
/* Bring the device up and pause to allow card to associate */
nm_device_set_essid (dev, network);
g_usleep (G_USEC_PER_SEC * 2);
g_usleep (G_USEC_PER_SEC * 3);
nm_device_update_link_active (dev, FALSE);
nm_device_get_ap_address (dev, &addr);

View file

@ -0,0 +1,123 @@
/* NetworkManager -- Network link manager
*
* Dan Williams <dcbw@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2004 Red Hat, Inc.
*/
#include <errno.h>
#include <glib.h>
#include <dbus/dbus-glib.h>
#include <hal/libhal.h>
#include <iwlib.h>
#include <signal.h>
#include <string.h>
#include "NetworkManager.h"
#include "NetworkManagerMain.h"
#include "NetworkManagerDevice.h"
#include "NetworkManagerAPList.h"
/* Wireless device specific options */
typedef struct NMDeviceWirelessOptions
{
char *cur_essid;
gboolean supports_wireless_scan;
guint8 max_quality;
guint8 noise;
gint8 strength;
gint8 invalid_strength_counter;
GMutex *scan_mutex;
/* We keep a couple lists around since wireless cards
* are a bit flakey and don't report the same access
* points every time. The lists get merged and diffed
* to figure out the "real" list, but the latest_ap_list
* is always the most-current scan.
*/
NMAccessPointList *ap_list;
NMAccessPointList *cached_ap_list1;
NMAccessPointList *cached_ap_list2;
NMAccessPointList *cached_ap_list3;
NMAccessPoint *best_ap;
GMutex *best_ap_mutex;
gboolean freeze_best_ap;
gboolean user_key_received;
gboolean now_scanning;
} NMDeviceWirelessOptions;
/* Wired device specific options */
typedef struct NMDeviceWiredOptions
{
int foo;
} NMDeviceWiredOptions;
typedef union NMDeviceOptions
{
NMDeviceWirelessOptions wireless;
NMDeviceWiredOptions wired;
} NMDeviceOptions;
typedef struct NMDeviceConfigInfo
{
gboolean use_dhcp;
guint32 ip4_gateway;
guint32 ip4_address;
guint32 ip4_netmask;
guint32 ip4_broadcast;
/* FIXME: ip6 stuff */
} NMDeviceConfigInfo;
/*
* NetworkManager device structure
*/
struct NMDevice
{
guint refcount;
char *udi;
char *iface;
NMDeviceType type;
NMDriverSupportLevel driver_support_level;
gboolean link_active;
guint32 ip4_address;
/* FIXME: ipv6 address too */
unsigned char hw_addr[ETH_ALEN];
NMData *app_data;
NMDeviceOptions options;
NMDeviceConfigInfo config_info;
struct dhcp_interface *dhcp_iface;
GMainContext *context;
GMainLoop *loop;
guint renew_timeout;
guint rebind_timeout;
gboolean activating; /* Set by main thread before beginning activation */
gboolean just_activated; /* Set by activation thread after successful activation */
gboolean quit_activation; /* Flag to signal activation thread to stop activating */
gboolean activation_failed; /* Did the activation fail? */
gboolean test_device;
gboolean test_device_up;
};

View file

@ -289,9 +289,9 @@ gboolean nm_state_modification_monitor (gpointer user_data)
syslog (LOG_INFO, " SWITCH: best device changed");
do_switch = TRUE; /* Device changed */
}
else if (best_dev && nm_device_is_wireless (best_dev))
else if (best_dev)
{
if (!nm_device_is_activating (best_dev) && nm_device_need_ap_switch (best_dev))
if (nm_device_is_wireless (best_dev) && !nm_device_is_activating (best_dev) && nm_device_need_ap_switch (best_dev))
{
syslog (LOG_INFO, " SWITCH: need to associate with new access point");
do_switch = TRUE;

View file

@ -143,6 +143,13 @@ int nm_wireless_qual_to_percent (NMDevice *dev, const struct iw_quality *qual)
/* Atmel driver seems to use qual->qual is the percentage value */
percent = CLAMP (qual->qual, 0, 100);
}
else if (qual->qual == (qual->level - qual->noise))
{
/* Ok, simple signal : noise ratio. Prism54 for example. */
//fprintf (stderr, "20 * log (level / noise) = 20 * log (%d / %d) = %f\n", qual->level, qual->noise, log ((255-qual->level) / (255-qual->noise)) * 100);
percent = (int)rint ((log (qual->qual) / log (96)) * 100.0);
percent = CLAMP (percent, 0, 100);
}
else if (qual->qual >= 1)
{
/* Try it the Gnome Wireless Applet way */