Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

C: pingコマンドの実装

5章で実装したソケットはUDPとTCPを対象としていました。ここではRAWソケット(SOCK_RAW)に対応させ、ICMP Echo要求/応答を直接やり取りするpingコマンドを作成してください。

pingは、宛先ホストにICMP Echo要求を送り、返ってくるEcho応答までの往復時間(RTT)を表示するツールです。TCP/UDPのようにトランスポート層を挟まず、IPの上で直接ICMPメッセージを組み立てるため、RAWソケットが必要になります。

目標

  • RAWソケット(SOCK_RAW)をソケット層に対応させる
  • pingコマンドを作成し、ホスト(192.0.2.1)へICMP Echo要求を送って応答(RTT)を表示できることを確認する

ヒント

RAWソケットは「指定したプロトコル番号のIPデータグラムを、そのまま送受信できるソケット」です。ここまでに実装しているソケットに対してRAWソケット用の仕組みを実装します。

  • RAWソケットの実装: IP層(ip_input())で受信したデータグラムを、プロトコル番号が一致するRAWソケットへ渡す仕組みを用意し、sock.cSOCK_RAWの振り分けを追加します。受信キューやブロックして待つ部分はudp.cの受信処理が参考になります。sock.huser/socket.hへのSOCK_RAWIPPROTO_ICMPの定義追加も必要です(socket()システムコールはprotocolを既にそのまま渡します)。
  • pingコマンド: RAWソケットでICMP Echo要求を組み立てて送受信します。ICMPチェックサムの計算や、RTT測定のための送信時刻の埋め込みが必要です。
  • 実装上の注意: RAWソケットの受信データにはIPヘッダが含まれる点と、応答が返らないときに受信でブロックし続けない工夫(fork()で受信を別プロセスにするなど)に気をつけてください。

Note

送信先の192.0.2.1は開発環境側のTapデバイス(ホスト)のアドレスです。ホストのカーネルがICMP Echo要求に応答するので、xv6側で応答(RTT)を確認できます。

完成イメージ

$ ping 192.0.2.1
PING 192.0.2.1: 56 data bytes
64 bytes from 192.0.2.1: icmp_seq=1 time=0.512 ms
64 bytes from 192.0.2.1: icmp_seq=2 time=0.487 ms
64 bytes from 192.0.2.1: icmp_seq=3 time=0.501 ms
64 bytes from 192.0.2.1: icmp_seq=4 time=0.498 ms

--- 192.0.2.1 ping statistics ---
4 packets transmitted, 4 packets received