The ICMP protocol (which must always be viewed in conjunction with IPv4) enables you to test whether a data packet reaches an end system (host) and whether it is acknowledged. A detailed description of ICMP is provided in RFC 792.
Please note the following two special features in the format of the protocol and of the data:
The ICMP header checksum must be generated by the application.
The socket’s port number is expected as the identifier. Before sending the message, you should therefore execute a bind() on the raw socket.
Before you call the bind() function to reserve a port, you must enable the delivery of possible ICMP error messages for this socket (see section "getsockopt(), setsockopt() - get and set socket options"):
setsockopt(...,IPPROTO_IPV4, IP_RECVERR,...,...)
The ICMP header is four bytes long. The length of the following data is variable. The following applies for the ECHO-REQUEST and ECHO-REPLY types: The first word contains the identifier (port number) and the sequence number. The next two words contain a timestamp. The time is contained in seconds in the first word and in microseconds in the second word:
00 | Type | Code | Checksum |
04 | Identifier | Sequence# | |
08 | Data (Timestamp struct timeval/tv_s) | ||
0C | Data (Timestamp struct timeval/tv_us) | ||
10 | Data (Testpattern) | ||
14 | Data (Testpattern) |
The associated IPv4 header is generated by the transport system. However, the application has the option of determining the hop limit. For this purpose you must set the raw socket appropriately before you send the data packet (ICMP message).
To set the hop limit specifically, use the function setsockopt(..., IPPROTO_ICMP, IP_TTL,...,...) (see section "getsockopt(), setsockopt() - get and set socket options").
The ICMP echo request message is sent using sendmsg(). The end system’s response is received as an ICMP echo reply message using recvmsg().