diff --git a/src/core/ipv4/dhcp.c b/src/core/ipv4/dhcp.c index 76b9f682..0dcecae4 100644 --- a/src/core/ipv4/dhcp.c +++ b/src/core/ipv4/dhcp.c @@ -73,6 +73,7 @@ #include "lwip/ip_addr.h" #include "lwip/netif.h" #include "lwip/def.h" +#include "lwip/sys.h" #include "lwip/dhcp.h" #include "lwip/autoip.h" #include "lwip/dns.h" @@ -445,7 +446,9 @@ dhcp_coarse_tmr(void) if (dhcp->t0_timeout && (++dhcp->lease_used == dhcp->t0_timeout)) { LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t0 timeout\n")); /* this clients' lease time has expired */ + igmp_report_groups_leave(netif); // not remove group to make able to report group when dhcp bind dhcp_release_and_stop(netif); + netif->dhcp->seconds_elapsed = sys_now(); dhcp_start(netif); /* timer is active (non zero), and triggers (zeroes) now? */ } else if (dhcp->t2_rebind_time && (dhcp->t2_rebind_time-- == 1)) { @@ -561,6 +564,7 @@ dhcp_t1_timeout(struct netif *netif) ("dhcp_t1_timeout(): must renew\n")); /* This slightly different to RFC2131: DHCPREQUEST will be sent from state DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */ + dhcp->seconds_elapsed = sys_now(); dhcp_renew(netif); /* Calculate next timeout */ if (((dhcp->t2_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) { @@ -778,6 +782,11 @@ dhcp_start(struct netif *netif) /* dhcp is cleared below, no need to reset flag*/ } +#if DHCP_CREATE_RAND_XID && defined(LWIP_SRAND) + /* For each system startup, fill in a random seed with different system ticks. */ + LWIP_SRAND(); +#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_SRAND) */ + /* clear data structure */ memset(dhcp, 0, sizeof(struct dhcp)); /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */ @@ -796,6 +805,7 @@ dhcp_start(struct netif *netif) } /* (re)start the DHCP negotiation */ + dhcp->seconds_elapsed = sys_now(); result = dhcp_discover(netif); if (result != ERR_OK) { /* free resources allocated above */ @@ -954,6 +964,9 @@ dhcp_decline(struct netif *netif) options_out_len = dhcp_option(options_out_len, msg_out->options, DHCP_OPTION_REQUESTED_IP, 4); options_out_len = dhcp_option_long(options_out_len, msg_out->options, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); + dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); + dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(&dhcp->server_ip_addr))); + LWIP_HOOK_DHCP_APPEND_OPTIONS(netif, dhcp, DHCP_STATE_BACKING_OFF, msg_out, DHCP_DECLINE, &options_out_len); dhcp_option_trailer(options_out_len, msg_out->options, p_out); @@ -1099,11 +1112,6 @@ dhcp_bind(struct netif *netif) dhcp->t2_rebind_time = dhcp->t2_timeout; } - /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */ - if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) { - dhcp->t1_timeout = 0; - } - if (dhcp->subnet_mask_given) { /* copy offered network mask */ ip4_addr_copy(sn_mask, dhcp->offered_sn_mask); @@ -1306,6 +1314,22 @@ dhcp_reboot(struct netif *netif) return result; } +/** check if DHCP supplied netif->ip_addr + * + * @param netif the netif to check + * @return 1 if DHCP supplied netif->ip_addr (states BOUND or RENEWING), + * 0 otherwise + */ +u8_t +dhcp_supplied_address(const struct netif *netif) +{ + if ((netif != NULL) && (netif->dhcp != NULL)) { + struct dhcp* dhcp = netif->dhcp; + return (dhcp->state == DHCP_BOUND) || (dhcp->state == DHCP_RENEWING); + } + return 0; +} + /** * @ingroup dhcp4 * Release a DHCP lease and stop DHCP statemachine (and AUTOIP if LWIP_DHCP_AUTOIP_COOP). @@ -1316,6 +1340,8 @@ void dhcp_release_and_stop(struct netif *netif) { struct dhcp *dhcp = netif_dhcp_data(netif); + err_t result; + u16_t msecs; ip_addr_t server_ip_addr; LWIP_ASSERT_CORE_LOCKED(); @@ -1929,6 +1955,11 @@ dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type, u16_t msg_out->htype = LWIP_IANA_HWTYPE_ETHERNET; msg_out->hlen = netif->hwaddr_len; msg_out->xid = lwip_htonl(dhcp->xid); + if ((message_type == DHCP_DISCOVER) || (message_type == DHCP_REQUEST)) { + dhcp->msg_out->secs = (uint16_t)((sys_now() - dhcp->seconds_elapsed) / configTICK_RATE_HZ); + } else { + dhcp->msg_out->secs = 0; + } /* we don't need the broadcast flag since we can receive unicast traffic before being fully configured! */ /* set ciaddr to netif->ip_addr based on message_type and state */ diff --git a/src/include/lwip/dhcp.h b/src/include/lwip/dhcp.h index c78aa0ba..49ff25e3 100644 --- a/src/include/lwip/dhcp.h +++ b/src/include/lwip/dhcp.h @@ -90,6 +90,7 @@ struct dhcp ip4_addr_t offered_ip_addr; ip4_addr_t offered_sn_mask; ip4_addr_t offered_gw_addr; + ip4_addr_t offered_bc_addr; u32_t offered_t0_lease; /* lease period (in seconds) */ u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ @@ -98,6 +99,7 @@ struct dhcp ip4_addr_t offered_si_addr; char boot_file_name[DHCP_BOOT_FILE_LEN]; #endif /* LWIP_DHCP_BOOTPFILE */ + u32_t seconds_elapsed; };