udhcp源碼詳解(二) 之定義的結構體
Author : hui <[email protected]>
From : <http://blog.csdn.net/hui_love2046>
Created : 2010-10-2 --- 2010-10-3
定義的數據結構對於C程序的重要性,不言而喻。面向對象設計的程序是一個個對象的集合,而面向過程語言設計的程序則是數據結構與算法的集合。
下面來分析的是dhcp server中的定義結構體:
1)、在packet.h文件裏定義了DHCP報文的格式:
struct dhcpMessage報文的字段雖然都有註釋,但還是有必要講下options字段。
options在大多文檔中的說法是可選字段,大小不定,對於這個字段的重要性沒有太多的強調。其實在DHCP交互過程,客戶得到IP的配置過程,這個options字段有着很重要的作用,傳遞個很多不可或缺的信息。
例如Server與Client交互時,數據包的類型,是通過該字段的指示的。還有Client要成功連接到互聯網,不只是需要IP,還需要其他的配置信息,如Dns、Router、Subnet等信息,Server就是通過options字段把這些信息傳遞給Client。(查看options支持哪些選項信息可以查看文檔RFC2132)
問題來啦!!
這麼多信息都放到一個字段,怎麼合理的組織在一起呢,怎麼能讓交互雙方準確的從這個字段取到相應的信息呢?
options字段才用“CLV“方式組織數據信息,OPT_CODE:標識號,唯一標識後面的信息內容;佔1byte;OPT_LEN:長度,表示後面信息內容的長度,佔1byte;value(OPT_DATA):信息內容,其長度由OPT_LEN所指定,以byte爲單位(RFC2132文檔給出所有支持選項的OPT_CODE,和可以確定長度的OPT_LEN的值)
CLV 的數據組織方式:
0 1 2 +Length
Code |
Length |
DATA |
這是一種很漂亮的把多種數據信息組織在一個字段的方式,後面會看到對options字段相應的操作函數,這些函數就是根據CLV的方式對數據進行提取或者組織的。
另外options字段存儲的信息分爲三大類:
① DHCP_PADDING 填充字節 //讀取的信息時候注意跳過
② DHCP_END 結束標誌 //標誌options字段的結束
③ CLV組織的有價值信息 //real value for us
options字段還有個讓人糾結的情況——選項過載,其實也沒什麼,在後面遇再說吧!
2)、在dhcpd.h裏定義裏一個貫穿整個Server端程序的結構體struct server_config_t
上面的註釋是源文件上的,本來的打算翻譯下的,看了下注釋很直白,沒什麼好翻譯的,只是講下其中的專業術語(好像是這麼說的)。
network order 網絡字節序, host order 主機字節序 相信大家瞭解她們的區別吧。
(定義類型是 uint32_t … ,說明變量是以network order存儲的
常用數據類型 int long … ,說明變量是以host order存儲的)
下面講解下其中一些重要的成員:
① start,end可分配地址空間,每個客戶的請求獲得的IP都在這個內。IP地址池。
② struct option_set結構體的定義也在dhcpd.h裏
Option set翻譯過來:選項集合,就是的該結構的意義。上面分析struct dhcpMessage報文裏有個選項字段options,她的值就是根據該集合(Option List)填寫賦值的。
集合(Option List)裏每個結點是一個選項信息,數據CLV的組織方式的。
與報文中options字段的區別是,報文裏用一個options字段存儲了所有的選項信息,options_set而是把一個一個的選項信息用鏈表鏈接起來。
③ 下面的幾個是與租賃期限有關的成員變量
unsigned long lease client請求的租賃期限最大值,>lease,就以lease爲租賃期限;client請求未指明租賃期限,lease作爲其租賃期限(靜態租賃的默認租期)。
unsigned long decline_time server的DHCPOFFER報文提供一個IP給client,client檢測IP已經被其他主機使用,發送DHCPDECLINE報文給server,server接到該報文後,把IP添加到動態租賃數組裏,租賃租期就是decline_time,對應的MAC爲blank_chaddr(黑戶,很形象^-^,實際值是全0)
unsigned long confict_time server在IP地址池找個a free IP時,檢測到IP已被網絡中的主機所使用,會把IP添加到動態租賃數組裏,租賃期限就是confict_time,MAC:blank_chaddr。
unsigned long offer_time server發送DHCPOFFER報文時,即向client提供了IP地址,server會把IP和對應得MAC添加的動態租賃表裏,但這個IP不一定會被client使用,所以添加到動態租賃表裏的租賃期限要短,offer_time就是這個租賃期限(default : 60s)。(當server接收到DHCPREQUEST的時候會把租賃期限修改成請求的租賃期限)。
unsigned long min_lease client端的請求租賃期限不能小於min_lease。
④ 與保存租賃信息有關的兩個成員變量:
char remaining 摘自dhcpd.conf裏的註釋(以及翻譯和註解):
# If remaining is true (default), udhcpd will store the time
# remaining for each lease in the udhcpd leases file. This is
# for embedded systems that cannot keep time between reboots.
# If you set remaining to no, the absolute time that the lease
# expires at will be stored in the dhcpd.leases file.
# 如果剩下的就是true(默認),udhcpd將存儲時間文件中
# 的每個udhcpd租賃租賃剩餘。
# 這對於嵌入式系統,不能保持在重新啓動的時間。
# (即重新啓動就不算入租賃時間裏)
# 如果您設置其餘爲NO,絕對時間,
# 租賃期滿時將被儲存在dhcpd.leases文件檔案。
# 絕對時間,例: starts 0 2000/01/30 08:02:54;
# ends 5 2000/02/04 08:02:54;
# 而嵌入式存儲的是租賃剩餘時間
# 即 leases[i].expires - time(0) 的值
unsigne long auto_time how long should udhcpd wait before writing a config file.
if this is zero, it will only write one on SIGUSR1
多長時間把動態租賃表裏的信息寫入文件(dhcpd.leases)裏。
Auto_time = 0的,只有等到SIGUSR1信號的時候才寫。
⑤ struct static_lease *static_lease
/* dhcpd.h */
struct static_lease{
uint8_t *mac;
uint32_t *ip;
struct static_lease *next;
};
因爲DHCP允許手動爲client端配置IP,server端管理這些手動配置的IP就是使用該結構。
在dhcpd.c文件裏聲明定義一個struct server_config_t的全局變量server_config,server對於client的響應交互都必須有這個變量的參與。
3)、server端對於租賃出去的IP的管理基於以下這個結構體:
uint8_t chaddr[16]; 客戶機的 MAC地址;
uint32_t yiaddr; 客戶機租賃的IP地址;
uint32_t expires; 客戶機租賃IP的到期時間
(是未來的一個時間點,是從1970.1.1午夜開始到租賃到期時刻的秒數)
這裏有些奇怪,使用uint32_t聲明的expires存儲方式用的是host order, 這是因爲server在把租賃記錄保存到dhcpd.leases文件時使用的是network order方式保存的。(個人認爲聲明爲unsigned long類型更爲合適)
在dhcpd.c文件裏聲明定義一個 指向struct dhcpOferedAddr類型數組的全局指針變量leases。leases指向的數組大小由IP地址池大小決定的。
Server端主要的結構體就是這些,他們是整個server端程序跑起來的基礎。還有一些其他結構體的設計是爲了某些函數特別定製的,在分析具體函數再做講解。