helloworlds

not a noun, it's a verb

【TCP/IP】tcpdumpの出力からTCP/IP再入門!

今回は、主にTCP/IPの分野の基礎を固めていければと思い記事にしました。

再入門みたいなかんじです!

本題に入る前に

まず、TCP/IPの説明に入る前に、前提知識として知っておくことがあります。

ネットワーク系の技術書なんかでは当たり前に出てくる2進数や10進数などといった数字の理解についてです。 私自身、プログラムを書く上でそんなに意識して勉強したことがありませんでしたので、 今回は再入門ということで、tcpdump というコマンドを使って、TCP/IPプロトコルなどネットワークの基礎をまとめてみようかと思います。

ただ単に読むだけでは眠くなってしまうので、tcpdumpコマンドで実際確認してみることで、少しでも理解が進むようにしてみますw

(できればEC2とかで動いているWEBアプリとかローカルで開発しているWEBアプリなんかがあるといい..)

「なんか難しそう...」 とか 「数学っぽくて嫌い...」なんて言う方に、よりわかりやすく書いていけばと思うのでよろしくお願いします!w (詳しく説明というよりか、シンプルに要点のみ説明できたらと思います。)

では、さっそく数字の話からしていきます。

進数

ここでは、プログラミング及び、ネットワークを理解していくにあたって最低限必要な 2進数、10進数、16進数 をみていきます。

最初に「どうして進数を知る必要があるの?」ということですが、 まず言えるのが、「この世界において bit で表現されている」ことを認識する必要があります。

bit自体はITに関わっていれば聞いたことはあるかと思います。

では、どうしてbitなのか?ということだが、bit は、コンピュータの中で扱う 最小単位 であることです。

bit は、binary digit の略です。

お、binaryなんてコードを書く人は避けては通れない用語ですね。この bi は、ラテン語bi-が由来です。 例えば、自転車、bicycleという単語があるが、これは 2輪車 のことを示します。2つの ということが大事な点ですね。

つまり、2進数 にもこうした語源から関わってくるのですね〜。なるほどなるほどと。

bitは最小単位であるといいました。コンピュータでは、すべてのデータはbitのonとoffで表現されています。それを数値化することが目的です。

2進数 (binary digit)

2進数 は、数字の 0と1 の2つを使って表現します。

人間がよく表現するならば、10進数を使用しています。(0〜9の10種類の数字を使用していますね。例えば、1,980円でも1と0以外に8と9を使用していますね。)

よく簡単な例として挙げられるのは、電源のonとoffですね。電気の電源とかかな? offが0で、onが1として解釈するのが簡単でいいですね、みたいな。

しかし、コンピュータの中ではそうはいきません。(実際そのonとoffなんだけれども)

23などは2進数でどうやって表現するのでしょう?

2 -> 103 -> 114 -> 1005 -> 101

なんだか規則性がありそうです。そして、桁が増していきそうな気がしますね。

数値が大きくなるにつれて、桁も増すのですがコンピュータの記憶領域に準ずるかたちになります。

つまり、8桁 になります。

言い換えると、1bit を8つ並べた 8bit1byte として扱うことになります。

これは0という1bitで表現可能な数を記憶するにしても、1byte(8bit)を必要することになります。

例を示します。

1001という 2進数 で表現された数字があります。これを 10進数(いつも我々が見慣れている数字)で表現するにはどうしたらいいでしょうか?

2進数から10進数などに変換してくれる便利なサイトがあります。

2進数、8進数、10進数、16進数相互変換ツール

こうしたサイトを利用するのが普段なら便利でいいでしょう。このサイトの2進数の入力フォームに1001と入力すれば、10進数のフォームに9と出てくるので、答えは9だとすぐわかります。

が、一応仕組みというか考え方も学んだ方がいいでしょうw

こちらの表を見てください。

23 22 21 20
1 0 0 1

^は、べき乗、*は、乗算

2進数の1001は、4桁なので、べき乗する数が、0,1,2,3と4つと位が上がっています。 なので、上記の表のように表します。

2^3は、1なので、8 = 1 * 8

2^2は、0なので、0 = 0 * 0

2^1は、0なので、0 = 0 * 0

2^0は、1なので、1 = 1 * 1

ここまでくればわかりましたね。この答えを足すと9になります。なので、1001は、9を表現しています。

そして、これを理解できていれば、2進数から10進数への変換はできることになります。

10進数 (decimal number)

10進数 については、2進数がわかれば特に覚えることはないでしょう。

上記でも記述した通り、 0〜9 の数字で表現するのが10進数です。

人間が理解するのに容易なのが、10進数ですね。

16進数 (hexadecimal number)

これまで数字の0〜9までで表現してきました。

これで十分な気もしますがw、16進数 は、0〜9に加えて アルファベットのA〜F を使用して表現します。

なんかアルファベットって... と、思うかもしれませんが、どういうふうに位が増えていくのかに注目すればなんら難しいことはありません。

以下のように位が増していきます。

0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F

これは、10進数にすると以下のように表現されていることになります。

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

0〜9はそのまま表現できますね。そして、A〜Fはそのまま10〜15を表現しています。

そして、16進数なので、16がくるタイミングで桁上りします。なので、16進数において10進数の16を表現するには、10とします。

16進数も2進数で学んだ計算式で考えると理解しやすいかと思います。

161 160
1 0

16^1は、1なので、16 = 1 * 16

16^0は、0なので、0 = 0 * 0

電卓が必要ですが、アルファベットが入っても同様に考えればおk!

163 162 161 160
1 f 3 6

fは、15ですね。

なので、1*4096 + 15*256 + 3*16 + 6*1 = 7990 ということになります。

bit

bit とは、「0 or 1を表す1桁の 」(= 1bit)のこと。

よくあるOS 32bit or 64bit??

単純に考えて、64bit版を選択するのが良いとされる。

  • 32bit = 2x32 = 4,294,967,296
  • 64bit = 2x64 = 18,446,744,073,709,551,616

記憶装置のメモリの制限が設けられているのが主な違いになる。

32bit版は、約3.5GBまでしか使用できないという制限がある。64bit版の方はというと、約128GBまで使用できる。また、ハードディスクの方も同様に制限がある。

TCP

tcpdump

それでは、tcpdump をインストールしてみましょう。

AmazonLinuxであれば、yumでインストールできます。 macはたしか入っていたと思います。そうでなければ、$ brew install tcpdumpとかでやってみてください。

インストールが完了できたら $ tcpdump -hで確認してみましょう。

以下のような出力できたら大丈夫です。

tcpdump version tcpdump version 4.9.2 -- Apple version 83.200.2
libpcap version 1.8.1 -- Apple version 79.200.4
LibreSSL 2.2.7
Usage: tcpdump [-aAbdDefhHIJKlLnNOpqStuUvxX#] [ -B size ] [ -c count ]
        [ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]
        [ -i interface ] [ -j tstamptype ] [ -M secret ] [ --number ]
        [ -Q in|out|inout ]
        [ -r file ] [ -s snaplen ] [ --time-stamp-precision precision ]
        [ --immediate-mode ] [ -T type ] [ --version ] [ -V file ]
        [ -w file ] [ -W filecount ] [ -y datalinktype ] [ -z postrotate-command ]
[ -g ] [ -k ] [ -o ] [ -P ] [ -Q met[ --time-zone-offset offset ]
        [ -Z user ] [ expression ]

たくさんオプションがあると思いますが、ここでは一部を扱います。

用途によって(出力したい目的など)、使用するオプションが違うと思います。随時、ググって自分固定のオプションを見つけるといいかもしれませんね!

さて、さっそくコマンドを実行します。

tcpdump コマンドは、スーパーユーザー になる必要があります。

これは、以下の記事でも紹介した通り、プロミス・キャストモード を利用するためです。

スーパーユーザーになる($sudo su -)か、sudoをつけて実行します。

そして、さっきやった進数がさっそく活用できるので、まずコマンドを実行してみます。

$ (sudo ) tcpdump -X

開発しているWebアプリなどがあれば、空いているportを指定してtcpdumpするのが一番良いですが、ローカルでそのまま実行していも構いません。 その代わり、以下のtcpdump出力例にそぐわないパケットを拾ってしまうことが多いので、 推奨はEC2インスタンスtcpdumpをインストールして、稼働しているWEBページにアクセスして出力させるのが好ましいです...

-Xオプションは、パケットの内容を16進数で出力してくれます。

バアーーーっとパケットが出力されたら、Ctr+cで出力をストップします。

tcpdumpの出力

では、出力を見てみましょう。

4500 0034 5125 4000 ff06 0821 0a00 0abb
0a00 03c3 1f36 b702 2e7d 893b 223b 4fd8
8011 00e6 22a4 0000 0101 080a 6aa2 79cb
4b56 71d1

私が実行したときのパケットのかたまりです。みなさんも、値は違えど4文字ずつの同じような文字列が出力されたと思います。

これは16進数で表現されているので、人間でも読み解くことが可能です。

まずは、上記の出力を例に、表にまとめてみました。

項目 bit 説明
バージョン 4 4bit IPv4, IPv6(の場合は"6")
IHL(ヘッダ長) 5 4bit 32bit単位、32x5=160bit=20byte
ToS 00 8bit 優先度
パケット長 0034 16bit 52byte(10進数で)
識別子 5125 16bit フラグメント時に使用されるランダムな値
フラグなど 4000 16bit フラグ,フラグメントオフセット
TTL ff 8bit パケットの寿命64(Linuxデフォルト64)
プロトコル番号 06 8bit TCP=06, UDP=17
チェックサム 0821 16bit IPヘッダーのみ
送信元IP 0a00 0abb 32bit 10.0.10.187
送信先IP 0a00 03c3 32bit 10.0.3.195
送信元port 1f36 16bit 7990 (10進数で)
送信先port b702 16bit 46850 (10進数で)
シーケンス番号 2e7d 893b 32bit
ACK番号 223b 4fd8 32bit
データオフセット 8 4bit 32bit単位、32bitx8=256bit=32byte
コントロールビット 011 12bit ACK/FIN (予約領域を含む: 内コントロールフラグ6bit)
ウィンドウサイズ 00e6 16bit 230 (10進数で)
チェックサム 22a4 16bit 疑似ヘッダー含むチェックサム
緊急ポインタ 0000 16bit
オプション(NOP) 0101 080a 可変
タイムスタンプ(TSval) 6aa2 79cb 16bit
タイムスタンプ(TSecr) 4b56 71d1 16bit

16進数ですので、10進数の変換するとport番号などが隠れていることがわかります。

たくさんの項目がありますが、順をおってみていきます。

IPv4IPv6(バージョン)

今回は、4と出力されています。

この4は、IPv4 を示しています。

IPv4 は、32bit で構成されているので、232で約43億個のアドレスを保有しているよーってことになります。

IPv6 は、128bit で構成されているので、2128で約340澗(かん)個のアドレスを保有しているよーってことになります。

桁が違うので、IPv6は世界の人々、一人一人に割り当てたとしても0.00000001%くらいにしかならないのです。 ほぼ無限に近い(無限に近いって言い方もへんだけど)数ですw

ここで、重要なのは表記についてです。

IPv4 IPv6
表記例 192.168.0.1 2001:0db8:1234:0088:90ab:cdef:0000:0000
bit 32bitを8bitずつ4つのフィールドになる 128bitを16bitずつにして、": (コロン)"で区切って8つのフィールドになる

パッと見、IPv6の方は抵抗がある方もいるかもしれませんが、ここでは進数について勉強したので大丈夫でしょう。 なんら考え方は変わりません。

にしても、IPv6は長い...

ということで、省略表記も存在します。上記の例から省略すると、

2001:db8:1234:88:90ab:cdef::

みたいになります。

特に難しいことはなく、各フィールドの0始まりなら0を省略できることと、0が連続している場合、:に省略できることくらいわかっていれば大体問題ないでしょう。::は1つのIPに1度だけです。

そして、もう1つ重要なのは 構成 です。

ネットワーク部とホスト部

IPv4 は、ネットワーク部ホスト部 によって構成されています。

こんなかんじです。

f:id:o21o21:20190129171601p:plain

この例では、ネットワーク部とホスト部の区切りが2つあるのですが、これは、IPアドレスによって 異なります

ネットワーク部 は、どのネットワークに所属しているかを示します。

ホスト部 は、そのネットワーク内のどのホスト(端末)なのかを示しています。

でも、どこから区切りになるのか、どうやって決まるのでしょうか?

それは、クラスフルアドレスクラスレスアドレス によって区別されることになります。

ただし、主流なのは クラスレスアドレス で、サブネットマスク によって区別されていると知っておけばよいでしょう。

サブネットマスク は、IPアドレスとセットで使用される。

イメージとしては、1つの大きなネットワークを小さいネットワークの集合体に分割したものとして覚えるといいかもしれません。

表記は、IPアドレスと変わらなく、255.255.255.0 のようなかんじになっている。表現の仕方は以下を参考にしてください。

# IP (192.168.0.1)の2進数表記
11000000.10101000.00000000.00000001

# サブネットマスク (255.255.255.0)の2進数表記
11111111.11111111.11111111.00000000

# IP (192.168.0.1)のネットワーク部
11000000.10101000.00000000

# IP (192.168.0.1)のホスト部
00000001

つまり、サブネットマスク11111111が並んでいるところがネットワーク部、ということですね。(このネットワークに属していますよ。)

サブネットマスクで表記することもできますが、CIDR表記 といってもう少し短くネットワーク部とホスト部を簡単に区別して表記する方法もあります。

192.168.0.1/24 と表記します。

これは、先頭から3つ(24bit)をネットワーク部とします、という書き方です。 なので、192.168.0.1/24 = 192.168.0.1 255.255.255.0は同様です。

さて、覚えることが多くなってきましたが、これは IPv4 の構成です。

次は、IPv6 について見てきます。

プレフィックスインターフェイスID

IPv6 は、プレフィックスインターフェイスID で構成されています。

IPv4は32bitでしたが、IPv6は128bitですね。

なので、プレフィックスインターフェイスID に何bitずつか割り当てられることになります。

プレフィックスに64bit、インターフェイスIDに64bitで、プレフィックス(ネットワーク部)が十分なためネットワーク部分のアドレスが変更されることは少ないでしょう。

2001:0db8:1234:0088:90ab:cdef:0000:0000

上記の例でいくと、2001:0db8:1234:0088ここの部分が64bit(1フィールド16bit)でプレフィックスになりますね。

また、同様に2001:0db8:1234:0088/64として、CIDR表記にしても大丈夫です。

こうしてIPアドレスの表記などについて見ていきましたが、どうしてこうしたことを知る必要があるのかというと、 ネットワークの作成などで役立つ知識となります。また、社内ネットワークなんかもこうしたIPの範囲で構成されていることになります。

まあ、大概IPv4で構成されているネットワークが現在多いのですが、ここではIPv6でイメージしてみます。

例えば、2001:0db8:1234::/48と書かれたネットワークが存在するとします。

これだと2^80個のアドレスを含む。(ちなみにIPv6においての推奨される割当の大きさは/48)

2001:0db8:1234:0001::/64
2001:0db8:1234:0002::/64
2001:0db8:1234:0003::/64
2001:0db8:1234:0004::/64
.
.
.
2001:0db8:1234:ffff::/64

となり、2001:0db8:1234:0000:0000:0000:0000:0000 〜 2001:0db8:1234:ffff:ffff:ffff:ffff:ffffの範囲である。

ちなみに数値すると1,208,925,819,614,629,174,706,176個の範囲を示すことができる。

社内ネットワークで考えてみて、社員人数分のIPが必要で、辞める社員がいたとしても、何世紀もつかわからんレベルの範囲であるw

IPv4で考えてみる。

192.168.0.0/24だとすると、192.168.0.0 〜 192.168.0.255になるので、IPの個数は256個となる。

うん、これなら現実的かな。むしろ大規模の会社では足りないですね。 だからこの部署は、こうして192.168.1.0/24、この部署は、192.168.2.0/24こうするか....みたいなかんじです。 なんとなくイメージはついてたでしょうか?

長くなりましたが、最初は重要な基礎が多いので、説明が長くなりますが、引き続きtcpdumpの出力から学んでいきます!w

ヘッダ長

tcpdumpの出力によると5が出力されています。

32bit単位で計算するので、5x32bit=160bit=20byteとなります。

この20byteはなにを意味しているのでしょうか。

理解するために、基礎知識がまた必要なので説明していきます。 長くなりますが、ご了承ください!ww

プロトコル

さて、どうしてプロトコルが出てくるのかということなのですが、 ここでは、「そもそも通信機器がどうやって互いにデータを送り合ったりできるのか?」ということを理解する必要があるためです。

プロトコル(Protocol) とは、機器同士が通信を行うための 手順や規格 ことです。

主に 約束事 として紹介されていると思います。

辞書には、議定書や原案、儀礼などとして載っています。

簡単にいうとデータを送受信するための端末情報、データの形式、パケットの構成、エラーだった場合の対処法などが詰まっているわけです。

プロトコル は複数存在します。基本的に一般の方はプロトコルを意識して生活するということはないでしょう。

プロトコルはアナログ通信にも存在するようです。プロトコルだからといって、なんでもランダムに使用されているわけではなさそうですね。

プロトコルの階層化

基本的な概念がプロトコルには存在します。

1980年に発表された OSI参照プロトコル というものです。

そして、このモデルに基づいてコンピュータ間の通信などにおいて使用されるプロトコルは1つではなく、それぞれ役割があって複数のプロトコルが使用されることになります。 OSI参照モデルを元にして 7つ の階層に分かれている構造のことを プロトコルスタック といいます。

色んなプロトコル

f:id:o21o21:20190129171721p:plain

このように7つのレイヤーに分かれていて、各レイヤーに色んなプロトコルが存在します。

よく聞く TCP/IP(プロトコル) とは一体どこのレイヤーに位置するのでしょうか?

実は、TCP/IPOSIモデルに沿っていないのです。 沿ってないというよりは、ネットワークの技術が普及するにつれて、そこまで「詳細に階層分けしなくなった」という方があってるかもしれません。

TCP/IPは、4階層 にわかれています。

f:id:o21o21:20190129171743p:plain

  • アプリケーション層

ここでの規定は、各アプリに依存する。 HTTP,SMTP,FTP,SSH,POP3...

ここでは、TCPUDPプロトコルが使用される。 ネットワーク内で接続されている機器(ノード間)のデータ転送の信頼性を確保する。 TCP, UDP

  • インターネット層

IPが代表的なプロトコルEnd2End の通信を実行するための規定。 IP, ARP, ICMP...

直接的に接続された機器(ノード)間の通信のための規定。 詳しくは、こちらEthernet, PPP...

各レイヤーの規定をみてくると、通信の順番がわかるかと思います。

送信する側は、アプリケーション層から始まりネットワークインターフェイス層でカプセル化を行い データを流します。

受信側はこの逆で、ネットワークインターフェイス層 -> アプリケーション層の カプセル化 を行ってデータを取り除いていきます。

自宅の環境を考えてみると簡単です。

自宅でスマホをいじっています -> 何かアプリで友人にメッセを送信します ->

自宅のWi-Fiを経由します -> たくさんのサーバーや基地局を経由します ->

宛先の機器のWi-Fiまで到達します -> 友人のスマホに到達します

ざっくりですがこんな流れでしょうか。

ゲームなんかのリアルタイム処理が重要な通信においては、ルーターの性能や機器の処理速度が重要になってくるのもこれを考えればなんとなく理解できるかと思います。

実際は開発者の匠の技がいくつも隠されているのですw

かるくネットワークについて

こうした通信(TCP/IP)は、巨大なネットワーク、インターネット (Internet) で行われていると理解することが大事です。

なんかインターネットって当たり前の技術みたいに思われがちですが、あくまで地球規模のネットワーク という風に認識することが重要です。

そして、上記で1例としてあげた「TCP/IPというプロトコルが使用されているよ」ということですね。

他にもネットワークと呼ばれるものはあります。

会社では、イントラネット (intranet) というネットワークです。

「あれ?会社でもYahoo開いてるし、ネット使ってるからインターネット環境じゃないの?」と思われる方もいるかもしれませんが、正確には呼び方が違います。

特定範囲(会社や学校など) のコンピュータを繋いで構成されているネットワークは、イントラネットと呼びます。おそらく大企業さんであれば、情シスの方?が管理されているのでしょうか?(大企業に入ったことないからわからないw)

これは、LAN という仕組みを応用したものになります。同じ建物など物理的に隣接している場所で、機器を同士をつないでネットワークを構成します。この時、無線やケーブルで機器同士をつないでると思います。

また、WAN という都市や国などもっと大きな枠組みで、離れた場所をつなぐ仕組みがあります。

WANは、光ケーブルなどを使用してネットワークを形成しています。

ヘッダ長にもどりますw

それはそうと、もとはなんの説明をしているかといえば、ヘッダ長ですねwww

ここまできて ヘッダ長 を理解できますw で、実はもうほとんど理解したようなもんです。

ヘッダ長とは、インターネット層で付けられたヘッダ (IPヘッダ) です。

以下の図も見てください。

f:id:o21o21:20190129171823p:plain

パケットの交換 といって、大きなデータを パケット(Packet) に分割して送信しています。

その時、通信するコンピュータは、プロトコルに従って、ヘッダを作成したり、ヘッダの内部を解読して処理したりしています。

高級なプロトコル(ここではTCP)は、低級なプロトコル(ここではIP)によって取り込まれていくイメージです。 TCPプロトコルは、IPプロトコルペイロードに属しているようなかんじです。

IPヘッダの長さは、5ですよ、というふうに出力されています。

単位は32bit、または4byteで、それぞれ、

  • 5 * 32bit = 160bit
  • 5 * 4byte = 20byte

このようになり、数値は一緒になりますね。

そして、この20byteは、以下のような内容が含まれている。(引用)

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |Version|  IHL  |Type of Service|          Total Length         |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |         Identification        |Flags|      Fragment Offset    |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |  Time to Live |    Protocol   |         Header Checksum       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                       Source Address                          |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                    Destination Address                        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                    Options                    |    Padding    |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                        data(ip payload)                       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

IPヘッダのフォーマットとして、IPヘッダIPペイロード になるが、送るデータがない限りの最小サイズは20byteということになる。

ToS,パケット長,識別子,フラグ,TTL,プロトコル番号,チェックサム,送信元IP,送信先IP

さて、上記のIPのヘッダの中身を見てみましたが、tcpdumpの出力の項目は上記の表に当てはまることがわかります。

IPヘッダには、送信先IP以降は載っていないように見えます。

送信先portからの出力は、TCPヘッダ の中身になります。

以下も参考にしてみてください。(引用)

0                   1                   2                   3   
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Data |           |U|A|P|R|S|F|                               |
| Offset| Reserved  |R|C|S|S|Y|I|            Window             |
|       |           |G|K|H|T|N|N|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             data(tcp payload)                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

TCPパケットもIPパケットのフォーマットに似ています。

TCPヘッダTCPペイロード にわかれています。

TCPペイロードTCPより高級のプロトコルを含むデータということです。

重要そうな項目をみていきます。

細かい項目の意味については、こちら(IP, TCP)を参考にしてみてください。

ToS (Type of Service)

送信しているIPのサービス品質を示しています。

現状、インターネットではあまり利用されていないそうです。

パケット長

IPヘッダIPペイロード を加えたパケット全体の長さを示します。

識別子

フラグメント(パケットの分割化処理)を復元する際の識別子。

フラグとフラグメントオフセット

  • フラグ

3bitで構成されていて、パケットの分割に関する制御を指示します。

  • フラグメントオフセット

13bitで構成されていて、分割されたフラグメントが、どこに位置していたのかを示します。

TTL (Time To Live)

もともとは、このパケットがネットワークに存在してよい時間(秒単位)を示していましたが、 実際のインターネットでは、いくつのルーターを中継してもよいか、という意味になります。

プロトコル番号

IPヘッダの次のプロトコルが何であるか を示します。

チェックサム

IPヘッダのチェックサムを示す。 詳しくは、こちらを参考。

送信元IP, 送信先IP

送信元・送信先IPアドレスを示します。

送信元port, 送信先port

送信元・送信先のポート番号(Port)を示します。

シーケンス番号

シーケンス番号。

シーケンス番号は、送信したデータの位置ということ。

ACK番号 (Acknowledgment Number) 確認応答番号

確認応答番号は、次に受信すべきデータのシーケンス番号になっています。

データオフセット (Data Offset)

TCPが運んでいるデータがTCPパケットの先頭のどこから始まるのかを意味しています。

つまり、TCPヘッダ の長さを示しているということになります。

コントロールビット(または、コントロールフラグ) と 予約(Reserved)

コントロールフラグ は、8bit長で、以下のフラグが存在する。

  • CWR
  • ECE
  • URG
  • ACK
  • PSH
  • RST
  • SYN
  • FIN

全ては紹介しませんが、代表的な 3way Hand Shake (3ウェイハンドシェイク) を紹介します。

3way Hand Shake (3ウェイハンドシェイク)

TCPで通信する際に利用されるやり取りです。

名前の通り、3回のやり取りを経て接続を確立する方法になります。 クライアントと対象のサーバーとのやり取りを例にしてみます。

順番はシンプルにこんなかんじです。 

f:id:o21o21:20190129171858p:plain

SYN は、コネクションの確立 に使われます。 1になっているときは、コネクションが確立されていることを示します。さらに、シーケンス番号(Seq)が初期化されます。

ACK は、1の時、確認応答番号(ACK番号)のフィールドが有効なことを意味します。

ここでは出てきませんが、FIN というフラグもあります。 これは、コネクションを切断したという意味を示します(1のとき)。

ウィンドウサイズ

TCPヘッダに含まれる確認応答番号で示した位置から、受信可能なデータサイズを通知するのに使われます。

チェックサム

TCPチェックサム

緊急ポインタ

コントロールフラグのURGが1の場合に有効になります。 ここの数値は、緊急を要するデータの格納場所を示すポインタとして扱わられます。

オプション

TCPによる通信の性能を向上させるために利用されます。

詳しくは、こちらを参考にしてみてください。

まとめ

tcpdumpは随時実行してみてください! 目的や欲しいキャプチャによってオプションは変わってくるので、自分で使いやすいようなオプションを見つけられるといいです。

まだまだ基礎については書き足らないところがたくさんあります...

次は、有名な本「マスタリング TCP/IP」でも読んでみてまとめてみようかと思います。 もちろんすべては無理なので、私が重要だと思うメモみたいになってしまうかもしれません...

以上.

参考&引用