Comment faire un ping avec les sockets C

  • Compilateur: Code :: Blocs (GNU GCC)
  • Plate-forme: Windows (x86)
  • Comprend: winsock.h winsock2.h (ws2_32 est également lié)

Je suis en train d’essayer d’écrire un programme qui lira un fichier texte contenant une liste d’adresses IP et envoie une requête ping à chaque adresse IP, respectivement. Si l’hôte répond au ping, l’adresse IP de l’hôte sera copiée dans un fichier secondé par l’utilisateur. Ce n’est pas le cas, c’est la première fois que j’utilise la bibliothèque de socket de C et que je ne trouve pas un bon tutoriel sur la manière de faire un ping avec C. J’ai besoin d’inclure un en-tête ICMP, qui est une structure contenant le type ICMP, le code et la sum de contrôle, dans un datagramme IP. Mais je ne sais pas comment procéder, dois-je déclarer la structure moi-même ou est-elle déclarée dans un fichier d’en-tête? Je suppose que c’est dans un en-tête mais les tutoriels se contredisent exactement sur l’endroit où il est déclaré. Je me suis fatigué, y compris icmp.h et netinet / icmp.h mais mon compilateur s’est plaint qu’ils n’existent pas alors j’ai créé ma propre structure.

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 }; 

J’ai pensé que je pourrais peut-être m’en sortir mais je n’ai même pas pu comstackr mon programme car mon compilateur dit que in_cksum () (générateur de sum de contrôle) n’est pas défini.

Pour résumer mes questions, quels fichiers en-tête dois-je inclure, comment créer un paquet ping, est-ce que j’utilise la fonction correcte de générateur de sum, si un ping doit être dirigé vers le port 80?

C’est ce que j’ai fait jusqu’à présent, veuillez noter que j’ai volontairement omis de vérifier les erreurs.

  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)); 

Si vous n’avez pas à implémenter le ping à partir de zéro et que vous ne voulez que la solution Windows, je suggèrerais en second lieu Anton pour IcmpSendEcho. Si vous devez implémenter une commande ping, regardez comment le package ICMP de POCO est implémenté. C’est un code portable et il fonctionne correctement sous Windows.

En ce qui concerne les questions spécifiques, voici les réponses:

quels fichiers d’en-tête dois-je inclure

 #include  

comment créer un paquet de ping

Voir ICMPv4PacketImpl :: initPacket () pour un exemple de paquet IPv4.

suis-je en train d’utiliser la fonction correcte du générateur de sum de contrôle

Pas pour les fenêtres. Voir ICMPPacketImpl :: checksum () pour un exemple de fonction de sum de contrôle.

si un ping doit être dirigé vers le port 80

Non, il n’y a pas de port en ce qui concerne ICMP. Voir ICMP utilise-t – il un port spécifique?

si le socket que j’utilise est RAW ou DGRAM

Ce devrait être RAW.

Il semble que vous vouliez une vraie solution, et pas seulement la réimplémentation de PING pour le plaisir.

Je recommande d’utiliser l’aide IP (ICMP.dll sur les systèmes pré-WinXP), en particulier IcmpSendEcho (ou ses versions améliorées, IcmpSendEcho2 , IcmpSendEcho2Ex , pour les opérations asynchrones).

Il existe un exemple complet de “ping” d’un hôte sur MSDN. Cela peut être un bon sharepoint départ.

Mise à jour: pour GCC (mingw), lien avec -liphlpapi.