
(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でもいいのでこのプログラムの実装例が載っているサイトなどを教えてください。(英語でもかまいません)
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
> ところで、jjk65536さんはこういった情報をどこから入手しているのですか。
> raw socketやpacket socketを解説してくれているサイトはかなり少ないように感じます。
> 掲示板やこういった質問サイトも普段から利用されているのでしょうか。
基本的にはGoogle検索で調べてますね。
自分の英語読解力があてにならないので、基本的には海外のサンプルコードを
自分で動かして見ながら期待動作するように作ったりしてます。
教えてGoo!では普段C言語あたりを見たり回答したりしてます。
ちなみに、パケットキャプチャ中にだれかがSynをだしてたんですよ。
それにはRstの応答が返ってるんですね。
試しにそれと同じパケットを自分で出してみたんですが、Rst応答が
来なかったんです。
なんなんでしょうね。セキュリティ上の理由で同じパケットが来ても
Rst応答はしない、とかあるかもしれません。
気になる内容なので、詳しい方が現れてズバっと解決してくれると僕も嬉しいんですが。
この回答への補足
>> ちなみに、パケットキャプチャ中にだれかがSynをだしてたんですよ。
それにはRstの応答が返ってるんですね。
試しにそれと同じパケットを自分で出してみたんですが、Rst応答が
来なかったんです。
なぜだかさっぱりです。僕の作ったパケットが悪いと思っていたのですが、原因はそれだけではないのかもしれませんね。
LinuxやBSDあたりのプロトコルスタックの実装をソースコードを読んで理解できればいいのですが... ちょっとハードルが高いです。
本当にズバッと解決できたらいいのですが。
No.3
- 回答日時:
> だとしたら`TCP header length(24bytes)` / 4 = 6であっているのではないでしょうか。
すんません、合ってましたね。
普段Wiresharkの解析に頼りっきりで、ちゃんと自分で読んでなかったから
そんなことも忘れてました。
さて、提示して頂いたバイナリをパケットにして手元のPCで出力してみましたが、
やっぱりRstも来ないですねぇ。
他に詳しい方が現れるかとも思っていたんですが、いらっしゃらないみたいですね…。
力及ばず申し訳ないです。
ところでSOCK_RAWって生ソケットですよね?
これでTCPヘッダの大半をOSが作ってくれるとは初耳です。
どこのサイトに解説があったのか、教えて頂けませんか?
私は普段SOCK_RAWをEtherフレームからCで構築するときに使ってるんですが…
この回答への補足
>> ところで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を解説してくれているサイトはかなり少ないように感じます。
掲示板やこういった質問サイトも普段から利用されているのでしょうか。
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)は観測できますか?
目で追っていったので、読み間違いがあるかもしれません。
指摘が間違ってたらすんません。
この回答への補足
>> 以下のように通信しようとしていると読めましたが、合ってますか?
はい、あっています。
>> 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を除くすべてのヘッダを自前で作りたいです。
よろしくお願いします。
No.1
- 回答日時:
OpenSouceでしたら、LinuxよりBSDのネットワークスタックが読みやすいと
詳しい人に聞いたことがあります。(自分ではまだ読んでません、すんません)
それよりも、送信したSynパケットのダンプデータでも貼ってみてはいかがでしょう?
スクリーンキャプチャを撮って画像添付するとか。
わかる方が間違いを指摘してくれると思いますよ。私も見ます。
また、対向のサーバはそのSynパケットに対して正しくAckを返せるように
調整されているのでしょうか?
そのポートはサーバでオープンされていますか?
そのポートをTCPでListenしているデーモンは可動していますか?
対向サーバ上のWiresharkでは、Synパケットは観測できていますか?
その辺がOKなら、やはりパケットのどこかに間違いがあるのだと思います。
見てみたいですね。
この回答への補足
ヘッダに設定したポートにサーバーを走らせてもうんともすんとも言わず、さらに普通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が見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Vba Replace関数について教えて...
-
CSSが全く分かりません、お助け...
-
DLLファイルの逆コンパイラにつ...
-
バッチファイルで以下のような...
-
CPUが16bitでも32bitOSでコンパ...
-
gccを行ってもexeファイルが生...
-
c言語
-
VisualStudio2022でC言語プログ...
-
Windows Formアプリからコンソ...
-
visual studio 2022でのC#プロ...
-
C言語の関数のextern宣言
-
プログラマー達は何故、プログ...
-
PIC12F1822でLED調光器を作りたい
-
最初に聞かれたこと
-
C言語 関数、変数の宣言について
-
C言語について(初心者)
-
プログラミングc++を全く分か...
-
あってる
-
DNCL(共テ用プログラミング言語...
-
DNCL(共テ用プログラミング言語...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Windows端末でのsyslog受信につ...
-
パケットの計算方法について
-
C言語でTCPの3way handshake
-
LinuxでIPモジュールとデバイス...
-
パケット数のカウント方法
-
ネットワークの学習方法
-
ネットワーク上に存在しないIP...
-
C++言語でのWinsock2を使用した...
-
「シェーピング」って何ですか。
-
セグメンテーション違反
-
構造体のメンバをfor文で回したい
-
mailto:の本文に文字数制限はあ...
-
Wi-Fiが繋がらなくなりました N...
-
batファイルでtelnetを起動⇒文...
-
USB3.2 GEN2×2のケーブルにThun...
-
mailto:の中に&を入れる
-
outlookのアドレス帳について
-
逆引き権限委譲とは?
-
アクセスで有給休暇管理表を作...
-
MACアドレスで逮捕できる?
おすすめ情報