2009-10-07 11 views
7

多数のTCPパケットに分割された大きなHTTPパケットがある場合、どのようにそれらを単一のHTTPパケットに再構成できますか?基本的に、パケットのどこでHTTPパケットが開始/終了しているかを調べますか? HTTPパケットの開始または終了を示すTCPヘッダーにフラグ/フィールドがないようです。HTTPパケットの再構成

編集:フォローアップの回答。 TCPがストリームを管理している場合、ストリームの開始と終了をどのように知るのですか?それはソケットの開閉によって決定されますか?いくつかのレベルでは、HTTPストリーム/パケットがいつ開始され、終了したかを知ることができなければならないプロトコルもあります。それは私が知りたいことです。

私は、TCPパケットを読み取るC#でパケットスニッファを使用していますが、HTTP要求/応答/などを再構築できるようにしたいと考えています。 wiresharkや他のさまざまなスニッファの管理方法のようなインターフェースを介して行きます。あるいは、HTTPストリーム/パケットを自分で再構築する必要がなくなり、より高いレベルでHTTPストリームを利用できるC#ライブラリがありますか?

ありがとうございました。

答えて

10

[OK]私はこれを行う方法を工夫しました(厄介ですが、それは仕事を完了します)。

イーサネット、IP、およびTCPヘッダーを取り除いて、「生の」データメッセージを残すことは簡単です。メッセージの内側を見ると、パケットの先頭にある "HTTP/1.1 ..."を探して、HTTPパケットの開始かどうかを簡単に検出できます。これは、パケットがHTTPストリーム/より大きなパケット/何の開始であるかを示します。また、単純な構文解析を行って、HTTPパケット全体の合計長である「Content-Length」フィールドを読み取ることもできます。

また、送信元/宛先IP &ポート番号を使用して、リンクの一意のIDを構成することもできます。したがって、ヘッダーパケットを受信した後、これら4つの事項(SRCIP、SRCPORT、DESTIP、DESTPORT)に注意してください。次回このポート/ IPコンボに一致するパケットを受信すると、そのパケットがHTTPパケットの次の部分であるかどうかを確認できます。シーケンス番号を使っていくつかの検証やその他の処理を行うことができますが、一般的にパケットは順番に並んでいるので問題ありません。私は、HTTPストリームごとに新しいポートが開かれているので、ストリームの一部ではないランダムなパケットを受信すべきではないと考えていますが、エラーが発生しやすいエリアになる可能性があります。

とにかく、このパケットを受け取ったら、再びヘッダーを取り除いて生のメッセージを取得してください。それをメッセージの既知の部分に追加します。これまでに受信した総メッセージの長さが「Content-Length」フィールドから読み取られた長さと等しい場合、パケットは完了です!

この方法は明らかに膨大な量のエラーが発生する傾向がありますが、非常に頑強な方法ではありません。私は、他の誰かがこの同じ問題を将来にわたって遭遇した場合に私自身の質問に答えると思った!あなたの嗅覚で幸運:D

+2

を、あまりにも長さをうまくする方法は他にもあります。例えばhttp://www.httpwatch.com/httpgallery/chunked/ – mike

+2

少し遅れているかもしれませんが、 'Content-Length'ヘッダーは総パケット長を指定しません。コンテンツのサイズ、つまりヘッダーの後に続く本文を指定するだけです。ヘッダーと本文は '\ r \ n \ r \ n'で区切られています。 –

7

HTTP要求の境界を特定するためにTCPレベルの情報を使用しないでください。 TCPは信頼できるバイトストリームサービスを提供します。あなたがそこにないので、これを助けるTCPの中のフィールドやフラグを見ることはできません。

境界がHTTPリクエスト内のどこにあるかを判断するには、RFC 2616に従う必要があります。境界は明確に定義されており、受け取ったデータを解析することによって境界を特定できます。

2

TCPは、ストリームプロトコルであり、パケットプロトコルではありません。アプリケーション層(つまりあなた)は、一連のパケットではなく、データのストリームを取得します。あなたはちょうどストリームからバイトを読み続けると、あなたはHTTPペイロード全体を取得し、TCPはエラーチェック、再送信などを行います。

4

各TCPパケットにおいて、ペイロードデータの開始はTCPヘッダの直後であり、ペイロードデータの終了はIPパケットの終了である。

Data Offsetは、32ビットワードのヘッダーの長さを含むヘッダーの4ビットフィールドです(したがって、8ビット長で長さを取得するには4を掛けます)ビットバイト)。

SequenceフィールドのTCPシーケンス番号を使用してペイロードを正しい順序でストリング化します。再送信の場合、重複が存在する可能性があることに注意してください。

1

私たちは同じ問題を解決するために取り組まなければなりませんでした。私たちはオープンソースプロジェクトでコア機能のいくつかを抽出することができました。

http://code.google.com/p/pcap-reconst/

それをチェックアウトし、それはあなたを助けるなら、私に知らせてください。

+0

あなたのコードの使用に興味があります。ソースに深く掘り下げなくても、あなたのプロジェクトは、a) 'Content-Encoding'ヘッダに基づいて圧縮データを解凍し、b)' Content-Type'の 'charset'に基づいて共通テキストエンコーディングに変換します。 c) 'Transfer-Encoding'ヘッダが' chunked'に設定されているときに、チャンク化されたエンコーディングを扱いますか? –

2

あなたはXplicoという名前のオープンソースプロジェクトのコードを使用することができます。Content-Lengthフィールドが指定されていない場合 http://www.xplico.org

関連する問題