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 навсегда.