PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : IP Header aus TCP-Packeten mit RAW Sockets auslesen


Anus+
20.10.2004, 19:37
Hallo Miteinander! :)

Ich arbeite gerade an einer Prototyp-Implementierung (in C) eines Protokolls, daß auf TCP/UDP etc. aufsetzt (Layer 4, wenn ich mich nicht irre).

Um auf der sicheren Seite zu bleiben, sende ich auf Client-Seite meine Datenpakete mit einem normalen TCP-Socket (SOCK_STREAM).

Auf der anderen Seite muss ich nun bestimmte Bereiche aus dem IP Header auslesen (Router Alert Option, TTL, etc.). Gibt es eine Möglichkeit die TTL und RAO (der eingehenden Datenpakete!) auszulesen (mögl. ohne RAW-Sockets)?

Mein schlaues Buch (UNIX Network Programming, W. Richard Stevens) sagt nämlich zur IP_TTL Socket-Option: "...there is no way to obtain the value from a received datagram."

Und mittels getsockopt bekomme ich die RAO (Router Alert Option) auch nicht heraus.

Eine Idee wäre, auf Server-Seite einen RAW- parallel zum TCP-Socket lauschen zu lassen, um so an die benötigten IP Header Felder zu gelangen (es gibt sonst keinen anderen vernünftigen Grund der für die Verwendung von RAW-Sockets bei dieser Implementierung sprechen würde).

Dazu steht in eben genanntem Buch aber: "Received UDP packets and received TCP packets are never passed to a raw socket." :mauer:

Irgendwelche Vorschläge? Bin für jedwede Hilfe dankbar.


Gruß, Anus+


Jan Krüger
20.10.2004, 19:55
Am einfachsten wäre es wahrscheinlich, das Netzwerkinterface in den Promiscuous Mode zu schalten; dann kann man nämlich sämtlichen Netzwerktraffic auslesen. Man muss dann nur noch den Traffic rauspicken, der einen interessiert.

Die Netzwerkanalysesoftware ettercap bzw. tcpdump (und wahrscheinlich jede andere auch) benutzt den Promiscuous Mode.

Die Aktivierung des Promiscuous Mode hängt -- wie alles auf der Welt -- vom verwendeten Betriebsystem ab. Ich kann aber in keinem Fall etwas dazu sagen, weil ich mich damit noch nicht beschäftigt habe.

Xpyder
22.10.2004, 09:08
Hallo Miteinander! :)
Mein schlaues Buch (UNIX Network Programming, W. Richard Stevens)
sagt nämlich zur IP_TTL Socket-Option: "...there is no way to obtain
the value from a received datagram."

Da hat das Buch (leider) recht...
Es ist so, daß ein Protokoll quasi das andere ja (mit Header) als
Paket verschickt, (diese "Schichten", ISO-OSI...) das heißt:
jedes Paket ist in dem anderen "eingepackt" - mit dem Ergebnis,
daß der Empfänger das Paket entpackt und die "Verpackung"
wegschmeißt, weil nicht mehr gebraucht.
IP ist dem TCP "übergeordnet", d.h. ein TCP-Paket kann
durch ein (oder mehrere!!!) IP-Pakete versendet werden,
der Empfänger nimmt das (oder die) IP-Paket, packt es aus,
setzt es evtl zusammen (wenn es aus mehrere bestand) und
gibt es auf Anfrage aus.
Was ich damit sagen will, ist: Im TCP-Paket sind keine
Daten des IP-Pakets mehr enthalten.


Eine Idee wäre, auf Server-Seite einen RAW- parallel zum TCP-Socket lauschen zu lassen, um so an die benötigten IP Header Felder zu gelangen (es gibt sonst keinen anderen vernünftigen Grund der für die Verwendung von RAW-Sockets bei dieser Implementierung sprechen würde).
Dazu steht in eben genanntem Buch aber: "Received UDP packets and received TCP packets are never passed to a raw socket." :mauer:

Ich denke, das ist so gemeint, daß ein UDP- oder
TCP-Paket, sobald es als solches erkannt wurde (von einem
TCP-Empfangs-Programmteil, das halt TCP-Paketteile aus dem
Datenstrom "filtert") diese Bauteile (aus denen die TCP-Pakete
bestehen) dann nicht mehr an einen RAW-Socket weiterleitet,
weil davon ausgegangen wird, daß man diese nicht mehr
braucht. (Dies passiert deswegen, weil in Netzwerken ein
Paket, wenn beim Empfänger eingetroffen, auch gelöscht
werden soll. Sonst würde es evtl im Netzwerk "kreisen" bis
seine Time-To-Live abgelaufen wäre - was ziemlichen
"Umsonst-Traffic" im Netzwerk verursachen würde.)

Lösung wäre hier wohl nur, SELBST die IP-Pakete zu
empfangen und daraus TCP-Pakete zu machen - mit einem
zusätzlichen "Datenfeld" oder ähnlichem, in dem man die
IP-Daten unterbringt (im TCP-Paket ist ja standardmäßig
keine Stelle für diese Daten vorgesehen). Und sollte das
TCP-Paket aus mehreren IP-Paketen zusammengesetzt gewesen
sein, muß man eben aus den IP-Headerdaten aller IP-Pakete
das "wichtige" herausfiltern. Oder man benutzt nur die
Daten des ersten oder letzten Pakets.

Eine andere Lösung wäre noch, die IP-Daten wie oben
herauszufinden und das IP-Paket aber trotzdem an die
Routinen weiterzuleiten, die daraus TCP-Pakete machen
(also quasi die Daten VORHER herausfinden, bevor der
"TCP-Interpreter" (also Packet Driver) sie wegschmeißt)
- da sollte man dann aber sehen, daß man nachher mit der
Zuordnung (also welche IP-Daten zu welchem TCP-Paket
gehören) noch zurechtkommt.
Es wäre also das "Lauschen parallel zum TCP-Socket".
Normalerweise sollte, das imo gehen, denn TCP baut auf
IP auf und IP auf "RAW", wenn man so will. (D.h. jedes
Protokoll ist an irgendeiner Stelle mal "Rohdaten".)

Solange ein IP-Paket z.B. ein TCP-Paket mit sich als Daten
herumschleppt, "weiß es nix" davon, für das IP sind das
einfach nur Daten. (OK, es gibt ein "Protocol"-Field im
Header - enthält z.B. 6 für TCP und 17 für UDP.)

Die Vorgehensweise hat wohl etwas damit zu tun, daß IP und
TCP fast immer "ZUSAMMEN angeboten" werden als TCP/IP. Und
daß ein Paket-Interpretierer (also Packet Driver) dann immer
gleich ein gefundenes die IP-Paket gleich auch auf TCP/UDP
untersucht.
Also wenn man sagt "Received UDP/TCP-packets are never
passed to a raw socket." bedeutet das nur, wenn korrektes
UDP/TCP-Paket empfangen zählts als "beim Empfänger
angekommen und muß nicht weitergeleitet werden". (Man kann
also normalerweise NICHT mehrere Anwendungen auf
dasselbe Paket zugreifen lassen, da es im Allgemeinen
nicht sinnvoll ist. Will man es doch, muß man es
(leider) selbst machen.)
Aber solange, bis ein Datenpaket auf irgendetwas trifft,
was es als UDP- oder TCP-Paket erkennt, ist es erstmal ein
ganz normales Paket. (Halt mit entsprechender Protokoll-Nr.)
Und so gesehen sind eigentlich ALLE Sockets im Grunde
auch erstmal "RAW"...


Noch eine Anmerkung zur allgemeinen Beruhigung, falls
einen das "Auseinandernehmen" stört (Fragmentierung
genannt) - NICHT lesen, falls kein Interesse, verwirrt
sonst nur noch mehr (sondern dann überlesen bis ++++++)

Die Teilung eines TCP-Pakets in MEHRERE IP-Pakete passiert
nur dann, wenn die maximalen Paketgrößen überschritten
werden. (MTU - Maximum Transfer Units) Wenn man es SELBER
programmiert (also selber die TCP/UDP Pakete schickt) kann
man dies ja vermeiden, indem man einfach keine zu großen
Pakete schickt. Man kann auch die Paketgrößen erhöhen.
(Wenn es geht - d.h. das Netzwerk/die Hardware es erlaubt.)
Oder man kann das "Don't Fragment"-Flag setzen - dann
werden allerdings zu große Pakete GAR NICHT geschickt,
sondern an der Stelle, wo sie eigentlich wegen ihrer Größe
fragmentiert würden, weggeschmissen.
("Don't Fragment" ist ein Flag des IP-Headers. Müßte man dann
auch BEIM SENDER den quasi "von Hand" anhängen, wenn man darin
was ändern will.)

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Welches IP-Header-Feld meinste denn eigentlich mit RAO
(Router Alert Option) ? Habe in der RFC 791 (zum IP halt)
nichts dergleichen gefunden. (In der Definition von TCP im
übrigen auch nicht.)

Wenn diese RAO vom Netzwerk und gar nicht vom IP kommt,
müßte man noch "weiter runter" gehen.
Denn TCP wird im IP verpackt. Und IP im (lokalen)
Netzwerkprotokoll.

Die einzigen Flags, die ein IP-Paket nämlich hat, sind die
für die Fragmentierung. Oder meinste eine der "Options"?
(In der Option List - also NACH Source/Dest-Address?)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Man möge mir ob der Länge des Postings verzeihen. Ich habe
mich schon bemüht, mich kurz zu fassen. Aber das Problem ist
eben nicht so trivial.

Anus+
23.10.2004, 11:55
Hallo Xpyder!

Erst einmal vielen Dank für die ausführliche Antwort, nur leider sind keine wirklich neuen Informationen für mich dabei. :(

Mit der RAO meine ich RFC2113.

Den Netzwerkverkehr im Promiscous-Mode zu "capturen", kommt auf keinen Fall in Frage, trotzdem Danke! @Jan Krüger

Ich werde jetzt doch dazu übergehen, das komplette Protokoll in RAW-Sockets zu implementieren, die Zeit drängt leider. :mad:

Falls jemand spezielle Tipps zur verwendung von RAW-Sockets hat, bitte melden! :) Ich hab' damit nämlich noch keinerlei Erfahrung.


Gruß, Anus+

Felix Kaiser
23.10.2004, 13:19
Windows XP mit SP2 unterstützt soweit ich weiß keine RAW Sockets mehr. Ansonsten kannste da auch nicht viel falsch machen. Ich hab unter Win2000 einen eigenen Dienst laufen, der über einen RAW Socket Protokoll 41 empfängt und an einen Rechner im lokalen Netzwerk weiterleitet und umgekehrt. Das praktische ist, du kannst das IP Protokoll verwenden. Du sendest nur die Daten über sendto, die über dem IP Protokoll versendet werden sollen, beim Empfang über recvfrom bekommst du aber das komplette Paket, also quasi das IP Protokoll. Wenn du ein eigenes Protokoll verwenden willst, nimm am besten eines, das noch nicht fest vergeben ist. Dann ist die Gefahr geringer, dass eine andere Anwendung mithört oder gar sich einmischt.

Anus+
23.10.2004, 16:54
Ähm, ich hab' wohl ganz vergessen zu erwähnen, daß ich das ganze unter SuSE Linux 8.2 in C implementieren muß.

Kernel-Version 2.4.20


Gruß, Anus+

Felix Kaiser
24.10.2004, 19:56
Na dann probiers doch einfach mal und finde herraus wie sich das unter Linux verhält. Sehr viel anders wird es aber auch nicht funktionieren. Zeig mal etwas Initiative.