DHCP流程
关于DHCP服务器的offer与ack阶段是单播还是广播的研究
看来都可以,DHCP协议有一位是表示发的是单波还是广播。
可以广播包,也可以单波包,因为第一步服务器肯定知道了客户端MAC,知道MAC就可以只发个单波就可以(交换机MAC-端口表,这样就可以单波传送特定端口了)
LwIP DHCP流程:
1: netif_add: dhcpif 设为全0
netif_set_default
netif_set_up
2: dhcp_start
3: dhcpif->ip_addr.addr 该值不为0则说明取得到IP
此时需要保存IP, Mask, GateWay, 否则在以下部操作之后就没了
dhcp_release 释放DHCP, 该操作后不需要调用netif_set_down
dhcp_stop remove the DHCP client.
4: netif_set_addr 用DHCP得到的值重设IP, Mask, GateWay.
5: netif_set_up 必须设置!
注: dhcp_fine_tmr(); 必须调用
dhcp_coarse_tmr(); 要求调用
IP4_ADDR(&ipaddr, 0, 0, 0, 0); // IP地址
IP4_ADDR(&netmask, 0, 0, 0, 0); // 子网掩码
IP4_ADDR(&gw, 0, 0, 0, 0); // 网关
netif_add(ðif, &ipaddr, &netmask, &gw,
NULL, ethernetif_init, ip_input); // 建立LwIP网络界面
netif_set_default(ðif); // 设为默认网络界面
netif_set_up(ðif); // 启动网络界面
ip_init(); // 初始化IP模块
tcp_init(); // 初始化TCP模块
result = dhcp_start(ðif);
while(1)
{
ethbuf_len = ENET_HandleRxPkt(ethbuf);
// 接收来自NIC的数据包
if(ethbuf_len > 0) // 有数据包被接收?
ethernetif_input(ðif); // 是,将数据包交给LwIP处理
if(ethif.dhcp!=NULL &&
ethif.dhcp->offered_ip_addr.addr!=0 &&
ethif.dhcp->offered_sn_mask.addr!=0 &&
ethif.dhcp->offered_gw_addr.addr!=0)
{
netif_set_addr(ðif, &(ethif.dhcp->offered_ip_addr)
,&(ethif.dhcp->offered_sn_mask)
, &(ethif.dhcp->offered_gw_addr));
netif_set_default(ðif);
netif_set_up(ðif);
ip_init();
dhcp_stop(ðif);
}
}
}
dhcp结构体
struct dhcp
{
/** current DHCP state machine state */
u8_t state;
/** retries of current request */
u8_t tries;
/** transaction identifier of last sent request */
u32_t xid;
/** our connection to the DHCP server */
struct udp_pcb *pcb;
/** (first) pbuf of incoming msg */
struct pbuf *p;
/** incoming msg */
struct dhcp_msg *msg_in;
/** incoming msg options */
struct dhcp_msg *options_in;
/** ingoing msg options length */
u16_t options_in_len;
struct pbuf *p_out; /* pbuf of outcoming msg */
struct dhcp_msg *msg_out; /* outgoing msg */
u16_t options_out_len; /* outgoing msg options length */
u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */
u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */
u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */
struct ip_addr server_ip_addr; /* dhcp server address that offered this lease */
struct ip_addr offered_ip_addr;
struct ip_addr offered_sn_mask;
struct ip_addr offered_gw_addr;
struct ip_addr offered_bc_addr;
#define DHCP_MAX_DNS 2
u32_t dns_count; /* actual number of DNS servers obtained */
struct ip_addr offered_dns_addr[DHCP_MAX_DNS]; /* DNS server addresses */
u32_t offered_t0_lease; /* lease period (in seconds) */
u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */
u32_t offered_t2_rebind; /* recommended rebind time (usually 66% of lease period) */
#if LWIP_DHCP_AUTOIP_COOP
u8_t autoip_coop_state;
#endif
/** Patch #1308
* TODO: See dhcp.c "TODO"s
*/
#if 0
struct ip_addr offered_si_addr;
u8_t *boot_file_name;
#endif
};