Rodzina protokołów TCP/IP. Aplikacja: ipconfig. dr Zbigniew Lipiński Instytut Matematyki i Informatyki ul. Oleska 48 50-204 Opole zlipinski@math.uni.opole.pl
Specyfikacja struktury FIXED_INFO Nazwa struktury: FIXED_INFO Opis: Atrybuty: Struktura FIXED_INFO zawiera informacje wspólne dla wszystkich kart sieciowych lokalnego hosta. Struktura FIXED_INFO jest zadeklarowana w pliku IPTypes.h. HostName - DomainName - CurrentDnsServer - DnsServerList - NodeType - ScopeId - EnableRouting - EnableProxy - EnableDns - Nazwa lokalnego hosta. Nazwa domeny w której lokalny host jest zarejestrowany. Atrybut zarezerwowany. Używa atrybutu DnsServerList do uzyskania listy serwerów DNS lokalnego hosta. Linkowana lista struktur IP_ADDR_STRING określająca listę serwerów DNS używanych przez lokalnego hosta. Typ węzła lokalnego hosta. Możliwe wartości atrybutu: BROADCAST_NODETYPE, PEER_TO_PEER_NODETYPE, MIXED_NODETYPE, HYBRID_NODETYPE. Nazwa zakresu DHCP (DHCP scope name). Czy jest udostępniony routing na lokalnym hoście? Czy lokalny host jest ma funkcje ARP proxy? Czy jest udostępniony DNS na lokalnym hoście? 2
Implementacja struktury FIXED_INFO typedef struct { char HostName[MAX_HOSTNAME_LEN + 4]; char DomainName[MAX_DOMAIN_NAME_LEN + 4]; PIP_ADDR_STRING CurrentDnsServer; IP_ADDR_STRING DnsServerList; UINT NodeType; char ScopeId[MAX_SCOPE_ID_LEN + 4]; UINT EnableRouting; UINT EnableProxy; UINT EnableDns; } FIXED_INFO, *PFIXED_INFO; 3
Specyfikacja struktury IP_ADAPTER_INFO Nazwa struktury: IP_ADAPTER_INFO Opis: Struktura IP_ADAPTER_INFO zawiera informacje specyficzne dla każdej karty sieciowej lokalnego hosta. Struktura IP_ADAPTER_INFO jest zadeklarowana w pliku IPTypes.h. Atrybuty: Next - Wskaźnik do następnej karty sieciowej na liście kart. ComboIndex - Atrybut zarezerwowany. AdapterName - Nazwa karty sieciowej. Description - Opis karty sieciowej. AddressLength - Długość adresu sprzętowego (adresu MAC) karty sieciowej. Address - Adres sprzętowy (adres MAC) karty sieciowej. Index - Indeks karty sieciowej. Type - Typ karty sieciowej. Możliwe typy kart: MIB_IF_TYPE_OTHER, MIB_IF_TYPE_ETHERNET, MIB_IF_TYPE_TOKEN_RING, MIB_IF_TYPE_FDDI, MIB_IF_TYPE_PPP, MIB_IF_TYPE_LOOPBACK, MIB_IF_TYPE_SLIP Typy kart zdefiniowane są w pliku IPIfCons.h. DhcpEnabled - Czy protokół DHCP jest udostępniony na danej karcie sieciowej. CurrentIpAddress - Atrybut zarezerwowany. IpAddressList - Lista adresów IP przypisanych do danej karty sieciowej. GatewayList - Adres IP domyślnej bramy dla danej karty sieciowej. DhcpServer - Adres IP serwera DHCP danej karty sieciowej. HaveWins - Czy dana karta sieciowa używa usługi WINS (Windows Internet Name Service). PrimaryWinsServer - Adres IP głównego serwera WINS. SecondaryWinsServer- Adres IP zapasowego serwera WINS. LeaseObtained - Czas uzyskania dzierżawy adresu IP z serwera DHCP. LeaseExpires - Czas wygaśnięcia dzierżawy adresu IP. 4
Implementacja struktury IP_ADAPTER_INFO typedef struct _IP_ADAPTER_INFO { struct _IP_ADAPTER_INFO * Next; DWORD ComboIndex; char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]; char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4]; UINT AddressLength; BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH]; DWORD Index; UINT Type; UINT DhcpEnabled; PIP_ADDR_STRING CurrentIpAddress; IP_ADDR_STRING IpAddressList; IP_ADDR_STRING GatewayList; IP_ADDR_STRING DhcpServer; BOOL HaveWins; IP_ADDR_STRING PrimaryWinsServer; IP_ADDR_STRING SecondaryWinsServer; time_t LeaseObtained; time_t LeaseExpires; } IP_ADAPTER_INFO, *PIP_ADAPTER_INFO; 5
Specyfikacja struktury IP_ADDR_STRING Nazwa struktury: IP_ADDR_STRING Opis: Struktura IP_ADDR_STRING określa adres węzła na linkowanej liście adresów IP. Atrybuty: Next - Wskaźnik do następnej struktury IP_ADDR_STRING na liście. IpAddress - String jest 16 wymiarową tablicą znaków.tablica zawiera adres IP. IpMask - String jest 16 wymiarową tablicą znaków. Tablica zawiera adres IP maski. Context - Tablica wejść sieciowych NTE (Network Table Entry). Wartości atrybutu odpowiadają parametrom NTEContext w funkcjach AddIPAddress() and DeleteIPAddress(). Implementacja struktury IP_ADDR_STRING typedef struct _IP_ADDR_STRING { struct _IP_ADDR_STRING* IP_ADDRESS_STRING IP_MASK_STRING DWORD } IP_ADDR_STRING, *PIP_ADDR_STRING; Next; IpAddress; IpMask; Context; 6
Struktury IP_ADDRESS_STRING, IP_MASK_STRING, time_t Nazwa struktury: IP_ADDRESS_STRING Opis: Tablica zawiera adres IP. Atrybuty: 16 wymiarowa tablica znaków. Nazwa struktury: IP_MASK_STRING Opis: Tablica zawiera adres IP maski. Atrybuty: 16 wymiarowa tablica znaków. Nazwa struktury: time_t Opis: Sruktura time_t przechowuje czas (w sekundach) od 1 stycznia 1970. Atrybuty: 7
Nazwa funkcji : GetNetworkParams() Zwracana wartość: DWORD Specyfikacja funkcji GetNetworkParams() Funkcja zwraca wartość ERROR_SUCCESS. Funkcja zwraca następujące kody błędów: ERROR_BUFFER_OVERFLOW, ERROR_INVALID_PARAMETER, ERROR_NO_DATA, ERROR_NOT_SUPPORTED. Argumenty : PFIXED_INFO pfixedinfo - [out] Wskaźnik do struktury FIXED_INFO przechowującej informacje parametrach konfiguracji sieciowej lokalnego hosta PULONG poutbuflen - [in] Wskaźnik do zmiennej ULONG która określa wielkość struktury FIXED_INFO. Jeżeli zmienna jest za mała aby zapisać wielkość struktury funkcja GetNetworkParams() wpisuje wartość wymaganą i zwraca błąd z kodem ERROR_BUFFER_OVERFLOW. Opis : Funkcja GetNetworkParams() służy do uzyskiwania informacji o konfiguracji TCP/IP lokalnego hosta. 8
Nazwa funkcji : GetAdaptersInfo() Zwracana wartość: DWORD Specyfikacja funkcji GetAdaptersInfo() Funkcja zwraca wartość ERROR_SUCCESS. Funkcja zwraca następujące kody błędów: ERROR_BUFFER_OVERFLOW, ERROR_INVALID_PARAMETER, ERROR_NO_DATA,ERROR_NOT_SUPPORTED, inne. Argumenty : PIP_ADAPTER_INFO padapterinfo - [out] wskaźnik do bufora który przechowuje dane z listy struktury IP_ADAPTER_INFO. PULONG poutbuflen - [in] Wskaźnik do zmiennej ULONG która określa wielkość struktury FIXED_INFO. Jeżeli zmienna jest za mała aby zapisać wielkość struktury funkcja GetNetworkParams() wpisuje wartość wymaganą i zwraca błąd z kodem ERROR_BUFFER_OVERFLOW. Opis : Funkcja GetAdaptersInfo() służy do uzyskiwania informacji o konfiguracji kart sieciowych na lokalnym hoście. 9
Specyfikacja funkcji gmtime() Nazwa funkcji : gmtime() Zwracana wartość: TIMER * Argumenty : long * Funkcjonalność : Funkcja dokonuje konwersji czasu na czas GMT (obecnie zwany czasem UTC, ang. Coordinated Universal Time). 10
Ćwiczenie Przed napisaniem programu ipconfig należy napisać dwa programy: przykład użycia funkcji GetNetworkParams(). przykład użycia funkcji gmtime() i typu struktury tm. 11
Pliki nagłówkowe: Specyfikacja projektu ipcfg windows.h, iphlpapi.h, time.h, iostream. Zmienne programu: DWORD Err; FIXED_INFO * pfixedinfo; IP_ADAPTER_INFO * padapterinfo; DWORD AdapterInfoSize; IP_ADDR_STRING * paddrstr; DWORD FixedInfoSize; Funkcje programu: GetNetworkParams(), GetAdaptersInfo(), gmtime() Struktury programu: FIXED_INFO IP_ADAPTER_INFO IP_ADDR_STRING IP_ADDRESS_STRING IP_MASK_STRING time_t 12
Specyfikacja projektu ipcfg Nazwa projektu: ipcfg Typ projektu: Win32 console application Lista plików: ipcfg.cpp Metoda kompilacji: Microsoft Visual C++ 2008. Opis programu: Utworzyć projekt typu 'Win32 console application w menu (-)File-> New -> Project-> Other languages-> Visual C++ -> win32 -> Win32 console application -> wpisać nazwę: ipcfg -> przycisk (OK) -> Okno Win32 application wizard ipcfg-> wybrać: Application settings -> wybrać: Empty project-> Przycisk (Finish). Konfiguracja projektu: (-)Project-> nazwa_projektu Properies... -> Configuration Properies-> Linker-> Input -> Additional Dependecies, wpisać: IPHlpApi.Lib. Funkcjonalność: (Run-> cmd) wpisać: \> ipcfg 13
Struktura programu 1. Sprawdzenie wielkości danych (wartośc parametru FixedInfoSize) i możliwości pobrania informacji o konfiguracji IP hosta za pomocą struktury FIXED_INFO. Czy (Err = GetNetworkParams(NULL, &FixedInfoSize))!= 0? 2. Alokacja pamięci na dane o konfiguracji IP hosta na podstawie wartości zmiennej FixedInfoSize. pfixedinfo = (PFIXED_INFO) GlobalAlloc(GPTR, FixedInfoSize); lub pfixedinfo = new FIXED_INFO[FixedInfoSize]; paddrstr = new IP_ADDR_STRING; po punkcie (4) należy usunąć obiekt poleceniem delete [] pfixedinfo; 3. Pobranie i sprawdzenie poprawności pobrania danych o konfiguracji hosta. Czy (Err = GetNetworkParams(pFixedInfo, &FixedInfoSize)) == 0? 14
Struktura programu 4. Przekierowanie na ekran informacji o konfiguracji IP hosta. (i) Nazwa hosta: pfixedinfo->hostname; (ii) Adres IP głównego serwera DNS: pfixedinfo->dnsserverlist.ipaddress.string; (iii) Adresy IP alternatywnych serwerów DNS (użycie wskaźnika paddrstr): paddrstr = pfixedinfo->dnsserverlist.next; paddrstr->ipaddress.string; paddrstr = paddrstr->next; (iv) Typ adresu hosta: pfixedinfo->nodetype Możliwe wartości: 1 Broadcast, 2 - Peer to peer, 4 Mixed, 8 Hybrid (v) NetBIOS Scope ID: pfixedinfo->scopeid; (vi) IP Routing Enabled: pfixedinfo->enablerouting? "yes" : "no ; (vii) WINS Proxy Enabled: pfixedinfo->enableproxy? "yes" : "no ; (viii) NetBIOS Resolution Uses DNS: pfixedinfo->enabledns? "yes" : "no ; 15
Struktura programu 5. Określenie wielkości danych zawierających informacje o kartach sieciowych (struktura IP_ADAPTER_INFO). Czy (Err = GetAdaptersInfo(NULL, &AdapterInfoSize))!= 0? 6. Alokacja pamięci na dane o parametrach karty na podstawie wartości zmiennej AdapterInfoSize. Czy (padapterinfo = (PIP_ADAPTER_INFO) GlobalAlloc(GPTR, AdapterInfoSize)) == NULL? lub padapterinfo = new IP_ADAPTER_INFO[AdapterInfoSize]; po ostatnim użyciu owskaźnika padapterinfo należy go usunąć poleceniem delete [] padapterinfo; 7. Pobranie i sprawdzenie poprawności pobrania danych o kartach sieciowych. Czy (Err = GetAdaptersInfo(pAdapterInfo, &AdapterInfoSize))!= 0? 16
Struktura programu 8. Przekierowanie na ekran informacji o konfiguracji karty sieciowej. (i) Pobranie informacji o typie karty. Wartość zmiennej: padapterinfo->type MIB_IF_TYPE_ETHERNET: karta typu Ethernet. MIB_IF_TYPE_TOKENRING: karta typu Token Ring. MIB_IF_TYPE_FDDI: karta typu FDDI; MIB_IF_TYPE_PPP: typ PPP; MIB_IF_TYPE_LOOPBACK: typ Loopback; MIB_IF_TYPE_SLIP: typ Slip; MIB_IF_TYPE_OTHER: inny typ. (ii) Pobranie informacji o nazwie karty: padapterinfo->adaptername; (iii) Pobranie opisu karty (nazwa producenta karty): padapterinfo->description 17
Struktura programu (iv) Pobranie adresu MAC Długość adresu MAC, wartość powinna być równa 6 (bajtów): padapterinfo->addresslength; Poszczególne elementy adresu znajdują się w tablicy adresu MAC: padapterinfo->address[i]; (v) Pobranie informacji o udostępnieniu opcji DHCP. DHCP Enabled: padapterinfo->dhcpenabled? "yes" : "no"; (vi) Pobranie listy adresów IP karty: adres IP, adres maski. Zmiana wartości wskaźnika: paddrstr = &(padapterinfo->ipaddresslist); Pobranie listy adresów IP: Adres IP: paddrstr->ipaddress.string; Adres maski: paddrstr->ipmask.string; paddrstr = paddrstr->next; (vii) Pobranie adresów IP domyślnych bram. Pierwsza domyślna brama: padapterinfo>gatewaylist.ipaddress.string. paddrstr = padapterinfo->gatewaylist.next; Pobranie adresów IP następnych domyślnych bram: paddrstr->ipaddress.string; paddrstr = paddrstr->next; 18
Struktura programu (viii) Pobranie adresu IP serwera DHCP. DHCP Server: padapterinfo->dhcpserver.ipaddress.string. (ix) Pobranie adresów IP serwerów WINS. Primary WINS Server: padapterinfo->primarywinsserver.ipaddress.string; Secondary WINS Server: padapterinfo->secondarywinsserver.ipaddress.string; (x) Pobranie czasu dzierżawy i terminu ważności adresu IP z serwera DHCP Konwersja czasu na wyrażonej w sekundach na czas w postaci hh:mm:ss struct tm *newtime; newtime = gmtime(&padapterinfo->leaseobtained); Czas uzyskania dzierżawy: asctime( newtime ); newtime = gmtime(&padapterinfo->leaseexpires); Czas wygaśnięcia dzierżawy: asctime( newtime ); (xi) Pobranie informacji o następnej karcie sieciowej: padapterinfo = padapterinfo->next; 19
#include <windows.h> #include <time.h> #include <iphlpapi.h> #include <iostream> using namespace std; int main() { DWORD Err; PFIXED_INFO pfixedinfo; DWORD FixedInfoSize = NULL; IP_ADAPTER_INFO * padapterinfo, * padapt; DWORD AdapterInfoSize = 0; IP_ADDR_STRING * paddrstr = NULL; GetNetworkParams(NULL, &FixedInfoSize); pfixedinfo = new FIXED_INFO[FixedInfoSize]; paddrstr = new IP_ADDR_STRING; GetNetworkParams(pFixedInfo, &FixedInfoSize); cout << "Host Name......... : " << pfixedinfo -> HostName << endl; cout << "Domain Name........ : " << pfixedinfo -> DomainName << endl; cout << "Preffered DNS Server.... : " << pfixedinfo -> DnsServerList.IpAddress.String << endl; cout << "Alternative DNS Servers: "<< endl; paddrstr = pfixedinfo -> DnsServerList.Next; while ( paddrstr ) { cout << "\t\t\t"<< paddrstr ->IpAddress.String << endl; paddrstr = paddrstr ->Next; } delete paddrstr; 20
cout << "Typ wezla......... : "; switch (pfixedinfo->nodetype) { case 1: cout << "Broadcast" << endl; case 2: cout << "Peer to peer" << endl; case 4: cout << "Mixed" << endl; case 8: cout << "Hybrid" << endl; default: cout << "\n" << endl; } cout <<"NetBIOS ScopeID...... : " << pfixedinfo->scopeid << endl; cout <<"IP Routing Enabled..... : " << (pfixedinfo->enablerouting? "yes" : "no") << endl; cout <<"WINS Proxy Enabled..... : " << (pfixedinfo->enableproxy? "yes" : "no") << endl; cout <<"NetBIOS Resolution Uses DNS.: " << (pfixedinfo->enabledns? "yes" : "no") << endl; delete [] pfixedinfo; GetAdaptersInfo(NULL, &AdapterInfoSize); padapterinfo = new IP_ADAPTER_INFO[AdapterInfoSize]; if ((Err = GetAdaptersInfo(pAdapterInfo, &AdapterInfoSize))!= 0) { cout << "GetAdaptersInfo() error no: "<< Err << endl; return 0; } 21
padapt = padapterinfo; while (padapt) { cout << "Karta typu......... : "; switch (padapt->type) { case MIB_IF_TYPE_ETHERNET: cout << "Ethernet"<< endl; case MIB_IF_TYPE_TOKENRING: cout << "Token Ring"<< endl; case MIB_IF_TYPE_FDDI: cout << "FDDI"<< endl; case MIB_IF_TYPE_PPP: cout << "PPP"<< endl; case MIB_IF_TYPE_LOOPBACK: cout << "Loopback"<< endl; case MIB_IF_TYPE_SLIP: cout << "Slip"<< endl; case MIB_IF_TYPE_OTHER: cout << "Nieznany"<< endl; default: cout << "Nieznany"<< endl; } cout << "Nazwa karty........ : " << padapt->adaptername << endl; cout << "Opis........ : " << padapt->description << endl; cout << "Adresy MAC..... : " ; 22
for (unsigned int i=0; i< padapt->addresslength; i++) { if (i == (padapt->addresslength - 1)) printf("%.2x\n",(int)padapt->address[i]); else printf("%.2x-",(int)padapt->address[i]); } cout << "DHCP Enabled.... : " << (padapt->dhcpenabled? "yes" : "no") << endl; paddrstr = &(padapt->ipaddresslist); while(paddrstr) { cout << "Adres IP...... : " << paddrstr->ipaddress.string << endl; cout << "Subnet Mask.... : " << paddrstr->ipmask.string << endl; paddrstr = paddrstr->next; } cout << "Default Gateway.. : " << padapt->gatewaylist.ipaddress.string << endl; paddrstr = padapt->gatewaylist.next; while(paddrstr) { cout << paddrstr->ipaddress.string << endl; paddrstr = paddrstr->next; } 23
cout << "DHCP Server..... : " << padapt->dhcpserver.ipaddress.string << endl; cout << "Primary WINS Server : " << padapt->primarywinsserver.ipaddress.string << endl; cout << "Secondary WINS Server: " << padapt->secondarywinsserver.ipaddress.string << endl; cout << "Dhcp Enabled: " << padapt->dhcpenabled << endl; if (padapt->dhcpenabled!= 0) { struct tm newtime; char buf[26]; errno_t err; err = _gmtime64_s( &newtime, &padapt->leaseobtained ); err = asctime_s(buf, 26, &newtime); cout << "Lease Obtained... : " << buf << endl; //asctime( newtime ) ; err = _gmtime64_s( &newtime, &padapt->leaseexpires); err = asctime_s(buf, 26, &newtime); cout << "Lease Expires... : " << buf << endl; } // end if padapt = padapt->next; } // end while (padapterinfo) delete [] padapterinfo; return 0; } // end main 24