Http-Sniffer in C++ Builder



  • Also dafür nen eigenen LSP zu programmieren halte ich für zu umständlich. Und vor allem stellt es dich schlussendlich wieder vor das gleiche Problem: Du musst den HTTP Stream doch wieder selber parsen. Der LSP bietet weit mehr Möglichkeiten als winpcap, ich sehe nur nicht, wie dir das weiterhilft. Du kannst ja mal von deinen Erfolgen berichten, wenn´s soweit ist.

    Gruß,
    Doc



  • nex schrieb:

    Mit Winpcap müsste ich mir selbst einen TCP/IP-Stack basteln um schlussendlich dann an die HTTP-Packete zu gelangen und das dürfte einen erheblichen Mehraufwand bedeuten.

    du brauchst keinen tcp-stack, sondern du musst nur die header auswerten. ethernet- ip- und tcp-header (letzterer ohne options) haben feste längen. du bekommst von winpcap in dieser reihenfolge:
    - 14 bytes eth header
    - 20 bytes ip header
    - 20 bytes tcp header
    - x bytes nutzdaten (z.b. http-protokoll)
    wenn dich z.b. nur das http interessiert, dann überspring' einfach die ersten 54 bytes.
    🙂



  • Grundsätzlich hast du schon recht mit deiner Aussage fricky, jedoch beginnen danach erst die wirklichen Probleme. Ich habe nun jedenfalls begonnen es mit Winpcap zu realisieren, da ich selbst auch keine Alternative mehr fand. Es funktioniert soweit auch wunderbar und ich erhalte brav die einzelnen Pakete. Stecken geblieben bin ich momentan beim Umwandeln der Pakete (Ethernet) in HTTP-Requests/-Responses. Folgende Tatsachen erschweren mein Weiterkommen:

    - Segmentierung. Falls die HTTP-Daten zu gross sind, werden sie in mehreren TCP-Paketen gesendet.
    - Werden mehrere HTTP-Requests abgeschickt, wird nicht zuerst auf den ersten Request geantwortet und danach auf die Weiteren sondern "gleichzeitig" auf alle - die TCP-Pakete der Requests wechseln sich ab.
    - Die Reihenfolge der TCP-Segmente kann sich während der Übertragung ändern.
    - "Content-Length" scheint in HTTP kein Pflichtfeld zu sein.

    Mir stellt sich momentan die Frage, wie ich erkennen kann, ob ich das "letzte" TCP-Paket erhalten habe und ob sämtliche Pakete zwischen Erstem und Letztem auch schon angekommen sind oder noch folgen werden?
    Zur Zeit ermittle ich anhand der TCP-Paket-Grösse, ob noch weitere Pakete folgen sollten. Es scheint mir jedoch nicht unbedingt der sauberste Weg zu sein ... womöglich übersehe ich aber auch einfach Etwas und werde mich nun erstmal noch besser über TCP informieren.



  • du könntest es vielleicht so machen:
    1. pakete die vom webserver kommen, deren local-port == 80 ist und die SYN+ACK im tcp-header gesetzt haben, bedeuten dass eine verbidnung stattgefunden hat. aus einem solchen paket extrahierst du beide ip-adressen und beide portnummern.
    2. von allen weiteren paketen, bei denen portnummern und ip-adressen gleich denen aus (1) sind, speicherst du die nutzdaten ab. das ist dann nämlich der http-datenstrom.
    3. kommt vom server ein tcp paket, in dessen header die flags FIN+ACK gesetzt sind, dann speicherst du ebenfalls die nutzdaten ab und die verbindung ist beendet.
    ^^so kriegst du alle daten vom server für diese verbindung. die daten vom client kriegst du, wenn du ähnliches machst, nur sind dabei portnummern und ip-adressen vertauscht.
    🙂



  • Die erste Filterung der Pakete (Port & IP) mache ich bereits mit Winpcap. Ich erhalte also nur Pakete, die mich auch interessieren.

    Die Detektion eines Verbindungsaufbaus habe ich bereits implementiert und es werden nun auch die richtigen Pakete in richtiger Reihenfolge zusammengefügt. Was noch fehlt ist weiterhin eine "saubere" Erkennung des letzten TCP-Paketes - momentan wird das immernoch anhand der Grösse des Paketes entschieden.

    Sauber wäre es natürlich, wenn man auf das FIN-Paket warten würde, jedoch dauert es im besten Fall um ~5 Sekunden, bis die Verbindung auch geschlossen wird. Ein Webbrowser wird also auch nicht auf das Beenden der TCP-Verbindung warten, ehe er die Daten auswertet und mir dauert das eigentlich auch zu lange ...



  • nex schrieb:

    Sauber wäre es natürlich, wenn man auf das FIN-Paket warten würde, jedoch dauert es im besten Fall um ~5 Sekunden, bis die Verbindung auch geschlossen wird.

    dann hast du aber 'ne super-lahme verbindung. normalerweise geht das viel schneller.

    nex schrieb:

    Ein Webbrowser wird also auch nicht auf das Beenden der TCP-Verbindung warten, ehe er die Daten auswertet und mir dauert das eigentlich auch zu lange ...

    ich denke auch, dass der browser die daten, während sie eintrudeln, schon verarbeitet. allerdings wird er mit dem darstellen warten müssen, bis alles da ist. es könnte ja ein CSS, etc. am ende sein, das alles ändern könnte. aber wenn keine content-length angegeben ist, dann ist die http-übertragung mit dem FIN vom server beendet. ich wüsste nicht, ob es noch 'ne andere möglichkeit gibt.
    🙂



  • Hm, also ich bin mir eigentlich sehr sicher, dass die Dauer, bis die TCP-Verbindung geschlossen wird nicht von der Geschwindigkeit der Internetverbindung abhängig ist. Wie ich gelesen habe wird die Verbindung nach einem Timeout geschlossen und dieser liegt nunmal im Bereich einiger Sekunden.
    Hast du mal mit Packetyzer oder Ähnlichem deinen TCP-Verkehr angeschaut? Bei mir treffen die FIN-Pakete um Einiges verzögert ein, während der Browser den Ladevorgang bereits abgeschlossen hat und die Seite darstellt.



  • nex schrieb:

    Hm, also ich bin mir eigentlich sehr sicher, dass die Dauer, bis die TCP-Verbindung geschlossen wird nicht von der Geschwindigkeit der Internetverbindung abhängig ist. Wie ich gelesen habe wird die Verbindung nach einem Timeout geschlossen und dieser liegt nunmal im Bereich einiger Sekunden.

    du meinst bestimmt diese fin-wait-x bzw. time-wait states von tcp? die greifen nur bei langsamen netzen. wenn beide ihre FIN-ACK/ACKs schnell genug austauschen, was im normalfall passiert, ist die verbindung schnell beendet (im millisekundenbereich).

    nex schrieb:

    Hast du mal mit Packetyzer oder Ähnlichem deinen TCP-Verkehr angeschaut? Bei mir treffen die FIN-Pakete um Einiges verzögert ein, während der Browser den Ladevorgang bereits abgeschlossen hat und die Seite darstellt.

    weiss nicht wo diese verzögerungen herkommen, aber normal ist das nicht. guck doch mal mit wireshark auf die zeitstempel der pakete.
    🙂



  • fricky schrieb:

    guck doch mal mit wireshark auf die zeitstempel der pakete.

    Genau das habe ich getan und deshalb bin ich auch auf die ~5 Sekunden gekommen. Der Wert schwankt jedoch sehr und hängt auch von der Seite ab, die ich aufrufe. Er bleibt jedoch mindestens im Bereich von einigen Sekunden.
    Z. B. Google schliesst die Verbindung erst nach ~20 Sekunden. Könntest du (oder ein Anderer ;)) mal prüfen, ob das bei dir wirklich anders ist?

    Ich habe es bereits bei mir zu Hause (ADSL 3500/300 Kbps) und hier an der Uni geprüft und vermute deshalb, dass es eigentlich nicht an mir liegen sollte.



  • nex schrieb:

    Z. B. Google schliesst die Verbindung erst nach ~20 Sekunden. Könntest du (oder ein Anderer ;)) mal prüfen, ob das bei dir wirklich anders ist?

    du hast recht. google lässt die verbindung eine ganze weile offen !?
    seltsam, seltsam.
    aber hier steht, wie man das ende einer http-message erkennen kann: http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html
    (unter 4.4 Message Length)
    🙂


Anmelden zum Antworten