mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 07:12:54 +08:00
Fix numerous bugs, mostly associated with broadcast
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1627 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
+44
-32
@@ -1,7 +1,7 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* netutils/dhcpd/dhcpd.c
|
* netutils/dhcpd/dhcpd.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -46,8 +46,8 @@ typedef unsigned char boolean;
|
|||||||
# define HTONS(a) htons(a)
|
# define HTONS(a) htons(a)
|
||||||
# define HTONL(a) htonl(a)
|
# define HTONL(a) htonl(a)
|
||||||
# define CONFIG_CPP_HAVE_WARNING 1
|
# define CONFIG_CPP_HAVE_WARNING 1
|
||||||
# define dbg(...) printf(__VA_ARGS__)
|
# define ndbg(...) printf(__VA_ARGS__)
|
||||||
# define vdbg(...) printf(__VA_ARGS__)
|
# define nvdbg(...) printf(__VA_ARGS__)
|
||||||
# define TRUE (1)
|
# define TRUE (1)
|
||||||
# define FALSE (0)
|
# define FALSE (0)
|
||||||
# define ERROR (-1)
|
# define ERROR (-1)
|
||||||
@@ -163,7 +163,7 @@ typedef unsigned char boolean;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_NETUTILS_DHCPD_STARTIP
|
#ifndef CONFIG_NETUTILS_DHCPD_STARTIP
|
||||||
# define CONFIG_NETUTILS_DHCPD_STARTIP (10<<24|0<<16|0<<16|2)
|
# define CONFIG_NETUTILS_DHCPD_STARTIP (10L<<24|0L<<16|0L<<16|2L)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#undef CONFIG_NETUTILS_DHCP_OPTION_ENDIP
|
#undef CONFIG_NETUTILS_DHCP_OPTION_ENDIP
|
||||||
@@ -426,7 +426,7 @@ static inline boolean dhcpd_parseoptions(void)
|
|||||||
{
|
{
|
||||||
/* Bad magic number... skip g_state.ds_outpacket */
|
/* Bad magic number... skip g_state.ds_outpacket */
|
||||||
|
|
||||||
dbg("Bad magic: %d,%d,%d,%d\n", ptr[0], ptr[1], ptr[2], ptr[3]);
|
ndbg("Bad magic: %d,%d,%d,%d\n", ptr[0], ptr[1], ptr[2], ptr[3]);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,7 +703,7 @@ static inline int dhcpd_socket(void)
|
|||||||
sockfd = socket(PF_INET, SOCK_DGRAM, 0);
|
sockfd = socket(PF_INET, SOCK_DGRAM, 0);
|
||||||
if (sockfd < 0)
|
if (sockfd < 0)
|
||||||
{
|
{
|
||||||
dbg("socket failed: %d\n", errno);
|
ndbg("socket failed: %d\n", errno);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -714,7 +714,7 @@ static inline int dhcpd_socket(void)
|
|||||||
ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, sizeof(int));
|
ret = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void*)&optval, sizeof(int));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
dbg("setsockopt SO_REUSEADDR failed: %d\n", errno);
|
ndbg("setsockopt SO_REUSEADDR failed: %d\n", errno);
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
@@ -725,7 +725,7 @@ static inline int dhcpd_socket(void)
|
|||||||
ret = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (void*)&optval, sizeof(int));
|
ret = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (void*)&optval, sizeof(int));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
dbg("setsockopt SO_BROADCAST failed: %d\n", errno);
|
ndbg("setsockopt SO_BROADCAST failed: %d\n", errno);
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
@@ -745,27 +745,28 @@ static inline int dhcpd_openresponder(void)
|
|||||||
int sockfd;
|
int sockfd;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
nvdbg("Responder: %08lx\n", (long)g_state.ds_serverip);
|
||||||
|
|
||||||
/* Create a socket to listen for requests from DHCP clients */
|
/* Create a socket to listen for requests from DHCP clients */
|
||||||
|
|
||||||
sockfd = dhcpd_socket();
|
sockfd = dhcpd_socket();
|
||||||
if (sockfd < 0)
|
if (sockfd < 0)
|
||||||
{
|
{
|
||||||
dbg("socket failed: %d\n", errno);
|
ndbg("socket failed: %d\n", errno);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bind the socket to a local port. We have to use INADDRY_ANY to
|
/* Bind the socket to a local port.*/
|
||||||
* receive broadcast messages.
|
|
||||||
*/
|
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(DHCP_SERVER_PORT);
|
addr.sin_port = 0;
|
||||||
addr.sin_addr.s_addr = g_state.ds_serverip;
|
addr.sin_addr.s_addr = g_state.ds_serverip;
|
||||||
|
|
||||||
ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
dbg("bind failed: %d\n", errno);
|
ndbg("bind failed, port=%d addr=%08lx: %d\n",
|
||||||
|
addr.sin_port, (long)addr.sin_addr.s_addr, errno);
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
@@ -842,7 +843,7 @@ static int dhcpd_sendpacket(int bbroadcast)
|
|||||||
memcpy(&ipaddr, g_state.ds_outpacket.yiaddr, 4);
|
memcpy(&ipaddr, g_state.ds_outpacket.yiaddr, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a socket to respond to send the packet to the client. We
|
/* Create a socket to respond with a packet to the client. We
|
||||||
* cannot re-use the listener socket because it is not bound correctly
|
* cannot re-use the listener socket because it is not bound correctly
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -859,6 +860,9 @@ static int dhcpd_sendpacket(int bbroadcast)
|
|||||||
/* Send the minimum sized packet that includes the END option */
|
/* Send the minimum sized packet that includes the END option */
|
||||||
|
|
||||||
len = (g_state.ds_optend - (uint8*)&g_state.ds_outpacket) + 1;
|
len = (g_state.ds_optend - (uint8*)&g_state.ds_outpacket) + 1;
|
||||||
|
nvdbg("sendto %08lx:%04x len=%d\n",
|
||||||
|
(long)addr.sin_addr.s_addr, addr.sin_port, len);
|
||||||
|
|
||||||
ret = sendto(sockfd, &g_state.ds_outpacket, len, 0,
|
ret = sendto(sockfd, &g_state.ds_outpacket, len, 0,
|
||||||
(struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
(struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
@@ -872,6 +876,8 @@ static int dhcpd_sendpacket(int bbroadcast)
|
|||||||
|
|
||||||
static inline int dhcpd_sendoffer(in_addr_t ipaddr, uint32 leasetime)
|
static inline int dhcpd_sendoffer(in_addr_t ipaddr, uint32 leasetime)
|
||||||
{
|
{
|
||||||
|
nvdbg("Sending offer: %08lx\n", (long)ipaddr);
|
||||||
|
|
||||||
/* Initialize the outgoing packet */
|
/* Initialize the outgoing packet */
|
||||||
|
|
||||||
dhcpd_initpacket(DHCPOFFER);
|
dhcpd_initpacket(DHCPOFFER);
|
||||||
@@ -886,7 +892,7 @@ static inline int dhcpd_sendoffer(in_addr_t ipaddr, uint32 leasetime)
|
|||||||
|
|
||||||
/* Send the offer response */
|
/* Send the offer response */
|
||||||
|
|
||||||
return dhcpd_sendpacket(FALSE);
|
return dhcpd_sendpacket(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@@ -927,7 +933,7 @@ int dhcpd_sendack(in_addr_t ipaddr)
|
|||||||
|
|
||||||
dhcpd_addoption32(DHCP_OPTION_LEASE_TIME, htonl(leasetime));
|
dhcpd_addoption32(DHCP_OPTION_LEASE_TIME, htonl(leasetime));
|
||||||
|
|
||||||
if (dhcpd_sendpacket(FALSE) < 0)
|
if (dhcpd_sendpacket(TRUE) < 0)
|
||||||
{
|
{
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
@@ -966,6 +972,7 @@ static inline int dhcpd_discover(void)
|
|||||||
/* Get the IP address associated with the lease */
|
/* Get the IP address associated with the lease */
|
||||||
|
|
||||||
ipaddr = dhcp_leaseipaddr(lease);
|
ipaddr = dhcp_leaseipaddr(lease);
|
||||||
|
nvdbg("Already have lease for IP %08lx\n", (long)ipaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if the client has requested a specific IP address */
|
/* Check if the client has requested a specific IP address */
|
||||||
@@ -975,12 +982,14 @@ static inline int dhcpd_discover(void)
|
|||||||
/* Use the requested IP address */
|
/* Use the requested IP address */
|
||||||
|
|
||||||
ipaddr = g_state.ds_optreqip;
|
ipaddr = g_state.ds_optreqip;
|
||||||
|
nvdbg("Use requested IP %08lx\n", (long)ipaddr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* No... allocate a new IP address */
|
/* No... allocate a new IP address */
|
||||||
|
|
||||||
ipaddr = dhcpd_allocipaddr();
|
ipaddr = dhcpd_allocipaddr();
|
||||||
|
nvdbg("Allocated IP %08lx\n", (long)ipaddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Did we get any IP address? */
|
/* Did we get any IP address? */
|
||||||
@@ -989,7 +998,7 @@ static inline int dhcpd_discover(void)
|
|||||||
{
|
{
|
||||||
/* Nope... return failure */
|
/* Nope... return failure */
|
||||||
|
|
||||||
dbg("Failed to get IP address\n");
|
ndbg("Failed to get IP address\n");
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -997,7 +1006,7 @@ static inline int dhcpd_discover(void)
|
|||||||
|
|
||||||
if (!dhcpd_setlease(g_state.ds_inpacket.chaddr, ipaddr, CONFIG_NETUTILS_DHCPD_OFFERTIME))
|
if (!dhcpd_setlease(g_state.ds_inpacket.chaddr, ipaddr, CONFIG_NETUTILS_DHCPD_OFFERTIME))
|
||||||
{
|
{
|
||||||
dbg("Failed to set lease\n");
|
ndbg("Failed to set lease\n");
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1120,10 +1129,12 @@ static inline int dhcpd_request(void)
|
|||||||
|
|
||||||
if (response == DHCPACK)
|
if (response == DHCPACK)
|
||||||
{
|
{
|
||||||
|
nvdbg("ACK IP %08lx\n", (long)ipaddr);
|
||||||
dhcpd_sendack(ipaddr);
|
dhcpd_sendack(ipaddr);
|
||||||
}
|
}
|
||||||
else if (response == DHCPNAK)
|
else if (response == DHCPNAK)
|
||||||
{
|
{
|
||||||
|
nvdbg("NAK IP %08lx\n", (long)ipaddr);
|
||||||
dhcpd_sendnak();
|
dhcpd_sendnak();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1187,7 +1198,7 @@ static inline int dhcpd_openlistener(void)
|
|||||||
sockfd = dhcpd_socket();
|
sockfd = dhcpd_socket();
|
||||||
if (sockfd < 0)
|
if (sockfd < 0)
|
||||||
{
|
{
|
||||||
dbg("socket failed: %d\n", errno);
|
ndbg("socket failed: %d\n", errno);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1197,12 +1208,12 @@ static inline int dhcpd_openlistener(void)
|
|||||||
ret = ioctl(sockfd, SIOCGIFADDR, (unsigned long)&req);
|
ret = ioctl(sockfd, SIOCGIFADDR, (unsigned long)&req);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
dbg("setsockopt SIOCGIFADDR failed: %d\n", errno);
|
ndbg("setsockopt SIOCGIFADDR failed: %d\n", errno);
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
g_state.ds_serverip = ((struct sockaddr_in*)&req.ifr_addr)->sin_addr.s_addr;
|
g_state.ds_serverip = ((struct sockaddr_in*)&req.ifr_addr)->sin_addr.s_addr;
|
||||||
vdbg("serverip: %08x\n", ntohl(g_state.ds_serverip));
|
nvdbg("serverip: %08lx\n", ntohl(g_state.ds_serverip));
|
||||||
|
|
||||||
/* Bind the socket to a local port. We have to bind to INADDRY_ANY to
|
/* Bind the socket to a local port. We have to bind to INADDRY_ANY to
|
||||||
* receive broadcast messages.
|
* receive broadcast messages.
|
||||||
@@ -1215,7 +1226,8 @@ static inline int dhcpd_openlistener(void)
|
|||||||
ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
dbg("bind failed: %d\n", errno);
|
ndbg("bind failed, port=%d addr=%08lx: %d\n",
|
||||||
|
addr.sin_port, (long)addr.sin_addr.s_addr, errno);
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
@@ -1236,7 +1248,7 @@ int dhcpd_run(void)
|
|||||||
int sockfd;
|
int sockfd;
|
||||||
int nbytes;
|
int nbytes;
|
||||||
|
|
||||||
vdbg("Started\n");
|
nvdbg("Started\n");
|
||||||
|
|
||||||
/* Initialize everything to zero */
|
/* Initialize everything to zero */
|
||||||
|
|
||||||
@@ -1254,7 +1266,7 @@ int dhcpd_run(void)
|
|||||||
sockfd = dhcpd_openlistener();
|
sockfd = dhcpd_openlistener();
|
||||||
if (sockfd < 0)
|
if (sockfd < 0)
|
||||||
{
|
{
|
||||||
dbg("Failed to create socket\n");
|
ndbg("Failed to create socket\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1266,7 +1278,7 @@ int dhcpd_run(void)
|
|||||||
{
|
{
|
||||||
/* On errors (other EINTR), close the socket and try again */
|
/* On errors (other EINTR), close the socket and try again */
|
||||||
|
|
||||||
dbg("recv failed: %d\n", errno);
|
ndbg("recv failed: %d\n", errno);
|
||||||
if (errno != EINTR)
|
if (errno != EINTR)
|
||||||
{
|
{
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
@@ -1281,7 +1293,7 @@ int dhcpd_run(void)
|
|||||||
{
|
{
|
||||||
/* Failed to parse the message options */
|
/* Failed to parse the message options */
|
||||||
|
|
||||||
dbg("No msg type\n");
|
ndbg("No msg type\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1296,28 +1308,28 @@ int dhcpd_run(void)
|
|||||||
switch (g_state.ds_optmsgtype)
|
switch (g_state.ds_optmsgtype)
|
||||||
{
|
{
|
||||||
case DHCPDISCOVER:
|
case DHCPDISCOVER:
|
||||||
vdbg("DHCPDISCOVER\n");
|
nvdbg("DHCPDISCOVER\n");
|
||||||
dhcpd_discover();
|
dhcpd_discover();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DHCPREQUEST:
|
case DHCPREQUEST:
|
||||||
vdbg("DHCPREQUEST\n");
|
nvdbg("DHCPREQUEST\n");
|
||||||
dhcpd_request();
|
dhcpd_request();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DHCPDECLINE:
|
case DHCPDECLINE:
|
||||||
vdbg("DHCPDECLINE\n");
|
nvdbg("DHCPDECLINE\n");
|
||||||
dhcpd_decline();
|
dhcpd_decline();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DHCPRELEASE:
|
case DHCPRELEASE:
|
||||||
vdbg("DHCPRELEASE\n");
|
nvdbg("DHCPRELEASE\n");
|
||||||
dhcpd_release();
|
dhcpd_release();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DHCPINFORM: /* Not supported */
|
case DHCPINFORM: /* Not supported */
|
||||||
default:
|
default:
|
||||||
dbg("Unsupported message type: %d\n", g_state.ds_optmsgtype);
|
ndbg("Unsupported message type: %d\n", g_state.ds_optmsgtype);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user