• 締切済み

C言語でTCPの3way handshake

(C言語)Linuxのpacket socket(socket(AF?PACKET, SOCK_DGRAM, htons(ETH_P_IP))) を使ってTCPの3way handshakeをOSのプロトコルスタックに頼らず自力で挑戦しています。 RFCやほかの技術本をよんでIPヘッダやTCPヘッダの実装は一応できたのですが、肝心のsynパケットを送った後のackパケットが返ってきません。 wiresharkでは問題なくsynパケットと認識できているのですが、きっとどこかに不備があるはずです。 そこでC, C++ Javaでもいいのでこのプログラムの実装例が載っているサイトなどを教えてください。(英語でもかまいません)

みんなの回答

  • jjk65536
  • ベストアンサー率59% (66/111)
回答No.4

> ところで、jjk65536さんはこういった情報をどこから入手しているのですか。 > raw socketやpacket socketを解説してくれているサイトはかなり少ないように感じます。 > 掲示板やこういった質問サイトも普段から利用されているのでしょうか。 基本的にはGoogle検索で調べてますね。 自分の英語読解力があてにならないので、基本的には海外のサンプルコードを 自分で動かして見ながら期待動作するように作ったりしてます。 教えてGoo!では普段C言語あたりを見たり回答したりしてます。 ちなみに、パケットキャプチャ中にだれかがSynをだしてたんですよ。 それにはRstの応答が返ってるんですね。 試しにそれと同じパケットを自分で出してみたんですが、Rst応答が 来なかったんです。 なんなんでしょうね。セキュリティ上の理由で同じパケットが来ても Rst応答はしない、とかあるかもしれません。 気になる内容なので、詳しい方が現れてズバっと解決してくれると僕も嬉しいんですが。

tcpl139480211
質問者

お礼

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

tcpl139480211
質問者

補足

>> ちなみに、パケットキャプチャ中にだれかがSynをだしてたんですよ。 それにはRstの応答が返ってるんですね。 試しにそれと同じパケットを自分で出してみたんですが、Rst応答が 来なかったんです。 なぜだかさっぱりです。僕の作ったパケットが悪いと思っていたのですが、原因はそれだけではないのかもしれませんね。 LinuxやBSDあたりのプロトコルスタックの実装をソースコードを読んで理解できればいいのですが... ちょっとハードルが高いです。 本当にズバッと解決できたらいいのですが。

  • jjk65536
  • ベストアンサー率59% (66/111)
回答No.3

> だとしたら`TCP header length(24bytes)` / 4 = 6であっているのではないでしょうか。 すんません、合ってましたね。 普段Wiresharkの解析に頼りっきりで、ちゃんと自分で読んでなかったから そんなことも忘れてました。 さて、提示して頂いたバイナリをパケットにして手元のPCで出力してみましたが、 やっぱりRstも来ないですねぇ。 他に詳しい方が現れるかとも思っていたんですが、いらっしゃらないみたいですね…。 力及ばず申し訳ないです。 ところでSOCK_RAWって生ソケットですよね? これでTCPヘッダの大半をOSが作ってくれるとは初耳です。 どこのサイトに解説があったのか、教えて頂けませんか? 私は普段SOCK_RAWをEtherフレームからCで構築するときに使ってるんですが…

tcpl139480211
質問者

補足

>> ところでSOCK_RAWって生ソケットですよね? これでTCPヘッダの大半をOSが作ってくれるとは初耳です。どこのサイトに解説があったのか、教えて頂けませんか? すみません、大嘘でした。 ハードディスクの片隅から探し出したところ0のダミーで埋めてあっただけで一応TCPヘッダは作っていました。そのときのソケットはsocket(AF_INET, SOCK_RAW, IPPROTO_TCP)でした。 どこのサイトにあったかは覚えていません。たぶん海外のサイトだったと思います。 packet socketは自分で作ったヘッダはkernelによって書きかえられませんが、RAW SOCKETはソースIPやチェックサム等はkernelによって書き換えられるので勘違いしていました。 (まぁ、考えようによってはkernelが作ってくれているともいえなくもありませんが) ところで、jjk65536さんはこういった情報をどこから入手しているのですか。 raw socketやpacket socketを解説してくれているサイトはかなり少ないように感じます。 掲示板やこういった質問サイトも普段から利用されているのでしょうか。

  • jjk65536
  • ベストアンサー率59% (66/111)
回答No.2

見ました。 TCPヘッダ内のヘッダレングスが96バイトって間違ってません? 24バイトくらいになるかと思いますが。 以下のように通信しようとしていると読めましたが、合ってますか? tcp/ip src=127.0.0.1:14818 dst=127.0.0.1:61256 そうであれば、そのPCの61256番ポートでは何かのデーモンがListen していますか? 例えば、パケットキャプチャ中にターミナルで # telnet 127.0.0.1 61256 としたときに、期待したAck(またはRst)は観測できますか? 目で追っていったので、読み間違いがあるかもしれません。 指摘が間違ってたらすんません。

tcpl139480211
質問者

補足

>> 以下のように通信しようとしていると読めましたが、合ってますか? はい、あっています。 >> TCPヘッダ内のヘッダレングスが96バイトって間違ってません? "TCPヘッダ内のヘッダレングス"というのはTCPヘッダの12バイト目から4ビット間のRFCでいうところの"Data offset"のことですか? だとしたら`TCP header length(24bytes)` / 4 = 6であっているのではないでしょうか。 間違っていたらすみません。(そのときはTCPヘッダのどの部分かご教授お願いします) 一応wiresharkと自作のパケットキャプチャーソフトではTCP header lengthは24byteとでていますが... いつもはLAN内のほかのPCで実験していますが、今回は自身に送りました。 >> そうであれば、そのPCの61256番ポートでは何かのデーモンがListenしていますか? 送信ポートは乱数で決めています。61256ポートで待機しているのはbind, listen, acceptでブロッキングしている自前のサーバプログラムではだめですか? またtelnetで自前のプログラムにconnect()したときはwiresharkとtcpdumpで3way handshakeが正常に動作していることを確認しました。自前プログラムがポートでlistenしていない場合はrstが帰ってくることも確認しました。 前にどこかのWebページでみたAF_INET, SOCK_RAWをつかったプログラムは今回と同じ環境できちんと動作しましたが、この場合TCPヘッダのControl Bitsを除くIPヘッダ全体とTCPヘッダの大半はOSが作ってくれていたので、今回はEthernet headerを除くすべてのヘッダを自前で作りたいです。 よろしくお願いします。

  • jjk65536
  • ベストアンサー率59% (66/111)
回答No.1

OpenSouceでしたら、LinuxよりBSDのネットワークスタックが読みやすいと 詳しい人に聞いたことがあります。(自分ではまだ読んでません、すんません) それよりも、送信したSynパケットのダンプデータでも貼ってみてはいかがでしょう? スクリーンキャプチャを撮って画像添付するとか。 わかる方が間違いを指摘してくれると思いますよ。私も見ます。 また、対向のサーバはそのSynパケットに対して正しくAckを返せるように 調整されているのでしょうか? そのポートはサーバでオープンされていますか? そのポートをTCPでListenしているデーモンは可動していますか? 対向サーバ上のWiresharkでは、Synパケットは観測できていますか? その辺がOKなら、やはりパケットのどこかに間違いがあるのだと思います。 見てみたいですね。

tcpl139480211
質問者

補足

ヘッダに設定したポートにサーバーを走らせてもうんともすんとも言わず、さらに普通listenしていないポートにsynパケットを送るとrstパケットが帰ってくるはずなのですが、それも帰ってきません。多分IPヘッダidやTCPヘッダのack numberあたりが怪しい。(完全に初心者) 絶対にどこかでとんちんかんなことになってるはずです。 以下wiresharkで確認したループバックに送ったsynパケットの16進ダンプ(MSS=1460のオプション付き) (Ethernet header)00 11 11 94 7f 34 00 00 00 00 00 00 08 00 (ここからIP header)45 00 00 2c 70 ea 40 00 40 06 cb df 7f 00 00 01 7f 00 00 01 (ここからTCP header)39 e2 ef 48 00 03 1b 32 00 00 00 00 60 02 0c cf f6 c7 00 00 02 04 05 b4

関連するQ&A