Параметры сети
В 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. Определение параметров сетевой карты |
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. |