From 4c256e7db375e46267bfb7ae05b7a52e2d57b6db Mon Sep 17 00:00:00 2001 From: "chao.an" Date: Wed, 24 Feb 2021 23:09:12 +0800 Subject: [PATCH] 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 --- netutils/dhcpd/dhcpd.c | 103 +++++++++++------------------------------ 1 file changed, 28 insertions(+), 75 deletions(-) diff --git a/netutils/dhcpd/dhcpd.c b/netutils/dhcpd/dhcpd.c index e7333d1aa..939da5bed 100644 --- a/netutils/dhcpd/dhcpd.c +++ b/netutils/dhcpd/dhcpd.c @@ -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: