W tym poście chciałbym opisać sposób wykonania modyfikacji LWIP, dotyczącej dołożenia parametru Vendor ID.
W protokole DHCP ustawienie opcji 60 czyli tzw. Vendor Class Id. W niej umieszczone są unikatowe informacje o urządzeniu np. nazwa wraz z numerem seryjnym, czy sam numer.
Biblioteka LWIP domyślnie nie posiada tej funkcji możliwej do uruchomienia. Natomiast dosyć łatwo można ją dołożyć.
Na samym początku należy przygotować funkcję zapisującą potrzebne dane:
- static int vendor_class_len = 0;
- static char * vendor_class_buf = NULL;
- err_t dhcp_set_vendor_class_identifier(uint8_t len, char *str) {
- if (len == 0) { return ERR_ARG; }
- if (str == NULL) { return ERR_ARG; }
- vendor_class_buf = (char *)mem_malloc(len + 1);
- if (vendor_class_buf == NULL) { return ERR_MEM; }
- vendor_class_len = len;
- memcpy(vendor_class_buf, str, len);
- return 0;
- }
- char vendorTmp[40] = {0x00};
- err_t
- dhcp_start(struct netif *netif)
- {
- struct dhcp *dhcp;
- err_t result = ERR_OK;
- extern volatile uint8_t serialNumber[3];
- uint8_t arraySize = sprintf(vendorTmp, "KKK-Test KK_V4.9w %x%x%x", serialNumber[0], serialNumber[1], serialNumber[2]);
- dhcp_set_vendor_class_identifier((arraySize), &vendorTmp[0]);
W powyższym przypadku wykorzystuję funkcję sprintf do sformatowania ciągu znaków z wprowadzeniem numeru seryjnego.
Wprowadzanie danych do ramki DHCP musimy wpisać w trzech funkcjach dhcp_renew, dhcp_rebind oraz dhcp_select.
- #if LWIP_NETIF_HOSTNAME
- dhcp_option_hostname(dhcp, netif);
- #endif /* LWIP_NETIF_HOSTNAME */
- #ifdef LWIP_DHCP_VENDOR_ID
- if (vendor_class_buf != NULL) {
- const char *p = (const char*)vendor_class_buf;
- if (vendor_class_len > 0) {
- uint8_t len = 0;
- size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3;
- len = LWIP_MIN(vendor_class_len, available);
- dhcp_option(dhcp, DHCP_OPTION_US, len);
- while (len--) {
- dhcp_option_byte(dhcp, *p++);
- }
- }
- }
- #endif
Powyższy kod sprawdza dostępność wolnego miejsca, jeśli będzie go za mało to w ramce zostanie umieszczony nie pełny ciąg znaków.
Można to umieścić w osobnej funkcji:
- #ifdef LWIP_DHCP_VENDOR_ID
- static void
- dhcp_option_vendor_id(struct dhcp *dhcp, struct netif *netif)
- {
- if (vendor_class_buf != NULL) {
- const char *p = (const char*)vendor_class_buf;
- if (vendor_class_len > 0) {
- u8_t len = 0;
- size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3;
- len = LWIP_MIN(vendor_class_len, available);
- dhcp_option(dhcp, DHCP_OPTION_US, len);
- while (len--) {
- dhcp_option_byte(dhcp, *p++);
- }
- }
- }
- }
- #endif
Dzięki takiemu zabiegowi, jest trochę przejrzyściej:
- #if LWIP_NETIF_HOSTNAME
- dhcp_option_hostname(dhcp, netif);
- #endif /* LWIP_NETIF_HOSTNAME */
- #ifdef LWIP_DHCP_VENDOR_ID
- dhcp_option_vendor_id(dhcp, netif);
- #endif /* LWIP_DHCP_VENDOR_ID */
Dodatkowo należy pamiętać o modyfikacji parametru DHCP_OPTIONS_LEN:
- #define DHCP_OPTIONS_LEN 150U //DHCP_MIN_OPTIONS_LEN