Программирование на C++ глазами хакера

         

DHCP-сервер


Если в вашей сети используется DHCP-сервер, то нельзя использовать удаление и добавление IP-адреса, которое мы рассматривали в главе 5. В этом случае адрес выдается и освобождается DHCP-сервером, и это нельзя делать вручную, иначе могут возникнуть проблемы и конфликты с другими компьютерами.

При использовании DHCP-адреса не удаляются из системы, а освобождаются. В этом случае сервер сможет отдать высвобожденный адрес другому компьютеру, если он жестко не привязан к определенному сетевому интерфейсу. Для освобождения используется функция IpReleaseAddress, которой надо передать нужный адаптер. Для получения адреса используется функция IpRenewAddress, которой также следует указать адаптер, нуждающийся в новом адресе.

6.6. Диалоговое окно будущей программы RenewIPAddress

Рассмотрю использование функций на примере. Для этого создайте новое MFC-приложение. Главное окно вы можете увидеть на 6.6. Для определения адаптера, нуждающегося в удалении, нужно знать его индекс. Для этого внизу окна расположен элемент управления List Box, в котором будет отображаться список установленных интерфейсов. Вывод списка адаптеров будет происходить по нажатии кнопки List Adapters. Код, который должен здесь выполняться, идентичен коду из листинга 5.2, где также выводилась информация об установленных адаптерах.

По нажатии кнопки Release освобождается IP-адрес. Код, который должен выполняться, приведен в листинге 6.5.

Листинг 6.5. Освобождение IP-адреса
void CRenewIPAddressDlg::OnBnClickedButton2() { char sAdaptIndex[20]; int iIndex; sAdapterIndex.GetWindowText(sAdaptIndex, 20); iIndex = atoi(sAdaptIndex);

DWORD InterfaceInfoSize = 0; PIP_INTERFACE_INFO pInterfaceInfo;

if (GetInterfaceInfo(NULL, InterfaceInfoSize) != ERROR_INSUFFICIENT_BUFFER) { AfxMessageBox("Error sizing buffer"); return; }

if ((pInterfaceInfo = (PIP_INTERFACE_INFO) GlobalAlloc(GPTR, InterfaceInfoSize)) == NULL) { AfxMessageBox("Can't allocate memory"); return; }

if (GetInterfaceInfo(pInterfaceInfo, InterfaceInfoSize) != 0) { AfxMessageBox("GetInterfaceInfo failed"); return; }




for (int i = 0; i pInterfaceInfo-NumAdapters; i++) if (iIndex == pInterfaceInfo-Adapter[i].Index) { if (IpReleaseAddress(pInterfaceInfo-Adapter[i]) != 0) { AfxMessageBox("IpReleaseAddress failed"); return; } break; } }

В поле ввода на главном окне пользователь указывает индекс адаптера. Теперь надо только пролистать все интерфейсы. И если какой-либо из них принадлежит адаптеру, то вызвать для него функцию IpReleaseAddress.

Для получения списка интерфейсов используется функция GetInterfaceInfo, которая работает так же, как и уже знакомая вам GetAdaptersInfo. При первом вызове определяется необходимый размер памяти для хранения всей информации, после чего выделяется эта память, и функция вызывается снова.

Затем запускается цикл перебора всех полученных интерфейсов. Если интерфейс указанного адаптера найден, то освобождается адрес.

Получение адреса происходит подобным образом. В листинге 6.6 показан код, который должен выполняться по нажатии кнопки Renew.

Листинг 6.6. Запрос нового IP-адреса
void CRenewIPAddressDlg::OnBnClickedButton3() { char sAdaptIndex[20]; int iIndex; sAdapterIndex.GetWindowText(sAdaptIndex, 20); iIndex = atoi(sAdaptIndex);

DWORD InterfaceInfoSize = 0; PIP_INTERFACE_INFO pInterfaceInfo;

if (GetInterfaceInfo(NULL, InterfaceInfoSize) != ERROR_INSUFFICIENT_BUFFER) { AfxMessageBox("Error sizing buffer"); return; }

if ((pInterfaceInfo = (PIP_INTERFACE_INFO) GlobalAlloc(GPTR, InterfaceInfoSize)) == NULL) { AfxMessageBox("Can't allocate memory"); return; }

if (GetInterfaceInfo(pInterfaceInfo, InterfaceInfoSize) != 0) { AfxMessageBox("GetInterfaceInfo failed"); return; }

for (int i=0; ipInterfaceInfo-NumAdapters; i++) if (iIndex == pInterfaceInfo-Adapter[i].Index) { if (IpRenewAddress(pInterfaceInfo-Adapter[i]) != 0) { AfxMessageBox("IpRenewAddress failed"); return; } break; } }

Код получения нового адреса идентичен освобождению (см. листинг 6.5). Разница только в том, что в данном случае вызывается функция IpRenewAddress.

Примечание
Исходный код примера, описанного в этом разделе, вы можете найти на компакт - диске в каталоге \Demo\Chapter6\RenewIPAddress.

Содержание раздела