5050#define DHCPRELEASE 7
5151
5252#define DHCP_OPTION_SUBNET_MASK 1
53+ #define DHCP_OPTION_HOST_NAME 12
5354#define DHCP_OPTION_ROUTER 3
5455#define DHCP_OPTION_DNS_SERVER 6
5556#define DHCP_OPTION_REQ_IPADDR 50
@@ -142,6 +143,11 @@ struct dhcps_t {
142143 struct udp_pcb * dhcps_pcb ;
143144 dhcps_handle_state state ;
144145 bool has_declined_ip ;
146+ #if CONFIG_LWIP_DHCPS_REPORT_CLIENT_HOSTNAME
147+ /* Temporary storage for option 12 parsed from the current packet */
148+ char opt_hostname [CONFIG_LWIP_DHCPS_MAX_HOSTNAME_LEN ];
149+ bool opt_hostname_present ;
150+ #endif
145151};
146152
147153
@@ -923,6 +929,33 @@ static u8_t parse_options(dhcps_t *dhcps, u8_t *optptr, s16_t len)
923929 type = * (optptr + 2 );
924930 break ;
925931
932+ #if CONFIG_LWIP_DHCPS_REPORT_CLIENT_HOSTNAME
933+ case DHCP_OPTION_HOST_NAME : {
934+ /* option format: code(1) len(1) value(len) */
935+ u8_t olen = * (optptr + 1 );
936+ const u8_t * oval = optptr + 2 ;
937+ if (olen > 0 ) {
938+ /* clamp to configured max, keep room for NUL */
939+ size_t copy_len = olen ;
940+ if (copy_len >= CONFIG_LWIP_DHCPS_MAX_HOSTNAME_LEN ) {
941+ copy_len = CONFIG_LWIP_DHCPS_MAX_HOSTNAME_LEN - 1 ;
942+ }
943+ size_t j = 0 ;
944+ for (; j < copy_len ; ++ j ) {
945+ char c = (char )oval [j ];
946+ if ((c >= 'a' && c <= 'z' ) || (c >= 'A' && c <= 'Z' ) || (c >= '0' && c <= '9' ) || c == '.' || c == '-' || c == '_' ) {
947+ dhcps -> opt_hostname [j ] = c ;
948+ } else {
949+ dhcps -> opt_hostname [j ] = '-' ;
950+ }
951+ }
952+ dhcps -> opt_hostname [j ] = '\0' ;
953+ dhcps -> opt_hostname_present = true;
954+ }
955+ break ;
956+ }
957+ #endif
958+
926959 case DHCP_OPTION_REQ_IPADDR ://50
927960 if (memcmp ((char * ) & client .addr , (char * ) optptr + 2 , 4 ) == 0 ) {
928961#if DHCPS_DEBUG
@@ -1111,7 +1144,7 @@ static s16_t parse_msg(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
11111144 return 4 ;
11121145 }
11131146
1114- s16_t ret = parse_options (dhcps , & m -> options [4 ], len );;
1147+ s16_t ret = parse_options (dhcps , & m -> options [4 ], len );
11151148
11161149 if (ret == DHCPS_STATE_RELEASE || ret == DHCPS_STATE_NAK || ret == DHCPS_STATE_DECLINE ) {
11171150 if (pnode != NULL ) {
@@ -1131,6 +1164,21 @@ static s16_t parse_msg(dhcps_t *dhcps, struct dhcps_msg *m, u16_t len)
11311164 memset (& dhcps -> client_address , 0x0 , sizeof (dhcps -> client_address ));
11321165 }
11331166
1167+ #if CONFIG_LWIP_DHCPS_REPORT_CLIENT_HOSTNAME
1168+ /* If we parsed a hostname from options and we have a lease entry, store it */
1169+ if (pdhcps_pool != NULL ) {
1170+ if (dhcps -> opt_hostname_present ) {
1171+ size_t n = strnlen (dhcps -> opt_hostname , CONFIG_LWIP_DHCPS_MAX_HOSTNAME_LEN );
1172+ if (n > 0 ) {
1173+ memset (pdhcps_pool -> hostname , 0 , sizeof (pdhcps_pool -> hostname ));
1174+ memcpy (pdhcps_pool -> hostname , dhcps -> opt_hostname , n );
1175+ } else {
1176+ pdhcps_pool -> hostname [0 ] = '\0' ;
1177+ }
1178+ }
1179+ }
1180+ #endif
1181+
11341182#if DHCPS_DEBUG
11351183 DHCPS_LOG ("dhcps: xid changed\n" );
11361184 DHCPS_LOG ("dhcps: client_address.addr = %x\n" , dhcps -> client_address .addr );
@@ -1619,4 +1667,40 @@ err_t dhcps_dns_getserver(dhcps_t *dhcps, ip4_addr_t *dnsserver)
16191667 return dhcps_dns_getserver_by_type (dhcps , dnsserver , DNS_TYPE_MAIN );
16201668}
16211669
1670+ #if CONFIG_LWIP_DHCPS_REPORT_CLIENT_HOSTNAME
1671+ bool dhcps_get_hostname_on_mac (dhcps_t * dhcps , const u8_t * mac , char * out , size_t out_len )
1672+ {
1673+ if ((dhcps == NULL ) || (mac == NULL ) || (out == NULL ) || (out_len == 0 )) {
1674+ return false;
1675+ }
1676+ list_node * pnode = dhcps -> plist ;
1677+ while (pnode ) {
1678+ struct dhcps_pool * pool = pnode -> pnode ;
1679+ if (memcmp (pool -> mac , mac , sizeof (pool -> mac )) == 0 ) {
1680+ size_t maxcpy = (out_len > 0 ) ? out_len - 1 : 0 ;
1681+ size_t srclen = 0 ;
1682+ /* hostname may be empty string */
1683+ srclen = strnlen (pool -> hostname , CONFIG_LWIP_DHCPS_MAX_HOSTNAME_LEN );
1684+ if (maxcpy > 0 ) {
1685+ if (srclen > maxcpy ) srclen = maxcpy ;
1686+ if (srclen ) memcpy (out , pool -> hostname , srclen );
1687+ out [srclen ] = '\0' ;
1688+ }
1689+ return true;
1690+ }
1691+ pnode = pnode -> pnext ;
1692+ }
1693+ return false;
1694+ }
1695+ #else
1696+ bool dhcps_get_hostname_on_mac (dhcps_t * dhcps , const u8_t * mac , char * out , size_t out_len )
1697+ {
1698+ LWIP_UNUSED_ARG (dhcps );
1699+ LWIP_UNUSED_ARG (mac );
1700+ if (out && out_len ) {
1701+ out [0 ] = '\0' ;
1702+ }
1703+ return false;
1704+ }
1705+ #endif
16221706#endif // ESP_DHCPS
0 commit comments