Protokoł ARP. - Uniwersytet Opolski

Transkrypt

Protokoł ARP. - Uniwersytet Opolski
Protokół ARP
Aplikacja printarp
dr Zbigniew Lipiński
Instytut Matematyki i Informatyki
ul. Oleska 48
50-204 Opole
[email protected]
Address Resolution Protocol
ARP, (ang.) Address Resolution Protocol.
RFC 826.
Protokół ARP jest protokołem warstwy Sieci modelu referencyjnego OSI.
Protokół ARP należy do rodziny protokołów TCP/IP.
Protokół ARP służy do znajdowania adresów fizycznych kart sieciowych (adresów MAC) na podstawie
adresów IP.
Protokół ARP służy do:
• wysyłania zapytań do sieci o adres MAC,
• uaktualniania tablic arp.
2
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Struktura nagłówka komunikatu ARP
Bity
4
1
1
2
8
12
16
20
Typ adresu nadawcy
Dl. adresu MAC
24
28
32
Typ adresu odbiorcy
Dl. adresu protokolu
Operacja
Pierwsze 32 bity adresu MAC nadawcy
3
Ostanie 16 bitow adresu MAC nadawcy
Pierwsze 16 bitow adresu protokolu nadawcy
4
Ostatnie16 bitow adresu protokolu nadawcy
Pierwsze 16 bitow adresu MAC odbiorcy
5
Ostatnie 32 bity adresu MAC odbiorcy
6
Ostatnie32 bity adresu protokolu odbiorcy
Struktura komunikatu ARP
3
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Struktura nagłówka komunikatu ARP
Pole:
Typ adresu fizycznego, (Hardware Type). Wielkość: 16 bitów.
Pole określa typ adresu MAC (typ karty sieciowej).
Typy adresów. Wartość: 1 (Ethernet), 2 (Experimental Ethernet), 3 (X.25), 4 (Proteon ProNET - Token Ring),
5 (Chaos), 6 (IEEE 802.X), 7 (ARCnet).
Pole:
Typ adresu protokołu, (Protocol Type). Wielkość: 16 bitów.
Pole określa typ protokołu jakiego użył host wysyłający zapytanie. Dla rodziny TCP/IP użyty protokół jest typu
'Ethernet'.
Pole:
Dł. adresu MAC, (Hardware Address Length). Wielkość: 8 bitów.
Długość (wyrażona w bajtach) adresu fizycznego w datagramie. Dla adresu MAC wartość = 6 bajtów.
Pole:
Dł. adresu protokołu, (Protocol Address Length). Wielkość: 8 bitów.
Długość (wyrażona w bajtach) adresu protokołu. Dla adresu IP wartość pola = 4 bajty.
Pole:
Operacja, (Operation Code, Opcode). Wielkość: 16 bitów.
Wartość kodu 1 dla wiadomości typu 'ARP reply' (odpowiedz),
Wartość kodu 2 dla wiadomości typu 'ARP request' (zapytanie).
Pole:
Adres MAC nadawcy, (Sender Hardware Address).
Wielkość: wartość z pola 'Hardware Address Length'. Adres MAC hosta wysyłającego ARP request.
Pole:
Adres nadawcy, (Sender Protocol Address).
Wielkość: wartość z pola 'Protocol Address Length'. Adres IP hosta wysyłającego ARP request.
Pole:
Adres MAC odbiorcy, (Target Hardware Address).
Wielkość: wartość z pola 'Hardware Address Length'.
Adres MAC hosta odbierającego wiadomość.
Pole:
Adres odbiorcy, (Target Protocol Address).
Wielkość: wartość z pola 'Protocol Address Length'. Adres IP hosta odbierającego wiadomość.
4
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Struktura adresu MAC karty sieciowej
Przykład: Adres fizyczny 00-B0-D0-2C-FC-B6
Pole I/G. Wartości: 0/1. 1 bit. Znaczenie: adres Indywidualny/Grupowy.
Pole U/L. Wartości: 0/1. 1 bit. Znaczenie: adres Uniwersalny/Lokalny.
Adres Univerwersaly: Karty sieciowe uniwersalne są zgodne ze standardem IEEE.
Adres Lokalny: Karty z takim adresem mogą nie być zgodne ze standardem IEEE.
Pole OUI (Organization Unique Identifier). 22 bity.
Część adresu MAC określająca producenta karty sieciowej.
Pole 24 bity. Znaczenie: numer karty sieciowej.
Numer karty sieciowej przydzielany przez producenta karty.
Przykłady kodów producentów kart:
00000C Cisco
0000D8 3Com, Novell PS/2
0080C2 IEEE 802.1 Committee
00AA00 Intel
02608C 3Com IBM PC; Imagen; Valid; Cisco
080020
Sun machines
Przykład: Karta o adresie 08:00:20:00:70:DF
została wyprodukowana przez Sun Microsystems.
5
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja projektu
Nazwa projektu: IpArp
Typ projektu : Win32 console application
Lista plików : IpArp.cpp
Kompilacja
: Microsoft Visual C++ 2008.
Wkopiować pliki svcrt.lib iphlpapi.lib WS2_32.Lib do katalog projektu.
W Project-> Setings-> Link-> Object/Library Modules->
Dodać: WS2_32.Lib iphlpapi.lib
Funkcjonalność:
\> printarp
// kieruje na ekran zawartość tablicy arp.
Przykład:
\>printarp
\> Interfejs: 10.60.17.94 --- 0x2
Adres internetowy
Adres fizyczny
Typ
10.60.17.5
00-02-a5-cd-37-c4
dynamiczne
6
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Struktura progamu
Pliki nagłówkowe:
windows.h, iphlpapi.h, iptypes.h, iostream.
Funkcje programu:
WSAStartup(), WSACleanup(), inet_ntoa(), GetIpNetTable(), GetIpAddrTable()
PrintIpNetTable(), MyGetIpNetTable(), MyGetIpAddrTable(),
PhysAddrToString(), StringToPhysAddr(), InterfaceIdxToInterfaceIp(),
Struktury programu:
WSADATA, MIB_IPNETTABLE, MIB_IPADDRTABLE, in_addr, MIB_IPNETROW
Zmienne programu:
WORD
wVersionRequested = MAKEWORD(1,1);
WSADATA
wsaData;
int
nRet;
DWORD
dwStatus;
PMIB_IPNETTABLE
pIpArpTab = NULL;
7
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja Struktury WSADATA
Nazwa struktury : WSADATA
Opis :
Struktura WSADATA zawiera informacje o implementacji gniazd (Windows Sockets). Struktura WSADATA jest zadeklarowana w pliku
Winsock2.h.
Aplikacja nie powinna używać atrybutów iMaxsockets, iMaxUdpDg, i lpVendorInfo struktury WSAData gdy wartość atrybutu
wVersion, po wywołaniu WSAStartup jest co najmniej 2.
Wyjaśnienie: This is because the architecture of Windows Sockets has been changed in version 2 to support multiple providers, and
WSAData no longer applies to a single vendor's stack. Two new socket options are introduced to supply provider- specific information:
SO_MAX_MSG_SIZE (replaces the iMaxUdpDg element) and PVD_CONFIG (allows any other provider-specific configuration to occur).
Atrybuty :
wVersion - Wersja gniazd WinSock którą ma używać biblioteka Ws2_32.dll.
wHighVersion - Najwyższa wersja WinSock jaką może używać biblioteka .dll. Standardowo, wartość taka sama, jak wVersion.
szDescription - Zerem zakończony string znaków ASCI (null-terminated ASCII string) do którego Ws2_32.dll kopiuje
opis implementacji gniazd. Tekst (do 256 znaków) może być używany do opisów wiadomości.
szSystemStatus - Zakończony zerem string znaków ASCI do którego WSs2_32.dll kopiuje informacje o statusie
lub konfiguracji. Ws2_32.dll powinna używać tego atrybutu do tylko gdy informacje mogą być ważne
dla użytkowników, atrybut nie powinien być traktowany jako rozszerzenie zmiennej szDescription.
iMaxSockets - Pozostawiony dla zgodności poprzednimi wersjami gniazd. Parametr powinien być ignorowany przez
Windows Socketsv.2 i wersje późniejsze (nie ma już jednej wartości dla wszystkich dostarczycieli usług).
iMaxUdpDg - Atrybut ignorowany przez gniazda wersji 2 i następne. iMaxUdpDg pozostawiony dla zgodności z
wersją gniazd Windows Sockets 1.1. Nie powinien być używany przy budowaniu nowych aplikacji.
Dla określenia wielkości wiadomości dostarczyciela usług dla gniazda i typu gniazda aplikacje
powinny używać getsockopt aby uzyskać wartość opcji SO_MAX_MSG_SIZE.
lpVendorInfo - Atrybut ignorowany przez Windows Sockets v.2 i następne. lpVendorInfo pozostawiono dla zgodności
z wersją gniazd Windows Sockets 1.1. Dla określenia konfiguracji dostarczyciela usług dla gniazda
powinny używać getsockopt aby uzyskać wartość opcji PVD_CONFIG.
8
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja struktury MIB_IPNETTABLE
Nazwa struktury : MIB_IPNETTABLE
Opis
Atrybuty
: Struktura MIB_IPNETTABLE zawiera tablicę z danymi ARP.
:
dwNumEntries – Liczba rekordów w tabeli ARP.
table - Wskaźnik do tablicy ARP implementowanej jako tablica struktur MIB_IPNETROW.
Implementacja struktury MIB_IPNETTABLE:
typedef struct _MIB_IPNETTABLE
{
DWORD
dwNumEntries;
MIB_IPNETROW
table[ANY_SIZE];
} MIB_IPNETTABLE, *PMIB_IPNETTABLE;
9
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja struktury MIB_IPNETROW
Nazwa struktury: MIB_IPNETROW
Opis
Atrybuty
: Struktura MIB_IPNETROW zawiera dane do rekordów tablicy ARP.
:
dwIndex -
Indeks karty sieciowej.
dwPhysAddrLen - Długość adresu fizycznego karty sieciowej.
bPhysAddr - Określa adres fizyczny karty sieciowej.
dwAddr -
Określa adres IP karty sieciowej.
dwType -
Określa typ rekordu ARP. Możliwe typy rekordów ARP: 4 Static, 3 Dynamic, 2 Invalid, 1 inne.
Implementacja struktury MIB_IPNETROW:
typedef struct _MIB_IPNETROW {
DWORD
dwIndex;
DWORD
dwPhysAddrLen;
BYTE
bPhysAddr[MAXLEN_PHYSADDR];
DWORD
dwAddr;
DWORD
dwType;
} MIB_IPNETROW, *PMIB_IPNETROW;
10
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja struktury MIB_IPADDRTABLE
Nazwa struktury: MIB_IPADDRTABLE
Opis
Atrybuty
: Struktura MIB_IPADDRTABLE zawiera tablicę adresów IP.
:
dwNumEntries –
table –
Określa numer adresu IP w tablicy.
Wskaźnik do rekordu w tablicy implementowanej jako tablica struktur MIB_IPADDRROW.
Implementacja struktury PMIB_IPADDRTABLE:
typedef struct _MIB_IPADDRTABLE {
DWORD
dwNumEntries;
MIB_IPADDRROW
table[ANY_SIZE];
} MIB_IPADDRTABLE, *PMIB_IPADDRTABLE;
typedef struct _MIB_IPADDRROW {
DWORD
dwAddr; //The IPv4 address in network byte order.
DWORD
dwIndex; // Index of nterface associated with this IPv4 address.
DWORD
dwMask; // Subnet mask for the IPv4 address in network byte order.
DWORD
dwBCastAddr; // The broadcast address in network byte order.
DWORD
dwReasmSize; // Maximum re-assembly size for received datagrams.
unsigned short
unused1;
unsigned short
wType; // The address type or state.
} MIB_IPADDRROW, *PMIB_IPADDRROW;
11
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja struktury in_addr
Nazwa struktury : in_addr
Opis:
Struktura in_addr adres IP hosta. Struktura zdefiniowana w WINSOCK.H
Atrybuty :
S_un_b - adres hosta w formacie u_chars.
S_un_w adres hosta w formacie dwóch u_shorts.
S_addr adres hosta w formacie u_long.
Implementacja struktury in_addr:
struct
{
in_addr
union
{
struct
{
unsigned char
s_b1, s_b2, s_b3, s_b4;
} S_un_b;
struct
{
unsigned short s_w1, s_w2;
} S_un_w;
unsigned long S_addr;
} S_un;
};
12
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja funkcji WSAStartup()
Nazwa funkcji
: WSAStartup()
Zwracana wartość: int
WSAStartup() zwraca zero gdy wywołanie funkcji zakończyło się sukcesem. W innym przypadku
zwraca następujące kody błędów:
WSASYSNOTREADY – Wskazuje, że sieć lub podsieć nie jest przygotowana do transmisji
danych.
WSAVERNOTSUPPORTED – Żądana wersja WinSock nie jest obsługiwana przez
implementację WinSock.
WSAEINPROGRESS –
Trwa operacja blokowania WinSock 1.1
WSAEPROCLIM Osiągnięto granicę liczby zadań dopuszczalną przez WinSock.
WSAEFAULT Błędna wartość wskaźnika lpWSAData (not a valid pointer).
Argumenty:
WORD wVersionRequested -
LPWSADATA lpWSAData Opis:
[in] Najwyższa obsługiwana wersja WinSock, którą nadawca
(caler) może użyć. Bajt najwyższy określa minimalną wersję,
najniższy bajt określa maksymalna wersję.
[out] Wskaźnik do struktury WSADATA.
Funkcja WSAStartup() inicjuje użycie przez proces biblioteki WS2_32.DLL.
Funkcja WSAStartup() musi być pierwszą funkcja Windows Sockets wywołana przez aplikacje.
13
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja funkcji WSACleanup()
Nazwa funkcji: WSACleanup()
Zwracana wartość: int
WSACleanup() zwraca zero gdy wywołanie funkcji zakończyło się sukcesem. W innym przypadku zwraca
SOCKET_ERROR, i określony kod błędu może być uzyskany poprzez wywołanie finkcji WSAGetLastError():
WSANOTINITIALISED - Przed wywołaniem tej funkcji WSACleanup() musi być wywołana z
sukcesem funkcja WSAStartup().
WSAENETDOWN Awaria sieci (network subsystem has failed).
WSAEINPROGRESS Trwa operacja blokowania WinSock 1.1 lub dostarczyciel usługi (service
provider) obsługuje komunikat zwrotny (a callback function).
Argumenty: brak
Opis:
Funkcja WSACleanup() kończy użycie biblioteki WS2_32.DLL.
14
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja funkcji inet_ntoa()
Nazwa funkcji: inet_ntoa()
Zwracana wartość: char* FAR
Jeżeli nie ma błędów inet_ntoa() zwraca wskaźnik char* do statycznego bufora zawierającego
adres w standardzie kropkowanym. W pozostałych przypadkach funkcja zwraca NULL.
Argumenty
Opis
:
: struct in_addr in
in - [in] Wskaźnik do struktury in_addr reprezentującej adres IP hosta.
Funkcja inet_ntoa() konwertuje adres IPv4 na adres w formacie kropkowanym (dotted format).
15
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja funkcji inet_addr()
Nazwa funkcji
: inet_addr()
Zwracana wartość: unsigned long
Argumenty
Opis
: const char* cp
cp - [in] Zerem zakończony string znaków reprezentujący adres IP zapisany w notacji
kropkowanej (np. 127.0.0.1).
: Funkcja inet_addr() konwertuje string zawierający adres IPv4 w wersji kropkowanej na
odpowiedni adres w strukturze IN_ADDR.
16
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja funkcji GetIpNetTable()
Nazwa funkcji
: GetIpNetTable()
Zwracana wartość: DWORD
Argumenty
:
pIpNetTable - [out] Wskaźnik do bufora który przechowuje adres tablicę danych ‘adres IP- adres MAC’ w
strukturze MIB_IPNETTABLE.
pdwSize - [in, out] Na wejściu wskaźnik do zmiennej przechowującej wielkość bufora (zmiennej
wskazywanej przez pIpNetTable). Na wyjściu, jeżeli bufor jest za mały na zwracaną tablicę danych, funkcja
ustawia wartość tego parametru na wielkość wymaganą.
bOrder - [in] Argument określa czy zwracana tablica ma być uporządkowana według rosnących adresów IP
(tablica jest uporządkowana gdy parametr ma wartość TRUE.
Opis
: Funkcja pobiera dane zawierające przyporządkowanie adres ‘IP adres MAC’ (tablica ARP).
Deklaracja funkcji w pliku iphlpapi.h.
17
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Specyfikacja funkcji GetIpAddrTable()
Nazwa funkcji
: GetIpAddrTable()
Zwracana wartość: DWORD
Argumenty
:
pIpAddrTable - [out] Wskaźnik do bufora który przechowuje adres tablicę danych ‘karta - adres IP’ w
strukturze MIB_IPADDRTABLE.
pdwSize - [in, out] Na wejściu wskaźnik do zmiennej przechowującej wielkość bufora (zmiennej wskazywanej
przez pIpAddrTable).
Na wyjściu, jeżeli bufor jest za mały na zwracaną tablicę danych, funkcja ustawia wartość tego
parametru na wielkość wymaganą.
bOrder - [in] Argument określa czy zwracana tablica ma być uporządkowana według rosnących adresów IP
(tablica jest uporządkowana gdy parametr ma wartość TRUE.
Opis
: Funkcja GetIpAddrTable() pobiera dane o przyporządkowaniu karty sieciowej do adresu IP.
18
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Implementacja funkcji InterfaceIdxToInterfaceIp()
bool InterfaceIdxToInterfaceIp(PMIB_IPADDRTABLE pIpAddrTable, DWORD dwIndex, char str[])
{
struct in_addr inadTmp;
char
*szIpAddr;
if (pIpAddrTable == NULL || str == NULL)
return FALSE;
str[0] = '\0';
for (DWORD dwIdx = 0; dwIdx < pIpAddrTable->dwNumEntries; dwIdx++)
{
if (dwIndex == pIpAddrTable->table[dwIdx].dwIndex)
{
inadTmp.s_addr = pIpAddrTable->table[dwIdx].dwAddr;
szIpAddr = inet_ntoa(inadTmp);
if (szIpAddr)
{
strcpy(str, szIpAddr);
return TRUE;
}
else
return FALSE;
}
}
return FALSE;
}
19
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Implementacja funkcji StringToPhysAddr()
int StringToPhysAddr(char* szInEther, char* szOutEther)
{
const char
DASH = '-';
register char
c;
register int
val;
if (strlen(szInEther) != 17)
return (-1);
if (szInEther[2] != DASH || szInEther[5] != DASH || szInEther[8] != DASH ||
szInEther[8] != DASH || szInEther[14] != DASH)
return (-1);
if (!isxdigit(szInEther[0])
|| !isxdigit(szInEther[1])
|| !isxdigit(szInEther[3])
||
!isxdigit(szInEther[4])
||
!isxdigit(szInEther[6])
|| !isxdigit(szInEther[7])
|| !isxdigit(szInEther[9])
||
!isxdigit(szInEther[10]) ||
!isxdigit(szInEther[12]) || !isxdigit(szInEther[13]) || !isxdigit(szInEther[15]) ||
!isxdigit(szInEther[16]))
return (-1);
for (int i = 0; i < 6; i++)
{
val = 0;
c = toupper(szInEther[i*3]);
c = c - (isdigit(c) ? '0' : ('A' - 10));
val += c;
val = (val << 4);
c = toupper(szInEther[i*3 + 1]);
c = c - (isdigit(c) ? '0' : ('A' - 10));
val += c;
szOutEther[i] = val;
}
return 0;
20
}
Implementacja funkcji PhysAddrToString()
bool PhysAddrToString(BYTE PhysAddr[], DWORD PhysAddrLen, char str[])
{
if (PhysAddr == NULL || PhysAddrLen == 0 || str == NULL)
return FALSE;
str[0] = '\0';
for (DWORD dwIdx = 0; dwIdx < PhysAddrLen; dwIdx++)
{
if (dwIdx == PhysAddrLen-1)
sprintf(str+(dwIdx*3), "%02X", ((int)PhysAddr[dwIdx])&0xff);
else
sprintf(str+(dwIdx*3), "%02X-", ((int)PhysAddr[dwIdx])&0xff);
}
return TRUE;
}
21
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Implementacja funkcji PrintIpNetTable()
void PrintIpNetTable(PMIB_IPNETTABLE pIpNetTable)
{
DWORD i, dwStatus, dwCurrIndex;
struct in_addr inadTmp;
char szPrintablePhysAddr[256];
char szType[128];
char szIpAddr[128];
PMIB_IPADDRTABLE pIpAddrTable = NULL;
if (pIpNetTable == NULL)
{
printf( "pIpNetTable == NULL in line %d\n", __LINE__);
return;
}
if ( (dwStatus = MyGetIpAddrTable(pIpAddrTable)) != NO_ERROR)
{
printf("GetIpAddrTable returned 0x%x\n", dwStatus);
if (pIpAddrTable)
delete [] pIpAddrTable;
return;
}
dwCurrIndex = pIpNetTable->table[0].dwIndex;
if (InterfaceIdxToInterfaceIp(pIpAddrTable, dwCurrIndex, szIpAddr))
{
printf("\nInterface: %s on Interface 0x%X\n", szIpAddr, dwCurrIndex);
printf(" Internet Address
Physical Address
Type\n");
}
else
{
printf("Error: Could not convert Interface number 0x%X to IP address.\n",
pIpNetTable->table[0].dwIndex);
return;
}
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
22
Implementacja funkcji PrintIpNetTable()
for (i = 0; i < pIpNetTable->dwNumEntries; ++i)
{ if (pIpNetTable->table[i].dwIndex != dwCurrIndex)
{
dwCurrIndex = pIpNetTable->table[i].dwIndex;
if (InterfaceIdxToInterfaceIp(pIpAddrTable, dwCurrIndex, szIpAddr))
{
printf("Interface: %s on Interface 0x%X\n", szIpAddr, dwCurrIndex);
Physical Address
Type\n");
printf(" Internet Address
}
else
{
printf("Error: Could not convert Interface number 0x%X to IP address.\n",
pIpNetTable->table[0].dwIndex);
return;
}
}
PhysAddrToString(pIpNetTable->table[i].bPhysAddr, pIpNetTable->table[i].dwPhysAddrLen,
szPrintablePhysAddr);
inadTmp.s_addr = pIpNetTable->table[i].dwAddr;
switch (pIpNetTable->table[i].dwType)
{
case 1: strcpy(szType,"other");
break;
case 2: strcpy(szType,"invalidated");
break;
case 3: strcpy(szType,"dynamic");
break;
case 4: strcpy(szType,"static");
break;
default: strcpy(szType,"invalidType");
}
printf(" %-16s
%-17s
%-11s\n", inet_ntoa(inadTmp), szPrintablePhysAddr, szType);
}
if (pIpAddrTable)
delete [] pIpAddrTable;
}
23
Implementacja funkcji MyGetIpNetTable()
DWORD MyGetIpNetTable(PMIB_IPNETTABLE& pIpNetTable, bool fOrder)
{
DWORD status = NO_ERROR;
DWORD statusRetry = NO_ERROR;
DWORD dwActualSize = 0;
dwActualSize = 0;
status = GetIpNetTable(pIpNetTable, &dwActualSize, fOrder);
if (status == NO_ERROR)
{
return status;
}
else if (status == ERROR_INSUFFICIENT_BUFFER)
{
pIpNetTable = new MIB_IPNETTABLE [dwActualSize];
statusRetry = GetIpNetTable(pIpNetTable, &dwActualSize, fOrder);
24
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Implementacja funkcji MyGetIpNetTable()
if (statusRetry != NO_ERROR)
{
#ifdef _DEBUG
printf("Retry failed.\n");
#endif
return statusRetry;
}
else
{
return statusRetry;
}
}
else
{
#ifdef _DEBUG
printf("first getipnettable call failed\n");
#endif
return status;
}
}
25
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Implementacja funkcji MyGetIpAddrTable()
DWORD MyGetIpAddrTable(PMIB_IPADDRTABLE& pIpAddrTable, bool fOrder)
{
DWORD status = NO_ERROR;
DWORD statusRetry = NO_ERROR;
DWORD dwActualSize = 0;
// query for buffer size needed
status = GetIpAddrTable(pIpAddrTable, &dwActualSize, fOrder);
if (status == NO_ERROR)
{
printf("No error\n");
return status;
}
else if (status == ERROR_INSUFFICIENT_BUFFER)
{
pIpAddrTable = new MIB_IPADDRTABLE [dwActualSize];
statusRetry = GetIpAddrTable(pIpAddrTable, &dwActualSize, fOrder);
return statusRetry;
}
else
{
return status;
}
}
26
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Struktura programu
1. Sprawdzenie wersji winsock.
nRet = WSAStartup(wVersionRequested, &wsaData);
Czy wsaData.wVersion != wVersionRequested ?
2. Pobranie danych z tablic arp
dwStatus = MyGetIpNetTable(pIpArpTab, TRUE)) == NO_ERROR
3. Przekazanie na ekran dnaych o tablicy arp.
PrintIpNetTable(pIpArpTab);
4. Zakończenie użycia biblioteki winsock WS2_32.DLL.
WSACleanup();
27
Z. Lipiński, Instytut Matematyki i Informatyki, Uniwersytet Opolski, Podstawy programowania sieciowego
Struktura funkcji main()
int main(int argc, char **argv)
{
WORD
wVersionRequested = MAKEWORD(1,1);
WSADATA wsaData;
int
nRet;
nRet = WSAStartup(wVersionRequested, &wsaData);
if (wsaData.wVersion != wVersionRequested)
{
cerr << "WinSock version: " << LOBYTE(wVersionRequested)
<<"." << HIBYTE(wVersionRequested) << " not supported" << endl;
WSACleanup();
return 1;
}
DWORD dwStatus;
PMIB_IPNETTABLE pIpArpTab = NULL;
if ( (dwStatus = MyGetIpNetTable(pIpArpTab, TRUE)) == NO_ERROR)
{
PrintIpNetTable(pIpArpTab);
delete [] pIpArpTab;
return 1;
}
else if ( dwStatus == ERROR_NO_DATA)
{
cerr << "No entries in arp cache." <<endl;
return 1;
}
else
{
if (pIpArpTab)
delete [] pIpArpTab;
cout <<"IpArp returned: " << dwStatus << endl;
return 1;
}
WSACleanup();
return 0;
}
28

Podobne dokumenty