Home | Artikel | LUGS Internet Protokoll

LUGS Vortrag vom 1996.12.05 - IP - Internet Protocol

Wozu Internet Protocol?

An ein globales Netz werden verschiedene, einander widersprechende, Anforderungen gestellt: hohe Geschwindigkeit, grosse Distanz, geringe Kosten, Rückwärtskompatibilität, Benutzerautonomie. Das kann, insbesonders im Anblick des technischen Fortschritts, der dauernd neue Angebote bringt, nur mit einem Gemisch aus verschiedenen Technologien erreicht werden.

Benützer wollen aber nicht, sich mit mehreren verschiedenen Systemen herumschlagen, geschweige denn wissen müssen, welche Leitung von wo nach wo mit welchem System ausgerüstet ist.

Als einzige gangbare Lösung müssen daher alle Leitungen als ein einzelnes virtuelles Netz (mit variablen Leistungsmerkmalen in den Teilsegmenten) behandelt werden, als ein internet (mit kleinem i). Vermittlerrechner (früher Gateways genannt, heute üblicherweise Router) zwischen den Leitungen reichen die Daten weiter, bis sie beim Empfänger ankommen.

Das grösste bisher konstruierte internet ist das Internet (grosses I), ausgehend vom ARPA (Advanced Research Projects Agency) und später dem NSF (National Science Foundation) der USA, basierend auf dem Internet Protocol (IP) Verfahren.

Wie funktioniert das IP Verfahren?

Genauso wie beliebige Ein-/Ausgabe Gerate (z.B. Console, RS-232) unter Unix als einheitliche Characterströme (tty0, ttyS0) representiert werden und die Details im jeweiligen Treiber versteckt werden, werden beliebige Leitungen (z.B. Ethernet, SLIP) als einheitliche Datenpaketübertrager (eth0, slip0) representiert und die Details im jeweiligen Treiber versteckt.

Ungleich Characterströmen haben (fast) alle Netzwerke Adressen, da ja mehrere Machinen erreicht werden können und man den Empfänger von den anderen unterscheiden muss. Dafür gibt es ebenfalls ein einheitliches Adressierungsformat. Jeder Anschluss jeder Maschine an jede Leitung bekommt eine weltweit einmalige Nummer (ihre IP Adresse) zugewiesen (z.B. 10.0.3.2 für meinen LUGS Ethernet Anschluss). Diese Nummern sind 32 Bit lang, der Bereich geht also von 0.0.0.0 bis 255.255.255.255, da die Nummern gemäss Konvention als 4 mal 8 Bit geschrieben werden. Wenn eine Maschine mehrere Anschlüsse an verschiedene Leitungen hat hat jeder dieser Anschlüsse eine eigene IP Adresse (z.B 193.72.192.35 mein SLIP Anschluss).

Um diese Adressen einzustellen (und anzuschauen) wird der ifconfig Befehl benutzt (üblicherweise von /etc/rc.d/rc.inet1 aufgerufen):

IPADDR="10.0.3.2"
NETMASK="255.0.0.0"
BROADCAST="10.255.255.255"
/sbin/ifconfig eth0 ${IPADDR} broadcast ${BROADCAST} netmask ${NETMASK}
Dabei bedeuten: Hier der ifconfig Ausdruck meiner Machine nach obigem:
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Bcast:127.255.255.255  Mask:255.0.0.0
          UP BROADCAST LOOPBACK RUNNING  MTU:2000  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0
          TX packets:199 errors:0 dropped:0 overruns:0

eth0      Link encap:10Mbps Ethernet  HWaddr 08:00:2B:1D:74:30
          inet addr:10.0.3.2  Bcast:10.255.255.255  Mask:255.0.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0
          TX packets:0 errors:0 dropped:0 overruns:0
          Interrupt:5 Base address:0x300 

Wie kommen die IP Pakete ans Ziel?

Nachdem alle Leitungen identisch geworden sind muss nun für die automatische Weiterreichung der Daten über mehrere Leitungen bis zum Empfängerrechner gesorgt werden.

Dazu werden die Datenpakete vom Absender mit der Empfängeradresse (genauer: die IP Adresse eines beliebigen Anschlusses der Empfängermaschine) versehen. Damit die Adressen (und noch etwas mehr Verwaltungskram) in das Datenpaket hinein können, ohne die Daten zu zerstören, wird vor den Daten ein Verwaltungsblock angefügt, der IP Header, formatiert nach den Regeln des Internet Protocols (IP).

Damit ein Rechner weiss an welchen eigener Anschlüsse und auf dessen Leitung an welchen anderen Anschluss er ein Datenpaket verschicken soll, muss er die Empfängeradresse analysieren. Um Arbeit zu sparen wurde festgelegt, dass alle Anschlüsse an einer Leitung in den ersten N Bits der Adresse identisch sein müssen (daher also die ganze Netmask Geschichte). Der Test zum Verschicken ist daher einfach:

Um dies einzustellen (und anzuschauen) wird der route Befehl benutzt (üblicherweise von /etc/rc.d/rc.inet1 aufgerufen):
NETWORK="10.0.0.0"
/sbin/route add -net ${NETWORK} netmask ${NETMASK}
GATEWAY="10.0.0.1" /sbin/route add default gw ${GATEWAY} metric 1 Dabei bedeuten: Hier der route Ausdruck meiner Machine nach obigem:
Kernel routing table
Destination     Gateway         Genmask         Flags MSS    Window Use Iface
loopback        *               255.0.0.0       U     1936   0      539 lo
10.0.0.0        *               255.0.0.0       U     1436   0        0 eth0

Wie kommen die Daten an?

Bisher haben wir stillschweigend angenommen, dass die Daten nach ihrer Ankunft im Empfängerrechner automatisch ausgeliefert werden. Doch dem ist nicht so! Zur Errinnerung: die Adressen gehören den Anschlüssen, nicht den Maschinen. Meine Maschine hat zwar die Anschlüsse 10.0.3.2 und 193.72.192.35, sie ist nicht selber die Maschine mit einer dieser Adressen. Sie hat wie alle anderen Maschinen gar keine Adresse! Das normale Verhalten mit einem Datempaket würde nun darin bestehen, es wieder an die Herkunftsleitung (zu der passt ja die Adresse) zu senden! Da das Paket den eigenen Anschluss als Ziel hat kommt es sofort zurück, das selbige nochmals von vorne, endlos hin und her!

Um die Daten auszuliefern muss der Routing Vorgang ausgetrickst werden. Dazu wird ein zusätzlicher Pseudo-Anschluss für einen "Auslieferer" gemacht, lo, der Localhost. Diesem wird mit ifconfig gemäss Konvention die Adresse 127.0.0.1 zugeordnet:

/sbin/ifconfig lo 127.0.0.1
Und der dazugehörige route Eintrag:
/sbin/route add -net 127.0.0.0
Damit nun die beim Rechner ankommenden Daten an Localhost weitergeleitet werden (und damit ausgeliefert werden) müssen auch alle Adressen der eigenen Anschlüsse auf Localhost umgebogen werden. Für meine Maschine am LUGS Ethernet heisst das: 10.x.y.z ans Ethernet aber mit der Ausnahme von 10.0.3.2, das umleiten an Localhost.

In den meisten IP Implementationen (z.B. mein alter NeXT) muss diese Umleitung explizit mit route Befehlen gemacht werden, in Linux aber geschieht dies implizit (und ohne dass route dies anzeigt!). Das Ergebnis davon ist, dass Linux User, die auf einer anderen Maschine IP zu konfigurieren versuchen auf die Nase fallen, z.B. Paul mit dem KA9Q DOS IP.

Was ist wenn meine IP Pakete zu gross für die Leitung sind?

Bisher haben wir stillschweigend angenommen, dass IP Pakete immer in ein Leitungspaket passen. Dafür hat der Leitungstreiber zu sorgen. Bloss: Ethernet erträgt maximal 1500 Bytes pro Paket, X.25 erträgt sogar nur ganze 128 Bytes. Diese maximale Grösse eines Leitungspaketes ist als die Maximal Transfer Unit (MTU) der Leitung bekannt.

IP Pakete kaönnen aber bis zu 64kByte (inclusive Header) gross sein (z.B. sendet NFS Pakete von 8kByte). Daher müssen IP Pakete in mehrere Leitungspakete zerlegt werden, das nennt man Fragmentierung. Dazu hat der IP Header mehrere Felder zum Ausfüllen:

Kann ein Paket nicht richtig Zusammengesetzt werden (z.B. ein Fragment fehlt) wird das ganze Paket fortgeworfen.

In der letzen Zeit war von einem Security Bug im ping die Rede. Dieser hatte aber gar nichts mit dem Ping Befehl zu tun! Der Fehler lag vielmehr beim Defragmenter! Dieser hatte die fatale Eigenschaft IP Pakete mit vielen Fragmenten die zusammen grösser als 64k sind zu akzeptieren, diese wurden beim zusammensetzten grösser als der reservierte Platz und überschrieben dabei einen Teil des Kernals, Folge: Absturz. Zu dem Namen ping Bug kam das ganze weil der ping in Windows95 dazu gebraucht werden kann solche ungültigen Pakete zu generieren (genauer 64k ohne Header). Aber richtig sollte man Security Bugs nach dem defekten Program benennen, nicht dem Angriffswerkzeug.

Was geschieht mit meinen Daten beim Empfänger?

Datenpakete von einem Rechner zum anderen zu bringen ist erst der Anfang einer erfolgreichen Kommunikation. Dort müssen sie auch an das richtige Programm (z.B. DNS oder NFS Server) ausgeliefert werden. Und es sollte (mehrere mögliche Client-Programme vorausgesetzt) zwischen diesen unterscheiden können (wegen der Antwort zurücksenden).

Dazu wird an beiden Enden der Verbindung eine Port vergeben. Das sind 16 bit Nummern, also im Bereich 0..65535. Damit dies Portnummern übertragen werden können wird vor dem eigentlichen Datenpaket (aber nach dem IP Header) ein zusätzlicher Header eingeführt, dieser wird formatiert nach den Regeln des User Datagram Protocol (UDP).

Will ein Client-Program eine Verbindung zu einem Server-Program haben bezieht es vom Kernal einen zufälligen UDP Port im Bereich 1024..65535. Will ein Server-Program sich anbieten bezieht es beim Kernal den für seinen spezifischen Servertyp festgelegten Port im Bereich 0..1023. Die Liste der festgelegten Ports ist in /etc/services einsehbar.

Unix Kernal erlauben übrigens nur den Bezug eines Portes unter 1024 wenn das Program, das den Port bestellt, mit root-Privilegien läuft, daher sind alle Server Programme SUID Programme oder müssen von root gestartet werden. Das gibt auch die berühmten Security Probleme, die regelmässig auftauchen (z.B. der LPD/lpr Bug letztehin in der Mailing Liste).

Aber kommen meine Daten überhaupt an?

IP, bzw manche Leitungstechnologien darunter, garantiere nicht, dass ein Datenpaket überhaupt ankommt (z.B. Ethernet), geschweige denn die Reihenfolge der Pakete (z.B. parallele Standleitungen), selbst Duplikate sind möglich. Es wird nur ein "möglichst guter Versuch" unternommen, ein Paket ans Ziel zu bringen. Damit die erwünschte Zuverlässigkeit in die Kommunikation kommt müssen daher alle Pakete überwacht (bestätigt), geordnet und Duplikate ausgeschieden werden. Dazu werden weitere Verwaltungsdaten mitgegeben, in einem Header, formatiert gemäss dem Transmission Control Protocol (TCP).

Der TCP Header wird wie der UDP Header zwischen Daten und IP Header eingefügt. TCP wird anstelle von UDP eingesetzt, daher muss es auch noch Portnummern transportieren. TCP hat ebenfalls daher eine eigene Portnummernvergabe im Kernal und eine eigene Liste von festgelegten Ports unter 1024. Die sind aber meistens parallel zu UDP. Diese Doppelspurigkeit ist historisch bedingt, UDP ist eine neuere Erfindung für weniger Overhead (z.B. NFS benutzt UDP für höhere Geschwindigkeit).

Jedes Paket trägt im TCP Header unter anderem folgende Angaben: N Bytes ab M-te Position in der Verbindung von Host:Port zu Host:Port und bestätige bisherigen Empfang bis L-ter Position in Gegenrichtung. Normalfall ist, das auf jedes Paket ein Bestätigungspaket in die andere Richtung geht, falls gerade auch Daten gehen müssen werden sie zusammen geschickt. Bekommt der Sender innerhalb einer Timeout-Zeit keine Bestätigung wird eine erneute Sendung aller Daten der Verbindung ab letzter bestätigter Position geschickt. Der Empfänger bestätigt immer den letzten zusammenhängenden Stand der Verbindung (auch nach einem Duplikat Empfang).

Mögliche Unfälle und ihre Korrektur:

Bei guter Leitung (wenige Korrekturen nötig) wird aus Geschwindigkeits Gründen "auf Vorrat gesendet", da sonst die Zeit für jedes hin-her den Datendurchsatz erheblich reduzieren würde. Dafür wird ein "maximaler Ueberbezug" für jede Verbindung auf dem Laufenden gehalten, bei jedem Unfall wird es verkleinert, bei jeden problemlosen Paket erhöht. Dieses Verhalten ist an dem TxD und RxD LEDs eines Modems schön zu sehen.

Kann ich mein Ziel via IP erreichen?

Wer soeben in seinem Rechner IP konfiguriert hat will es testen. Dazu gibt es handliche Werkzeuge:

Aber kann ichs nicht mit Namen haben?

Jeden Anschluss eines Rechners mit einer Nummer zu versehen mag zwar effizient für das Routing sein, aber zum merken durch die Benutzer sind die blöden Adressen alles andere als komfortabel.

Damit die Benutzer mit einfach zu merkenden Namen hantieren können muss eine Namen zu Adressen Umwandlung stattfinden. Dazu gibt es 2 Methoden:

Kann ich IP über RS-232 benutzen?

IP Datenpakete können über jede Leitungsart, für die ein Treiber existiert, geschickt werden. Also auch über die an jedem PC vorhandene serielle Schnittstelle und einem eventuell daran hängendem Moden. Dazu müssen die IP Pakete "verpackt" werden, dazu wird seit langem das einfache Serial Line IP (SLIP) und seit neuerem das flexiblere Point to Point Protocol (PPP) benutzt. PPP verursacht einen höheren Overhead, ist aber einfacher zum konfigurieren und bei verkürzt ISDN den wieder-Login nachdem man die Leitung unterbrochen hat.

Da eine RS-232 Leitung von IP aus betrachtet eine Leitung wie jede andere ist brauchen die beiden Anschlüsse je eine IP Adresse. Zudem wird damit der Rechner mit der RS-232 Schnittstelle zum Router und muss daher auf allen Machinen auf dem Ethernet das solcher bekannt sein. Das ist aber lästig zum vergeben, geschweige denn zum konfigurieren. Ein Ausweg aus diesen Dilemma bietet ein als Proxy ARP bekanntes Verfahren:

Die (miss-)Konfiguration erreicht man mit:
arp -s rs232ipadresse etheradresse pub

Dieses Verfahren funktioniert natürlich nur, wenn am RS-232 nur ein Rechner ist. Sitzt hinter dem RS-232 ein zweites Ethernet mit mehreren Maschinen muss eine richtige IP Konfiguration gemacht werden.

Korrektur 1999.06.30:
Dieses Verfahren funktionierte mit SLIP, es geht aber nicht mehr mit PPP. Der für PPP benutzte pppd will für die beiden Enden der RS232 verschiedene IP Adressen, weil er wie bei Ethernet die lokale IP auf 127.0.0.1 routet. Dafür müssen die beiden IP Adressen nicht mehr einem Subnetz angehören (die RS232 Leitung hat keine Netzadresse mehr, dafuer den speziellen Typ p-t-p im ifconfig).

Für den Router ist es üblich für den RS232 Anschluss die selbige IP Adresse zu nehmen wie für seinen Ethernet Anschluss (dies funktioniert weil heutige Systeme auf den Anschluss routen können und nicht mehr auf die IP Adresse beschränkt sind). Der Client bekommt irgendeine andere IP, vom selbigen Subnetz mit Proxy ARP (bei fest verbundenen Rechnern) oder von einem anderen Subnetz, das bis zu diesem Router geroutet werden muss (bei einem Pool von Dialup Rechnern). Client IP Adressen werden oft via PPP vom Router her bezogen statt lokal eingegeben, dieser vergibt entweder eine IP Adresse pro Rechner oder eine pro RS232 Anschluss.

Kann ich mehrere IP Adressen für meinen Rechner haben?

Manche Rechner brauchen mehrere Adressen, z.B. damit darauf virtuelle Web Server darauf laufen können. Dazu gibt es ein einfaches Verfahren (für die Details siehe Philip Markwalders Artikel im FLUGS 5/95, Seite 14): Hier die Befehle:
insmod -o dummyname dummy
ifconfig dummyname ipadresse
arp -s ipadresse etheradresse pub
route add ipadresse

Aber kann ich nicht verhindern, erreicht zu werden?

Eigentlich dienen Netzwerke dazu, Daten ans Ziel zu bringen. Aber manchmal will man, dass nur erwünschte Daten ankommen und andere aussen vor bleiben. Dazu kann man das Internet absichtlich "kaputtmachen". Dazu wird eine Leitung absichtlich unterbrochen und in das Loch eine Maschine eingesetzt, die selektiv Daten weiterleitet oder fortwirft, eine Firewall.

Dazu gibt es 4 grundsätzliche Verfahren:

Wo find ich mehr zum Thema IP?

Douglas E Comer, Internetworking with TCP/IP
Prentice-Hall, 1991, ISBN 0-13-474321-0

Der standard Universitätstext über TCP/IP. Trotzdem gut zum lesen!

Douglas E Comer/David L Stevens, Internetworking with TCP/IP II
Prentice-Hall, 1991, ISBN 0-13-465378-5

Ein Beispielimplementation von TCP/IP (im Xinu Betriebssystem) wird detailiert besprochen.

Douglas E Comer/David L Stevens, Internetworking with TCP/IP III
Prentice-Hall, 1993, ISBN 0-13-020272-X

Wie man Programme schreibt, die TCP/IP via dem Berkley Sockets interface benutzen.


Home | Artikel | LUGS Internet Protokoll

Diese Seite ist von Neil Franklin, letzte Aenderung 2000.12.30