DHCP多个IP地址请求

时间:2012-06-13 15:17:38

标签: networking udp router dhcp

我正在尝试使用C ++代码模仿我的终端。我的目标是从DHCP服务器获取一些空闲/未使用的IP以将其分配给不同的设备 - 类似于DHCP中继,但技术上不一样。我的CLIENT正在嵌入式Linux平台上运行,并通过我们的内部网络与DHCP服务器通信。

根据DHCP协议,有一个正式的程序(DISCOVEROFFERREQUESTACK/NAKRELEASE)与DHCP服务器通信。根据RFC(2131),当我执行DISCOVER时,我在YIAddr字段中收到了OFFER未使用的IP地址。我在REQUEST消息中使用RFC 2132中提到的选项50进一步使用此IP地址。

我的主路由器make-Edgewater(也是DHCP服务器)在发送DISCOVER消息时,在YIAddr字段中发回一条带有未使用IP地址的OFFER消息(我用过这个我的后续REQUEST消息中未使用的IP,这是我的要求。我用其他几个路由器(NetGear,Dlink,Broadcom)做了同样的实验,发现OFFER消息正在向我发回请求未使用的IP的CLIENT的相同IP地址。我很想知道为什么会这样。据我了解,我正在按照RFC2131 / RFC2131 / RFC4361中提到的步骤创建我的DHCP数据包格式。

是否有其他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

选项字段

发现消息

CID和DUID是随机唯一编号,用于创建唯一的客户端标识符

 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

1 个答案:

答案 0 :(得分:0)

使用路由器作为DHCP中继和服务器,它将为您分配在其上配置的基于唯一IP的DHCP子网,说10.1.2.0/24是在路由器上为DHCP请求定义的池,它将为您的MAC分配第一个未分配的IP只有这个分配是随机的,你不能在路由器上保留mac。在DORA之后,它会触发该MAC-IP的租用计时器。

如果您使用DHCP服务器Microsoft / Unix,则他们具有扩展功能,可以永久保留特定mac的IP。