PINGの挙動を調べているうちに、ICMPプロトコル以外でもPINGが送信できることにようやく気づきました。プロトコルによるPINGの違いについて調べてみました。
環境
クライアント windows 11 home (192.168.19.1)
Wireshark 4.2.3
perl 5.34
サーバ Ubuntu 22.04 IP (192.168.19.129)
※VMware 上で稼働 VMnet8で接続
実験に使用したプログラム
perlを使ってTCPとICPMプロトコルでPINGを送信する簡単なプログラムを作りました。
#filename :perl_ping.pl
use strict;
use warnings;
use Net::Ping;
# 引数の数が正しいかをチェックしてハッシュを作成するサブルーチン
sub parse_args {
my %args;
my ($option, $ip);
while (my $arg = shift @_) {
if ($arg eq '-i' || $arg eq '-t') {
$option = $arg;
} elsif ($arg eq '-ip') {
$ip = shift @_;
} else {
die "Invalid argument: $arg\n";
}
}
die "Ping Sender Program \n_
USING: perl_ping.pl -i|-t -ip <target_ip>_
EXEAMPLE perl perl_ping.pl -i -ip 192.168.1.1"
unless defined $option && defined $ip;
return ($option, $ip);
}
# ICMPを使用してPINGを送信する関数
sub send_icmp_ping {
my ($target) = @_;
# Net::Pingオブジェクトを作成(ICMPを使用)
my $ping = Net::Ping->new("icmp");
# PINGを送信し、レスポンスを取得
if ($ping->ping($target)) {
print "target ( $target ) is arrive (ICMP). $ping \n";
} else {
print "target ( $target ) is die (ICMP).\n";
}
# Net::Pingオブジェクトをクローズ
$ping->close();
}
# TCPを使用してPINGを送信する関数
sub send_tcp_ping {
my ($target) = @_;
# Net::Pingオブジェクトを作成(TCPを使用)
my $ping = Net::Ping->new("tcp");
# PINGを送信し、レスポンスを取得
if ($ping->ping($target)) {
print "target ( $target ) is arraive (TCP). $ping \n";
} else {
print "target ( $target ) is die (TCP).\n";
}
# Net::Pingオブジェクトをクローズ
$ping->close();
}
my ($option, $target_ip) = parse_args(@ARGV);
unless ($target_ip && $target_ip =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
die "USING: perl perl_ping.pl -i|-t -ip <target_ip>\n";
}
if ($option eq '-i') {
send_icmp_ping($target_ip);
} elsif ($option eq '-t') {
send_tcp_ping($target_ip);
}
このプログラムの実行には管理者権限が必要です。
Net::Pingがsocketを使っているので、管理者権限がないと実行できません。
(コマンドプロンプトのアイコンを右クリックして『管理者として実行』を選ぶ)
実行結果
①通常のPING挙動
コマンドプロンプトから次のコマンドを入力します。
c:\ > ping -n 192.168.19.129
192.168.19.129 の ping 統計:
パケット数: 送信 = 1、受信 = 1、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
最小 = 0ms、最大 = 0ms、平均 = 0ms
wiresharkの出力はこんな感じです。
②作成したperl_pingを使ってPING(ICMP)を送信します
次のコマンドで実行させます。
C:\> perl .\perl_ping.pl -i -ip 192.168.19.129
target ( 192.168.19.129 ) is arrive (ICMP). Net::Ping=HASH(0x67c108)
wirersharkでは次のように表示されます。
レスポンスタイムも本家PINGとほとんど変わりません。
余分なデータを入れていないので、トラフィックに与える影響が小さい気がします。
③作成したperl_pingを使ってPING(TCP)を送信します
次のコマンドで実行させます。
C:\> perl .\perl_ping.pl -t -ip 192.168.19.129
target ( 192.168.19.129 ) is arraive (TCP). Net::Ping=HASH(0xebc188)
wirersharkでは次のように表示されます。
3wayハンドシェイクしてから通信をするかと思っていましたが、RST? もう少し勉強します。
ただ、TCP通信でPINGを行うことはできますが、レスポンスに2秒以上かかっていることがわかります。
このほかにも機会があればチャレンジしてみます。