分类: LINUX
2015-12-29 14:34:23
原文地址:DHCP协议和dhcpcd源码分析 作者:xlzxlz2
转:http://blog.csdn.net/lenovo_/article/details/6654770
dhcpcd是一个dhcp客户端程序。
下载地址:
DHCP 协议的几种报文:
1 dhcpdiscover: 此为client开始DHCP过程中的第一个请求报文
2 dhcpoffer : 此为server 对dhcpdiscover 报文的响应
3 dhcprequst : 此为client 对dihcpoffer 报文的响应
4 dhcpdeclient: 当client发现server 分配给它的IP地址无法使用,如 IP地址发生冲突时,将发
出此报文让server禁止使用这次分配的IP地址。
5 dhcpack : server对 dhcprequst 报文的响应,client收到此报文后才真正获得了IP地址和相关
配置信息。
6 dhcpnak : 此报文是server对client的dhcprequst报文的拒绝响应,client 收到此报文后,一般
会重新开始DHCP过程。
7 dhcprelease :此报文是 client主动释放IP地址,当server 收到此报文后就可以收回IP地址分配
给其他的client.
DHCP的工作过程:
DHCP的工作过程主要分为以下六个阶段:
发现阶段,即DHCP客户端寻找DHCP服务器的阶段。DHCP客户端首先以广播方式发送DHCP DISCOVER发
现信息来寻找DHCP服务器(因为DHCP服务器的IP地址对于客户端来说是未知的),即客户端向地址
255.255.255.255发送特定的广播信息。请求信息主要包含客户端的网卡MAC地址还有客户端的计算机名
称。网络上每一台安装了TCP/IP协议的主机都会接收到这种广播信息,但只有DHCP服务器才会做出响应。
提供阶段,即DHCP服务器提供IP地址的阶段。在网络中接收到DHCP DISCOVER发现信息的DHCP服务器
都会做出响应,它从尚未出租的IP地址中挑选一个分配给DHCP客户端,向DHCP客户端发送一个包含出租的
IP地址和其他设置的DHCP OFFER提供信息。
选择阶段,即DHCP客户端选择某台DHCP服务器提供的IP地址的阶段。如果网络中有多台DHCP服务器向
DHCP客户端发来的DHCP OFFER提供信息,则DHCP客户端只接受第一个收到的DHCP OFFER提供信息。在客户
端收到DHCP OFFER提供信息后,会以广播方式回答一个DHCP REQUEST请求信息,所有的DHCP服务器都会收
到这个信息,该信息中包含它所选定的DHCP服务器和服务器提供的IP地址。之所以要以广播方式回答,是
为了通知所有的DHCP服务器,他将选择某台DHCP服务器所提供的IP地址,其他没有被选择的DHCP服务器则
会收回发出的IP地址。
确认阶段,即DHCP服务器确认所提供的IP地址的阶段。当DHCP服务器收到DHCP客户端回答的DHCP
REQUEST请求信息之后,它便向DHCP客户端发送一个包含它所提供的IP地址和其他设置的DHCP ACK确认信
息,告诉DHCP客户端可以使用它所提供的IP地址。至此DHCP客户端可以使用DHCP服务器所提供的IP地址与
网卡绑定。
重新登录阶段。以后DHCP客户端每次重新登录网络时,就不需要再发送DHCP DISCOVER发现信息了,而
是直接发送包含前一次所分配的IP地址的DHCP REQUEST请求信息。当DHCP服务器收到这一信息后,它会尝
试让DHCP客户端继续使用原来的IP地址,并回答一个DHCP ACK确认信息。如果此IP地址已无法再分配给原
来的DHCP客户端使用时(比如此IP地址已分配给其它DHCP客户端使用),则DHCP服务器给DHCP客户端回答一
个DHCP NACK否认信息。当原来的DHCP客户端收到此DHCP NACK否认信息后,它就必须重新发送DHCP
DISCOVER发现信息来请求新的IP地址。 更新租约阶段。DHCP服务器所提供的IP地址一般都是有期限的,
我们把这个期限称为租期,租期的长短通过DHCP服务器来设置。设置这个期限是为了让那些过了租期又不
活动的IP能空出来,由DHCP服务器重新分配给DHCP客户端,这样就会有效减少IP地址的浪费现象。期满后
DHCP服务器便会收回出租的IP地址。如果DHCP客户端要延长其IP租约,则必须更新其IP租约。DHCP客户端
启动时和IP租约期限过一半时,DHCP客户端都会自动向DHCP服务器发送更新其IP租约的信息。
如果DHCP客户端一直开启,客户端会在租约过去50%的时候向原DHCP服务器提出DHCP REQUEST请求信
息,信息中包含一个客户端正使用的IP地址,并请求服务机延长对此地址的租用。如果原服务器同意会发
出DHCP ACK确认信息。这样,续租成功,客户端获得新的租约。如果这个请求信息没有得到回复,因为租约
尚未结束,DHCP客户端会继续使用原来的IP,并且每隔大约2分钟向原DHCP服务器再次发送DHCP REQUEST请
求信息申请续租。如果到了租约期限的87.5%,DHCP客户端依然没有收到原DHCP服务器的DHCP ACK确认信
息,则客户端转为重新绑定状态。在重新绑定状态下,DHCP客户端会以广播的方式向网络中的所有服务器
发送DHCP REQUEST请求信息,如果有DHCP服务器响应,并发回DHCP ACK确认信息则DHCP客户端从新的DHCP
服务器获得新的IP地址还有新的租约。如果直到租约结束也没有收到任何DHCP服务器的DHCP ACK确认信
息,则DHCP客户端会停用租来的IP地址,然后返回初始化状态。
主函数流程就是:
do currState=(void *(*)())currState(); while ( currState );
执行完一个函数后,返回下一个要执行的函数的地址,继续执行。
dhcpcd一共有7种状态:
REBOOTING , INIT , SELECTING , REQUESTING , BOUND , REBINDING , RENEWING
void *dhcpReboot()
重新启动DHCPCD时的动作,这时直接发生request申请上次获取到的IP。
void *dhcpInit()
用户初始化动作,发送discover,转换到SELECTING状态。
void *dhcpRequest(xid,buildDhcpMsg)
unsigned xid;
void (*buildDhcpMsg)(unsigned);
接收服务器的ACK报文,对下发的IP 进行验证,然后转换到BOUND状态。
void *dhcpBound()
将获取到的IP设置成网卡的地址,进入绑定状态,等待超时。
void *dhcpRenew()
当租约定时器超时的时候,发送request,进行续约。
void *dhcpRebind()
当80%租期的时候,服务器还没有回应ACK,则进行广播request,若在原租期到期时
收到了ACK 则进入BOUND状态,否则转换到INIT状态。