Das Protokoll ICMP (das immer im Zusammenhang mit IPv4 zu sehen ist) bietet die Möglichkeit, zu testen, ob ein Datenpaket ein Endsystem (Host) erreicht, und ob es quittiert wird. Eine detaillierte Beschreibung des ICMP entnehmen Sie dem RFC 792.
Beachten Sie beim Aufbau des Protokolls und der Daten folgende zwei Besonderheiten:
Die ICMP-Header-Checksum muss von der Anwendung generiert werden.
Als Identifier wird die Portnummer des Socket erwartet. Führen Sie daher vor dem Senden der Nachricht einen bind() auf den Raw-Socket aus.
Bevor Sie die bind()-Funktion aufrufen, um einen Port zu reservieren, müssen Sie für diesen Socket die Zustellung von möglichen ICMP-Fehlermeldungen aktivieren (siehe Abschnitt "getsockopt(), setsockopt() - Socket-Optionen abfragen und ändern"ff):
setsockopt(...,IPPROTO_IPV4, IP_RECVERR,...,...)
Der ICMP-Header hat eine Länge von 4 Byte. Die Länge der folgenden Daten ist variabel. Beim Type ECHO-REQUEST und ECHO-REPLY gilt: Das erste Wort enthält den Identifier (Portnummer) und die Sequence-Nummer. Die nächsten zwei Worte enthalten einen Zeitstempel. Im ersten Wort ist die Zeit in Sekunden, im zweiten Wort in Mikrosekunden abgelegt:
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) |
Der dazugehörige IPv4-Header wird vom Transportsystem generiert. Die Anwendung hat jedoch die Möglichkeit, das Hop-Limit zu bestimmen. Dazu müssen Sie den Raw-Socket entsprechend einstellen, bevor Sie das Datenpaket (ICMP-Nachricht) senden.
Um das Hop-Limit gezielt einzustellen, verwenden Sie die Funktion setsockopt(..., IPPROTO_ICMP, IP_TTL,...,...) (siehe Abschnitt "getsockopt(), setsockopt() - Socket-Optionen abfragen und ändern"ff).
Die ICMP-Echo-Request-Nachricht wird mit sendmsg() gesendet. Die Antwort des Endsystems wird als ICMP-Echo-Reply-Nachricht mit recvmsg() empfangen.