3. Das ICMP Protokoll
Auf das schon oben erwähnte ICMP Protokoll soll hier näher eingangen werden. Das Internet Protocol (IP) wird für Host zu Host Kommunikation in einem System von zusammengeschloßenen Netzwerken (zum Beispiel das Internet), Catenet genannt (siehe IEN 4
, genutzt. Die Elemente, die zwei Netzwerke dieses Systems verbinden, werden Gateway genannt, diese kommunizieren wegen Kontrollfragen über das Gateway-to-Gateway Protocol (GGC). Gateway kann jeder Computer sein, der an zwei Netzwerke angeschloßen ist, da das ICMP schon im Kernel aller netzwerktauglichen Betriebssysteme implementiert ist und auch nicht abgeschaltet werden kann. Eine Ausnahme bilden hier Firewalls, welche die ICMP Pakete abblocken, bevor diese zum Kernel gelangen. Kommt es jedoch zu einem Fehler, der einen Host betrifft, wie zum Beispiel "Host Unreachable", würde es wenig Sinn machen, den zum fehlerverursachenden Host nächsten Gateway zu benachrichtigen. Für solche Gateway zu Host Verbindungen wurde das Internet Control Message Protocol (ICMP) eingeführt. Mittels des ICMP können auch zwei Hosts miteinander kommunizieren, um zum Beispiel die Verbindungsgeschwindigkeit festzustellen ("Ping"). Jedoch wurde das ICMP nicht entwickelt, um zuverläßig Daten zu übermitteln, vielmehr um ein Feedback zu liefern. Damit ein Host nicht mit Fehlermeldungen überhäuft wird, werden keine Statusmeldungen über ICMP Pakete gesendet. Weiterhin werden ICMP Pakete nur für das nullte Fragment eines Datagramms gesendet (betrf. Fragmentierung von Datagrammen, siehe RFC 791).
Das ICMP baut sich aus einem IP Header und einem Direkt folgendem ICMP Header auf. Der Protocol Wert des IP Header wird auf 1 für ICMP gesetzt, sonst gibt es an diesen IP Header nichts besonderes. Der darauf folgende ICMP Header baut sich wie folgt auf:
|
Quellcode
|
1
2
3
4
5
6
7
8
9
|
typedef struct
{
unsigned char ucType // ICMP Message Typ
unsigned char ucCode // Message Interner (Fehler-)Code
unsigned short usCheckSum // Checksum für das ICMP Paket
unsigned short usID // ID des Pakets, oft wie Port bei TCP / UDP genutzt
unsigned short usSequence // Sequenznummer, bei mehreren typgleichen, (sinn-)zusammenhängenden Paketen
unsigned long ulTimeStamp // Zeitstempel beim Abesenden
} icmp_header_t;
|
Die sogenannte Checksum ist ein Wert der zur Fehlerfeststellung innerhalb eines Datagramms fungiert. Er wird erstellt, in dem man das zu versendende Datagramm erstellt und die Checksum auf null stellt. Nun kann die eigentliche Checksum berrechnet werden, indem man als erstes einen unsigned short erstellt und in einem Schleiffendurchlauf mit dem aktuellen Wert des Puffers addiert. Nun wird der Zeiger auf den Puffer incrementiert. Wenn die Länge des Puffer ungerade ist (d.h. aus dem letztem byte kann kein short gebildet werden), wird eine 0 ans Ende angefügt. Am Ende wird sie mit ihrem 16-Bit Wert addiert. Da dies ein wenig schwierig ist zu verstehene, hier das ganze als Funktion. Das Wissen des berrechnens der Checksum ist nicht elementar, d.h. folgender Code kann einfach übernommen werden:
|
C-/C++-Quelltext
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
unsigned short Checksum(unsigned short *p_usBuffer, int iSize)
{
unsigned long lCheckSum = 0;
while(iSize > 1)
{
lCheckSum += *p_usBuffer++;
iSize -= sizeof(unsigned short);
}
if(iSize)
lCheckSum += *(unsigned char*)p_usBuffer; // + 0 entfällt, da überflüßig
lCheckSum = ((lCheckSum >> 16) + (lChecksum & ffff)) + (lCheckSum >> 16);
return (unsigned short)(~lCheckSum);
}
|
Hier nun eine Liste der Nachrichten die ICMP unterstüzt:
a. Echo Request
ucType: 8, ucCode: 0
Die Echo Request Nachricht wird an einen anderen Host oder Gateway gesendet, damit dieser die angehängten Daten unveräandert zurücksendet. Dies wird genutzt um einen Computer zu "pingen", d.h. die Zeit zu ermitteln, die ein Paket bestimmter größe zum Ziel-Host braucht. Nach dem Header folgen die Daten die zurückgesendet werden sollen.
Um beispielsweise einen Computer mit einem 32 byte großen Datenpaket zu pingen, sendet man den Header plus 32 - 12 (größe des ICMP Headers) = 20 byte beliebigen Daten. Ausgewertet wird die Zeit, indem man die Milisekunden vom Absenden des Packets bis zur Antwort misst. Von der Verwendung des Timestamp Feldes der ICMP Header ist dringend abzuraten, da dieses von der Systemzeit des Ziel-Host abhängig ist. Folgendes Beispiel: Ein User in Berlin / Deutschland pingt einen Computer in Shanghai / China. Die Differenz von Timestamp und Systemzeit ist negativ, da man in China mit der Zeit "in der Zukunft ist", das ganze wird jedoch mit unsigned longs berrechnet. Das hat zur Folge das eine Ping-Zeit von bis zu mehreren Jahren errechnet werden kann.