Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DHCP client options 43 and 60 (IDFGH-4998) #6786

Closed
RadekHvizdos opened this issue Mar 26, 2021 · 18 comments
Closed

Add DHCP client options 43 and 60 (IDFGH-4998) #6786

RadekHvizdos opened this issue Mar 26, 2021 · 18 comments
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally Type: Feature Request Feature request for IDF

Comments

@RadekHvizdos
Copy link

RadekHvizdos commented Mar 26, 2021

Is your feature request related to a problem? Please describe.

We are developing a new ESP32 based product that should receive its configuration from network's DHCP server. We have investigated esp-idf's DHCP client, but currently it does not support sending or receiving DHCP options 43 (Vendor Specific Information) and 60 (Vendor Class Identifier (VCI)).

Describe the solution you'd like

Could we extend the capabilities of the DHCP client, so that we could:

  • Send option 60 to specify a Vendor Class Identifier, so that the DHCP would recognize our device.
  • Request and receive option 43, which would be provided by the DHCP server, specifying the configuration information.
  • Both options would be provided as an opaque byte array or string, no further processing by the stack is needed.

Describe alternatives you've considered

We are experimenting with requesting this information via UDP packets to the DHCP server, but as it is not possible to set the proper UDP source port, such implementation would be non-compliant.

Additional context

Explanation of the options:
https://docs.paloaltonetworks.com/pan-os/8-1/pan-os-admin/networking/dhcp/dhcp-options/dhcp-options-43-55-and-60-and-other-customized-options.html

Currently supported DHCP options in esp-idf:

/** @brief Supported options for DHCP client or DHCP server */
typedef enum{
    ESP_NETIF_SUBNET_MASK                   = 1,    /**< Network mask */
    ESP_NETIF_DOMAIN_NAME_SERVER            = 6,    /**< Domain name server */
    ESP_NETIF_ROUTER_SOLICITATION_ADDRESS   = 32,   /**< Solicitation router address */
    ESP_NETIF_REQUESTED_IP_ADDRESS          = 50,   /**< Request specific IP address */
    ESP_NETIF_IP_ADDRESS_LEASE_TIME         = 51,   /**< Request IP address lease time */
    ESP_NETIF_IP_REQUEST_RETRY_TIME         = 52,   /**< Request IP address retry counter */
} esp_netif_dhcp_option_id_t;
@RadekHvizdos RadekHvizdos added the Type: Feature Request Feature request for IDF label Mar 26, 2021
@espressif-bot espressif-bot added the Status: Opened Issue is new label Mar 26, 2021
@github-actions github-actions bot changed the title Add DHCP client options 43 and 60 Add DHCP client options 43 and 60 (IDFGH-4998) Mar 26, 2021
@Alvin1Zhang
Copy link
Collaborator

Thanks for raising this feature request.

@RadekHvizdos
Copy link
Author

Hi @Alvin1Zhang,

Is there an ETA for implementation of this request?

Thanks!

@Alvin1Zhang
Copy link
Collaborator

@RadekHvizdos Thanks for reporting and sorry for replying late, we are still evaluating this feature, will get back to you once we have any progress. Thanks.

@espressif-bot espressif-bot added Status: In Progress Work is in progress and removed Status: Opened Issue is new labels May 7, 2021
@lhespress
Copy link
Collaborator

@RadekHvizdos
Please replace the attachment as follows and checkout. dhcp_option.zip

@RadekHvizdos
Copy link
Author

Hi @lhespress,

Thank you for the patch. I have deployed it on the latest master build:

  1. I can see the VCI option 60 getting sent and it is visible on my DHCP server:
    dnsmasq-dhcp[12041]: 3547769312 vendor class: espressif

  2. I was unable to call the function to override the class name, which was made available in lwip\src\include\lwip\prot\dhcp.h, I was trying all sorts of #include statements but it wasn't working:
    err_t dhcp_set_vendor_class_identifier(u8_t len, char *str);
    What am I missing?

  3. I suggest to rename the following:
    static u16_t dhcp_option_vendor_class_identify() -> static u16_t dhcp_option_vendor_class_identifier()
    ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFY -> ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
    DHCP_OPTION_US -> DHCP_OPTION_VCI

  4. Assuming the points 2 and 3 are addressed, this solves the first part of my request. But we still need to implement handling of receiving option 43 (Vendor Specific Information) from DHCP server. We will also need to add option 43 to dhcp_discover_request_options array.

Thank you for your support!

@lhespress
Copy link
Collaborator

@RadekHvizdos 43 option is sent from server to client. we can add a handle of receiving option, but I think it shouldn't add discover and request array.

@lhespress
Copy link
Collaborator

@RadekHvizdos Please replace the attachment which modify 1, 2, 3 and add 43 option receive handle.
dhcp_vendor_2021_06_08.zip

@RadekHvizdos
Copy link
Author

Hi @lhespress,
Thank you for the second patch.

I can confirm that items 1, 2 and 3 are now working as expected.

With regards to receiving VSI. This works, but you have to add DHCP_OPTION_VSI to the dhcp_discover_request_options, otherwise the DHCP server will not send the VSI. This is a requirement as per DHCP specification

static u8_t dhcp_discover_request_options[] = {
DHCP_OPTION_SUBNET_MASK,
DHCP_OPTION_ROUTER,
DHCP_OPTION_BROADCAST,
DHCP_OPTION_VSI
#if LWIP_DHCP_PROVIDE_DNS_SERVERS
, DHCP_OPTION_DNS_SERVER
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS /
#if LWIP_DHCP_GET_NTP_SRV
, DHCP_OPTION_NTP
#endif /
LWIP_DHCP_GET_NTP_SRV */
};

DHCP log when DHCP_OPTION_VSI is not requested (patch #2 default):

vendor class: espressif
client provides name: espressif
DHCPREQUEST(br-esp) 10.1.4.130 30:ae:a4:1a:98:14
tags: esp4, br-esp
DHCPACK(br-esp) 10.1.4.130 30:ae:a4:1a:98:14 espressif
requested options: 1:netmask, 3:router, 28:broadcast, 6:dns-server
next server: 10.1.4.1
sent size: 1 option: 53 message-type 5
sent size: 4 option: 54 server-identifier 10.1.4.1
sent size: 4 option: 51 lease-time 2d
sent size: 4 option: 58 T1 1d
sent size: 4 option: 59 T2 1d18h
sent size: 4 option: 1 netmask 255.255.255.0
sent size: 4 option: 28 broadcast 10.1.4.255
sent size: 4 option: 3 router 10.1.4.1
sent size: 4 option: 6 dns-server 10.1.4.1

DHCP log when DHCP_OPTION_VSI is requested:

vendor class: espressif
client provides name: espressif
DHCPDISCOVER(br-esp) 30:ae:a4:1a:98:14
tags: esp4, br-esp
DHCPOFFER(br-esp) 10.1.4.130 30:ae:a4:1a:98:14
requested options: 1:netmask, 3:router, 28:broadcast, 43:vendor-encap,
requested options: 6:dns-server
next server: 10.1.4.1
sent size: 1 option: 53 message-type 2
sent size: 4 option: 54 server-identifier 10.1.4.1
sent size: 4 option: 51 lease-time 2d
sent size: 4 option: 58 T1 1d
sent size: 4 option: 59 T2 1d18h
sent size: 4 option: 1 netmask 255.255.255.0
sent size: 4 option: 28 broadcast 10.1.4.255
sent size: 4 option: 3 router 10.1.4.1
sent size: 4 option: 6 dns-server 10.1.4.1
sent size: 11 option: 43 vendor-encap 01:08:49:74:5f:77:6f:72:6b:73:ff
sent size: 9 option: 60 vendor-class 65:73:70:72:65:73:73:69:66

Notice that the VSI is transmitted as a byte array.

My dnsmasq DNS server is confirgured:
dhcp-option=vendor:espressif,01,It_works
This is transfered as:
01:08:49:74:5f:77:6f:72:6b:73:ff

And printed in the console as:
I (1585) wifi station: vendor specific information It_works�r

It starts with a vendor specified number (1-254) and always ends with 0xff.

Thanks!

@lhespress
Copy link
Collaborator

@RadekHvizdos

Could you explain it which on RFC2132? in my option, it's ignore by DHCP Server.

8.4. Vendor Specific Information

This option is used by clients and servers to exchange vendor-
specific information. The information is an opaque object of n
octets, presumably interpreted by vendor-specific code on the clients
and servers. The definition of this information is vendor specific.
The vendor is indicated in the vendor class identifier option.
Servers not equipped to interpret the vendor-specific information
sent by a client MUST ignore it (although it may be reported).

@RadekHvizdos
Copy link
Author

Hi @lhespress,

We have to let the DHCP server know that we want the VSI by requesting this option. The server will not send it just because we have indicated the proper VCI (class name).

The highlighted text only talks about ignoring this option if it is not supported.

My testing under dnsmasq supports this. Perhaps we could get someone to test this under different DHCP server?

Thanks!

@lhespress
Copy link
Collaborator

@RadekHvizdos Great, If there are multiple DHCP server support that, we can add it.

@RadekHvizdos
Copy link
Author

RadekHvizdos commented Jun 9, 2021

Hi @lhespress,

I have installed Windows Server 2022, and enabled its DHCP server to test its behavior.

I was surprised to see it provided the VSI even without our client explicitly requesting the option. So I have looked at the source code of my Linux DHCP server (dnsmasq) and found it's behavior is intentionally different, but can be overridden to work like Windows DHCP does.

--dhcp-option-force=[tag:,[tag:,]][encap:,][vi-encap:,][vendor:[],],[[,]]
This works in exactly the same way as --dhcp-option except that the option will always be sent, even if the client does not ask for it in the parameter request list. This is sometimes needed, for example when sending options to PXELinux.

This works:
dhcp-option-force=vendor:espressif_vendor,01,It_works

I still think it would be more proper to explicitly request this option, but I understand your hesitation with introducing this change. Perhaps we could hide it behind #if macros ?

Thanks!

@lhespress
Copy link
Collaborator

lhespress commented Jun 17, 2021

@RadekHvizdos

I add the DHCP_OPTION_VSI to dhcp_discover_request_options array, but you can see the attachment, add the option to DHCP Discover & DHCP Request message or not, The DHCP Server response the specific information. , you can pick it out by MAC address: 7c:df:a1:76:41:5c

static u8_t dhcp_discover_request_options[] = {
  DHCP_OPTION_SUBNET_MASK,
  DHCP_OPTION_ROUTER,
  DHCP_OPTION_BROADCAST
#if ESP_DHCP && !ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER
  , DHCP_OPTION_VSI
#endif
#if LWIP_DHCP_PROVIDE_DNS_SERVERS
  , DHCP_OPTION_DNS_SERVER
#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */
#if LWIP_DHCP_GET_NTP_SRV
  , DHCP_OPTION_NTP
#endif /* LWIP_DHCP_GET_NTP_SRV */
};

dhcp_option.zip

@RadekHvizdos
Copy link
Author

Hi @lhespress,

Thank you for implementing a configurable DHCP_OPTION_VSI option in the Parameter Request List. I have confirmed both use cases look correct, thanks for the packet captures.

One last thing that we have missed is this incorrect label, can you please rename it to LWIP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER ?

dhcp\components\lwip\Kconfig
Line 251: config LWIP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFY
dhcp\components\lwip\port\esp32\include\lwipopts.h
Line 270: * LWIP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFY==1: Do not add option 60 (Vendor Class Identifier) to DHCP packets
Line 272: #define ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFY

What are the next steps? How can I support this effort moving forward to mainline? I would love to have this present in 4.4 if possible.

Thanks!

@lhespress
Copy link
Collaborator

@RadekHvizdos

Thanks for your feedback, I have created an internal merge request, it's reviewing now. I'll update it to you once merged.

@RadekHvizdos
Copy link
Author

Hello @lhespress

Are there any updates regarding this?

Thanks!

@lhespress
Copy link
Collaborator

@RadekHvizdos It's reviewing now and it'll take a long time because of this is a modification of LWIP. I'll update it to you once merged.

@espressif-bot espressif-bot added Resolution: Done Issue is done internally Status: Done Issue is done internally and removed Status: In Progress Work is in progress labels Aug 23, 2021
espressif-bot pushed a commit that referenced this issue Mar 11, 2022
* Cherry-pick important fixes to 2.1.2-esp
  - CVE-2020-22283: Attacker could craft a packet that would disclose 8 bytes of some heap memory:
    - icmp6: Don't copy too much data
    - icmp6: Fix copying of chained pbuf in reply
    - icmp6: keep to the RFC and send as much as possible with icmp6 error messages
  - CVE-2020-22284: ZEP - ZigBee Encapsulation Protocol/6LoWPAN is not supported in IDF,
    the netif module (zepif.c) is not included in the build, but users can still inject
    the file into compilation process, implement IO interface and use this.
    - zepif: Copy possibly chained output pbuf properly
    - Add #define for minimum IPv6 MTU length
    - pbuf: Add pbuf_copy_partial_pbuf library function
* PPPoS: Fix null-deref when processing double break packet
  - pppos: fix in_tail null (espressif/esp-lwip@537c69d5)
  - PPP: Add test exhibiting empty packet null-deref (espressif/esp-lwip@202a07da)
* NAPT: Fix PBUF_REF type to clone the pbuf before forwarding
  - IP-FORWARD: If packet-type is PBUF_REF clone it before forwarding
  - Add NAPT unit test to exercise NAT feature for both RAM and REF pbuf types
* version: Update version numbers to match 2.1.2-esp
* Minor fixes listed below: Fix client receive KOD, NAPT fixes, restore
  dhcp_cb, sntp docs, vendor class id (disabled)

* Update submodule: espressif/esp-lwip@2195f74...76303df

Detailed description of the changes:
  - test/napt: Add unit test for IP forward with PBUF_REF (espressif/esp-lwip@76303df2)
  - napt: Fix PBUF_REF type to clone the pbuf before forwarding (espressif/esp-lwip@39068263)
  - version: Update version numbers to match 2.1.2-esp (espressif/esp-lwip@2b922919)
  - pppos: fix in_tail null (espressif/esp-lwip@537c69d5)
  - PPP: Add test exhibiting empty packet null-deref (espressif/esp-lwip@202a07da)
  - pbuf: Add pbuf_copy_partial_pbuf library function (espressif/esp-lwip@1c9cd9c1)
  - Add #define for minimum IPv6 MTU length (espressif/esp-lwip@d2dc577b)
  - zepif: Copy possibly chained output pbuf properly (espressif/esp-lwip@64ab7f2a)
  - icmp6: Don't copy too much data (espressif/esp-lwip@4a64731b)
  - icmp6: Fix copying of chained pbuf in reply (espressif/esp-lwip@7c822ff4)
  - icmp6: keep to the RFC and send as much as possible with icmp6 error messages (espressif/esp-lwip@29100ab6)
  - dns: Add API to clear dns cache (espressif/esp-lwip@ee59f77d)
  - CI: Fixed adding gitlab key (espressif/esp-lwip@5a2bdba7)
  - test case: modify test case test_tcp_new_max_num_remove_FIN_WAIT_1 (espressif/esp-lwip@6b090f7d)
  - add function for deinit lwip timers (espressif/esp-lwip@2749568f)
  - dhcp: Fix build issue that set ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER to true will build fail (espressif/esp-lwip@d827dbf7)
  - Document that sntp_setservername doesn't copy the string (espressif/esp-lwip@54acdb59) #6786
  - lwip/dhcp: add 60 option for vendor class identify (espressif/esp-lwip@ae7edc2a) espressif/esp-lwip#32
  - dhcp: Restore dhcp_cb on restart after dhcp_release_and_stop() (espressif/esp-lwip@55ea9d9c) #7217
  - napt: Fix disbale IPv6 and enable NAPT will build error (espressif/esp-lwip@74cf7f9f)
  - napt: fix checksum of UDP (espressif/esp-lwip@bb63eed1)
  - sntp: Fix client receive KOD packet that make pool MEMP_SYS_TIMEOUT not be freed (espressif/esp-lwip@1c1642fe)
  - test case: add tcp state and reset test cases. (espressif/esp-lwip@67deb805)

Closes #8300
Closes #8451
@ipqate
Copy link

ipqate commented May 5, 2022

Is your feature request related to a problem? Please describe.

We are developing a new ESP32 based product that should receive its configuration from network's DHCP server. We have investigated esp-idf's DHCP client, but currently it does not support sending or receiving DHCP options 43 (Vendor Specific Information) and 60 (Vendor Class Identifier (VCI)).

Describe the solution you'd like

Could we extend the capabilities of the DHCP client, so that we could:

  • Send option 60 to specify a Vendor Class Identifier, so that the DHCP would recognize our device.
  • Request and receive option 43, which would be provided by the DHCP server, specifying the configuration information.
  • Both options would be provided as an opaque byte array or string, no further processing by the stack is needed.

Describe alternatives you've considered

We are experimenting with requesting this information via UDP packets to the DHCP server, but as it is not possible to set the proper UDP source port, such implementation would be non-compliant.

Additional context

Explanation of the options: https://docs.paloaltonetworks.com/pan-os/8-1/pan-os-admin/networking/dhcp/dhcp-options/dhcp-options-43-55-and-60-and-other-customized-options.html

Currently supported DHCP options in esp-idf:

/** @brief Supported options for DHCP client or DHCP server */
typedef enum{
    ESP_NETIF_SUBNET_MASK                   = 1,    /**< Network mask */
    ESP_NETIF_DOMAIN_NAME_SERVER            = 6,    /**< Domain name server */
    ESP_NETIF_ROUTER_SOLICITATION_ADDRESS   = 32,   /**< Solicitation router address */
    ESP_NETIF_REQUESTED_IP_ADDRESS          = 50,   /**< Request specific IP address */
    ESP_NETIF_IP_ADDRESS_LEASE_TIME         = 51,   /**< Request IP address lease time */
    ESP_NETIF_IP_REQUEST_RETRY_TIME         = 52,   /**< Request IP address retry counter */
} esp_netif_dhcp_option_id_t;

Hello,

First of all I'd like to apologize for posting a question rather than an issue but I did not find any other way to figure out how to get DHCP options...

Could you please share a piece of code showing how to do it?

Thank you in advance.

espressif-bot pushed a commit that referenced this issue Jun 8, 2023
* Update submodule: git log --oneline 2195f7416fb3136831babf3e96c027a73075bd4f..6bb132e3797d5449a923804c75c57d458920f8ac

Detailed description of the changes:
  - tcp_in/ooseq: Fix incorrect segment trim when FIN moved (espressif/esp-lwip@6bb132e3)
  - api_msg: fix tcp_abort thread safety (2.1.2-esp) (espressif/esp-lwip@53a6e019)
  - lwip:optimization dhcp coarse timer (espressif/esp-lwip@a7abf28e)
  - napt: Fix ip_portmap_add() to keep only one port mapping (espressif/esp-lwip@abab9fef)
  - reduce the DHCP Request timeout (espressif/esp-lwip@6fa02bd3)
  - lwip timer:optimization dhcp fine timer (espressif/esp-lwip@79182163)
  - optimization lwip ip4 reassembly timer (espressif/esp-lwip@17f41c9f)
  - optimization lwip ip6 reassembly timer (espressif/esp-lwip@c943fc5a)
  - optimization lwip dns timer (espressif/esp-lwip@7f5ab42c)
  - napt: Fix clean compilation (espressif/esp-lwip@6132c975)
  - Lwip:add TCP Fin2 timeout configuration (espressif/esp-lwip@15b4400e)
  - napt: Fix IP forwarding when forward netif enable NAPT (espressif/esp-lwip@c950063f)
  - napt/stats: Move some napt counters to stats module (espressif/esp-lwip@475d658a)
  - ip_napt_maint: Fix timestamp overflow handling (espressif/esp-lwip@2e904508)
  - napt: Fixes and improvements (espressif/esp-lwip@fb1f3552)
  - test/napt: Add unit test for IP forward with PBUF_REF (espressif/esp-lwip@76303df2)
  - napt: Fix PBUF_REF type to clone the pbuf before forwarding (espressif/esp-lwip@39068263)
  - version: Update version numbers to match 2.1.2-esp (espressif/esp-lwip@2b922919)
  - pppos: fix in_tail null (espressif/esp-lwip@537c69d5)
  - PPP: Add test exhibiting empty packet null-deref (espressif/esp-lwip@202a07da)
  - pbuf: Add pbuf_copy_partial_pbuf library function (espressif/esp-lwip@1c9cd9c1)
  - Add #define for minimum IPv6 MTU length (espressif/esp-lwip@d2dc577b)
  - zepif: Copy possibly chained output pbuf properly (espressif/esp-lwip@64ab7f2a)
  - icmp6: Don't copy too much data (espressif/esp-lwip@4a64731b)
  - icmp6: Fix copying of chained pbuf in reply (espressif/esp-lwip@7c822ff4)
  - icmp6: keep to the RFC and send as much as possible with icmp6 error messages (espressif/esp-lwip@29100ab6)
  - dns: Add API to clear dns cache (espressif/esp-lwip@ee59f77d)
  - CI: Fixed adding gitlab key (espressif/esp-lwip@5a2bdba7)
  - test case: modify test case test_tcp_new_max_num_remove_FIN_WAIT_1 (espressif/esp-lwip@6b090f7d)
  - add function for deinit lwip timers (espressif/esp-lwip@2749568f)
  - dhcp: Fix build issue that set ESP_DHCP_DISABLE_VENDOR_CLASS_IDENTIFIER to true will build fail (espressif/esp-lwip@d827dbf7)
  - Document that sntp_setservername doesn't copy the string (espressif/esp-lwip@54acdb59)
  - Closes #6786
  - lwip/dhcp: add 60 option for vendor class identify (espressif/esp-lwip@ae7edc2a)
  - Closes espressif/esp-lwip#32
  - dhcp: Restore dhcp_cb on restart after dhcp_release_and_stop() (espressif/esp-lwip@55ea9d9c)
  - Closes #7217
  - napt: Fix disbale IPv6 and enable NAPT will build error (espressif/esp-lwip@74cf7f9f)
  - napt: fix checksum of UDP (espressif/esp-lwip@bb63eed1)
  - sntp: Fix client receive KOD packet that make pool MEMP_SYS_TIMEOUT not be freed (espressif/esp-lwip@1c1642fe)
  - test case: add tcp state and reset test cases. (espressif/esp-lwip@67deb805)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution: Done Issue is done internally Status: Done Issue is done internally Type: Feature Request Feature request for IDF
Projects
None yet
Development

No branches or pull requests

5 participants