TCP PINGとICMP PINGの違い

ネットワーク

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秒以上かかっていることがわかります。
 このほかにも機会があればチャレンジしてみます。