DHCP协议分析

一、DHCP客户机初始化:
1. 寻找DHCP Server
当DHCP客户机第一次登录网络的时候(也就是客户机上没有任何IP地址数据时),它会通过客户端基于UDP的源端口号68,向网络上发出一个DHCPDISCOVER数据包(包中包含客户机的MAC地址和计算机名等信息)。因为客户机还不知道自己属于哪一个网络,所以封包的源地址为0.0.0.0,目标地址为255.255.255.255,目的端口号67,然后再附上DHCP discover的信息,向网络进行广播。
DHCP discover的等待时间预设为1秒,也就是当客户机将第一个DHCP discover封包送出去之后,在1秒之内没有得到回应的话,就会进行第二次DHCP discover广播。若一直没有得到回应,客户机会将这一广播包重新发送四次(以2,4,8,16秒为间隔,加上1-1000毫秒之间随机长度的时间)。如果都没有得到DHCP Server的回应,客户机会从169.254.0.0/16这个自动保留的私有IP地址中选用一个IP地址。并且每隔5分钟重新广播一次,如果收到某个服务器的响应,则继续IP租用过程。

2. 提供IP地址租用
当DHCP Server监听到客户机发出的DHCP discover广播后,它会从那些还没有租出去的地址中,选择最前面的空置IP,连同其它TCP/IP设定,通过UDP 68端口响应给客户机一个DHCP OFFER数据包(包中包含IP地址、子网掩码、地址租期等信息)。此时还是使用广播进行通讯,源IP地址为DHCP Server的IP地址,目标地址为255.255.255.255(可以单播可以广播,取决于DHCP报文中的bootp flag位)。同时,DHCP Server为此客户保留它提供的IP地址,从而不会为其他DHCP客户分配此IP地址。
由于客户机在开始的时候还没有IP地址,所以在其DHCP discover封包内会带有其MAC地址信息,并且有一个XID编号来辨别该封包,DHCP Server响应的DHCP OFFER封包则会根据这些资料传递给要求租约的客户。
服务器收到请求后会它从尚未出租的IP地址中挑选一个分配给DHCP客户机,在本地形成一个绑定。

3. 接受IP租约
如果客户机收到网络上多台DHCP服务器的响应,只会挑选其中一个DHCP OFFER(一般是最先到达的那个),并且会向网络发送一个DHCP REQUEST广播数据包(包中包含客户端的MAC地址、接受的租约中的IP地址、提供此租约的DHCP服务器地址等),告诉所有DHCP Server它将接受哪一台服务器提供的IP地址,所有其他的DHCP服务器撤销它们的提供以便将IP地址提供给下一次IP租用请求。此时,由于还没有得到DHCP Server的最后确认,客户端仍然使用0.0.0.0为源IP地址,255.255.255.255为目标地址进行广播。
事实上,并不是所有DHCP客户机都会无条件接受DHCP Server的OFFER,特别是如果这些主机上安装有其它TCP/IP相关的客户机软件。客户机也可以用DHCP REQUEST向服务器提出DHCP选择,这些选择会以不同的号码填写在DHCP Option Field里面。客户机可以保留自己的一些TCP/IP设定。

4. 租约确认ACK
当DHCP Server接收到客户机的DHCP REQUEST之后,会广播(可以单播可以广播,取决于DHCP报文中的bootp flag位)返回给客户机一个DHCP ACK消息包,表明已经接受客户机的选择,并将这一IP地址的合法租用以及其他的配置信息都放入该广播包发给客户机。
客户机在接收到DHCP ACK广播后,会向网络发送三个针对此IP地址的ARP解析请求以执行冲突检测,查询网络上有没有其它机器使用该IP地址;如果发现该IP地址已经被使用,客户机会发出一个DHCP DECLINE数据包给DHCP Server,拒绝此IP地址租约,并重新发送DHCP discover信息。此时,在DHCP服务器管理控制台中,会显示此IP地址为BAD_ADDRESS。
如果网络上没有其它主机使用此IP地址,则客户机的TCP/IP使用租约中提供的IP地址完成初始化,从而可以和其他网络中的主机进行通讯。
当然也可以发送nak拒绝

二、DHCP客户机租期续约:
客户机会在租期过去50%的时候,直接向为其提供IP地址的DHCP Server发送DHCP REQUEST消息包。如果客户机接收到该服务器回应的DHCP ACK消息包,客户机就根据包中所提供的新的租期以及其它已经更新的TCP/IP参数,更新自己的配置,IP租用更新完成。如果没有收到该服务器的回复,则客户机继续使用现有的IP地址,因为当前租期还有50%。
如果在租期过去50%的时候没有更新,则客户机将在租期过去87.5%的时候再次向为其提供IP地址的DHCP联系。如果还不成功,到租约的100%时候,客户机必须放弃这个IP地址,重新申请。如果此时无DHCP可用,客户机会使用169.254.0.0/16中随机的一个地址,并且每隔5分钟再进行尝试。

当DHCP服务器收到这一信息后,它会尝试让DHCP客户机继续使用原来的IP地址,并回答一个DHCP ACK确认信息。

如果此IP地址已无法再分配给原来的DHCP客户机使用时(比如此IP地址已分配给其它DHCP客户机使用),则DHCP服务器给DHCP客户机回答一个DHCP NAK否认信息。

当原来的DHCP客户机收到此DHCP NAK否认信息后,它就必须重新发送DHCP discover发现信息来请求新的IP地址。

收到DHCP ACK就续期,收到DHCP NAK就直接发送DHCP RELESE报文释放IP地址,然后开始重新一轮的DHCP

以下是图文以及源码包解析

我们发现在offer阶段会有单播,广播的2种方式:
单播/广播的截图

在单播的时候我们会发现bootp flag是0x0000,在广播的时候是0x8000
这不是server随机的结果,是根据client在discover时候传递的数据
bootp flag在discover时候截图
至此我们还是不能太确定这是否是因为client对server的结果.我们从源码分析
/* Take the fields that we care about… */

    raw.op = BOOTREPLY;
    raw.htype = packet -> raw -> htype;
    raw.hlen = packet -> raw -> hlen;
    memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);
    raw.hops = packet -> raw -> hops;
    raw.xid = packet -> raw -> xid;
    raw.secs = packet -> raw -> secs;
    raw.flags = packet -> raw -> flags;
    raw.ciaddr = packet -> raw -> ciaddr;

/* yiaddr is an ipv4 address, it must be 4 octets. */

memcpy (&raw.yiaddr, lease->ip_addr.iabuf, 4);

/* If we're always supposed to broadcast to this client, set
   the broadcast bit in the bootp flags field. */

if ((oc = lookup_option (&server_universe,
            options, SV_ALWAYS_BROADCAST)) &&
    evaluate_boolean_option_cache (&ignorep, packet, lease,
                   (struct client_state *)0,
                   packet -> options, options,
                   &lease -> scope, oc, MDL))
    raw.flags |= htons (BOOTP_BROADCAST);

在源码可以清楚的看到编写代码的人很清楚的说明了我们可以允许广播的方式到达client,将该broadcast bit至高位填充到bootp flags
然后我们在源码包偶然看到这样的一个内容描述文件一下是原文

The DHCP and BOOTP protocols both require DHCP and BOOTP clients to
set the broadcast bit in the flags field of the BOOTP message header.
Unfortunately, some DHCP and BOOTP clients do not do this, and
therefore may not receive responses from the DHCP server.   The DHCP
server can be made to always broadcast its responses to clients by
setting this flag to \'on\' for the relevant scope; relevant scopes would be
inside a conditional statement, as a parameter for a class, or as a parameter
for a host declaration.   To avoid creating excess broadcast traffic on your
network, we recommend that you restrict the use of this option to as few
clients as possible.   For example, the Microsoft DHCP client is known not
to have this problem, as are the OpenTransport and ISC DHCP clients.

大致意思就是(翻译来自有道,如有误差可自行理解):

DHCP和BOOTP协议都需要DHCP和BOOTP客户端,在BOOTP消息头的flags字段中设置广播位。不幸的是,一些DHCP和BOOTP客户端并没有这样做.因此,可能不会收到DHCP服务器的响应。DHCP服务器可以随时向客户广播其响应将此标志设置为\ ‘on\ ‘的相关范围;相关的范围是在条件语句中,作为类的参数,或作为参数主机宣言。为了避免产生过多的广播流量网络,我们建议您将此选项限制为少数客户。例如,Microsoft DHCP客户机是不知道的为了解决这个问题,OpenTransport和ISC DHCP客户端也是如此

三.DHCP服务器工作流程

1,初始化DHCP服务器。
2,初始化请求模块,监听客户请求。
3,当客户请求到来时,调用处理线程来处理应答客户端请求。
4,处理线程处理完请求信息,返回给客户端处理结果。等待下一个客户请求。
这里写图片描述
在处理请求模块中调用dispatch()函数,根据不同类型的包,接收和调度packet。处理请求模块在处理任务时,首先根据包类型的不同,调用do_packet/do_packet6函数分析处理客户请求信息包,若调用do_packet则先判断请求包的类型是bootp还是dhcp。最后,分别调用bootp子模块和dhcp/dhcpv6子模块进行处理,如下:
这里写图片描述

以上是个人节选分析总结,如有差异错误处请说明指导,感谢檀明老师指导.

文章部分节选地址
http://blog.csdn.net/wuyongpeng0912/article/details/50444842
http://blog.51cto.com/tonyguo/163475

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值