// // Created by xajhuang on 2023/3/16. // #ifndef VCPE_DHCPD_H #define VCPE_DHCPD_H #include #ifdef __cplusplus extern "C" { #endif #define DHCP_SVR_PORT (67) #define DHCP_CLI_PORT (68) /** * Message op code / message type * Request Message */ #define BOOTP_REQUEST 1 /** * Message op code / message type * Response Message */ #define BOOTP_REPLY 2 #define DHCP_MSG_NONE 0 /** * DHCP客户端在请求IP地址时并不知道DHCP服务器的位置, * 因此DHCP客户端会在本地网络内以广播方式发送Discover请求报文,以发现网络中的DHCP服务器。 * 所有收到Discover报文的DHCP服务器都会发送应答报文, * DHCP客户端据此可以知道网络中存在的DHCP服务器的位置 */ #define DHCP_MSG_DISCOVER 1 /** * DHCP服务器收到Discover报文后,就会在所配置的地址池中查找一个合适的IP地址, * 加上相应的租约期限和其他配置信息(如网关、DNS服务器等),构造一个Offer报文, * 发送给DHCP客户端,告知用户本服务器可以为其提供IP地址。但这个报文只是告诉DHCP客户端可以提供IP地址, * 最终还需要客户端通过ARP来检测该IP地址是否重复 */ #define DHCP_MSG_OFFER 2 /** * DHCP客户端可能会收到很多Offer请求报文,所以必须在这些应答中选择一个。 * 通常是选择第一个Offer应答报文的服务器作为自己的目标服务器, * 并向该服务器发送一个广播的Request请求报文,通告选择的服务器,希望获得所分配的IP地址。 * 另外,DHCP客户端在成功获取IP地址后,在地址使用租期达到50%时, * 会向DHCP服务器发送单播Request请求报文请求续延租约, * 如果没有收到ACK报文,在租期达到87.5%时,会再次发送广播的Request请求报文以请求续延租约 */ #define DHCP_MSG_REQUEST 3 /** * DHCP客户端收到DHCP服务器ACK应答报文后, * 通过地址冲突检测发现服务器分配的地址冲突或者由于其他原因导致不能使用, * 则会向DHCP服务器发送Decline请求报文,通知服务器所分配的IP地址不可用,以期获得新的IP地址 */ #define DHCP_MSG_DECLINE 4 /** * DHCP服务器收到Request请求报文后,根据Request报文中携带的用户MAC来查找有没有相应的租约记录, * 如果有则发送ACK应答报文,通知用户可以使用分配的IP地址 */ #define DHCP_MSG_ACK 5 /** * 如果DHCP服务器收到Request请求报文后,没有发现有相应的租约记录或者由于某些原因无法正常分配IP地址, * 则向DHCP客户端发送NAK应答报文,通知用户无法分配合适的IP地址 */ #define DHCP_MSG_NAK 6 /** * 当DHCP客户端不再需要使用分配IP地址时(一般出现在客户端关机、下线等状况) * 就会主动向DHCP服务器发送RELEASE请求报文,告知服务器用户不再需要分配IP地址, * 请求DHCP服务器释放对应的IP地址 */ #define DHCP_MSG_RELEASE 7 /** * DHCP客户端如果需要从DHCP服务器端获取更为详细的配置信息, * 则向DHCP服务器发送Inform请求报文;DHCP服务器在收到该报文后, * 将根据租约进行查找到相应的配置信息后,向DHCP客户端发送ACK应答报文。目前基本上不用了 */ #define DHCP_MSG_INFORM 8 #pragma pack(push) #pragma pack(1) /* 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | op (1) | htype (1) | hlen (1) | hops (1) | +---------------+---------------+---------------+---------------+ | xid (4) | +-------------------------------+-------------------------------+ | secs (2) | flags (2) | +-------------------------------+-------------------------------+ | ciaddr (4) | +---------------------------------------------------------------+ | yiaddr (4) | +---------------------------------------------------------------+ | siaddr (4) | +---------------------------------------------------------------+ | giaddr (4) | +---------------------------------------------------------------+ | | | chaddr (16) | | | | | +---------------------------------------------------------------+ | | | sname (64) | +---------------------------------------------------------------+ | | | file (128) | +---------------+---------------+---------------+---------------+ | cookie (4) | +---------------------------------------------------------------+ | | | options (variable) | +---------------------------------------------------------------+ */ typedef struct { ///< 报文的操作类型。分为请求报文和响应报文。1:请求报文,2:应答报文。即client送给server的封包,设为1,反之为2 U8 op; ///< DHCP客户端的MAC地址类型。MAC地址类型其实是指明网络类型。htype值为1时表示为最常见的以太网MAC地址类型 U8 htype; ///< DHCP客户端的MAC地址长度。以太网MAC地址长度为6个字节,即以太网时hlen值为6 U8 hlen; ///< DHCP报文经过的DHCP中继的数目,默认为0。DHCP请求报文每经过一个DHCP中继,该字段就会增加1。没有经过DHCP中继时值为0 U8 hops; ///< 客户端通过DHCP Discover报文发起一次IP地址请求时选择的随机数,相当于请求标识。用来标识一次IP地址请求过程。在一次请求中所有报文的Xid都是一样的 U32 xid; ///< DHCP客户端从获取到IP地址或者续约过程开始到现在所消耗的时间,以秒为单位。 ///< 在没有获得IP地址前该字段始终为0(DHCP客户端开始DHCP请求后所经过的时间。目前尚未使用,固定为0) U16 secs; ///< 标志位,只使用第0比特位,是广播应答标识位,用来标识DHCP服务器应答报文是采用单播还是广播发送, ///< 0表示采用单播发送方式,1表示采用广播发送方式。其余位尚未使用。(即从0-15bits,最左1bit为1时表示server将以广播方式传送封包给client。) U16 flags; ///< DHCP客户端的IP地址。仅在DHCP服务器发送的ACK报文中显示,因为在得到DHCP服务器确认前,DHCP客户端是还没有分配到IP地址的。 ///< 在其他报文中均显示,只有客户端是Bound、Renew、Rebinding状态,并且能响应ARP请求时,才能被填充 U32 ciaddr; ///< DHCP服务器分配给客户端的IP地址。仅在DHCP服务器发送的Offer和ACK报文中显示,其他报文中显示为0 U32 yiaddr; ///< 下一个为DHCP客户端分配IP地址等信息的DHCP服务器IP地址。仅在DHCP Offer、DHCP ACK报文中显示,其他报文中显示为0 U32 siaddr; ///< DHCP客户端发出请求报文后经过的第一个DHCP中继的IP地址。如果没有经过DHCP中继,则显示为0。(转发代理(网关)IP地址) U32 giaddr; ///< DHCP客户端的MAC地址。在每个报文中都会显示对应DHCP客户端的MAC地址 U8 chaddr[16]; ///< 为DHCP客户端分配IP地址的DHCP服务器名称(DNS域名格式)。在Offer和ACK报文中显示发送报文的DHCP服务器名称,其他报文显示为0 U8 sname[64]; ///< DHCP服务器为DHCP客户端指定的启动配置文件名称及路径信息。仅在DHCP Offer报文中显示,其他报文中显示为空 U8 file[128]; ///< 缓存数据 U32 cookie; ///< 可选项字段,长度可变,格式为"代码+长度+数据" U8 options[0]; } DHCP_PROTO, *PDHCP_PROTO; #pragma pack(pop) int dhcpd_init(); #ifdef __cplusplus } #endif #endif //VCPE_DHCPD_H