どうやってIPからMACアドレスを解決するか - ARPの挙動を調べた - $shibayu36->blog; に続き、マスタリングTCP/IPで気になったことの実践。tracerouteではIPヘッダのttlの値とICMPをうまく利用して、経路を教えてくれるというのを見たので、今回はそのパケットの様子をtcpdump + wiresharkを使って見てみることで、仕組みの理解を深めてみたい。
tracerouteの仕組み
まず手元でtracerouteを8.8.8.8に対して打つと、以下のように経路情報を教えてくれる。
$ traceroute 8.8.8.8 traceroute to 8.8.8.8 (8.8.8.8), 64 hops max, 52 byte packets 1 aterm.me (192.168.10.1) 4.408 ms 3.977 ms 3.989 ms 2 * * * 3 10.1.194.227 (10.1.194.227) 18.208 ms 18.145 ms 16.765 ms 4 10.1.12.221 (10.1.12.221) 19.256 ms 25.289 ms 18.419 ms 5 110-134-112-25.rev.home.ne.jp (110.134.112.25) 19.733 ms 110-134-112-29.rev.home.ne.jp (110.134.112.29) 28.411 ms 110-134-112-25.rev.home.ne.jp (110.134.112.25) 21.976 ms 6 c3-be1.kb-dc.zaq.ad.jp (110.134.112.30) 15.741 ms c3-be2.kb-dc.zaq.ad.jp (110.134.112.26) 17.432 ms 20.679 ms 7 gw1-be3.dj-dc.zaq.ad.jp (220.152.35.34) 16.314 ms 19.365 ms 21.640 ms 8 74.125.48.225 (74.125.48.225) 20.817 ms 22.107 ms 22.983 ms 9 108.170.243.33 (108.170.243.33) 16.376 ms 108.170.243.65 (108.170.243.65) 18.259 ms 108.170.243.129 (108.170.243.129) 17.609 ms 10 72.14.237.127 (72.14.237.127) 19.487 ms 108.177.3.85 (108.177.3.85) 18.998 ms 108.170.235.47 (108.170.235.47) 22.041 ms 11 google-public-dns-a.google.com (8.8.8.8)
これはtracert / traceroute の仕組み TCP/IP入門に書いてあるとおりで、途中の経路でTTLが0になったらICMPのType11(時間超過)を返してくる特性を活かして、IPヘッダのTTLの値を1から順に2、3、4、...と増やしていきながらUDPパケットを送信し応答を使って経路を知るという仕組みになっている。
ただ仕組みを見ただけではちゃんと理解できているとはいえないと思ったので、実際にパケットの様子を見てみたい。
tcpdumpとwiresharkでtracerouteのパケットを眺める
実際のパケットをtcpdumpとwiresharkを使って眺めることにした。もちろん手元PCからtracerouteしようと思っているので、wiresharkだけでも見れるのだけど、tcpdumpの練習もしておいた方が良いと思い、tcpdumpで出力したdumpファイルをwiresharkで見るという方法を取ってみた。
まずtcpdumpはこういう感じ。
tcpdump -n -i en0 -w dump.cap \ '(udp and ip[8] < 15 and dst 8.8.8.8) or (icmp and (icmp[icmptype] == 11 or icmp[icmptype] == 3))'
オプションは
- -nオプションで名前逆引きをしない
- -iオプションでen0のパケットをキャプチャ
- -wで出力先ファイルを指定
あとはフィルタの説明。対象は送信するUDPと返ってくるICMPなので
(udp and ip[8] < 15 and dst 8.8.8.8)
icmp and (icmp[icmptype] == 11 or icmp[icmptype] == 3)
- ICMPで
- icmp[icmptype] == 11: ICMPのタイプがTime Exceeded
- TTL切れたら返ってくるやつ
- icmp[icmptype] == 3: ICMPのタイプがDestination Unreachable
- 最後到達した時に、ポートが塞がれていてDestination Unreachableで返ってくることが多い
そしてこのdump.capファイルをWiresharkで眺めてみる。
こんな感じで、まずはTTLを1にしたUDPのパケットを3回投げて、ICMPのTime-to-live exceededが3つ返ってきて、TTLを2にしたUDPパケットを3つ投げて、・・・と繰り返していき、最後に8.8.8.8に到達して、ICMPのDestination Unreachableが返ってくる様子が確認できた。まだなんでUDPを3回投げるのかとか、など少し疑問は残ったが、今回はこのあたりで追うのをやめておく。