DHCP協議和dhcpcd原始碼分析

Just4life發表於2014-06-14

dhcpcd是一個dhcp客戶端程式。
下載地址:
http://www.phystech.com/download/dhcpcd.html

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狀態。

相關文章