Internet Control Message Protocol Aplikacja ping



Podobne dokumenty
Rodzina protokołów TCP/IP. Aplikacja: ipconfig.

Statystyka protokołów i połączeń sieciowych.

Sieci Komputerowe. Protokół ICMP - Internet Control Message Protocol Protokół ICMP version 6. dr Zbigniew Lipiński

SUMA KONTROLNA (icmp_cksum) NUMER KOLEJNY (icmp_seq)

Gniazda surowe. Bartłomiej Świercz. Łódź,9maja2006. Katedra Mikroelektroniki i Technik Informatycznych. Bartłomiej Świercz Gniazda surowe

Protokół ARP. dr Zbigniew Lipiński. Instytut Matematyki i Informatyki ul. Oleska Opole zlipinski@math.uni.opole.pl

DR INŻ. ROBERT WÓJCIK DR INŻ. JERZY DOMŻAŁ

Aplikacja Sieciowa. Najpierw tworzymy nowy projekt, tym razem pracować będziemy w konsoli, a zatem: File->New- >Project

Iteracyjny serwer TCP i aplikacja UDP

Programowanie Sieciowe 1

Laboratorium 6.7.2: Śledzenie pakietów ICMP

Literatura uzupełniająca: W. Richard Stevens, Programowanie zastosowań sieciowych w systemie Unix WNT 1998

Oprogramowanie komunikacyjne dla Internetu rzeczy Laboratorium nr 4 komunikacja unicastowa IPv6

Programowanie sieciowe

Protokół DNS. Aplikacja dnsquery

Instytut Teleinformatyki

Gniazda UDP. Bartłomiej Świercz. Łódź, 3 kwietnia Katedra Mikroelektroniki i Technik Informatycznych. Bartłomiej Świercz Gniazda UDP

Programowanie sieciowe

Interfejs programowy Windows Sockets 2. Aplikacja klient-serwer TCP Echo

Internet Control Message Protocol (ICMP) Łukasz Trzciałkowski

ZiMSK. Routing statyczny, ICMP 1

Gniazda BSD. komunikacja bezpołączeniowa

Warstwa sieciowa. Model OSI Model TCP/IP. Aplikacji. Aplikacji. Prezentacji. Sesji. Transportowa. Transportowa

Gniazda BSD. Procesy w środowisku sieciowym. Gniazda podstawowe funkcje dla serwera. Gniazda podstawowe funkcje dla klienta

Instrukcja 5 - Zastosowania protokołu ICMP

Sieci komputerowe. Zajęcia 3 c.d. Warstwa transportu, protokoły UDP, ICMP

Podstawy Transmisji Danych. Wykład IV. Protokół IPV4. Sieci WAN to połączenia pomiędzy sieciami LAN

SEGMENT TCP CZ. II. Suma kontrolna (ang. Checksum) liczona dla danych jak i nagłówka, weryfikowana po stronie odbiorczej

3. Identyfikacja. SKŁADNIA #include <sys/socket.h> int getpeername(int socket, struct sockaddr *addr, int *addrlen);

Programowanie aplikacji równoległych i rozproszonych. Wykład 4

MODEL OSI A INTERNET

Gniazda - Wstęp. Oprogramowanie systemów równoległych i rozproszonych. Sposób komunikacji. Domena adresowa. olas@icis.pcz.pl

Komunikacja międzyprocesowa. Krzysztof Banaś Systemy rozproszone 1

Akademia Techniczno-Humanistyczna w Bielsku-Białej

Zarządzanie ruchem w sieci IP. Komunikat ICMP. Internet Control Message Protocol DSRG DSRG. DSRG Warstwa sieciowa DSRG. Protokół sterujący

I - Microsoft Visual Studio C++

Protokoły wspomagające. Mikołaj Leszczuk

Przesyłania danych przez protokół TCP/IP

ZESZYTY ETI ZESPOŁU SZKÓŁ W TARNOBRZEGU Nr 1 Seria: Teleinformatyka 2013

Programowanie przy użyciu gniazdek

Komunikacja sieciowa - interfejs gniazd

Klient-Serwer Komunikacja przy pomocy gniazd

Standardy programowania protokołów komunikacyjnych Laboratorium nr 5 komunikacja multicastowa IPv6

Architektura typu klient serwer: przesyłanie pliku tekstowo oraz logowania do serwera za pomocą szyfrowanego hasła

Adresowanie grupowe. Bartłomiej Świercz. Katedra Mikroelektroniki i Technik Informatycznych. Łódź, 25 kwietnia 2006

Podstawowe typy serwerów

Laboratorium 6.7.1: Ping i Traceroute

Architektura typu klient serwer: uproszczony klient POP3

TCP - receive buffer (queue), send buffer (queue)

Gniazda. S. Samolej: Gniazda 1

Katedra Inżynierii Komputerowej Politechnika Częstochowska. Zastosowania protokołu ICMP Laboratorium podstaw sieci komputerowych

Akademickie Centrum Informatyki PS. Wydział Informatyki PS

Sieci komputerowe - administracja

TCP/IP formaty ramek, datagramów, pakietów...

1. Wartość, jaką odczytuje się z obszaru przydzielonego obiektowi to: a) I - wartość b) definicja obiektu c) typ oboektu d) p - wartość

Sieci komputerowe - Wstęp do intersieci, protokół IPv4

Sieci Komputerowe Protokół TCP

Gniazda BSD implementacja w C#

1.1 Przykład znajdowanie liczb pierwszych leżących w zadanym zakresie, tryb bezpołączeniowy

Zygmunt Kubiak Instytut Informatyki Politechnika Poznańska

Tryb bezpołączeniowy (datagramowy)

Zdalne wywołania procedur. Jarosław Kuchta Programowanie Współbieżne

Schemat dla UDP. = możliwe zablokowanie aplikacji KLIENT SERWER. s=socket(...) bind(s,...) recvfrom(s,...) sendto(s,...) recvfrom(s,...

Przykład aplikacji UDP

Zdalne wywoływanie procedur RPC

Zdalne wywoływanie procedur RPC

Unicast jeden nadawca i jeden odbiorca Broadcast jeden nadawca przesyła do wszystkich Multicast jeden nadawca i wielu (podzbiór wszystkich) odbiorców

Warstwa sieciowa. mgr inż. Krzysztof Szałajko

Bezpieczeństwo w M875

Sieci komputerowe. Wykład 7: Transport: protokół TCP. Marcin Bieńkowski. Instytut Informatyki Uniwersytet Wrocławski

ARP Address Resolution Protocol (RFC 826)

Wykład 15. Literatura. Kompilatory. Elementarne różnice. Preprocesor. Słowa kluczowe

Zdalne wywoływanie procedur RPC. Dariusz Wawrzyniak 1

polega na opakowaniu danych - w każdej warstwie modelu OSI, kolejno idąc z góry na dół - w konieczne nagłówki/stopki odpowiednich protokołów

Krótkie wprowadzenie do korzystania z OpenSSL

ADRESY PRYWATNE W IPv4

1 Moduł Diagnostyki Sieci

2. Interfejs gniazd Gniazdo

#line #endif #ifndef #pragma

Routing. część 1: adresowanie. Sieci komputerowe. Wykład 2. Marcin Bieńkowski

Laboratorium 1 Temat: Przygotowanie środowiska programistycznego. Poznanie edytora. Kompilacja i uruchomienie prostych programów przykładowych.

Język ludzki kod maszynowy

Akademia Techniczno-Humanistyczna w Bielsku-Białej

Pobieranie argumentów wiersza polecenia

Obsługa wyjątków. Język C++ WW12

Architektura INTERNET

Zdalne wywoływanie procedur RPC 27. października Dariusz Wawrzyniak (IIPP) 1

Akademickie Centrum Informatyki PS. Wydział Informatyki PS

Winsock. Sieci Komputerowe II Wyk ład 3

C++ wprowadzanie zmiennych

Zdalne wywoływanie procedur RPC 27. października 2010

Sieci Komputerowe Mechanizmy kontroli błędów w sieciach

Sieciowa komunikacja procesów - XDR i RPC

iseries Programowanie z użyciem gniazd

Stos TCP/IP Warstwa Internetu. Sieci komputerowe Wykład 4

Wywoływanie procedur zdalnych

Protokoły sieciowe - TCP/IP

Stos protokołów TCP/IP (ang. Transmission Control Protocol/Internet Protocol)

Komputery i Systemy Równoległe Jędrzej Ułasiewicz 1

Transkrypt:

Internet Control Message Protocol Aplikacja ping Zagadnienia: Protokół ICMP. Specyfikacja projektu ping. Specyfikacja struktur i funkcji programu. Struktura programu. dr Zbigniew Lipiński Instytut Matematyki i Informatyki ul. Oleska 48 50-204 Opole zlipinski@math.uni.opole.pl

Internet Control Message Protocol ICMP, ang. Internet Control Message Protocol. Protokół ICMP jest protokołem warstwy sieci modelu OSI. Protokół IP jest protokołem bezpołączeniowym, bez mechanizmów kontroli błędów. Protokół ICMP został opracowany do obsługi błędów w transmisji datagramów IP. Protokół ICMP wykorzystywany jest do: przesyłania informacji do nadawcy o błędach w transmisji, generowania pakietów do testowania sieci. 2

Internet Control Message Protocol Wiadomości ICMP są generowane gdy: datagram IP nie może być przesłany do odbiorcy ze względu na wartość pola TTL = 0 w nagłówku datagramu IP, przesyłane datgramy IP są zbyt duże dla danej sieci a datagram ma ustawioną opcję nie fragmentować, szybkość transmisji jest zbyt duża i odbiorca nie może odebrać nadchodzących pakietów, pole 'Window' w nagłówku segmentu TCP, odbiorca chce aby datagramy były przesyłane inna trasą, pole 'Opcje' w datagramie IP, błędna wartość w polu 'Header Checksum, np. z powodu uszkodzenia datagramu. 3

Wartości pola 'Typ wiadomości' w komunikacie ICMP Pole 'Type' 0 3 4 5 8 11 12 13 14 15 16 Opis pola Odpowiedz Echo Cel nieosiagalny (Destination Unreachable). Wygasniecie zrodla (Source Quench). Przekierowanie (Redirect). Zadanie Echo (Echo Request). Parametr TTL =0 (Time To Live Exceeded) Niewlasciwy parametr (Parameter Problem). Zadanie znacznika czasu (Timestamp). Odpowiedz ze znacznikiem czasu (Timestamp Reply). Zadanie informacji (Information Request). Odpowiedz z informacja (Information Reply). Wartosci pola 'Typ wiadomosci' 4

Struktura wiadomości ICMP typu 0, 8 Wiadomość: Echo request, Echo Reply. Pole: Typ = 8 (typ wiadomości: echo). 0 (typ wiadomości: echo reply). Pole: Kod = 0. Typ=8, 0 Identyfikator Kod=0 Suma kontr. Kolejny numer Dane Wiadomosci ICMP: Echo, Echo Reply Pole: Suma kontrolna. Pole: Identyfikator. Dla pola Kod = 0 pole służy do skojarzenia odpowiedzi z zapytaniem. Pole: Kolejny numer. Dla pola Kod = 0 pole służy do skojarzenia odpowiedzi z zapytaniem. Pole: Dane. Dane zawarte w wiadomości 'Echo' muszą być zwrócone w wiadomości 'Echo Replay'. Wiadomości: echo, echo reply (typ 8, 0) są używane do sprawdzania jakości łączy i stanu urządzeń w sieci. 5

Specyfikacja struktury ECHOREQUEST Nazwa struktury: ECHOREQUEST Opis : Struktura zawiera komunikat ICMP Echo Request typedef struct tagechorequest ICMPHDR icmphdr; DWORD dwtime; char cdata[req_datasize]; } ECHOREQUEST, *PECHOREQUEST; 6

Specyfikacja struktury ECHOREPLY Nazwa struktury : ECHOREPLY Opis : Struktura zawiera komunikat ICMP Echo Reply typedef struct tagechoreply IPHDR iphdr; ECHOREQUEST echorequest; char cfiller[256]; } ECHOREPLY, *PECHOREPLY; 7

Specyfikacja struktury IPHDR Nazwa struktury : IPHDR Opis : Struktura zawiera nagłówek datagramu IP, pole Protocol = 1. typedef struct tagiphdr u_char VIHL; // Pola: wersja protokolu IP, długość nagłówka (4 bity, 4 bity) u_char TOS; // Pole: Type of service (8 bitów) short TotLen; // Pole: Total length (8 bitów) short ID; // Pole: Identification (16 bitów) short FlagOff; // Pola: Flags, Fragment offset (3 bity, 13 bitow) u_char TTL; // Pole: Time-to-live (8 bitów) u_char Protocol; // Pole: Protocol, dla ICMP pole Protocol = 1, (8 bitów) u_short Checksum; // Pole: Checksum, (16 bitów) struct in_addr iasrc; // Pole: Internet address, source (32 bity) struct in_addr iadst; // Pole: Internet address, destination (32 bity) } IPHDR, *PIPHDR; 8

Specyfikacja struktury ICMPHDR Nazwa struktury : ICMPHDR Opis : Struktura zawiera nagłówek wiadomości ICMP echo request/reply. typedef struct tagicmphdr u_char Type; // Pole: Type, (8 bitów) u_char Code; // Pole: Code, (pole kod błędu powinno mieć wielkość 32 bitów) u_short Checksum; // Pole: Checksum, (16 bitów) u_short ID; // Pole: Identification, (8 bitów) u_short Seq; // Pole: Sequence, (8 bitów) // pola ID i Seq służą do kojarzenia pytań z odpowiedziami } ICMPHDR, *PICMPHDR; 9

Specyfikacja struktury sockaddr_in Nazwa struktury: sockaddr_in Opis : Zawiera adres IP i numer portu odbiorcy danych. Struktura zadeklarowana w pliku Winsock2.h (dla IPv4), ws2tcpip.h (dla IPv6). Atrybuty : short sin_family; unsigned short sin_port; struct in_addr sin_addr; char sin_zero[8]; sin_family sin_port sin_addr sin_zero Kod rodziny adresów TCP//IP (wartość musi być AF_INET). Numer portu (IP port). Adres IP odbiorcy. Pole służy do uzupełniania tak, aby wielkość struktury była taka sama jak SOCKADDR. Implementacja struktury sockaddr_in: struct sockaddr_in short sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; }; struct sockaddr_in6 short sin6_family; u_short sin6_port; u_long sin6_flowinfo; struct in6_addr sin6_addr; u_long sin6_scope_id; }; 10

Specyfikacja struktury in_addr Nazwa struktury : in_addr Opis : Struktura zdefiniowana w pliku WINSOCK.H 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; }; 11

Specyfikacja struktury fd_set Nazwa struktury: fd_set Opis : Struktura służy do tworzenia zbiorów gniazd. Struktura używana przez funkcje winsock np. funkcję select(). Struktura zadeklarowana w pliku Winsock2.h. Atrybuty : u_int fd_count; SOCKET fd_array[fd_setsize]; fd_count - Liczba gniazd w zbiorze. fd_array - Tablica gniazd. Implementacja struktury fd_set: typedef struct fd_set u_int fd_count; SOCKET fd_array[fd_setsize]; } fd_set; 12

Specyfikacja struktury timeval Nazwa struktury: timeval Opis : Struktura stosowana do określania wartości czasu. Struktura zadeklarowana w pliku time.h. Atrybuty : long tv_sec; long tv_usec; tv_sec - wartość czasu w sekundach. tv_usec - wartość czasu w mikrosekundach (mikro µ = 1 / 1.000.000). Implementacja struktury timeval: typedef struct timeval long tv_sec; long tv_usec; } timeval; 13

Specyfikacja funkcji GetTickCount() Nazwa funkcji : GetTickCount() Zwracana wartość: DWORD Zwarcaną wartością jest liczba milisekund od czasu uruchmienia systemu. Argumenty : brak Opis : Funkcja zwraca liczbę milisekund jak upłynęła od czasu uruchomienia systemu, maks. czas 49,7 dnia. Zwracane wartości ograniczone są rozdzielczością czasową systemu. Do uzyskania infomacji o rozdzielczości czasowej systemu należy użyć funkcji GetSystemTimeAdjustment(). Zwracana wartość jest przechowywana w zmienej DWORD (32-bit unsigned integer), dlatego po około 49,7 dniach ciągłej pracy systemu wartość jest liczona ponownie (zerowna). Funkcja zadeklarowana w plilku Winbase.h. Implementacja w pliku Kernel32.lib. Przykład: użycie funkcji GetTickCount(). #define TIMELIMIT = 774545841 DWORD dwstart = GetTickCount(); // zatrzymaj gdy działanie programu przekroczy czas TIMELIMIT if( GetTickCount() - dwstart >= TIMELIMIT ) Cancel(); 14

Specyfikacja funkcji select() Nazwa funkcji : select() Zwracana wartość: int Funkcja zwraca - liczbę uchwytów do gniazd (socket handles) które są w strukturze fd_set, - zero, gdy wygasł limit czasu lub - SOCKET_ERROR, gdy wystąpił błąd. Kody błędów: WSANOTINITIALISED, WSAEFAULT, WSAENETDOWN, WSAEINVAL, WSAEINTR, WSAEINPROGRESS, WSAENOTSOCK Argumenty : int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval* timeout nfds - Readfds - writefds - exceptfds - timeout - [in] Ignorowany. Parameter dodany dla zgodności z gniazdami Berkeley. [in-ot] Opcjonalny, wskaźnik do zbioru gniazd, do weryfikacji czy mają atrybut do czytania (readability). [in-out] Opcjonalny, wskaźnik do zbioru gniazd, do weryfikacji czy mają atrybut for zapisu (writability). [in-out] Opcjonalny, wskaźnik do zbioru gniazd, do weryfikacji czy są bez błędów. [in] Maksymalny czas oczekiwania pod warunkiem, że jest w formacie struktury TIMEVAL. Wartość parametru równa zero blokuje operacje. Opis : Funkcja select() określa status gniazd oczekujących na wykonanie synchronicznej operacji wejścia/wyjścia. 15

Specyfikacja funkcji Ping() int Ping(SOCKET raw, SOCKADDR_IN target_addr) DWORD start; struct timeval timeout; fd_set readfds; int sel; int rcv; //liczba wysłanych bajtów, sendto() if(sendechorequest(raw, &target_addr) == SOCKET_ERROR) cerr << "sendto() error no: " << WSAGetLastError() << endl; WSACleanup(); return 1; } start = GetTickCount(); do readfds.fd_count = 1; // struktura fd_set readfds.fd_array[0] = raw; // struktura fd_set timeout.tv_sec = 5; // struktura timeval timeout.tv_usec = 0; // struktura timeval if((sel = select(1, &readfds, NULL, NULL, &timeout)) == SOCKET_ERROR) cerr << "select() error no: " << WSAGetLastError() << endl; WSACleanup(); return 1; } if(sel == 0) cout << "uplynal czas oczekiwania na odpowiedz... " << endl; else if((rcv = RecvEchoReply(raw, start)) == SOCKET_ERROR) cerr << "recvfrom() error no: " << WSAGetLastError() << endl; WSACleanup(); return 1; } } while( rcv == 0 ); return 0; } 16

Specyfikacja funkcji in_cksum() Nazwa funkcji : in_cksum() Zwracana wartość: u_short Argumenty : u_short *addr, int len Opis : Funkcja wylicza sumę kontrolną tak, jak dla nagłówka datagramu IP, czyli zwracaną wartością jest liczba 16-bitowych słów w nagłówku datagramu IP (jeżeli wyliczona suma nie zajmuje 16 bitów wartość jest uzupełniana jedynkami). Przy obliczaniu sumy kontrolnej przyjmuje się, że pole Header Checksum zawiera same zera. u_short in_cksum(u_short *addr, int len) register int nleft = len; register u_short *w = addr; register u_short answer; register int sum = 0; } while( nleft > 1 ) sum += *w++; nleft -= 2; } if( nleft == 1 ) u_short u = 0; *(u_char *)(&u) = *(u_char *)w; sum += u; } // sum & 65535 (sum & 1111111111111111) sum = (sum >> 16) + (sum & 0xffff); sum += (sum >> 16); answer = ~sum; return (answer); 17

Specyfikacja funkcji SendEchoRequest() Nazwa funkcji : SendEchoRequest(); Zwracana wartość: int Argumenty : SOCKET, SOCKADDR_IN * Wartości arg : Funkcjonalność : Funkcja wysyła żądanie echa. int SendEchoRequest(SOCKET sock, SOCKADDR_IN * target_addr) static ECHOREQUEST echo_req; static int seq = 1; int rc; // liczba wysłanych bajtów echo_req.icmphdr.type = ICMP_ECHOREQ; // typ wiadomosci icmp, typy wiadomosci ICMP (RFC 792) echo_req.icmphdr.code = 0; // kod wiadomosci 0 echo_req.icmphdr.checksum = 0; // przed obliczniem sumy kontrolnej pole Checksum=0 echo_req.icmphdr.id = _getpid(); // proces id echo_req.icmphdr.seq = seq++; // kolejny numer memset(echo_req.cdata, '*', REQ_DATASIZE); echo_req.dwtime = GetTickCount(); echo_req.icmphdr.checksum = in_cksum((u_short *)&echo_req, sizeof(echorequest)); } rc = sendto(sock, (const char *)&echo_req, sizeof(echorequest), 0, (SOCKADDR *) target_addr, sizeof(sockaddr_in)); return (rc); 18

Specyfikacja funkcji RecvEchoReply() Nazwa funkcji : RecvEchoReply() Zwracana wartośc: int Argumenty : SOCKET, DWORD Opis : Funkcja odbiera komunikat Echo Reply. int RecvEchoReply(SOCKET sock, DWORD start) ECHOREPLY echo_reply; SOCKADDR_IN from_addr; int addrlen; int rc; // liczba wysłanych bajtów DWORD elapsed; addrlen = sizeof(struct sockaddr_in); rc = recvfrom(sock, (char *) &echo_reply, sizeof(echoreply), 0, (SOCKADDR *) &from_addr, &addrlen); if (rc == SOCKET_ERROR) return(rc); if (echo_reply.echorequest.icmphdr.id!= _getpid()) cout << "Brak odpowiedzi na zapytanie o ID: " << echo_reply.echorequest.icmphdr.id << endl; return 1; } elapsed = GetTickCount() - start; } if (echo_reply.echorequest.icmphdr.type!= ICMP_ECHOREPLY) cout << "Niewlasciwy typ odpowiedzi: "<< echo_reply.echorequest.icmphdr.type << endl; else cout << "Czas odpowiedzi: " << elapsed << " ms, (id= " << echo_reply.echorequest.icmphdr.id << ", seq= " << echo_reply.echorequest.icmphdr.seq << ") "<< endl; return 1; 19

Specyfikacja funkcji sendto() Nazwa funkcji : sendto() Zwracana wartość: Funkcja sento() zwraca całkowitą liczbę wysłanych bajtów. W pozostałych przypadkach zwracana jest wartość SOCKET_ERROR. Argumenty : SOCKET s, const char* buf, int len, int flags, const struct sockaddr* to, int tolen. s [in] Obiekt identyfikujący gniazdo. buf [in] Bufor na dane do wysłania. len [in] Długośc danych w buf, (liczona w bajtach). flags [in] Wskaźnik określający sposób wywołania funkcji. to [in] Argument opcjonalny, wskaźnik do struktury sockaddr zawierającej adres gniazda odbiorcy. tolen [in] Wielkość adresu w zmiennej to, (liczona w bajtach). Opis : Funkcja sendto() wysyła dane do konkretnego odbiorcy. Funkcja zadeklarowana w pliku: Winsock2.h. Implementacja w bibliotece: Ws2_32.lib. 20

Nazwa funkcji : recvfrom() Zwracana wartość: typ int, liczba odebranych bajtów Specyfikacja funkcji recvfrom() Argumenty : SOCKET s, char* buf, int len, int flags, struct sockaddr* from, int* fromlen s - [in] Obiekt identyfikujący połączone gniazdo (bound socket). buf - [out] Bufor na przychodzące dane. len - [in] Długość zmiennej buf (w bajtach). flags - [in] Wskaźnik określający sposób wywołania funkcji. Określa procesy OOB ( Out-of-Band Data ). MSG_PEEK Peeks at the incoming data. The data is copied into the buffer but is not removed from the input queue. The function subsequently returns the amount of data that can be read in a single call to the recvfrom (or recv) function, which may not be the same as the total amount of data queued on the socket. The amount of data that can actually be read in a single call to the recvfrom (or recv) function is limited to the data size written in the send or sendto function call. MSG_OOB. from - [out] Argument opcjonalny, wskaźnik do atrybutu struct in_addr sin_addr w strukturze SOCKADDR. fromlen - [in, out] Argument opcjonalny, wskaźnik do zmiennej przechowującej wielkość zmiennej from. Opis : Funkcja recvfrom() odbiera datagramy i przechowuje adres nadawcy. 21

Specyfikacja funkcji socket() Nazwa funkcji : socket() Zwracana wartość: SOCKET Jeżeli nie ma błędów, funkcja socket() zwraca referencje do nowego gniazda. W przeciwnym przypadku zwraca kod INVALID_SOCKET. Kod błędu można uzyskać przez wywołanie funkcji WSAGetLastError(). Argumenty : int af, int type, int protocol af - [in] Typ adresu stosu (address family specification). type - [in] Typ adresu dla nowych gniazd (SOCK_STREAM, SOCK_DGRAM). protocol- [in] Numer protokołu użytego przez gniazdo. Wartości parametruprotocol: IPPROTO_IP, IPPROTO_TCP, 0. Opis : Funkcja socket() tworzy gniazdo o określonym typie (specific service provider). Funkcja zadeklarowana w pliku winsock2.h, implementacja w pliku ws2_32.lib. 22

Specyfikacja funkcji _getpid() Nazwa funkcji : _getpid() Zwracana wartość: int Funkcja _getpid() zwraca identyfikator procesu (process ID). Argumenty : brak Opis : Funkcja zadeklarowana w pliku process.h 23

Surowe gniazda (typ gniazda SOCK_RAW) Obsługa gniazd typu SOCK_RAW nie jest wymagana. Odmiany gniazd typu SOCK_RAW: odmiana w której zakłada się, że znany jest typ protokołu zapisany w nagłówku datagramu IP. Przykładem takiego gniazda jest gniazdo ICMP. druga odmiana pozwala użyć dowolnego typ protokołu. Odmiana gniazda stosowana np. dla protokołów eksperymentalnych, gdy nie jest znana wartość pola typ protokołu w nagłówku datagramu IP. 24

Zasady użycia gniazd SOCK_RAW Wysyłany datagram może nie zawierać nagłówka IP jeżeli jest ustawiona opcja gniazda IP_HDRINCL. Do gniazda odbiorcy zawsze dociera datagram z nagłówkiem bez względu na to, czy jest ustawiona opcja gniazda IP_HDRINCL. Odebrane datagramy są kopiowane do wszystkich gniazd SOCK_RAW jeżeli spełniają następujące warunki: Numer protokołu określony dla gniazda jest zgodny z numerem w nagłówku przychodzącego datagramu IP. Jeżeli adres IP lokalnego hosta jest przypisany do gniazda to powinien być zgodny z adresem IP odbiorcy w nagłówku datagramu IP. Aplikacja może określić adres IP lokalnego hosta poprzez wywołanie funkcji bind(). Jeżeli żaden adres IP lokalnego hosta jest nie jest przypisany do gniazda to datagramy są zawsze kopiowane do gniazda (bez względu jaki adres jest w nagłówku datagramu IP). Jeżeli adres IP nadawcy jest przypisany do gniazda to powinien być zgodny z adresem IP nadawcy w nagłówku datagramu IP. Aplikacja może określić adres IP nadawcy poprzez wywołanie funkcji connect(). Jeżeli adres IP nadawcy jest nie jest przypisany do gniazda to datagramy są zawsze kopiowane do gniazda. Uwaga: Gniazda typu SOCK_RAW mogą odbierać przypadkowe, nieoczekiwane datagramy, np. aplikacja ping wysyła żądanie echa (datagram ICMP echo requests ), spodziewa się odebrać datagram ICMP echo response ale może odebrać inne datagramy np. ICMP HOST_UNREACHABLE. Jeżeli kilka gniazd typu SOCK_RAW jest otwartych na danym hoście to do wszystkich gniazd docierają takie same datagramy. Apliakcja powinna mieć mechanizm rozróżniania datagramów. 25

Specyfikacja projektu Nazwa projektu: ping2 Typ projektu : Win32 console application Lista plików : ping2.cpp, icmp.h Kompilacja : Microsoft Visual C++ 2008 Utworzyć projekt typu 'Win32 console application w menu (-)File-> New -> Project-> Other languages-> Visual C++ -> win32 -> Win32 console application -> wpisać nazwę: ping2 -> przycisk (OK) -> Okno Win32 application wizard ping2-> wybrać: Application settings -> wybrać: Empty project-> Przycisk (Finish). Konfiguracja projektu: (-)Project-> nazwa_projektu Properies... -> Configuration Properies-> Linker-> Input -> Additional Dependecies, wpisać: ws2_32.lib. Wkopiować pliki: icmp.h do katalogu projektu. Funkcjonalność: uruchomienie \> ping2 adres_ip_hosta 26

Specyfikacja projektu Pliki nagłówkowe: process.h, winsock2.h, iostream, "icmp.h" Funkcje programu: WSAStartup(), socket(), gethostbyname(), select(), sendto(), recvfrom(), _getpid() Ping(), SendEchoRequest(), RecvEchoReply(), GetTickCount(), in_cksum() 27

Specyfikacja projektu Zmienne programu: #define NUM_PINGS 10 // Liczba wyslanych zapytan Echo Request WSADATA WORD int SOCKET HOSTENT * SOCKADDR_IN int struct timeval fd_set wsadata; wversionrequested = MAKEWORD(2,2); rc; raw; host_ent; target_addr; count; timeout; readfds; static ECHOREQUEST echo_req; ECHOREPLY echo_reply; 28

Struktura programu (struktura funkcji main()) 1. Sprawdzenie poprawności argumentów programu. 2. Uruchomienie Winsock a rc = WSAStartup(wVersionRequested, &wsadata); 3. Sprawdzenie wersji Winsock Czy wsadata.wversion!= wversionrequested? 4. Utworzenie gniazda raw = socket(af_inet, SOCK_RAW, IPPROTO_ICMP); 5. Inicjowanie zmiennej adresem IP odbiorcy lub nazwą hosta target_addr.sin_addr.s_addr = inet_addr(argv[1]) 6. Gdy podano adres hosta host_ent = gethostbyname(argv[1]); 7. Przekazanie nazwy do obiektu target_addr: memcpy(&target_addr.sin_addr, host_ent->h_addr, host_ent->h_length); 29

Struktura programu (struktura funkcji main()) 8. Przekazanie wartości atrybutów obiektu target_addr target_addr.sin_family = AF_INET; target_addr.sin_port = 0; 9. Przekierowanie na ekran wiadomości: cout << "Pingowanie hosta: " << argv[1] << " (" << inet_ntoa(target_addr.sin_addr) << ") " << endl; 10. Wywołanie funkcji Ping() Ping(raw, target_addr); 11. Zamknięcie gniazda closesocket(raw); WSACleanup(); 30

#include <process.h> #include <winsock2.h> #include <iostream> #include "icmp.h" using namespace std; #define NUM_PINGS 10 // liczba wysłanych wiad. ICMP Echo Request int Ping(SOCKET, SOCKADDR_IN); u_short in_cksum(u_short *addr, int len); int SendEchoRequest(SOCKET, SOCKADDR_IN *); int RecvEchoReply(SOCKET, DWORD); 31

int main(int argc, char **argv) WSADATA wsadata; WORD wversionrequested = MAKEWORD(2,2); int rc; SOCKET raw; HOSTENT * host_ent; SOCKADDR_IN target_addr; int count; if (argc!= 2) cerr << "Wpisz: " << argv[0] << " hazwahosta" << endl; return 1; } if (rc = WSAStartup(wVersionRequested, &wsadata)) cerr << "WSAStartup() error no: " << rc << endl; if (wsadata.wversion!= wversionrequested) cerr << "WinSock version: " << LOBYTE(wVersionRequested) <<"." << HIBYTE(wVersionRequested) << " not supported" << endl; WSACleanup(); return 1; } 32

if ((raw = socket(af_inet, SOCK_RAW, IPPROTO_ICMP)) == SOCKET_ERROR) cerr << "socket() error no: " << WSAGetLastError() << endl; WSACleanup(); return 1; } if ((target_addr.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE) if (host_ent = gethostbyname(argv[1])) memcpy(&target_addr.sin_addr, host_ent->h_addr, host_ent->h_length); else cerr << "Nie znaleziono hosta " << argv[1] << " error no: " << WSAGetLastError() << endl; WSACleanup(); return 1; } } target_addr.sin_family = AF_INET; target_addr.sin_port = 0; cout << "Pingowanie hosta: " << argv[1] << " ("<< inet_ntoa(target_addr.sin_addr) << ") "<< endl; for (count = 0; count < NUM_PINGS; ++count) Ping(raw, target_addr); closesocket(raw); WSACleanup(); return 0; } 33

Specyfikacja funkcji setsockopt() (aplikacja tracert) Nazwa funkcji : setsockopt() Zwracana wartość: int setsockopt() 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 funkcji WSAGetLastError(): Argumenty : SOCKET s, int level, int optname, const char* optval, int optlen s [in] identyfikator gniazda. level [in] nazwa poziomu opcji (SOL_SOCKET, IPPROTO_TCP). SOL_SOCKET: SO_ACCEPTCONN, SO_BROADCAST, SO_CONDITIONAL_ACCEPT,SO_CONNDATA, SO_CONNDATALEN, SO_CONNECT_TIME, SO_CONNOPT, SO_CONNOPTLEN, SO_DISCDATA, SO_DISCDATALEN, SO_DISCOPT, SO_DISCOPTLEN, SO_DEBUG, SO_DONTLINGER, SO_DONTROUTE, SO_ERROR, SO_EXCLUSIVEADDRUSE, SO_GROUP_ID, SO_GROUP_PRIORITY, SO_KEEPALIVE, SO_LINGER, SO_MAX_MSG_SIZE, SO_MAXDG, SO_MAXPATHDG, SO_OOBINLINE, SO_OPENTYPE, SO_PROTECT, SO_PROTOCOL_INFO, SO_PROTOCOL_INFOA, SO_PROTOCOL_INFOW,SO_RCVBUF, SO_RCVLOWAT, SO_RCVTIMEO, SO_REUSEADDR, SO_SNDBUF, SO_SNDLOWAT, SO_SNDTIMEO, SO_SYNCHRONOUS_ALERT, SO_SYNCHRONOUS_NONALERT, SO_TYPE, SO_UPDATE_ACCEPT_CONTEXT, SO_UPDATE_CONNECT_CONTEXT, SO_USELOOPBACK. IPPROTO_TCP: TCP_EXPEDITED_1122, TCP_NODELAY. IPPROTO_IP: IP_ADD_MEMBERSHIP, IP_ADD_SOURCE_MEMBERSHIP, IP_BLOCK_SOURCE, IP_DONTFRAGMENT, IP_DROP_MEMBERSHIP, IP_DROP_SOURCE_MEMBERSHIP, IP_HDRINCL,IP_MULTICAST_IF, IP_MULTICAST_LOOP, IP_MULTICAST_TTL, IP_OPTIONS, IP_PKTINFO,IP_RECEIVE_BROADCAST,IP_TOS, IP_TTL, IP_UNBLOCK_SOURCE. optname [in] nazwa opcji, wartość poziomu opcji. optval [in] wskaźnik do zmiennej która przechowuje dane o opcji. optlen [in] wielkość zmiennej która przechowuje dane o opcji. Opis : Funkcja służy do ustawiania opcji gniazd. Funkcja zadeklarowana w pliku Winbase.h. Implementacja w pliku ws2_32.lib. Note If the setsockopt function is called before the bind function, TCP/IP options will not be checked with TCP/IP until the bind occurs. In this case, the setsockopt function call will always succeed, but the bind function call may fail because of an early setsockopt failing. Note If a socket is opened, a setsockopt call is made, and then a sendto call is made, Windows Sockets performs an implicit bind function call. 34