2

C++ コードを使用して、自分の側から DHCP クライアントを模倣しようとしています。私の目的は、DHCPサーバーからいくつかの空き/未使用のIPを取得して、それをさまざまな機器に割り当てることです.DHCPリレーに似ていますが、技術的には同じではありません. 私CLIENTは組み込み Linux プラットフォームで実行されており、内部ネットワークを介して DHCP サーバーと通信しています。

DHCP プロトコルに従って、DHCP サーバーと通信するための正式な手順 ( DISCOVEROFFERREQUEST、 ) があります。さらに、RFC 2132 に記載されているオプション 50 を使用して、この IP アドレスをメッセージで使用します。ACK/NAKRELEASEDISCOVEROFFERREQUEST

私のメイン ルーターである make-Edgewater (これは DHCP サーバーでもあります) は、DISCOVERメッセージを送信するOFFER際に、YIAddr フィールドに未使用の IP アドレスを含むメッセージを返信します (結果のREQUESTメッセージでこの未使用の IP を使用しました)。これが私の要件です。他のいくつかのルーター (NetGear、Dlink、Broadcom) で同じ実験を行ったところ、未使用の IP を要求しているOFFERの同じ IP アドレスがメッセージで返されていることがわかりました。CLIENTなぜこれが起こっているのか知りたいです。私が理解しているように、DHCP パケット形式を作成するために RFC2131/RFC2131/RFC4361 に記載されている手順に従っています。

他の DHCP サーバー/ルーターが未使用の IP を提供することを期待している特定の形式または特定のオプションはありますか? RFC4361 に記載されているように、オプション フィールドで一意のクライアント識別子を使用しています。

これは、dhcp パケットを作成しているセクションのスナップ ショットです。

    request_packet.m_OperationCode  =   0x01;
request_packet.m_HwareType  =   0x01;
request_packet.m_HwareLen   =   0x06;
request_packet.m_Hops       =   0x01;
request_packet.m_XID        =   htonl(XID[m_numberOfIPs]);
request_packet.m_Secs       =   htons(0x10);
request_packet.m_flags      =   htons(0x8000);
request_packet.m_CIAddr     =   0x000000; //Client IP
request_packet.m_YIAddr     =   0x000000; //Your IP
request_packet.m_SIAddr     =   0x000000; //Server IP
request_packet.m_GIAddr         =   0x000000;
request_packet.m_CHAddr[0]  =   MACADDRESS[m_numberOfIPs][0];
request_packet.m_CHAddr[1]  =   MACADDRESS[m_numberOfIPs][1];//[1];
request_packet.m_CHAddr[2]  =   MACADDRESS[m_numberOfIPs][2];//[2];
request_packet.m_CHAddr[3]  =   MACADDRESS[m_numberOfIPs][3];//[3];
request_packet.m_CHAddr[4]  =   MACADDRESS[m_numberOfIPs][4];//[4];
request_packet.m_CHAddr[5]  =   MACADDRESS[m_numberOfIPs][5];//[5];
memset(request_packet.m_CHAddr+6, 0, 10);
memset(request_packet.m_SName, 0, 64);      
memset(request_packet.m_File, 0, 128);  
request_packet.m_pOptions[0]    =   99; //Start of magic cookie
request_packet.m_pOptions[1]    =   130;            
request_packet.m_pOptions[2]    =   83;
request_packet.m_pOptions[3]    =   99; //end of magic cookie

オプション フィールド

DISCOVER メッセージ

CID と DUID は、一意のクライアント ID を作成するためのランダムな一意の番号です

 request_packet.m_pOptions[4]   =   53; //DHCP MESSAGE TYPE OPTION CODE
 request_packet.m_pOptions[5]   =   1;  //OPTION DATA LEN
 request_packet.m_pOptions[6]   =   1;  //DHCP DISCOVER

 request_packet.m_pOptions[7]   =   55; //Parameter Request List
 request_packet.m_pOptions[8]   =   7; //Length
 request_packet.m_pOptions[9]   =   1; //Subnet Mask
 request_packet.m_pOptions[10]  =   3; //Router
 request_packet.m_pOptions[11]  =   6; //Domain Name Server
 request_packet.m_pOptions[12]  =   12; // Host Name
 request_packet.m_pOptions[13]  =   15; //Domain Name
 request_packet.m_pOptions[14]  =   28; //Broadcast Address
 request_packet.m_pOptions[15]  =   42; //NTP servers

 request_packet.m_pOptions[16]  =   51; //IP Address Lease Time
 request_packet.m_pOptions[17]  =   4;  
 request_packet.m_pOptions[18]  =   0x00;
 request_packet.m_pOptions[19]  =   0x00;
 request_packet.m_pOptions[20]  =   0xFF;
 request_packet.m_pOptions[21]  =   0xFF;

 request_packet.m_pOptions[22]  =   61;//Client Identifier code
 request_packet.m_pOptions[23]  =   15;//Length
 request_packet.m_pOptions[24]  =   255;//IAID Type
 printf("The CID generated inside REQUEST is %x\n", CID[m_numberOfIPs]);
 request_packet.m_pOptions[25]  =   CID[m_numberOfIPs][0];
 request_packet.m_pOptions[26]  =   CID[m_numberOfIPs][1];
 request_packet.m_pOptions[27]  =   CID[m_numberOfIPs][2];
 request_packet.m_pOptions[28]  =   CID[m_numberOfIPs][3];
 request_packet.m_pOptions[29]  =   0x00;//DUID Type
 request_packet.m_pOptions[30]  =   0x03;//DUID Type
 request_packet.m_pOptions[31]  =   0x00;//HW Type code - Ethernet
 request_packet.m_pOptions[32]  =   0x01;//HW Type code - Ethernet
 request_packet.m_pOptions[33]  =   DUID[m_numberOfIPs][0];
 request_packet.m_pOptions[34]  =   DUID[m_numberOfIPs][1];
 request_packet.m_pOptions[35]  =   DUID[m_numberOfIPs][2];
 request_packet.m_pOptions[36]  =   DUID[m_numberOfIPs][3];
 request_packet.m_pOptions[37]  =   DUID[m_numberOfIPs][4];
 request_packet.m_pOptions[38]  =   DUID[m_numberOfIPs][5];


 request_packet.m_pOptions[39]  =   (0xff);  // End option

リクエストメッセージ

request_packet.m_pOptions[4]    =   53; //DHCP MESSAGE TYPE OPTION CODE
request_packet.m_pOptions[5]    =   1;  //OPTION DATA LEN
request_packet.m_pOptions[6]    =   3;  //DHCP REQUEST

request_packet.m_pOptions[7]    =   50; //DHCP REQUESTION OPTION
request_packet.m_pOptions[8]    =   4;  //OPTION DATA LEN
request_packet.m_pOptions[9]    =   (m_YourIP & 0xff000000)>>24;  //first byte
request_packet.m_pOptions[10]   =   (m_YourIP & 0xff0000)>>16;  //second byte
request_packet.m_pOptions[11]   =   (m_YourIP & 0xff00)>>8;  //third byte
request_packet.m_pOptions[12]   =   (m_YourIP & 0xff);  //fourth byte
/*- Added by JA. Refer 3.1.3 Section of RFC2131.txt - Server identifier option*/
 request_packet.m_pOptions[13]  =   54;
 request_packet.m_pOptions[14]   =  4;
 request_packet.m_pOptions[15]  =   (m_ServerIP & 0xff000000) >> 24; //first byte
 request_packet.m_pOptions[16]  =   (m_ServerIP & 0xff0000)>>16;  //second byte
 request_packet.m_pOptions[17]  =   (m_ServerIP & 0xff00)>>8;  //third byte
 request_packet.m_pOptions[18]  =   (m_ServerIP & 0xff);  //fourth byte

 request_packet.m_pOptions[19]  =   55; //Parameter Request List
 request_packet.m_pOptions[20]  =   7; //Length
 request_packet.m_pOptions[21]  =   1; //Subnet Mask
 request_packet.m_pOptions[22]  =   3; //Router
 request_packet.m_pOptions[23]  =   6; //Domain Name Server
 request_packet.m_pOptions[24]  =   12; // Host Name
 request_packet.m_pOptions[25]  =   15; //Domain Name
 request_packet.m_pOptions[26]  =   28; //Broadcast Address
 request_packet.m_pOptions[27]  =   42; //NTP servers

     request_packet.m_pOptions[28]  =   51; //IP Address Lease Time
     request_packet.m_pOptions[29]  =   4;  
     request_packet.m_pOptions[30]  =   0x00;
     request_packet.m_pOptions[31]  =   0x00;
     request_packet.m_pOptions[32]  =   0xFF;
     request_packet.m_pOptions[33]  =   0xFF;

     /*- Added by JA. Refer 6.1 Section of RFC4361.txt - Client identifier option*/
     request_packet.m_pOptions[34]  =   61;//Client Identifier code
     request_packet.m_pOptions[35]  =   15;//Length
     request_packet.m_pOptions[36]  =   255;//IAID Type
     printf("The CID generated inside REQUEST is %x\n", CID[m_numberOfIPs]);
     request_packet.m_pOptions[37]  =   CID[m_numberOfIPs][0];
     request_packet.m_pOptions[38]  =   CID[m_numberOfIPs][1];
     request_packet.m_pOptions[39]  =   CID[m_numberOfIPs][2];
     request_packet.m_pOptions[40]  =   CID[m_numberOfIPs][3];
     request_packet.m_pOptions[41]  =   0x00;//DUID Type
     request_packet.m_pOptions[42]  =   0x03;//DUID Type
     request_packet.m_pOptions[43]  =   0x00;//HW Type code - Ethernet
     request_packet.m_pOptions[44]  =   0x01;//HW Type code - Ethernet
     request_packet.m_pOptions[45]  =   DUID[m_numberOfIPs][0];
     request_packet.m_pOptions[46]  =   DUID[m_numberOfIPs][1];
     request_packet.m_pOptions[47]  =   DUID[m_numberOfIPs][2];
     request_packet.m_pOptions[48]  =   DUID[m_numberOfIPs][3];
     request_packet.m_pOptions[49]  =   DUID[m_numberOfIPs][4];
     request_packet.m_pOptions[50]  =   DUID[m_numberOfIPs][5];
     request_packet.m_pOptions[51]  =   (0xff);  // End option
4

1 に答える 1

0

ルーターをDHCPリレーおよびサーバーとして使用すると、その上に構成された一意のIPベースのDHCPサブネットワークが割り当てられます。たとえば、10.1.2.0/24はDHCP要求用にルーターで定義されたプールであり、MACに対してのみ割り当てられていない最初のIPを割り当てます。割り当てはランダムです。ルーターで mac を予約することはできません。DORA の後、その MAC-IP のリース タイマーがトリガーされます。

DHCPサーバーのMicrosoft / Unixを使用している場合、特定のMacのIPを永続的に予約する機能が拡張されています。

于 2012-08-22T11:51:43.177 に答える