DHCP-запрос нескольких IP-адресов

Я пытаюсь имитировать клиента DHCP с моей стороны, используя код C++. Моя цель - получить несколько свободных / неиспользуемых IP-адресов от DHCP-сервера, чтобы назначить их разным устройствам - аналогично ретранслятору DHCP, но технически не то же самое. мой CLIENT работает на платформе Embedded linux и общается с DHCP-сервером через нашу внутреннюю сеть.

Согласно протоколу DHCP существует формальная процедура (DISCOVER, OFFER, REQUEST, ACK/NAK, RELEASE) для связи с сервером DHCP. Согласно RFC (2131), когда я делаю DISCOVERЯ получаю и OFFER с неиспользованным IP-адресом в поле YIAddr. Я также использую этот IP-адрес в моем REQUEST сообщение с использованием опции 50, как указано в RFC 2132.

Мой основной маршрутизатор, make- Edgewater(который также является сервером DHCP) при отправке DISCOVER сообщение, отправляет обратно OFFER сообщение с неиспользуемым IP-адресом в поле YIAddr (я использовал этот неиспользуемый IP в своем последующем REQUEST сообщение), которое является моим требованием. Я провел такой же эксперимент с несколькими другими маршрутизаторами (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 ответ

Используя маршрутизатор в качестве DHCP-ретранслятора и сервера, он назначит вам уникальную подсеть на основе IP-адреса, настроенную в ней, например, 10.1.2.0/24 - это пул, определенный на маршрутизаторе для запросов DHCP, который назначит вам самый первый нераспределенный IP-адрес только для вашего MAC, и это назначение является случайным, вы не можете зарезервировать mac на маршрутизаторе. После DORA он запускает таймер аренды для этого MAC-IP .

Если вы используете DHCP-сервер Microsoft/Unix, они имеют расширенные функциональные возможности, как резервирование IP для определенного Mac навсегда.

Другие вопросы по тегам