ESP-IF DHCP Server Does Not Check if IP Address is Already in Use Before Offering a Lease

PeterG76
Posts: 17
Joined: Wed May 25, 2022 10:25 am

ESP-IF DHCP Server Does Not Check if IP Address is Already in Use Before Offering a Lease

Postby PeterG76 » Wed Jun 15, 2022 12:51 pm

I'm using ESP-IF v4.1

I have noticed that the Lwip DHCP server is allocating an IP address that is already allocated to another device.

I have run Wireshark on my device configured as both a DHCP server with other clients, and as DHCP Client with another DHCP server on the network. When running tests with my ESP32 device as a DHCP client with other DHCP Server sources, I see the DHCP Servers sending an ARP (Who has x.x.x.x? Tell y.y.y.y) request to test if the IP address it is about to offer is in use.

I've even looked at buildroot's udhcpd source code and it does an ARP request before offering an IP address by DHCP.

Is there a configuration option in the ESP-IF dhcpserver that I can set to make the DHCP server check for the existence of an IP address before making an offer or is this a bug in the ESP-IF?

ESP_YJM
Posts: 300
Joined: Fri Feb 26, 2021 10:30 am

Re: ESP-IF DHCP Server Does Not Check if IP Address is Already in Use Before Offering a Lease

Postby ESP_YJM » Thu Jun 16, 2022 3:18 am

Yes, ESP-IDF indeed has this problem. This is an known issue and we will fix this in future release version.

PeterG76
Posts: 17
Joined: Wed May 25, 2022 10:25 am

Re: ESP-IF DHCP Server Does Not Check if IP Address is Already in Use Before Offering a Lease

Postby PeterG76 » Tue Nov 21, 2023 10:24 am

I've encountered a similar problem.

I have two instances of my ESP-IDF app, one running as esp-netif DHCP server and one running as DHCP client. The instance running as client is correctly sending a DHCP Decline when it realises the IP address is already in use. However when the DHCP client performs another 'DORA' request, the DHCP server is offering the same IP address again. It should be picking another one from the pool.

The lwip apps dhcpserver isn't handling a DHCP decline in the way I would expect.

The same issue occurs when my desktop PC DHCP client requests an IP address and it declines it because it realises it is in use.

Is this a known issue? If so has it been fixed?

PeterG76
Posts: 17
Joined: Wed May 25, 2022 10:25 am

Re: ESP-IF DHCP Server Does Not Check if IP Address is Already in Use Before Offering a Lease

Postby PeterG76 » Wed Nov 22, 2023 2:44 pm

Hello,

I've produced a fix to your dhcpserver.c which is solving my perpetual DHCPS address lease and decline issue. This code (diff below) increments the offered IP address when a Decline is received to an already ACKed IP address lease.

[Codebox]
  1. diff --git a/components/lwip/apps/dhcpserver/dhcpserver.c b/components/lwip/apps/dhcpserver/dhcpserver.c
  2. index 8a4bc00bb..d93b823aa 100644
  3. --- a/components/lwip/apps/dhcpserver/dhcpserver.c
  4. +++ b/components/lwip/apps/dhcpserver/dhcpserver.c
  5. @@ -782,16 +782,16 @@ static u8_t parse_options(u8_t *optptr, s16_t len)
  6.              break;
  7.  
  8.          case DHCPDECLINE://4
  9. -            s.state = DHCPS_STATE_IDLE;
  10. +            s.state = DHCPS_STATE_DECLINE;
  11.  #if DHCPS_DEBUG
  12. -            DHCPS_LOG("dhcps: DHCPD_STATE_IDLE\n");
  13. +            DHCPS_LOG("dhcps: DHCPS_STATE_DECLINE\n");
  14.  #endif
  15.              break;
  16.  
  17.          case DHCPRELEASE://7
  18.              s.state = DHCPS_STATE_RELEASE;
  19.  #if DHCPS_DEBUG
  20. -            DHCPS_LOG("dhcps: DHCPD_STATE_IDLE\n");
  21. +            DHCPS_LOG("dhcps: DHCPD_STATE_RELEASE\n");
  22.  #endif
  23.              break;
  24.      }
  25. @@ -913,7 +913,7 @@ POOL_CHECK:
  26.  
  27.          s16_t ret = parse_options(&m->options[4], len);;
  28.  
  29. -        if (ret == DHCPS_STATE_RELEASE || ret == DHCPS_STATE_NAK) {
  30. +        if (ret == DHCPS_STATE_RELEASE || ret == DHCPS_STATE_NAK || ret == DHCPS_STATE_DECLINE) {
  31.              if (pnode != NULL) {
  32.                  node_remove_from_list(&plist, pnode);
  33.                  free(pnode);
  34. @@ -926,6 +926,34 @@ POOL_CHECK:
  35.              }
  36.  
  37.              memset(&client_address, 0x0, sizeof(client_address));
  38. +
  39. +            if(ret == DHCPS_STATE_DECLINE)
  40. +            {
  41. +                // IP address is in use increment the start ip address
  42. +                // of the pool of free addresses.
  43. +                addr_tmp.addr = htonl(dhcps_poll.start_ip.addr);
  44. +                addr_tmp.addr++;
  45. +                dhcps_poll.start_ip.addr = htonl(addr_tmp.addr);
  46. +
  47. +#if DHCPS_DEBUG
  48. +                DHCPS_LOG("IP address declined. DHCPS pool is now %x to %x\n",
  49. +                                dhcps_poll.start_ip.addr,
  50. +                                dhcps_poll.end_ip.addr);
  51. +#endif
  52. +
  53. +                if(dhcps_poll.start_ip.addr == dhcps_poll.end_ip.addr)
  54. +                {
  55. +                    addr_tmp.addr = htonl(server_address.addr);
  56. +                    addr_tmp.addr++;
  57. +                    dhcps_poll.start_ip.addr = htonl(addr_tmp.addr);
  58. +
  59. +#if DHCPS_DEBUG
  60. +                    DHCPS_LOG("Exhausted ip address pool. Start afresh from %x to %x\n",
  61. +                                    dhcps_poll.start_ip.addr,
  62. +                                    dhcps_poll.end_ip.addr);
  63. +#endif
  64. +                }
  65. +            }
  66.          }
  67.  
  68.  #if DHCPS_DEBUG
[/Codebox]

Regards,

Peter

Who is online

Users browsing this forum: Majestic-12 [Bot] and 80 guests