はじめに
普段何気なく使っているpingコマンドだが,送信しているパケットの中身については特に考えたことがなかったためまとめてみることにした.
実行環境
mac OS High Sierra(10.13.4)
pingとは?
$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8): 56 data bytes
64 bytes from 8.8.8.8: icmp_seq=0 ttl=59 time=6.408 ms
64 bytes from 8.8.8.8: icmp_seq=1 ttl=59 time=9.990 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=59 time=6.384 ms
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 6.384/7.594/9.990/1.694 ms
基本的には,$ ping {ipアドレス or ホスト名}で事足りる. pingを飛ばすことで,宛先のホストが正しく応答しているかどうか確認することができる.
私自身,基本的にpingを飛ばす際にはipアドレスやホスト名しか指定しないのだが,実はpingコマンドにはいくつかオプションが存在している.
オプション
詳しくはping オプションなどとググると出てくるが,今回使用するのは以下の3つ.
-
-cパケットを飛ばす回数を指定する -
-pパケットのデータパターンを指定する,パターンは指定したパケットサイズ分だけ繰り返される -
-sパケットのサイズをbyte単位で指定する(デフォルトは56byte)
実践
今回は,pingコマンドで8.8.8.8に対してHello World!という文字列を送信してみることとする.
データは16進数文字列で指定しなければならないので,まずは文字列→16進数文字列の変換を行う.
(こちらのサイトを使用させていただいた)
変換の結果,48656c6c6f20576f726c6421という16進数文字列を送信すれば良いことがわかった.いま,この16進数文字列は12byteなので,
$ ping 8.8.8.8 -c 1 -s 12 -p 48656c6c6f20576f726c6421
PATTERN: 0x48656c6c6f20576f726c6421
PING 8.8.8.8 (8.8.8.8): 2 data bytes
10 bytes from 8.8.8.8: icmp_seq=0 ttl=59
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
このようなpingを飛ばした.これは8.8.8.8に対して,1回,データ部分に48656c6c6f20576f726c6421を乗せた12byteのパケットを送信するコマンドである.
ところが実際にwiresharkを用いて飛ばしたパケットを見てみると,次のようなことがわかった.
データが4byteしか送られていない.12byteって指定したはずじゃ...
実はこれは正しい挙動で,本来なら-s 20として20byteのパケットを送らなけばいけなかった.
ICMPヘッダフィールド
こちらのページ が大変参考になった.
pingはICMPを利用したプロトコルであり,パケットにはICMPヘッダが付与される.このサイズが8byteなので,パケットサイズ12byteのうち8byteがヘッダに使用され,残り4byte分しかデータを送ることができなかったというわけである.
気を取り直して
$ ping 8.8.8.8 -c 1 -s 20 -p 48656c6c6f20576f726c6421
PATTERN: 0x48656c6c6f20576f726c6421
PING 8.8.8.8 (8.8.8.8): 20 data bytes
28 bytes from 8.8.8.8: icmp_seq=0 ttl=59 time=5.425 ms
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 5.425/5.425/5.425/0.000 ms
無事にHello World!を送信できた.
まとめ
pingで任意のデータ列を送信したい場合は,
- 送信したい文字列を16進数に変換
-
-pで16進数文字列,-sで16進数文字列のサイズに8を足した数字を指定
すれば良いことがわかった.
普段何気なく使用しているコマンドだが,調べてみると結構面白い.