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

Параметры сети


В Windows 9x была очень удобная и полезная утилита WinIPConfig, которая отображала параметры сети. С помощью этой утилиты легко можно было узнать IP-адрес каждого сетевого устройства или МАС-адрес.

Сетевой МАС-адрес является уникальным и прошит в памяти сетевого устройства. Это свойство МАС-адреса стали использовать для обеспечения безопасности или защиты программ. Если в компьютере есть сетевая карта, то ее уникальный номер получить достаточно просто.

Для работы с параметрами сети используется библиотека IPHlpApi.lib. Давайте рассмотрим пример, и на его основе я познакомлю вас с самыми интересными функциями.

Создайте новое приложение MFC-Application на базе диалогового окна. Расположите в главном окне пять полей Edit Control, один List Box и кнопку с надписью Get info. Окно, которое получилось у меня, вы можете увидеть на 5.1.

5.1. Окно будущей программы VisualIPConfig

Для полей ввода создайте следующие переменные: eHostName, DNSServers, eNodeType, eIPRouting, eWinsProxy. Для списка введите переменную eAdaptersInfo.

Сетевых устройств может быть несколько, поэтому информация о них будет выводиться в список, а общая информация будет отображаться в полях ввода.

Создайте обработчик события BN_CLICKED для кнопки (для этого можно просто дважды щелкнуть по ней) и в него добавьте содержимое листинга 5.1. Я советую набрать код вручную, а не использовать пример с диска.



Листинг 5.1. Определение параметров сетевой карты
void CVisualIPConfigDlg::OnBnClickedButton1() { PFIXED_INFO pFixedInfo; ULONG iFixedInfo;

PIP_ADAPTER_INFO pAdapterInfo, pAdapter; ULONG iAdapterInfo; PIP_ADDR_STRING chAddr;

CString Str; TCHAR lpszText[1024]; int iErr;

if ((iErr = GetNetworkParams(NULL, iFixedInfo)) != 0) { if (iErr != ERROR_BUFFER_OVERFLOW) { AfxMessageBox("GetNetworkParams failed"); return; } }

if ((pFixedInfo=(PFIXED_INFO)GlobalAlloc(GPTR, iFixedInfo))==NULL) { AfxMessageBox("Memory allocation error"); return; }

if (GetNetworkParams(pFixedInfo, iFixedInfo) != 0) { AfxMessageBox("GetNetworkParams failed"); return; }


eHostName.SetWindowText(pFixedInfo-HostName);

CString s=pFixedInfo-DnsServerList.IpAddress.String; chAddr = pFixedInfo-DnsServerList.Next; while(chAddr) { s=s+" "+chAddr-IpAddress.String; chAddr = chAddr-Next; } DNSServers.SetWindowText(s);

switch (pFixedInfo-NodeType) { case 1: eNodeType.SetWindowText("Broadcast"); break; case 2: eNodeType.SetWindowText("Peer to peer"); break; case 4: eNodeType.SetWindowText("Mixed"); break; case 8: eNodeType.SetWindowText("Hybrid"); break; default: eNodeType.SetWindowText("Don't know"); }

eIPRouting.SetWindowText(pFixedInfo-EnableRouting ? "Enabled" : "Disabled"); eWinsProxy.SetWindowText(pFixedInfo-EnableProxy ? "Enabled" : "Disabled");

iAdapterInfo = 0; iErr=GetAdaptersInfo(NULL, iAdapterInfo); if ((iErr!= 0) (iErr != ERROR_BUFFER_OVERFLOW)) { AfxMessageBox("GetAdaptersInfo failed"); return; }

if ((pAdapterInfo = (PIP_ADAPTER_INFO) GlobalAlloc(GPTR, iAdapterInfo)) == NULL) { AfxMessageBox("Memory allocation error\n"); return; }

if (GetAdaptersInfo(pAdapterInfo, iAdapterInfo) != 0) { AfxMessageBox("GetAdaptersInfo failed"); return; }

pAdapter = pAdapterInfo;

eAdaptersInfo.AddString("===========================");

while (pAdapter) { switch (pAdapter-Type) { case MIB_IF_TYPE_ETHERNET: Str="Ethernet adapter: "; break; case MIB_IF_TYPE_PPP: Str="PPP adapter: "; break; case MIB_IF_TYPE_LOOPBACK: Str="Loopback adapter: "; break; case MIB_IF_TYPE_TOKENRING: Str=" Token Ring adapter: "; break; case MIB_IF_TYPE_FDDI: Str="FDDI adapter: "; break; case MIB_IF_TYPE_SLIP: Str="Slip adapter: "; break; case MIB_IF_TYPE_OTHER: default: Str="Other adapter: "; } eAdaptersInfo.AddString(Str+pAdapter-AdapterName);

Str= "Description: "; eAdaptersInfo.AddString(Str+pAdapter-Description);



Str="Physical Address: "; for (UINT i=0; ipAdapter-AddressLength; i++) { if (i == (pAdapter-AddressLength - 1)) sprintf(lpszText, "%.2X",(int)pAdapter-Address[i]); else sprintf(lpszText, "%.2X",(int)pAdapter-Address[i]); Str=Str+lpszText; } eAdaptersInfo.AddString(Str);

sprintf(lpszText, "DHCP Enabled: %s", (pAdapter-DhcpEnabled ? "yes" : "no")); eAdaptersInfo.AddString(lpszText);

chAddr = (pAdapter-IpAddressList); while(chAddr) { Str="IP Address: "; eAdaptersInfo.AddString(Str+chAddr-IpAddress.String);

Str="Subnet Mask: "; eAdaptersInfo.AddString(Str+chAddr-IpMask.String);

chAddr = chAddr-Next; }

Str="Default Gateway: "; eAdaptersInfo.AddString(Str+pAdapter-GatewayList.IpAddress.String);

chAddr = pAdapter-GatewayList.Next; while(chAddr) { //print next Gateway chAddr = chAddr-Next; }

Str="DHCP Server: "; eAdaptersInfo.AddString(Str+pAdapter-DhcpServer.IpAddress.String);

Str="Primary WINS Server: "; eAdaptersInfo.AddString(Str+pAdapter-PrimaryWinsServer.IpAddress.String);

Str="Secondary WINS Server: "; eAdaptersInfo.AddString(Str+pAdapter-SecondaryWinsServer.IpAddress.String);

eAdaptersInfo.AddString("==========================="); pAdapter = pAdapter-Next; } }

Общую информацию о сети можно получить с помощью функции GetNetworkParams. У нее два параметра: структура типа PFIXED_INFO и размер структуры.

Если первый параметр оставить нулевым, а в качестве второго указать числовую переменную, то в эту переменную запишется размер памяти, необходимый для структуры PFIXED_INFO. Именно это и делается первый раз. Память надо выделять в глобальной области с помощью функции GlobalAlloc, иначе функция может вернуть некорректные данные.

После этого функция GetNetworkParams вызывается еще раз, но с указанием двух параметров. Если результатом выполнения функции будет 0, то получение данных прошло успешно.



Теперь разберем параметры структуры PFIXED_INFO:

HostName — имя компьютера;

DnsServerList.IpAddress — список IP-адресов серверов DNS;

NodeType — тип сетевого устройства;

EnableRouting — если равно TRUE, то маршрутизация включена;

EnаblеРrоху — если равно TRUE, то кэширование включено.

Получив общую информацию, можно приступить к перечислению параметров всех установленных адаптеров. Для этого используется функция GetAdaptersInfо. У нее также два параметра: переменная типа PIP_ADAPTER_INFO и размер. Если первый параметр указать нулевым, то через второй параметр функция вернет необходимый размер для структуры PIP_ADAPTER_INFO.

Рассмотрим параметры полученной структуры PIP_ADAPTER_INFO:

Tуре — тип адаптера. Может принимать одно из следующих значений:


    MIB_IF_TYPE_ETHERNET — сетевой адаптер Ethernet;

    MIB_IF_TYPE_TOKENRING — адаптер Token Ring;

    MIB_IF_TYPE_FDDI — адаптер FDDI;

    MIB_IF_TYPE_PPP — РРР-адаптер;

    MIB_IF_TYPE_LOOPBACK — адаптер LoopBack;

    MIB_IF_TYPE_SLIP — Slip-адаптер ;

    MIB_IF_TYPE_OTHER — другое;

    AdapterName — имя адаптера;

    Description — описание, которое может хранить название фирмы-производителя или предназначение;

    AddressLength — длина МАС-адреса;

    Address — МАС-адрес;

    DhcpEnabled — принимает значение TRUE, если включен DHCP;

    IpAddressList — список IP -адресов и масок сети. Каждый адаптер может иметь одновременно несколько адресов;

    GatewayList — список шлюзов;

    DhcpServer — адреса DHCP -серверов;

    PrimaryWinsServer — адрес первичного WINS-сервера;

    SecondaryWinsServer — адрес вторичного WINS-сервера.

    Для компиляции примера необходимо открыть свойства проекта и в разделе Lnker/Input добавить библиотеку IPHlpApi.lib в свойство Additional Dependencies. А в начале модуля нужно добавить описание заголовочного файла iphlpapi.h.

    Запустите файл VisualIPConfig.exe. Нажмите кнопку Get info. Все сведения о сетевой карте, полученные с помощью программы, представлены на 5.2.



    5.2. Результат работы программы VisualIPConfig

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

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