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

4.3. ICMPモジュール

ICMPモジュールを移植します。これを追加するとping(ICMP Echo)に応答できるようになります。

ICMPモジュールのコードのコピー

ICMPモジュールのコードをmicropsからコピーします。修正は不要で、そのまま利用できます。

$ cp $MICROPS/icmp.{h,c} kernel/net/

IPモジュールのICMPエラー通知の有効化

4.1で暫定的にコメントアウトしていたip.cicmp_output()呼び出し(未対応プロトコル受信時のICMPエラー通知)を有効に戻します。

📝 kernel/net/ip.c

...
 #include "util.h"
 #include "net.h"
 #include "arp.h"
 #include "ip.h"
-//#include "icmp.h"
+#include "icmp.h"

...
 static void
 ip_input(const uint8_t *data, size_t len, struct net_device *dev)
 {
...
     /* unsupported protocol */
     if (hlen + 8 <= total) {
         /*
          * It should not be sent in response to ICMP error messages,
          * but ICMP is always registered and will not reach this point.
          */
-//        icmp_output(ICMP_TYPE_DEST_UNREACH, ICMP_CODE_PROTO_UNREACH, 0, data, hlen + 8,
-//                    iface->unicast, hdr->src);
+        icmp_output(ICMP_TYPE_DEST_UNREACH, ICMP_CODE_PROTO_UNREACH, 0, data, hlen + 8,
+                    iface->unicast, hdr->src);
     }
 }
...

初期化関数の呼び出し

net.cでICMPモジュールのヘッダをインクルードし、net_init()からicmp_init()を呼び出すようにします。

📝 kernel/net/net.c

...
-//#include "icmp.h"
+#include "icmp.h"
...

 int
 net_init(void)
 {
...
-//    if (icmp_init() == -1) {
-//        errorf("icmp_init() failure");
-//        return -1;
-//    }
+    if (icmp_init() == -1) {
+        errorf("icmp_init() failure");
+        return -1;
+    }
...
 }
...
...

Makefileの修正

icmp.oをビルド対象に追加します。

📝 Makefile

...
   $N/ether.o \
   $N/arp.o \
   $N/ip.o \
+  $N/icmp.o \
   $P/platform.o \
...

動作確認

再ビルドした後、make qemuを実行してxv6を起動します。ユニキャストアドレス192.0.2.2に対してpingを実行します。

$ ping -c 3 192.0.2.2

今度はICMP Echo Replyが返るので、pingが成功します。

$ ping -c 3 192.0.2.2
PING 192.0.2.2 (192.0.2.2) 56(84) bytes of data.
64 bytes from 192.0.2.2: icmp_seq=1 ttl=255 time=1.23 ms
64 bytes from 192.0.2.2: icmp_seq=2 ttl=255 time=0.98 ms
64 bytes from 192.0.2.2: icmp_seq=3 ttl=255 time=1.05 ms

--- 192.0.2.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms

xv6側のログにも、ICMP Echo要求を受信してEcho Replyを送信している様子が出力されます。

10:05:00.101 [D] icmp_input: 192.0.2.1 => 192.0.2.2, len=64 (kernel/net/icmp.c:117)
10:05:00.102 [D] icmp_output: 192.0.2.2 => 192.0.2.1, len=64 (kernel/net/icmp.c:163)