- 1 pingコマンドとは
- 2 検証環境
- 3 オプション一覧
- 4 基本的な使い方
- 5 ICMP echo requestパケットの送信回数の指定方法(-c)
- 5 タイムスタンプを表示する方法(-D)
- 6 ICMP echo requestパケットの送信間隔を指定する方法(-i)
- 7 パケットサイズを指定する方法(-s)
- 8 送信インタフェースを指定する方法(-I)
- 9 Flood pingを実行する方法(-f)
- 10 応答を待たずにICMP Echo Requestパケットを送信する方法(-l)
- 11 ペイロードのパターンを指定する方法(-p)
- 12 タイムアウトを指定する方法(-W)
- 13 pingの実行結果を簡潔に表示する方法(-q)
- 14 IPv6アドレスに対するping
- 15 Path MTU Discoveryの使い方(-M)
- Z 参考情報
1 pingコマンドとは
宛先までIPパケットが到達するかどうかを確認するために使うコマンドです。
2 検証環境
サーバとクライアントの2台構成です。図中のeth0はNICの名前です。
192.168.2.0/24 client(eth0) -------------------------------------(eth0) server .105 .120
2.2 版数
サーバ、クライアントともに下記版数です。
[root@server ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core)
カーネル版数は以下のとおりです。
[root@server ~]# uname -r 3.10.0-1160.el7.x86_64
2.3 pingの版数
pingの版数は以下のとおりです。
[root@server ~]# ping -V ping utility, iputils-s20160308
3 オプション一覧
[root@server ~]# ping -h Usage: ping [-aAbBdDfhLnOqrRUvV64] [-c count] [-i interval] [-I interface] [-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos] [-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option] [-w deadline] [-W timeout] [hop1 ...] destination Usage: ping -6 [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface] [-l preload] [-m mark] [-M pmtudisc_option] [-N nodeinfo_option] [-p pattern] [-Q tclass] [-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option] [-w deadline] [-W timeout] destination
4 基本的な使い方
クライアントからサーバまでIPパケットが到達するかどうか確認をしてみます。 クライアントでpingを実行します。終了するときは、Ctrl + cを押下します。
[root@client ~]# ping 192.168.2.100 PING 192.168.2.100 (192.168.2.100) 56(84) bytes of data. 64 bytes from 192.168.2.100: icmp_seq=1 ttl=64 time=1.98 ms 64 bytes from 192.168.2.100: icmp_seq=2 ttl=64 time=0.655 ms 64 bytes from 192.168.2.100: icmp_seq=3 ttl=64 time=0.602 ms ^C --- 192.168.2.100 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 0.602/1.081/1.987/0.641 ms
5 ICMP echo requestパケットの送信回数の指定方法(-c)
pingを実行すると、ICMP echo requestパケットが送信されます。 -cオプションは、送信するICMP echo requestパケット数を指定します。
ICMP echo requestパケットを1つだけ送信してみます。
[root@client ~]# ping -c 1 192.168.2.100 PING 192.168.2.100 (192.168.2.100) 56(84) bytes of data. 64 bytes from 192.168.2.100: icmp_seq=1 ttl=64 time=2.24 ms --- 192.168.2.100 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 2.240/2.240/2.240/0.000 ms
次に、ICMP echo requestパケットを2つ送信してみます。
[root@client ~]# ping -c 2 192.168.2.100 PING 192.168.2.100 (192.168.2.100) 56(84) bytes of data. 64 bytes from 192.168.2.100: icmp_seq=1 ttl=64 time=0.886 ms 64 bytes from 192.168.2.100: icmp_seq=2 ttl=64 time=0.790 ms --- 192.168.2.100 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 0.790/0.838/0.886/0.048 ms
5 タイムスタンプを表示する方法(-D)
タイムスタンプ(マイクロ秒単位)を表示してみます。 1秒間隔でサーバ(192.168.2.100)から応答を受信していることがわかります。
[root@client ~]# ping -D 192.168.2.100 PING 192.168.2.100 (192.168.2.100) 56(84) bytes of data. [1639998814.956947] 64 bytes from 192.168.2.100: icmp_seq=1 ttl=64 time=1.13 ms [1639998815.960743] 64 bytes from 192.168.2.100: icmp_seq=2 ttl=64 time=0.709 ms [1639998816.966041] 64 bytes from 192.168.2.100: icmp_seq=3 ttl=64 time=0.771 ms -snip-
6 ICMP echo requestパケットの送信間隔を指定する方法(-i)
クライアントからサーバにICMP echo requestを200ミリ秒間隔で送信してみます。サーバから200ミリ秒間隔で応答を受信していることがわかります。
[root@client ~]# ping -D -i 0.2 192.168.2.100 PING 192.168.2.100 (192.168.2.100) 56(84) bytes of data. [1639998927.370328] 64 bytes from 192.168.2.100: icmp_seq=1 ttl=64 time=0.816 ms [1639998927.585093] 64 bytes from 192.168.2.100: icmp_seq=2 ttl=64 time=0.664 ms [1639998927.799582] 64 bytes from 192.168.2.100: icmp_seq=3 ttl=64 time=0.710 ms -snip-
次に、ICMP echo requestを500ミリ秒間隔で送信してみます。 サーバ(192.168.2.100)から500ミリ秒間隔で応答を受信していることがわかります。
[root@client ~]# ping -D -i 0.5 192.168.2.100 PING 192.168.2.100 (192.168.2.100) 56(84) bytes of data. [1639998972.566876] 64 bytes from 192.168.2.100: icmp_seq=1 ttl=64 time=1.32 ms [1639998973.082046] 64 bytes from 192.168.2.100: icmp_seq=2 ttl=64 time=1.08 ms [1639998973.595965] 64 bytes from 192.168.2.100: icmp_seq=3 ttl=64 time=0.794 ms -snip-
7 パケットサイズを指定する方法(-s)
ICMPパケットは以下の構成になります。
|<- IP header(20byte) ->|<- ICMP header(8byte) ->|<------- Payload -------->| +-----------------------+------------------------+--------------------------+ | | | | | | | | | | | | +-----------------------+------------------------+--------------------------+
本オプションを使うと、ICMP echo requestのPayload長を指定することができます。 オプション未指定の場合、Payload長が56(byte)になります。 つまり、IPヘッダを含めたパケットサイズが84(byte)になります。
次に、pingを実行します。 このとき表示される56(84)は、56がICMPペイロード長を表します。 84はICMPペイロード長に、IP/ICMPヘッダ長を加えた値を表しています。
[root@server ~]# ping 192.168.2.1 PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data. 64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=7.57 ms -snip-
次に、Payload長に0を指定してみます。 ICMPペイロード長が0、IP/ICMPヘッダにICMPペイロードを加えたサイズを表していることがわかります。
[root@server ~]# ping -s 0 192.168.2.1 PING 192.168.2.1 (192.168.2.1) 0(28) bytes of data. 8 bytes from 192.168.2.1: icmp_seq=1 ttl=64 -snip-
最後に、ちょうどMTU長(本環境は1500byte)になるICMPパケットを送信してみます。
[root@server ~]# ping -s 1472 192.168.2.1 PING 192.168.2.1 (192.168.2.1) 1472(1500) bytes of data. 1480 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=3.15 ms -snip-
8 送信インタフェースを指定する方法(-I)
ICMP echo requestパケットの送信インタフェースを指定するときに使います。 複数のインタフェースを持つサーバ等で使用します。
[root@server ~]# ping -I eth0 192.168.2.1 PING 192.168.2.1 (192.168.2.1) from 192.168.2.100 eth0: 56(84) bytes of data. 64 bytes from 192.168.2.1: icmp_seq=1 ttl=64 time=33.9 ms 64 bytes from 192.168.2.1: icmp_seq=2 ttl=64 time=5.38 ms -snip-
9 Flood pingを実行する方法(-f)
Flood pingは、単位時間に大量のICMP echo requestパケットを送信する機能です。 クライアントからサーバに対してFlood pingを実行してみます。 そのときの様子をstraceコマンドを使って確認してみます。 1ミリ秒程度でsendtoシステムコールを繰り返し実行して、クライアントからサーバに、 ICMP echo requestが100(packet/s)程度送信されていることがわかります。 なお、straceの使い方は、ここ(straceコマンドの使い方)を参照してください。
[root@client ~]# strace -tt -s 0 -e trace=sendto ping -c 10 -f 192.168.2.100 PING 192.168.2.100 (192.168.2.100) 56(84) bytes of data. 19:15:45.246809 sendto(3, ""..., 64, 0, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.2.100")}, 16) = 64 19:15:45.249444 sendto(3, ""..., 64, 0, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.2.100")}, 16) = 64 19:15:45.251079 sendto(3, ""..., 64, 0, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.2.100")}, 16) = 64 19:15:45.252611 sendto(3, ""..., 64, 0, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.2.100")}, 16) = 64 19:15:45.253581 sendto(3, ""..., 64, 0, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.2.100")}, 16) = 64 19:15:45.255097 sendto(3, ""..., 64, 0, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.2.100")}, 16) = 64 19:15:45.256587 sendto(3, ""..., 64, 0, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.2.100")}, 16) = 64 19:15:45.258229 sendto(3, ""..., 64, 0, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.2.100")}, 16) = 64 19:15:45.258846 sendto(3, ""..., 64, 0, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.2.100")}, 16) = 64 19:15:45.259518 sendto(3, ""..., 64, 0, {sa_family=AF_INET, sin_port=htons(0), sin_addr=inet_addr("192.168.2.100")}, 16) = 64
10 応答を待たずにICMP Echo Requestパケットを送信する方法(-l)
ICMP echo requestに対する応答を受信してから、次のICMP echo requestを送信します。 しかし、本オプションを指定すると、応答を待たずに、次のICMP echo requestを送信できます。 本オプションは、応答を待たずに送信できるICMP echo requestのパケット数を指定します。
以下の例では、5つ目までは短い間隔でICMPパケットを受信していますが、 6つ目からは1秒間隔でICMPパケットを受信していることがわかります。
[root@client ~]# ping -D -l 5 192.168.2.100 PING 192.168.2.100 (192.168.2.100) 56(84) bytes of data. [1640255841.972294] 64 bytes from 192.168.2.100: icmp_seq=1 ttl=64 time=0.706 ms [1640255841.972329] 64 bytes from 192.168.2.100: icmp_seq=2 ttl=64 time=0.536 ms [1640255841.972338] 64 bytes from 192.168.2.100: icmp_seq=3 ttl=64 time=0.848 ms [1640255841.972345] 64 bytes from 192.168.2.100: icmp_seq=4 ttl=64 time=0.770 ms [1640255841.972352] 64 bytes from 192.168.2.100: icmp_seq=5 ttl=64 time=0.701 ms [1640255842.986215] 64 bytes from 192.168.2.100: icmp_seq=6 ttl=64 time=0.796 ms [1640255843.979614] 64 bytes from 192.168.2.100: icmp_seq=7 ttl=64 time=0.699 ms [1640255844.976921] 64 bytes from 192.168.2.100: icmp_seq=8 ttl=64 time=0.705 ms [1640255845.983677] 64 bytes from 192.168.2.100: icmp_seq=9 ttl=64 time=0.731 ms [1640255846.976107] 64 bytes from 192.168.2.100: icmp_seq=10 ttl=64 time=0.504 ms
11 ペイロードのパターンを指定する方法(-p)
ICMP Echo Requestパケットのペイロードを確認するため、サーバ側でtcpdumpを実行します。 なお、tcpdumpの使い方は、tcpdumpの使い方(基本編) - hana_shinのLinux技術ブログを参照してください。
[root@server ~]# tcpdump -i eth0 icmp -x
クライアントからサーバに対してpingを1回実行します。 このとき、ペイロードを0xffで埋めたICMP Echo Requestパケットを送信してみます
[root@client ~]# ping -c 1 -p ff 192.168.2.100 PATTERN: 0xff PING 192.168.2.100 (192.168.2.100) 56(84) bytes of data. 64 bytes from 192.168.2.100: icmp_seq=1 ttl=64 time=0.648 ms --- 192.168.2.100 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.648/0.648/0.648/0.000 ms
サーバ側で受信したICMP Echo Requestパケットの中身を確認します。 ペイロードが0xffのICMP Echo Requestパケットを受信し、その応答としてICMP Echo Replyパケットを返信しているのがわかります。
[root@server ~]# tcpdump -i eth0 icmp -x tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes 18:34:49.006655 IP 192.168.2.105 > server: ICMP echo request, id 1922, seq 1, length 64 0x0000: 4500 0054 78f5 4000 4001 3b96 c0a8 0269 0x0010: c0a8 0264 0800 f4b7 0782 0001 b942 c461 0x0020: 0000 0000 7e20 0000 0000 0000 ffff ffff 0x0030: ffff ffff ffff ffff ffff ffff ffff ffff 0x0040: ffff ffff ffff ffff ffff ffff ffff ffff 0x0050: ffff ffff 18:34:49.006721 IP server > 192.168.2.105: ICMP echo reply, id 1922, seq 1, length 64 0x0000: 4500 0054 586e 0000 4001 9c1d c0a8 0264 0x0010: c0a8 0269 0000 fcb7 0782 0001 b942 c461 0x0020: 0000 0000 7e20 0000 0000 0000 ffff ffff 0x0030: ffff ffff ffff ffff ffff ffff ffff ffff 0x0040: ffff ffff ffff ffff ffff ffff ffff ffff 0x0050: ffff ffff
12 タイムアウトを指定する方法(-W)
存在しないホストに対してpingを実行してみます。 pingコマンドがタイムアウトするまで3秒(★)かかっていることがわかります。
[root@server ~]# date;ping -c 1 192.168.2.200;date 2021年 12月 22日 水曜日 ★19:27:26 JST PING 192.168.2.200 (192.168.2.200) 56(84) bytes of data. From 192.168.2.36 icmp_seq=1 Destination Host Unreachable --- 192.168.2.200 ping statistics --- 1 packets transmitted, 0 received, +1 errors, 100% packet loss, time 0ms 2021年 12月 22日 水曜日 ★19:27:29 JST
次に、1秒のタイムアウトを指定してみます。 コマンドが1秒(★)で完了していることがわかります。
[root@server ~]# date;ping -W 1 -c 1 192.168.2.200;date 2021年 12月 22日 水曜日 ★19:28:43 JST PING 192.168.2.200 (192.168.2.200) 56(84) bytes of data. --- 192.168.2.200 ping statistics --- 1 packets transmitted, 0 received, 100% packet loss, time 0ms 2021年 12月 22日 水曜日 ★19:28:44 JST
13 pingの実行結果を簡潔に表示する方法(-q)
pingの実行結果(統計情報)だけを表示します。 ここでは、デフォルトルータにpingを10回実行してみます。
[root@server ~]# ping -q -c 10 192.168.2.1 PING 192.168.2.1 (192.168.2.1) 56(84) bytes of data. --- 192.168.2.1 ping statistics --- 10 packets transmitted, 10 received, 0% packet loss, time 9073ms rtt min/avg/max/mdev = 2.220/3.224/5.763/1.309 ms
14 IPv6アドレスに対するping
検証環境のIPv6は以下のとおりです。ともに、リンクローカルアドレスです。
client(eth0) ---------------------------------------------------(eth0) server fe80::3e2:a9c0:9fa6:a8ad/64 fe80::174:936a:8876:8055/64
クライアントでpingを実行します。 pingに指定する宛先IPv6アドレスは、サーバのIPv6リンクローカルアドレスです。 このとき、IPv6パケットを送信するデバイス名を-Iオプションで指定します。
[root@client ~]# ping -6 -I eth0 fe80::174:936a:8876:8055 PING fe80::174:936a:8876:8055(fe80::174:936a:8876:8055) from fe80::3e2:a9c0:9fa6:a8ad%eth0 eth0: 56 data bytes 64 bytes from fe80::174:936a:8876:8055%eth0: icmp_seq=1 ttl=64 time=0.640 ms 64 bytes from fe80::174:936a:8876:8055%eth0: icmp_seq=2 ttl=64 time=0.781 ms -snip-
15 Path MTU Discoveryの使い方(-M)
-Mオプションを使うと、宛先までの経路上で最小のMTUを見つけることができます。
15.1 環境構築
作成したネットワークは以下のようになります。 r1,r2間のMTUは1000になります。
192.168.100.0/24 192.168.110.0/24 192.168.120.0/24 MTU=1500 MTU=1000 MTU=1500 h1 ------------------------ r1 ------------------------ r2 ------------------------ h2 (veth1-h1) (veth1-r1) (veth2-r1) (veth1-r2) (veth2-r2) (veth1-h2) .10 .20 .10 .20 .10 .20
15.2 フラグメント禁止の指定方法(-M do)
1500(byte)のICMPパケットを送信してみます。1500(byte)の内訳は以下のとおりです。
・IPヘッダ:20(byte)
・ICMPヘッダ:8(byte)
・ICMPペイロード:1472(byte)
フラグメントを禁止にすることで、パケット長がMTUを超える場合、ICMP Packet Too Bigが返信されます。
[root@client ~]# ping -M do -s 1472 192.168.120.20 PING 192.168.120.20 (192.168.120.20) 1472(1500) bytes of data. From 192.168.100.20 icmp_seq=1 Frag needed and DF set (mtu = 1000) ping: local error: Message too long, mtu=1000 ping: local error: Message too long, mtu=1000 ping: local error: Message too long, mtu=1000 ping: local error: Message too long, mtu=1000 -snip-
オプションを指定していないと、途中のルータがパケットを分割して宛先まで転送していることがわかります。
[root@client ~]# ping -s 1472 192.168.120.20 PING 192.168.120.20 (192.168.120.20) 1472(1500) bytes of data. 1480 bytes from 192.168.120.20: icmp_seq=1 ttl=62 time=0.054 ms 1480 bytes from 192.168.120.20: icmp_seq=2 ttl=62 time=0.056 ms 1480 bytes from 192.168.120.20: icmp_seq=3 ttl=62 time=0.058 ms -snip-
なお、宛先までの経路上の最小MTUは、tracerouteコマンドでも調べることができます。 tracerouteコマンドは、tracerouteコマンドの使い方 - hana_shinのLinux技術ブログを参照してください。
Z 参考情報
私が業務や記事執筆で参考にした書籍を以下のページに記載します。 Linux技術のスキルアップをしよう! - hana_shinのLinux技術ブログ