日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

DHCP服务器的设计

發布時間:2024/2/2 综合教程 36 生活家
生活随笔 收集整理的這篇文章主要介紹了 DHCP服务器的设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

介紹

DHCP(Dynamic Host Configuration Protocol,動態主機配置協議)通常被應用在大型的局域網絡環境中,主要作用是集中的管理、分配IP地址,使網絡環境中的主機動態的獲得IP地址、Gateway地址、DNS服務器地址等信息,并能夠提升地址的使用率。

DHCP協議采用客戶端/服務器模式。客戶機登錄服務器時可以自動獲得DHCP服務器分配的IP地址和子網掩碼,這也是現在接入網技術中供應商給用戶(賬號)提供IP地址的手段。

原理

端口

首先DHCP是基于UDP的兩個端口實現的,DHCP提供服務時,客戶端以68號端口進行數據傳輸,服務器端以67號端口進行數據傳輸。

DHCP報文類型

DHCP一共有8中報文,分別為DHCP Discover、DHCP Offer、DHCP Request、DHCP ACK、DHCP NAK、DHCP Release、DHCP Decline、DHCP Inform。

DHCP Discover: DHCP客戶端在請求IP地址時并不知道DHCP服務器的位置,因此DHCP客戶端會在本地網絡內以廣播方式發送Discover請求報文,以發現網絡中的DHCP服務器。所有收到Discover報文的DHCP服務器都會發送應答報文,DHCP客戶端據此可以知道網絡中存在的DHCP服務器的位置。

DHCP Offer:DHCP服務器收到Discover報文后,就會在所配置的地址池中查找一個合適的IP地址,加上相應的租約期限和其他配置信息(如網關、DNS服務器等),構造一個Offer報文,發送給DHCP客戶端,告知用戶本服務器可以為其提供IP地址。但這個報文只是告訴DHCP客戶端可以提供IP地址,最終還需要客戶端通過ARP來檢測該IP地址是否重復。

DHCP Request:DHCP客戶端可能會收到很多Offer請求報文,所以必須在這些應答中選擇一個。通常是選擇第一個Offer應答報文的服務器作為自己的目標服務器,并向該服務器發送一個廣播的Request請求報文,通告選擇的服務器,希望獲得所分配的IP地址。另外,DHCP客戶端在成功獲取IP地址后,在地址使用租期達到50%時,會向DHCP服務器發送單播Request請求報文請求續延租約,如果沒有收到ACK報文,在租期達到87.5%時,會再次發送廣播的Request請求報文以請求續延租約。

DHCP ACK:DHCP服務器收到Request請求報文后,根據Request報文中攜帶的用戶MAC來查找有沒有相應的租約記錄,如果有則發送ACK應答報文,通知用戶可以使用分配的IP地址。

DHCP NAK:如果DHCP服務器收到Request請求報文后,沒有發現有相應的租約記錄或者由于某些原因無法正常分配IP地址,則向DHCP客戶端發送NAK應答報文,通知用戶無法分配合適的IP地址。

DHCP Release:當DHCP客戶端不再需要使用分配IP地址時,就會主動向DHCP服務器發送RELEASE請求報文,告知服務器用戶不再需要分配IP地址,請求DHCP服務器釋放對應的IP地址。

DHCP Decline:DHCP客戶端收到DHCP服務器ACK應答報文后,通過地址沖突檢測發現服務器分配的地址沖突或者由于其他原因導致不能使用,則會向DHCP服務器發送Decline請求報文,通知服務器所分配的IP地址不可用,以期獲得新的IP地址。

DHCP Inform:DHCP客戶端如果需要從DHCP服務器端獲取更為詳細的配置信息,則向DHCP服務器發送Inform請求報文;DHCP服務器在收到該報文后,將根據租約進行查找到相應的配置信息后,向DHCP客戶端發送ACK應答報文。目前基本上不用了。

DHCP報文格式

我們通過抓包看一下DHCP的報文:

1.Message type:Boot Request(1)當為1時表示是client的請求,為2時是server的應答

2.Hardware type是網絡硬件地址類型

3.Hardware address length表示網絡硬件地址長度(6Bytes表示是以太網類型的MAC地址)

4.HOPS表示跳數,是當前的DHCP報文經過的DHCP RELAY的數目,每經過一個DHCP中繼,此字段就會加1;當這個字段大于4時,DHCP報文直接丟棄。

5.Transaction id:事務ID,是DHCP請求報文時選擇的隨機數

6.Elapsed boot time描述,表示client開始DHCP請求后的時間流逝秒數

7.flags標志

8.Client self-assigned IP address:客戶機IP地址

9.Client IP address:分配給client的IP地址

10.Next Server IP address:服務器IP地址

11.Relay AgentDHCP:中繼代理IP地址

12.Client Hardware address客戶機硬件地址MAC

13.Client Hardware address padding:客戶機硬件MAC填充地址

14.Host Name:服務器的主機名

15.Boot File name:是client的啟動配置文件名

16.Magic cookie是服務器可以根據這個cookie直到該用戶是否需要重新登錄。

之后的字段會根據報文類型而有不同的改變:

17.DHCP Message Type:此字段表示DHCP報文類型

18.DHCP Server Identifier是DHCP Server的報文類型

19.Client identifier:客戶端報文類型

交互過程

通過觀察抓包順序可以知道是,客戶端首先從68端口發出廣播(UDP報文)即discover報文尋找DHCP服務器,請求租用IP地址。該廣播包中的源IP地址為0.0.0.0,目標IP地址由于是廣播所以為255.255.255.255,報文中還包含客戶機的MAC地址和計算機名。DHCP服務器會將67端口開啟,收到客戶端的discover報文后會回應一個offer報文,此報文的源IP地址為服務器的IP,目標IP地址為255.255.255.255,數據報中還包含著提供的IP地址、子網掩碼、網關、DNS及租期等信息。

然后客戶端就會廣播一個request報文,表示自己已經接受了一個DHCP服務器提供的IP地址,廣播包中包含所接受的IP地址和服務器的IP地址。服務器在接收到request廣播后,會廣播返回給客戶機一個ACK消息包,表示已經接受了客戶機的選擇,并將這一IP地址的合法租用以及其他的配置信息都放入該廣播包發給客戶。此客戶此時就已經獲得一個可用的IP地址。整體流程如下圖:

代碼設計

首先工程的結構如下:

---dhcpserver
      |
      |--DHCPOptionEnum.h
      |--maker.h--parser.h
      |--stdafx.h
      |--Mystruct.h
      |
      |--DHCPserver.cpp

代碼是基于DHCP的原理、報文以及DavidAnson的DHCPLite0的代碼邏輯框架。下面將逐一分析一下代碼:

main函數

邏輯是首先獲取運行環境下的網絡設備所有網卡信息,然后以"鏈表"的形式存儲在PIP_ADAPTER_INFO結構體所聲明的 AdapterWalker對象中,然后將需要選擇的網卡信息作為輸入與bindInterfaceAddress進行綁定。以上都是初始化信息,主要是為了讓用戶選擇需要進行綁定的網絡設備。

然后m_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)setsockopt(m_socket, SOL_SOCKET, SO_BROADCAST, (char*)&optval, sizeof(bool))將套接字設置為UDP格式,同時通過setsockopt對套接字的功能進行設置,是套接字是符合我們想做為DHCP的廣播環境的。之后創建一個線程thread mThread(ClientListen, bindInterfaceAddress)用來模擬客戶端進行廣播消息的交互。

接下來就是服務端與客戶端的報文交互了,我們需要處理好的就是報文格式以及相應的判斷就行了。主要就是在客戶端發來報文后,服務端進行解析(parse),解析完成后再回應一個報文,需要先制作(make)一個報文。通過這樣完成報文的交互。

ClientListen

這個函數是在新線程下用來模擬客戶端的,所以邏輯是與主函數相同的。由于是線程,可以模擬多個客戶。

GetIpFromTable

在這里利用了一個unordered_map的存儲方式,因為利用map存儲數據不論是插入還是查詢的速度都是非常快的。在這個結構里我們將已經申請了IP地址的客戶放入這個結構中,如果有就返回信息;如果沒有這個客戶,則加入這個用戶的IP地址及信息。

MyStruct.h

在這里定義了DHCP報文格式的結構體

struct DHCP_PACKET {
	byte OP;
	byte HTYPE;
	byte HLEN;
	byte HOPS;
	UINT32 TRANSACTION_ID;
	UINT16 SECONDS;
	UINT16 FLAGS;
	byte ciaddr[4];
	byte yiaddr[4];
	byte siaddr[4];
	byte giaddr[4];
	byte chaddr[16];
	byte sname[64];
	byte file[128];
	UINT32 magicCode;
	byte Options[308];
};

同時定義了Packet_Information的結構體:

struct Packet_Information {
	char HostName[256];
	USHORT BootFileSize;
	char MeritDumpFile[256];
	byte DHCPMessageType;
	int IPLeaseTime;          // client
	byte ServerIdentifier[4]; // client
	byte ClientIdentifier[4];
	byte ParameterRequestList[256];
	byte VendorClassIdentifier[256];
	byte RequestedIPAddress[4];
	byte Unsupport[256];
	bool OptionToReplay[256];
};

parser.h與maker.h

這里直接調用了解析與封包的相關函數,主要是對IP地址、端口以及相應數據報格式字段信息的轉換,判斷與賦值。

DHCPOptionEnum.h

這個頭文件定義了DHCP Option的所有情況,利用enum結構進行存儲;在主函數中調用時就可以通過數字進行表示與區分。

結果

項目請見:Github

總結

以上是生活随笔為你收集整理的DHCP服务器的设计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。