How to use Ping using the Sockets - C library

  • Compiler: Code :: Blocks (GNU GCC)
  • Platform: Windows (x86)
  • Includes: winsock.h winsock2.h (ws2_32 is also related)

I'm currently trying to write a program that will read a text file containing a list of IP addresses and ping each IP address accordingly. If the host responds to ping, then the host's IP address will be copied to the forged file specified by the user. This is directly the first time I have used the C socket library, and I cannot find a good tutorial on how to ping using C. From what I understand from the training folders that I found. I need to include the ICMP header, which is a structure containing the ICMP type, code, and checksum in the IP datagram. But I do not know how to do this, should I declare the structure myself or declared in the header file? I assume it is in the title, but the textbooks contradict each other about where exactly it is announced. I was tired, including icmp.h and netinet / icmp.h, but my compiler complained that they did not exist, so I created my own 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 }; 

I thought I could succeed, but I couldn’t even compile my program because my compiler says that in_cksum () (checksum generator) is undefined.

Summing up my questions, what kind of header files should I include, how to create a ping package, do I use the correct checksum generator function if ping should be directed to port 80, and if the socket I use is RAW or DGRAM?

This is what I have so far, please note that I specifically missed error checking.

  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)); 
+7
source share
2 answers

If you do not need to ping from scratch, and you only want a solution for Windows, I would prefer Anton’s second suggestion for IcmpSendEcho. If you need to implement ping, see how POCO implements the ICMP packet. This is portable code, and it works great on Windows.

For specific questions, here are the answers:

what header files should be included

 #include <winsock2.h> 

how to create a ping package

See ICMPv4PacketImpl :: initPacket () for an example IPv4 packet.

I am using the correct checksum generator function

Not for windows. See ICMPPacketImpl :: checksum () for an example of a checksum function.

if ping should be directed to port 80

No. There is no such thing as a port in ICMP. See Does ICMP use a specific port?

if the socket I'm using is RAW or DGRAM

It must be RAW.

+4
source

It sounds like you want to find a real solution, not just override PING for it.

I recommend using the IP Assistant (ICMP.dll on pre-WinXP systems), in particular IcmpSendEcho (or its extended versions, IcmpSendEcho2 , IcmpSendEcho2Ex , for asynchronous operations).

There is a complete example of pinging a host on MSDN. This could be a good starting point.

Update: for GCC (mingw), link to -liphlpapi.

+2
source

Source: https://habr.com/ru/post/987609/


All Articles