Presentation is loading. Please wait.

Presentation is loading. Please wait.

TCP基礎講座 徳田研 ECN sada.

Similar presentations


Presentation on theme: "TCP基礎講座 徳田研 ECN sada."— Presentation transcript:

1 TCP基礎講座 徳田研 ECN sada

2 TCP とは? Transmission Control Protocol と言われてもイメージが湧かないですよね

3 隣の人、受け渡しが遅いけど、いつも通り送っちゃえ
IPのイメージ IPって実は結構テキトウ 途中でデータを無くしてもお構いなし 途中のネットワークが混んでてもお構いなし 隣の人、受け渡しが遅いけど、いつも通り送っちゃえ 水こぼしちゃったけど まあいいか

4 TCPのイメージ(1) TCPはテキトウな部分を補う データの到達保証(信頼性確保) ネットワーク混雑の回避(輻輳制御)
返ってくるバケツが足りないな・・・ ・再送しないと ・少し送る頻度を控えよう

5 TCPのイメージ(2) コネクション型 初めに信頼関係をガッチリ作っておく 今からバケツを送るけどいい?
いいよー、自分も今からバケツを送るけどいい? いいよー

6 もっと詳しく見てみよう 以下の手順で話します コネクション確立 信頼性確保をするには 効率良く送信するには 輻輳制御するには
コネクション切断

7 1.コネクション確立 スリーウェイハンドシェイク SYN SYN+ACK ACK 今からコネクション確立するよ?
了解、自分からも確立するよ? いいよー SYN SYN+ACK ACK

8 データの分割 セグメント データはMSSのサイズで分割されます 3000 1000 1000 1000
MSS: Maximum Segment Size 例えば MSS = 1000 だとすると... 元のデータ 3000 分割された データ 1000 1000 1000 セグメント

9 シーケンス番号 分割されたデータ(TCPセグメント)に識別するために,ユニークな番号を割り当てます 初期値を例えば10000とすると

10 1.コネクション確立 スリーウェイハンドシェイク時に,初期シーケンス番号,ACK番号,MSS長を交換する SYN SYN+ACK ACK
Seq No. Ack No. MSS 10000 1000 SYN+ACK Seq No. Ack No. MSS 20000 10001 1000 ACK Seq No. Ack No. MSS 10001 20001 1000

11 × 2.信頼性確保をするには データ 1000 データ 1000 データ 1000 データ 1000 1000 20001 10001
MSS Ack No. Seq No. データ 1000 1000 11001 20000 MSS Ack No. Seq No. × 1000 20001 11001 MSS Ack No. Seq No. データ 1000 1000 20001 12001 MSS Ack No. Seq No. データ 1000 1000 11001 20000 MSS Ack No. Seq No. 1000 20001 11001 MSS Ack No. Seq No. データ 1000

12 3.効率良く送信するには 毎回ACKを待っているのは効率悪い! まとめて送っちゃおう データ 1000 データ 1000 データ 1000
20001 10001 MSS Ack No. Seq No. データ 1000 1000 20001 11001 MSS Ack No. Seq No. データ 1000 1000 20001 12001 MSS Ack No. Seq No. データ 1000 1000 11001 20000 MSS Ack No. Seq No.

13 ウィンドウ セグメントのどの部分を送るか 送信に成功したらウィンドウをずらす →スライディングウィンドウ ウィンドウ

14 3.効率良く送信するには ウィンドウ 効率よく送信する=ウィンドウを大きくする ただし,単にウィンドウを大きくしてもダメ
輻輳(ふくそう)が発生する 送信相手の限界を超える可能性がある 最大ウィンドウサイズをスリーウェイハンドシェイクに,現在の利用可能ウィンドウサイズをACKに含める ウィンドウ

15 出典: 3 Minutes Networking
4.輻輳制御するには 一般的なアルゴリズム (AIMD) ウィンドウサイズを倍々に大きくする ある程度の閾値で少しずつ大きくする 輻輳が起きたらウィンドウを半分にする 出典: 3 Minutes Networking

16 5.コネクション切断 最後も礼儀正しく FIN ACK FIN ACK もうコネクションを切るよ? 了解 自分からもコネクションを切るよ?
いいよー FIN ACK FIN ACK

17 TCPヘッダ 20バイトで構成される

18 ネットワークの中身を覗こう

19 ネットワークの中身を覗く ソフトウェアといえば
09:51: localhost.miteksys-lm > localhost.echo: P 1:7(6) ack 1 win (DF) [tos 0x10] c5a e049 7f 7f ca a535 a018 e000 85de a ffd 0001 5fea b 0d0a 09:51: localhost.echo > localhost.miteksys-lm: P 1:23(22) ack 7 win (DF) c5b e048 7f 7f ca 0249 a a018 e000 b4ad a ffd 0001 5ffd b a 6f 696e 616c f64 3a 09:51: localhost.miteksys-lm > localhost.echo: . ack 23 win (DF) [tos 0x10] c 5c5c e04d 7f 7f ca a54b a010 dfea 7ab a ffd 0001 5ffd b tcpdump Ethereal 3D-tcpdump

20 自作ネットワーク監視ツール 自分で簡単に作成することが出来ます 今日はWindows上で作成してみましょう 必要なもの
UNIX系OSならもっと簡単にできます 必要なもの WinPcap Cygwin + gcc (C言語コンパイラ)

21 今日の授業のURL ここからも情報を参照できます

22 今日の目標 サンプルプログラムに下記の改造を加えよう Ehternetフレームを16進表示しよう IPの送信元・送信先アドレスを表示しよう
pingを受け取ったら “Hello, ping world” と表示しよう HTTPのGETリクエストだったら, “HTTP DATA” と表示しよう (発展編)自分でパケットを組み立てて送信しよう

23 1.Ethernetフレームを16進表示しよう
122行目の pkt_data に取得したネットワークのデータが入っています 構造 pkt_data Ethernet ヘッダ IPヘッダ TCPヘッダ ペイロード

24 1.Ethernetフレームを16進表示しよう
header->len で参照できます 表示するには printf(“%2X”, pkt_data[0]) とすると最初の1バイトを表示できます あとはフレームのサイズ分を繰り返すだけ

25 1.Ethernetフレームを16進表示しよう
16進表示する関数 void hexdump(unsigned char *p, int count) { int i, j; for(i = 0; i < count; i += 16) { printf("%04x : ", i); for (j = 0; j < 16 && i + j < count; j++) printf("%2.2x ", p[i + j]); for (; j < 16; j++) { printf(" "); } printf(": "); for (j = 0; j < 16 && i + j < count; j++) { char c = toascii(p[i + j]); printf("%c", isalnum(c) ? c : '.'); printf("\n\n");

26 2. IPの送信元・送信先アドレスを表示しよう
struct ip *ip = (struct ip_header *) (pkt_data + sizeof(struct eth_header)); pkt_data Ethernet ヘッダ IPヘッダ TCPヘッダ ペイロード

27 2. IPの送信元・送信先アドレスを表示しよう
ip->src IPの送信先アドレスを取得するには ip->dst でも,このアドレスはバイナリ表現(32ビットの整数)

28 2. IPの送信元・送信先アドレスを表示しよう
表示例 winsock2 のinet_ntoa を利用する方法もあります そっちの方が一般的かも? printf("SRC %d.%d.%d.%d DST %d.%d.%d.%d\n", ip->src.a, ip->src.b, ip->src.c, ip->src.d, ip->dst.a, ip->dst.b, ip->dst.c, ip->dst.d );

29 3. pingを受け取ったら “Hello, ping world” と表示しよう
IPパケットがICMPかどうかを参照するには ip->protocol を見ます ICMPなら1 TCPなら6 UDPなら17

30 3. pingを受け取ったら “Hello, ping world” と表示しよう
解答例 if (ip->protocol == ICMP){ printf("Hello, ping world!\n");

31 4. HTTPのGETリクエストだったら, “HTTP DATA” と表示しよう
この問題文はつまり トランスポートプロトコルがTCPであること ポートが80番であること ペイロードの最初の3文字が“GET”であること

32 4. HTTPのGETリクエストだったら, “HTTP DATA” と表示しよう
IPパケットがICMPかどうかを参照するには ip->protocol を見ます ICMPなら1 TCPなら6 UDPなら17

33 4. HTTPのGETリクエストだったら, “HTTP DATA” と表示しよう
TCPの定義 struct tcp_header{ short int Port[2]; unsigned int Squence; unsigned int Ack; u_char Offset; u_char FLG; short int Window; short int CheckSum; short int Urgent; unsigned char Option; };

34 4. HTTPのGETリクエストだったら, “HTTP DATA” と表示しよう
TCPヘッダを取得するには 送信先ポートを参照するには Port[1] struct tcp_header *tcp = (struct tcp_header *) (pkt_data + sizeof(struct eth_header) + sizeof(struct ip_header)); pkt_data Ethernet ヘッダ IPヘッダ TCPヘッダ ペイロード

35 4. HTTPのGETリクエストだったら, “HTTP DATA” と表示しよう
ペイロードを取得するには 最初の3文字がGETであるかを確認するには strncmp を使いましょう struct u_char *payload = (u_char *) (pkt_data + sizeof(struct eth_header) + sizeof(struct ip_header) + sizeof(struct tcp_header)); pkt_data Ethernet ヘッダ IPヘッダ TCPヘッダ ペイロード

36 5.(発展編)自分でパケットを組み立てて送信しよう
ここを参考に... pcap_sendpacket 関数を使います ヘンテコなEthernetフレーム・IPパケットも簡単に作れます 悪用厳禁!


Download ppt "TCP基礎講座 徳田研 ECN sada."

Similar presentations


Ads by Google