目次
ICMP Ping
Pingコマンドは、「ping IPアドレス⏎」のように入力して、ネットワークの動作確認に良く使用します。下図は Ping コマンドの実行例です。
pi@raspberrypi:~/ping $ ping 192.168.1.1 ⏎
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.921 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.758 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.613 ms
このPingには、ICMP (Internet Control Message Protocol)と呼ばれるIP上で動作するプロトコルが使われています。
また、上記の例の「56(84) bytes of data」から推測できるように 56 バイトのデータを送信しています。
Ping コマンドの送信データ
まずは、Pingコマンドの送信データの内容を見てみましょう。下図は、筆者が作成した icmp_logger.py で Ping を受信した時のようすです。下の方の ICMP Data の部分に、16進数で 56バイトのデータが得られていることが分かります。
pi@raspberrypi:~/ping $ sudo ./icmp_logger.py ⏎
ICMP Logger
Usage: sudo ./icmp_logger.py
Listening ICMP...
Date = 2023/04/08 15:03:59
ICMP RX(40) = 08 00 f5 13 00 04 00 01
IP Version = v4
IP Header = 20
IP Length = 84
Protocol = 0x01
Source = 127.0.0.1
Destination = 127.0.0.1
ICMP Length = 64
ICMP Type = 08
ICMP Code = 00
Checksum = Passed
Identifier = 0004
Sequence N = 0001
ICMP Data = cf 03 31 64 00 00 00 00
42 ac 01 00 00 00 00 00
10 11 12 13 14 15 16 17
18 19 1a 1b 1c 1d 1e 1f
20 21 22 23 24 25 26 27
28 29 2a 2b 2c 2d 2e 2f
30 31 32 33 34 35 36 37
このパケットは、全長(IP Length)が84バイト、IPヘッダを除くICMPデータ長(ICMP Length)が64バイトで構成されています。また、ICMPヘッダは、ICMP RX(40)の部分に書かれている8バイトです。
ICMP Data データの長さや内容は、OSによって異なります。また、Ping コマンドで データの長さや内容を変更することも出来ます。
ICMP で Hello, world!
それでは、 ICMP を使って、Hello, world! を送信し、それを受信してみましょう。
ここでは、1台のRaspberry Pi で送信側と受信側の両方を実験します。下図のように LXTerminalを2つ開き、左側を送信用(リクエスト側)、右側を受信(応答側)として実験を行う方法について説明します。
受信の準備
はじめに、筆者が作成した Python 用のプログラムを下記の git clone コマンドでダウンロードし、前述の icmp_logger.py を実行します。これで、受信の準備が出来ました。
pi@raspberrypi:~ $ git clone https://bokunimo.net/git/ping ⏎
pi@raspberrypi:~ $ cd ping ⏎
pi@raspberrypi:~/ping $ sudo ./icmp_logger.py ⏎
Hello, world! 送信
いよいよ Hello, world! の送信です。受信側とは異なる別の LXTerminal を開き、icmp_sender.py を下記の実行します。
pi@raspberrypi:~ $ cd ~/ping ⏎
pi@raspberrypi:~/ping $ sudo ./icmp_sender.py Hello, world! ⏎
Hello, world! 受信結果
受信に成功すると、 元の icmp_logger.py の画面に、Hello, world! が表示されます。
下図は受信結果の一例です。
Date = 2023/04/08 15:35:04
ICMP RX(15) = 08 00 0a 93 a1 08 0b 18
IP Version = v4
IP Header = 20
IP Length = 41
Protocol = 0x01
Source = 127.0.0.1
Destination = 127.0.0.1
ICMP Length = 21
ICMP Type = 08
ICMP Code = 00
Checksum = Passed
Identifier = a108
Sequence N = 0b18
ICMP Data = Hello, world!
icmp_logger.py 画面には、ICMP Typeが08と00の2つの受信結果が表示されたと思います。ICMP Type の08は、Pingのリクエストで、00はその応答です。
Ping 応答
icmp_logger.py の画面に ICMP Type 00 の応答が含まれていますが、icmp_logger.py にPingの応答機能は実装されていません。この応答は、Raspberry Pi OS 標準の機能によるものです。
Ping応答用の ICMPのデータは、ICMP Type が 00 であることと、チェックサムと呼ばれる誤り検出データ以外は、同じデータです。このため、応答にも Hello, world! が含まれています。
プログラムの概要
ファイル名 | 概要 |
icmp_logger.py | ICMP Ping を受信する(応答はしない) |
icmp_ping.py | ICMP Ping を送信し、応答を受信して表示する |
icmp_sender.py | ICMP Ping を送信し、応答を受信する(表示しない) |
Wiresharkで確認
下図は、Wiresharkで確認した時のようすです。画面の下の方にあるマーカ部に、Hello, world!が表示されているのが分かります。
応用に向けて
ICMPは、ネットワークの疎通確認などに使われている点から、低コストなシステムや、学習用、実験用として便利なプロトコルです。
最大の特徴は、ポート番号が不要な点でしょう。また、多くのネットワーク対応機器が Ping 応答機能を搭載しているので、手軽にLAN内の通信を試すことが出来ます。
TCPに比べて、パケットの節約が可能な点も特徴の一つです。とくにモバイル通信(閉域網)では、低コストな IoTシステムを構築できる可能性があります。LAN内や閉域モバイル・ネットワーク通信などで、センサ・システムに応用することが出来ると思います。
本稿では Raspberry Pi で試しましたが、Raspberry Pi Pico の MicroPython用に簡素化したプログラムも作成して、picoフォルダに収録しました。
これらのプログラムを基に、独自の通信システムを構築してみてはいかがでしょう。
GitHub Pages
本稿で使用したプログラムは、前述の git clone でダウンロードできるほか、GitHub Pages でも公開しています。
GitHub Pages:
https://git.bokunimo.com/ping
IPネットワーク通信プログラム入門
2023年4月21日発売予定の書籍「IPネットワーク通信プログラム入門」では、UDPやHTTPを使ったIPネットワーク通信のプログラムについて書かせていただきました(本書にICMPの説明はありません)。
ぜひ、目次をご覧いただき、ご予約いただければ幸いです。
IoTマイコンの入出力をワイヤレス通信で自由自在
ラズパイ/M5Stack用サンプルで学ぶ
IPネットワーク通信
CQ出版社(販売サイト):
https://shop.cqpub.co.jp/hanbai/books/42/42241.html
Amazon:
https://www.amazon.co.jp/dp/478984224X
by bokunimo.net