2010-12-31 27 views
1

私はLinuxでC/C++クライアント/サーバプログラムを書いています。メッセージmがクライアントからサーバに送信されると仮定する。パケットを送信する前にTCPシーケンス番号を読む

mを送信する前に、クライアントがmを運ぶパケットのTCPシーケンス番号を読み取ることは可能ですか?実際に

、私はメートルにこのシーケンス番号を付加したい、そして得られたパケットを送信すると思います。 (まあ、物事はより複雑ですが、のは、単純な、それを維持しましょう。実は、私はこのシーケンス番号に認証情報を適用し、メートルにそれを追加したいと思います。)また

サーバがmを運ぶパケットのTCPシーケンス番号を読み取ることは可能ですか?

+1

なぜ地球上であなたがこれを行うにしたいですか? – Omnifarious

+0

@Omnifarious:セキュリティプロトコルで「シーケンス番号」が必要でした。それらを実装するには(TCPのように)ウィンドウを保持する必要があるため、多くのコーディングが必要になるため、ホイールを再作成しないようにし、基礎となるTCPシーケンス番号を使用する方が簡単かもしれないと考えました。下の答えから、この考え方は不可能と思われます。 「シーケンス番号」の実装を簡単にするアイデアはありますか? –

+2

セキュリティプロトコルは、TCPデータストリームの基礎となるパケット化に依存してはいけません。 TLSと他のストリームベースの暗号化プロトコルがこれを処理する方法は、データをチャンクアップすることです。データの各部分には、長さの接頭辞が付けられ、MACの後ろに接尾辞が付けられます。したがって、ストリーム内にレコード構造を提供します。 – Omnifarious

答えて

4

に非常に良いビデオチュートリアルがない、あなたがそれを行うことができない - ので、少なくともではないと予想結果

とこれがある:TCPはストリームベースである

  • パケットベースではありません。
  • TCPシーケンス番号は、パケットではなく、バイトのです。
  • TCPレイヤーは、あなたのためにセグメント化を行います。
  • TCPウィンドウサイズ/パケットサイズを使用すると、「パケット」の末尾にシーケンス番号を持つ「パケット」を送信することがありますこれらの手段

動的です。基本的な魔法はあなたのパケットを再分割します。

あなたが欲しい:

1 2 3 4 
    +---+---+---+---+   
    | A | B | C |"1"| packet 1, seq=1, len=4 
    +---+---+---+---+   

    5 6 7 8 
    +---+---+---+---+   
    | A | B | C |"5"| packet 2, seq=5, len=4 
    +---+---+---+---+   

あなたが得るかもしれないもの:

1 2 3 4   
    +---+---+---+---+ 
    | A | B | C |"1"| packet 1 (seq=1, len=4) 
    +---+---+---+---+ 

(packet 1 got lost) 

    1 2 3 4 5 6 
    +---+---+---+---+---+---+ 
    | A | B | C |"1"| A | B | packet 1, resent, seq=1, len=6 
    +---+---+---+---+---+---+ 

    7 8 
    +---+---+ 
    | C |"5"| packet 2, seq=7, len=2 
    +---+---+ 
+0

また、カーネルでさえもセグメンテーションがないので、TCPオフロードは不可能になりがちです。 –

+0

賢いASCIIアートFTW! :-) – Omnifarious

6

これとほぼ同じことができます。送信したすべてのバイト数を数え、メッセージの最後にメッセージの前に送信されたすべてのバイト数を入れることができます。

TCPを使用して「パケット」について誰かが話すときはいつも本当に緊張します。なぜなら、パケットとTCPについて同時に話すなら、混合してはならないプロトコルレベルを混合しているからです。 TCPで送信するデータとIP経由で送信されるパケットには意味のある対応がありません。

はい、TCP情報を送信するために使用されるIPパケットには、シーケンス番号があります。これらのシーケンス番号は、今までに送信されたバイト数(別名オクテット)の数です。それらは、パケット内のバイトがストリーム内のどこに属しているかを識別しますが、パケットとは無関係です。

Nagleアルゴリズムを使用している場合や、TCPスタックがその日のように感じられる場合、2つの送信操作が同じパケットに終わることがあります。または、1つのパケットで終わる1つの送信操作の半分と、別のパケットの半分で終了する可能性があります。これらのパケットはそれぞれ独自のシーケンス番号を持ちます。

私が言ったように、トランスポート層で実行する送信操作とネットワーク層で送信されるパケットには意味のある関係はありません。私は理論的にも話していません。それは本当にすべてのパケットではなく、一般的に送信します。奇妙な状態を除いて、すべてのバイトを1つのパケットに入れます。いいえ、単一の送信操作からのバイトが複数のパケットに広がっている前述のシナリオは、頻繁に起こり、予測不可能な状況下で発生します。

なぜ、パケットのシーケンス番号について何か知りたいのか分かりません。しかし、送信したバイト数のプロキシとしてシーケンス番号を使用していた場合は、その数を自分で保持して、自分自身でストリームに入れることができます。これらのバイトもカウントすることを忘れないでください。

1

TCP/IPスタックはすべての処理を行います。ペイロードのみを受信します。スタックはすべてのヘッダーを削除し、ユーザー空間にペイロードを提供します。

実際にパケットヘッダーレベルで追加または変更する場合は、RAW socketsを試してみてください。 RAWソケットは、トランスポートタイプ(TCPまたはUDP)に関係なく、ネットワークカードから直接パケットを送受信します。この場合、すべてのヘッダー(TCP/UDP Header, IP Header and Ethernet Header)をペイロードで取り除く/追加する必要があります。

アウトRAW Sockets

関連する問題