$shibayu36->blog;

エンジニアをしています。プログラミングや読書のことなどについて書いています。

tracerouteの仕組みをtcpdumpとwiresharkで理解する

どうやって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パケットを送信し応答を使って経路を知るという仕組みになっている。

ただ仕組みを見ただけではちゃんと理解できているとはいえないと思ったので、実際にパケットの様子を見てみたい。

tcpdumpwiresharkでtracerouteのパケットを眺める

実際のパケットをtcpdumpwiresharkを使って眺めることにした。もちろん手元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)
    • UDP
    • dst 8.8.8.8: 8.8.8.8への送信である
    • ip[8] < 15: IPパケットのTTL(IPの中の9バイト目)が15未満で
      • UDP and 8.8.8.8の指定で十分なのだけど、TTLでの絞り込みもやってみたかったのでやっている
      • 通常TTLは64とかなので、TTLの絞り込みだけでも十分そうだけど、QUICとかのプロトコルTTLが4だったりしていらないパケットが流れてきたので、dst指定をした
  • 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回投げるのかとか、など少し疑問は残ったが、今回はこのあたりで追うのをやめておく。

まとめ

今回はtracerouteの実際のパケットの様子をtcpdump + wiresharkを使って眺めるという実践を行い、挙動を理解してみた。やってみたことにより、tcpdumpのいろんなフィルタ方法やそれをWiresharkに食わせて可視化する方法を学ぶことが出来たので良かった。