
(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で質問しましょう!
似たような質問が見つかりました
- その他(コンピューター・テクノロジー) 「プロトコル」の定義について 5 2023/04/16 13:13
- UNIX・Linux Ubuntuサーバーでメールを受信できない 7 2022/08/23 20:55
- その他(プログラミング・Web制作) プログラムの勉強のおすすめは 7 2022/12/09 20:09
- 固定IP スマホやPCのIPアドレスについて教えてください。 5 2023/07/07 19:53
- ネットワーク 回線を体系的に勉強する方法。 ネットワークを勉強している者です。 ネットワークを「体系的に」学習する 3 2022/11/26 20:36
- C言語・C++・C# linux C言語について ./ファイル名 入力値 入力値が表示 という風に実行と入力を同時にしたい 3 2022/10/17 16:57
- その他(自然科学) 科学技術計算の仕事について 2 2023/02/04 18:09
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- 哲学 日本語は 言語類型として あたかも始原のごとくである 3 2022/05/29 04:41
- C言語・C++・C# exeファイルが作れない(windows10) 6 2022/08/13 08:47
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
プログラミングについて。 1つ...
-
visual studio 2022でのC#プロ...
-
c++でテンプレートのコードでわ...
-
C# DatagridviewにExcelシート...
-
Linux Cプログラミングを学ぶた...
-
C言語って古いですか?
-
パソコン
-
License='MIT' ってなんでmitな...
-
C++でデスクトップGUIアプリ開...
-
C言語について。
-
C言語について。
-
ストリームについて。
-
C言語の質問です。バイナリ形...
-
Windows Formアプリからコンソ...
-
大量のデータを読み込んで表示...
-
C言語の関数のextern宣言
-
プログラマー達は何故、プログ...
-
PIC12F1822でLED調光器を作りたい
-
最初に聞かれたこと
-
C言語 関数、変数の宣言について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ソケットを使ったプログラムに...
-
ゲームプログラミングのネット...
-
Windows端末でのsyslog受信につ...
-
Linuxでパケットのデータ部分を...
-
ネットワーク上に存在しないIP...
-
「シェーピング」って何ですか。
-
C言語でTCPの3way handshake
-
パケット数のカウント方法
-
C++言語でのWinsock2を使用した...
-
LinuxでIPモジュールとデバイス...
-
ユニックス時間(秒)を普通の日...
-
セグメンテーション違反
-
F-09D
-
ネットワークの学習方法
-
パケットの中身について。 始点...
-
構造体のメンバをfor文で回したい
-
batファイルでtelnetを起動⇒文...
-
mailto:の本文に文字数制限はあ...
-
Wi-Fiが繋がらなくなりました N...
-
アクセスで有給休暇管理表を作...
おすすめ情報