DHCP:主机动态配置协议过流解析和数据包格式说明

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tyler_download/article/details/88556136

本节,我们使用代码实现主机配置协议。对协议实现而言,一是要理解数据包的交互流程,二是要了解数据包的结构,因此我们首先抓取DHCP协议的数据包,先了解它的大致结构。

首先启动wireshark,然后输入过滤条件为:bootp.option.type == 53 。然后找到DHCP协议配置地方,在我的mac机器上,情景如下:

屏幕快照 2019-03-05 下午5.36.22.png

然后点击按钮"DHCP续租”,在wireshark上可以捕捉到数据包:

屏幕快照 2019-03-14 上午9.19.37.png

双击其中一条数据展开查看其具体格式如下:

屏幕快照 2019-03-14 上午9.21.16.png

我们看到DHCP协议数据包的组成格式为IP数据包->UDP数据包->Boostrap Protocoal数据包。IP数据包在前面章节我们提到过,以后会详细分析。UDP数据包我们在前几节也展示过,它的内容简单,除了表明端口外,并没有太多内容,因此我们略过对它的解析,于是剩下需要掌握的就是Bootstrap Protocol。

Boostrap 是DHCP协议的前身,它叫主机静态配置协议。DHCP其实是它的扩展,将原来静态配置的过程动态化,于是配置起来更加灵活方便,只不过DHCP数据包的依然以Boostrap协议数据包为基础。

我们点开Boostrap Protocol看看具体内容:

屏幕快照 2019-03-14 上午9.28.00.png

扫描二维码关注公众号,回复: 5611651 查看本文章

通过观察,我们大概可以知道DHCP数据包大概有哪些字段,要了解这些字段的作用,我们还得充分了解协议的具体交互流程。DHCP协议以客户端<->服务器的方式进行交互,整个过程由客户端主导,服务器被动回应,因此掌握客户端的运行状态,我们就可以掌握DHCP的协议交互流程。

客户端在运行时维持一个内部状态机,其运行过程如下:
1,INIT状态。客户端创建一个DHCPDISCOVER消息在局域网内广播,查询可用的DHCP服务器,然后进入SELECTING状态。
2,SELECTING 状态。局域网内的DHCP收到广播消息后,发送DHCPOFFER消息,客户端会收到一个或多个DHCP服务器的回应,然后它从众多回应中选取一个服务器,向它发送DHCPREQUEST消息,然后进入REQUESTING状态。
3,REQUESTING状态。客户端向服务器发送DHCPREQUEST消息中包含了它对服务器的数据请求,例如可用IP地址以及各类配置参数,请求发送出去后它等待服务器回应。服务器会返回DHCPACK消息,里面包含了客户端想要的可用IP以及配置参数等信息。

收到消息后,客户端检测服务器返回的IP地址是否可用,可用的话进入使用状态并像上一节描述的那样设置两个超时时钟。如果客户端发现IP地址不可用,它向服务器发送DHCPDECLINE消息,然后转入状态1。

如果客户端从服务器收到的是DHCPNAK消息,它表示服务器拒绝向客户端提供服务,因此客户端重新进入状态1.

4,INIT-REBOOT状态。如果客户端已经租借到IP,它重启后进入该状态。此时它会向服务器发送DHCPREQUEST消息,重新确定它对IP的使用权,然后客户端进入REBOOTING状态,等待服务器反应。

5,REBOOTING状态。此时客户正在等待服务器返回确认消息,此时会有3中情况。一是客户端收到服务器发来的DHCPACK消息,表明可以继续使用它当前IP,于是客户端进入BOUND状态;二是,客户端得到DHCPACK回应,然后发现它原来使用的IP在自己关机或重启时,被其他设备抢夺了,于是他想服务器发送DHCPDECLINE消息,然后进入状态1;三是收到服务器发来的DHCPNAK消息,这表明服务器告诉客户端IP不能再继续使用,于是客户端进入状态1.

6,BOUND状态。此时客户端得到可用IP地址,并进入使用状态。此时它启动两个时钟,T1和T2。当T1超时时,它进入状态RENEWING。如果客户端主动要放弃使用当前IP,它会向服务器发送DHCPRELEASE消息,然后进入状态1.

7,RENEWING状态。此时客户端希望续租当前IP,于是他想客户端发送DHCPREQUEST消息,然后等待服务器确认。此时客户端要面临三种情况,一是服务器返回DHCPACK消息,它可以继续使用当前IP;二是收到DHCPNAK消息,服务器拒绝客户端继续租用当前IP;三是客户端的T2时钟超时,客户端进入REBINGDING状态。

8,REBIDING状态。此时客户端无法继续续租原有IP,于是它持续向局域网广播DHCPREQUEST消息,直到有服务器响应它为止。此时客户端又面临三种情况。一是有服务器向客户端返回DHCPACK消息,于是客户端可以使用新分配的IP;二是服务器返回DHCPNAK消息,这表明服务器希望客户端重新启动租借流程,于是客户端进入INIT状态;第三是,在收到回应前,客户端当前租用的IP到期,它重新进入INIT状态。

我们看到上面所述的流程已经足够复杂,而且它只提及客户端状态,服务器如何转变并没有提及。为了简单起见,我们将以客户端的方式编写代码,上面的流程状态可以使用下图统一描述:

屏幕快照 2019-03-14 上午10.23.23.png

由于协议过程较为复杂,我们需要一点一滴的吃透,因此我们先完成第一步是客户端向局域网广播消息,然后收到服务器应答。我们看看DHCP消息的具体格式:

屏幕快照 2019-03-14 上午10.35.52.png

上面我们看到的是前面抓包时对应的Boostrap Protocol部分。我们有依次解析各个字段:
op字段1字节,它表明消息类型,请求消息使用数值1,回应消息使用数值2.
HType1字节,它表明消息发送所使用的网络类型,由于我们默认使用互联网,因此它的值固定为1.
HLen字段1字节,它表明设备硬件地址的长度,由于我们默认使用mac地址,因此该字段固定为6.
Hops字段1字节,它表明数据包可以跨越几个不同网络,该字段的作用我们在前面traceroute程序中了解过,由于我们希望限制消息在当前局域网内流通,因此设置为0.
XID字段4字节。它与ICMP消息中的session作用一样,用来标志一次对话过程。
Secs字段2字节。它用来表明客户端发出请求后等待的时间,一般该字段不常使用,我们将它固定为0.
Flags字段2字节,取值0或1,如果设置为1,客户端要求服务器以广播的方式发送回应消息,因为此时客户端可能还没有IP地址。
CIAddr字段4字节,它存放客户端当前IP地址,如果客户端当前有IP,而且进入状态BOUND,RENEWING状态,其他情况下统一设置为0.
YIAddr字段4字节,这是服务器返回给客户端使用的IP。
SIAddr字段4字节,服务器IP地址,它有点特殊,这个IP是不一定是当前交互的服务器IP,而是设备下次启动时去获取IP地址的服务器IP。
GIAddr字段4字节,网关IP,当DHCP服务器不在本地局域网时,设备将通过该IP将数据包转发给处于另一个局域网的服务器,通常情况下使用不到。
CHAddr字段16字节,设备的硬件地址。由于我们默认设备使用mac地址,因此只使用到6个字节,其余10个字节用0填充。
SName字段64个字节,该字段用做DHCP服务器的字符串名称。
File字段128字节,该字段用于在设备和服务器间交换特定信息。
Options字段,可变长。该字段用于设备和服务器间交换多种配置信息。

接下来我们看看Options字段,由于所有信息的交互都存储在该字段,因此我们需搞清楚它的结构。在该字段开始前是4个字节的”魔术字“,固定为"99.130.83.99",然后才是一系列Option数据结构,Option数据结构组成如下:

屏幕快照 2019-03-14 下午4.08.02.png

每个Option由三字段组成,第一字段是Code,用来表明当前Option类型,它有两个特殊值,一个是0,它表示当前Option只有这一个字节,另一个特殊值是255,它表示后续不再含有Option结构体;第二字段是len,用来标志数据段的长度;第三字段是Data,用来存储数据。

由于Option结构体用于客户端与服务器进行数据交换,因此它的种类相当繁杂,因此在下一节我们使用代码实现协议时,再就具体的option结构及其作用做对照讲解。

更详细的讲解和代码调试演示过程,请点击链接

更多技术信息,包括操作系统,编译器,面试算法,机器学习,人工智能,请关照我的公众号:
这里写图片描述

猜你喜欢

转载自blog.csdn.net/tyler_download/article/details/88556136