netutils/dhcpd: handshake the dhcpd message with server port.

resolve the dhcpd compatibility issues on some strict system, such as Windows XP,7,10

Signed-off-by: chao.an <anchao@xiaomi.com>
This commit is contained in:
chao.an 2021-02-24 23:09:12 +08:00 committed by Xiang Xiao
parent 017f5ed65c
commit 4c256e7db3

View File

@ -882,45 +882,6 @@ static inline int dhcpd_socket(void)
return sockfd;
}
/****************************************************************************
* Name: dhcpd_openresponder
****************************************************************************/
static inline int dhcpd_openresponder(void)
{
struct sockaddr_in addr;
int sockfd;
int ret;
ninfo("Responder: %08" PRIx32 "\n", ntohl(g_state.ds_serverip));
/* Create a socket to listen for requests from DHCP clients */
sockfd = dhcpd_socket();
if (sockfd < 0)
{
nerr("ERROR: socket failed: %d\n", errno);
return ERROR;
}
/* Bind the socket to a local port. */
addr.sin_family = AF_INET;
addr.sin_port = 0;
addr.sin_addr.s_addr = g_state.ds_serverip;
ret = bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
if (ret < 0)
{
nerr("ERROR: bind failed, port=%d addr=%08lx: %d\n",
addr.sin_port, (long)addr.sin_addr.s_addr, errno);
close(sockfd);
return ERROR;
}
return sockfd;
}
/****************************************************************************
* Name: dhcpd_initpacket
****************************************************************************/
@ -958,13 +919,11 @@ static void dhcpd_initpacket(uint8_t mtype)
* Name: dhcpd_sendpacket
****************************************************************************/
static int dhcpd_sendpacket(int bbroadcast)
static int dhcpd_sendpacket(int sockfd, int bbroadcast)
{
struct sockaddr_in addr;
in_addr_t ipaddr;
int sockfd;
int len;
int ret = ERROR;
#ifdef CONFIG_NETUTILS_DHCPD_IGNOREBROADCAST
/* This is a hack. I've had problems with Windows machines responding
@ -1025,35 +984,29 @@ static int dhcpd_sendpacket(int bbroadcast)
* cannot re-use the listener socket because it is not bound correctly
*/
sockfd = dhcpd_openresponder();
if (sockfd >= 0)
{
/* Then send the response to the DHCP client port at that address */
/* Then send the response to the DHCP client port at that address */
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = HTONS(DHCP_CLIENT_PORT);
addr.sin_addr.s_addr = ipaddr;
memset(&addr, 0, sizeof(struct sockaddr_in));
addr.sin_family = AF_INET;
addr.sin_port = HTONS(DHCP_CLIENT_PORT);
addr.sin_addr.s_addr = ipaddr;
/* 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 - (FAR uint8_t *)&g_state.ds_outpacket) + 1;
ninfo("sendto %08lx:%04x len=%d\n",
(long)ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port), len);
len = (g_state.ds_optend - (FAR uint8_t *)&g_state.ds_outpacket) + 1;
ninfo("sendto %08lx:%04x len=%d\n",
(long)ntohl(addr.sin_addr.s_addr), ntohs(addr.sin_port), len);
ret = sendto(sockfd, &g_state.ds_outpacket, len, 0,
(struct sockaddr *)&addr, sizeof(struct sockaddr_in));
close(sockfd);
}
return ret;
return sendto(sockfd, &g_state.ds_outpacket, len, 0,
(struct sockaddr *)&addr, sizeof(struct sockaddr_in));
}
/****************************************************************************
* Name: dhcpd_sendoffer
****************************************************************************/
static inline int dhcpd_sendoffer(in_addr_t ipaddr, uint32_t leasetime)
static inline int dhcpd_sendoffer(int sockfd, in_addr_t ipaddr,
uint32_t leasetime)
{
in_addr_t netaddr;
#ifdef HAVE_DNSIP
@ -1091,9 +1044,9 @@ static inline int dhcpd_sendoffer(in_addr_t ipaddr, uint32_t leasetime)
/* Send the offer response */
#ifdef CONFIG_NETUTILS_DHCPD_IGNOREBROADCAST
return dhcpd_sendpacket(true);
return dhcpd_sendpacket(sockfd, true);
#else
return dhcpd_sendpacket(false);
return dhcpd_sendpacket(sockfd, false);
#endif
}
@ -1101,20 +1054,20 @@ static inline int dhcpd_sendoffer(in_addr_t ipaddr, uint32_t leasetime)
* Name: dhcpd_sendnak
****************************************************************************/
static int dhcpd_sendnak(void)
static int dhcpd_sendnak(int sockfd)
{
/* Initialize and send the NAK response */
dhcpd_initpacket(DHCPNAK);
memcpy(g_state.ds_outpacket.ciaddr, g_state.ds_inpacket.ciaddr, 4);
return dhcpd_sendpacket(true);
return dhcpd_sendpacket(sockfd, true);
}
/****************************************************************************
* Name: dhcpd_sendack
****************************************************************************/
int dhcpd_sendack(in_addr_t ipaddr)
int dhcpd_sendack(int sockfd, in_addr_t ipaddr)
{
uint32_t leasetime = CONFIG_NETUTILS_DHCPD_LEASETIME;
in_addr_t netaddr;
@ -1153,9 +1106,9 @@ int dhcpd_sendack(in_addr_t ipaddr)
#endif
#ifdef CONFIG_NETUTILS_DHCPD_IGNOREBROADCAST
if (dhcpd_sendpacket(true) < 0)
if (dhcpd_sendpacket(sockfd, true) < 0)
#else
if (dhcpd_sendpacket(false) < 0)
if (dhcpd_sendpacket(sockfd, false) < 0)
#endif
{
return ERROR;
@ -1169,7 +1122,7 @@ int dhcpd_sendack(in_addr_t ipaddr)
* Name: dhcpd_discover
****************************************************************************/
static inline int dhcpd_discover(void)
static inline int dhcpd_discover(int sockfd)
{
struct lease_s *lease;
in_addr_t ipaddr;
@ -1241,14 +1194,14 @@ static inline int dhcpd_discover(void)
/* Send the offer response */
return dhcpd_sendoffer(ipaddr, leasetime);
return dhcpd_sendoffer(sockfd, ipaddr, leasetime);
}
/****************************************************************************
* Name: dhcpd_request
****************************************************************************/
static inline int dhcpd_request(void)
static inline int dhcpd_request(int sockfd)
{
struct lease_s *lease;
in_addr_t ipaddr = 0;
@ -1388,12 +1341,12 @@ static inline int dhcpd_request(void)
if (response == DHCPACK)
{
ninfo("ACK IP %08lx\n", (long)ipaddr);
dhcpd_sendack(ipaddr);
dhcpd_sendack(sockfd, ipaddr);
}
else if (response == DHCPNAK)
{
ninfo("NAK IP %08lx\n", (long)ipaddr);
dhcpd_sendnak();
dhcpd_sendnak(sockfd);
}
else
{
@ -1604,12 +1557,12 @@ int dhcpd_run(FAR const char *interface)
{
case DHCPDISCOVER:
ninfo("DHCPDISCOVER\n");
dhcpd_discover();
dhcpd_discover(sockfd);
break;
case DHCPREQUEST:
ninfo("DHCPREQUEST\n");
dhcpd_request();
dhcpd_request(sockfd);
break;
case DHCPDECLINE: