首页 文章

DHCP多个IP地址请求

提问于
浏览
2

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

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

我的主路由器make-Edgewater(也是DHCP服务器)在发送 DISCOVER 消息时,在YIAddr字段中发回一条带有未使用IP地址的 OFFER 消息(我在后续的 REQUEST 消息中使用了这个未使用的IP),这是我的要求 . 我用其他几个路由器(NetGear,Dlink,Broadcom)做了同样的实验,发现 OFFER 消息正在按照RFC2131 / RFC2131 /中提到的步骤向我发回请求未使用的IP 's. I am curious to know why this is happening. As I understand, I'的 CLIENT 的相同IP地址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

选项字段

DISCOVER消息

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消息

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

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

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

相关问题