Networking DHCP多IP地址请求 我试图用C++代码模拟我的DHCP客户端。我的目标是从DHCP服务器获得一些免费/未使用的IP,将其分配给不同的设备-类似于DHCP中继,但技术上不同。我的客户机运行在嵌入式linux平台上,通过我们的内部网络与DHCP服务器通信

Networking DHCP多IP地址请求 我试图用C++代码模拟我的DHCP客户端。我的目标是从DHCP服务器获得一些免费/未使用的IP,将其分配给不同的设备-类似于DHCP中继,但技术上不同。我的客户机运行在嵌入式linux平台上,通过我们的内部网络与DHCP服务器通信,networking,udp,router,dhcp,Networking,Udp,Router,Dhcp,根据DHCP协议,有一个正式的过程DISCOVER、OFFER、REQUEST、ACK/NAK、RELEASE与DHCP服务器通信。根据RFC的2131,当我进行DISCOVER时,我在YIAddr字段中接收并提供一个未使用的IP地址。我进一步使用RFC 2132中提到的选项50在请求消息中使用此IP地址 我的主路由器make-EdgeWater也是发送发现消息时的DHCP服务器,它在YIAddr字段中使用未使用的IP地址发回提供消息。我在随后的请求消息中使用了该未使用的IP,这是我的要求。我对

根据DHCP协议,有一个正式的过程DISCOVER、OFFER、REQUEST、ACK/NAK、RELEASE与DHCP服务器通信。根据RFC的2131,当我进行DISCOVER时,我在YIAddr字段中接收并提供一个未使用的IP地址。我进一步使用RFC 2132中提到的选项50在请求消息中使用此IP地址

我的主路由器make-EdgeWater也是发送发现消息时的DHCP服务器,它在YIAddr字段中使用未使用的IP地址发回提供消息。我在随后的请求消息中使用了该未使用的IP,这是我的要求。我对其他几家路由器的NetGear、Dlink、Broadcom做了同样的实验,发现提供消息正在将请求未使用IP的客户端的相同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
请求消息
使用路由器作为DHCP中继和服务器,它将为您分配唯一的配置在其上的基于IP的DHCP子网络,例如10.1.2.0/24是路由器上为DHCP请求定义的池,它将仅针对您的MAC为您分配第一个未分配的IP,此分配是随机的,您无法在路由器上保留MAC。在DORA之后,它将为此触发租约计时器MAC-IP


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

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


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

我调用此函数,它根据我需要的免费IP数量创建数据包“x”次。现在,在m_ChAddr字段中为每个DORADiscover提供请求确认提供一个唯一的MAC地址字段后,我将在m_YIAddr字段中获得一个未使用的IP地址,这正是我所需要的。通过阅读rfc,我认为通过保持MAC地址不变,并为每个DORA提供唯一的客户端标识符,它应该已经工作了,并且正在与我们的主路由器-Edgewater一起工作。一些路由器是否期望在每个DORA中提供一个唯一的MAC地址来释放一个未使用的IP?我正在调用这个函数,它根据我需要的免费IP的数量创建数据包“x”次。现在,在m_ChAddr字段中为每个DORADiscover提供请求确认提供一个唯一的MAC地址字段后,我将在m_YIAddr字段中获得一个未使用的IP地址,这正是我所需要的。通过阅读rfc,我认为通过保持MAC地址不变,并为每个DORA提供唯一的客户端标识符,它应该已经工作了,并且正在与我们的主路由器-Edgewater一起工作。一些路由器是否希望在每个DORA中提供一个唯一的MAC地址来释放一个未使用的IP?谢谢回复。我知道IP是根据MAC地址分配的。我试图弄清楚协议/RFC是否支持DHCP客户端使用相同的MAC地址和DHCP客户端的MAC地址获得不同的唯一未分配IP。路由器不会永久保留特定MAC的IP;每次dhcp客户端查询时,都可以通过dhcp中继获得唯一的ip。我的dhcp客户端与dhcp服务器位于同一子网中。我不想永久保留mac的IP。我希望dhcp客户端获得一些IP地址,例如中继代理,但不完全基于其MAC地址,并将这些IP传递给各种设备这些设备没有MAC地址感谢回复。我知道IP是根据MAC地址分配的。我试图弄清楚协议/RFC是否支持DHCP客户端使用相同的MAC地址和DHCP客户端的MAC地址获得不同的唯一未分配IP。路由器不会永久保留特定MAC的IP;每次dhcp客户端查询时,都可以通过dhcp中继获得唯一的ip。我的dhcp客户端位于 与dhcp服务器的子网相同。我不想永久保留mac的IP。我希望dhcp客户端获得一些IP地址,例如中继代理,但不完全基于其MAC地址,并将这些IP传递给各种设备这些设备没有MAC地址
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