2013-01-13 11 views
6
  • Compiler: Code :: Blocks (GNU GCC)
  • Platforma: Windows (x86)
  • Zawiera: winsock.h winsock2.h (ws2_32 jest związana również)

Obecnie próbuję napisać program, który odczyta plik tekstowy zawierający listę adresów IP i pinguje każdy adres IP, odpowiednio. Jeśli host odpowie na polecenie ping, adres IP hosta zostanie skopiowany do drugiego pliku określonego przez użytkownika. Niestety, po raz pierwszy użyłem biblioteki gniazd C i nie mogę znaleźć dobrego tutoriala o tym, jak pingować przy użyciu C. Z tego, co rozumiem w tutorialach dla par, znalazłem. Muszę dołączyć nagłówek ICMP, który jest strukturą zawierającą typ ICMP, kod i sumę kontrolną w datagramie IP. Ale nie mam pojęcia, jak to zrobić, czy powinienem zadeklarować samą strukturę, czy jest ona zadeklarowana w pliku nagłówkowym? Zakładam, że jest w nagłówku, ale samouczki przeczyły sobie nawzajem dokładnie, gdzie jest zadeklarowane. Byłem zmęczony, włączając w to icmp.h i netinet/icmp.h, ale mój kompilator narzekał, że nie istnieją, więc stworzyłem własną strukturę.Jak Ping Korzystanie Sockets Library - C

struct echo_request 
    { 
     char type; // Type 
     char code; // Code 
     short checksum; // Checksum 
     short id; // Identification 
     short seq; // Sequence 
     int time; // Time 
     char data[16]; // Data 
    }; 

Myślałem, że mogę być w stanie uciec z nim, ale nie byłem nawet w stanie skompilować mój program, bo mój kompilator mówi, że in_cksum() (generator suma kontrolna) jest niezdefiniowane.

Podsumowując moje pytania, jakie pliki nagłówkowe należy dołączyć, jak utworzyć pakiet ping, czy używam poprawnej funkcji generatora sum kontrolnych, czy ping powinien być przekierowany do portu 80, a gniazdo, którego używam, powinno być RAW lub DGRAM?

To, co do tej pory miałem, proszę zauważyć, że celowo pominąłem sprawdzanie błędów.

int socket_descriptor = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 

    struct sockaddr_in address; //Initialize address struct 
    memset(&address, 0, sizeof(address)); //Clear address struct 

    //Declare address 
    address.sin_family = AF_INET; 
    address.sin_addr.s_addr = inet_addr(ipaddress); 
    address.sin_port = htons(80); 

    //Bind socket to address 
    bind(socket_descriptor, (struct sockaddr *)&address, sizeof(address)); 

    //Create packet 
    struct echo_request packet; //See above for declaration of struct 
    memset(packet.data, 1, 16); 
    packet.type = 8; //ECHO_REQUEST 
    packet.code = 0; 
    packet.time = gettime(); 
    packet.checksum = 0; 
    packet.checksum = in_cksum(packet, sizeof(packet)); 
+0

1) struktura musi być spakowana, upewnij się, że kompilator nie wyrównuje pól 2) Czy system Windows obsługuje dobrze gniazda źródłowe (tego nie wiem)? –

Odpowiedz

3

Jeśli nie musisz implementować polecenia ping od zera, a chcesz mieć tylko rozwiązanie dla systemu Windows, to zająłbym się sugestią Antona dla IcmpSendEcho. Jeśli musisz zaimplementować ping, spójrz, jak implementowany jest pakiet ICMP POCO. Jest to przenośny kod i działa dobrze w systemie Windows.

W odniesieniu do konkretnych pytań, oto odpowiedzi:

jakie pliki Nagłówek powinien zawierać

#include <winsock2.h> 

Jak mogę stworzyć pakiet ping

Zobacz przykład ICMPv4PacketImpl::initPacket() dla przykładu adresu IPv4 cket.

używam prawidłową funkcję generatora kontrolna

Nie dla okien. Zobacz ICMPPacketImpl::checksum() dla przykładu funkcji sumy kontrolnej.

powinien ping być kierowane do portu 80

No. Nie ma czegoś takiego jak portu, jeśli chodzi o ICMP. Zobacz Does ICMP use a specific port?

powinno gniazdo używam być surowe lub dgram

Należy RAW.

+0

Dziękuję za bardzo pouczającą i pomocną odpowiedź. –

2

Wygląda na to, że potrzebujesz prawdziwego rozwiązania, a nie tylko reimplementacji PING ze względu na to.

Polecam przy użyciu pomocnika IP (ICMP.dll na pre-WinXP systemów), w szczególności, IcmpSendEcho (lub jego ulepszone wersje, IcmpSendEcho2, IcmpSendEcho2Ex, dla operacji asynchronicznych).

Istnieje pełny przykład "pingowania" hosta w witrynie MSDN. To może być dobry punkt wyjścia.

Aktualizacja: dla GCC (mingw), link z opcją -liphlpapi.

+0

Dziękuję za odpowiedź. Jestem świadomy IcmpSendEcho, ale chcę wdrożyć stosunkowo przenośne rozwiązanie. –