日志:
1.图片占位,空了更新。20230307-1826
2.增加“一、租用“、“二、重连或续租”和”三、报文解析”。20230810-1045
3.简易的实现代码,可以见我的项目:https://github.com/1225297600/mini-DHCP
一、租用
1.Discover(设备广播请求)
设备以0.0.0.0的地址,向255.255.255.255地址UDP广播
报文携带:
1.设备MAC
2.名称(128Byte以内的字符串)
2.Offer(路由器广播IP)
路由器以192.168.x.x的地址,向255.255.255.255地址UDP广播
报文携带:
分配的IP地址
租用时长(秒)
3.Request(设备广播接受)
设备以0.0.0.0的地址,向255.255.255.255地址UDP广播
报文携带:
1.分配的IP地址
4.ACK/NAC(路由器广播接受响应)
路由器以192.168.x.x的地址,向255.255.255.255地址UDP广播
报文携带:
1.分配的IP地址
2.租用时长(秒)
设备收到ACK报文,结束申请过程,收到NAC报文,则回到步骤1,重新Discover。
二、重连或续租
网络重连,或者在达到一半的租用时间后,应当发起继续租用,仍然使用Request和ACK/NAC报文。
1.Request(设备广播租用)
设备以0.0.0.0的地址,向255.255.255.255地址UDP广播Request
2.ACK/NAC(路由器广播租用响应)
路由器以192.168.x.x的地址,向255.255.255.255地址UDP广播
设备收到ACK报文,继续使用该IP,收到NAC报文,则回到"一、租用",重新Discover。
三、报文解析
1.结构
报文由两个部分组成:报文头和信息
其中OPT为信息,其余为报文头
typedef struct {
uint8_t op; ///1代表设备发出的报文;2代表路由器发出的
uint8_t htype; ///1以太网设备
uint8_t hlen; ///MAC地址的长度
uint8_t hops; ///中继次数,大于4会被路由器抛弃
uint32_t xid; ///流水号
uint16_t secs; ///系统运行时长秒数
uint16_t flags; ///广播0x8000,单播0x0000
uint8_t ciaddr[4]; ///分配的IP(或想要继续租用的IP)
uint8_t yiaddr[4]; ///路由器的IP
uint8_t siaddr[4]; ///< No use
uint8_t giaddr[4]; ///< No use
uint8_t chaddr[16]; ///
uint8_t sname[64]; ///< No use
uint8_t file[128]; ///设备名
uint8_t OPT[312]; ///信息
}RIP_MSG;
2.组包
详见代码“DRV_DHCP_RipMsgInit”、“DRV_DHCP_SendDiscover”和“DRV_DHCP_SendRequest”函数
3.解析
详见代码“DRV_DHCP_UdpHandle”函数