【バックヤード】Wake on Lanアプリを自作して、Windowsのファイアウォールで「Ping」コマンドの応答のみ許可する方法がわかった

バックヤード

 先回、3m先にあるパソコンをWake on Lanマジックパケットを送信することで起動できるようにしました。ラスト3mを解決しました。

 そこで、簡単にパソコンを起動できるようにWake on Lanアプリを自作しました。開発環境は、無償で使用できるVisual Studio 2019 Community版(VS2019C)です。VS2019Cの入手方法や使い方については、以下を参照してください。

Wake on Lanアプリの作成

 作成したWake on Lanアプリの名称は、「WoL」です。WoLのメイン画面です。2台のパソコンまで起動できるようにしました。この画面の状態は、DESKTOP PCというパソコンがWake on Lanで起動済みの状態を表しています。下段のデバイス名2は、MACアドレスやIPアドレスを設定していない状態を示しています。

 ボタンが状態によって、色と名称が変わるようになっています。「未設定(赤)」がMACアドレスなど未設定状態を表し、「送信(黄)」が設定済みでWake on Lanパケットを送信できる状態を表し、「起動済(緑)」が送信後、パソコンが起動した状態を表します。

 メイン画面の右下の歯車マークをクリックすると、WoLの設定画面が開きます。こちらで2台のパソコンの名称とMACアドレス、IPアドレスを設定します。設定は手間なので「コンピューターから取得」ボタンをクリックするとパソコンから直接取得できるようにしました。

 遠隔のパソコンが起動したときに、起動したかどうかの「死活状態」を確認できるようにしています。「死活状態」はPingコマンドを実行して確認するようにしました。

Pingとは

 Pingというのは、コマンドプロンプトから以下のPingコマンドを実行します。「192.168.0.1」は確認したいパソコンのIPアドレスです。

>ping 192.168.0.1

 コマンドを実行して相手パソコンから応答が返ってきたら起動していることがわかります。これをWoLアプリにプログラムで組み込みました。パソコンが起動するまでには時間がかかります。そのため、Pingコマンドを時間をおいて何回か実行しないと本当に起動しているかわかりません。そこで、時間間隔と何回繰り返すかを指定できるようにしました。

 最後に「OK」ボタンをクリックすると、JSON形式ファイルで設定を保存するようにしました。次回、WoLアプリを実行すると保存ファイルを読み込んで設定済み状態でメイン画面が開きます。

JSON形式ファイルとは

 JSON(JavaScript Object Notation)形式ファイルは、データを保存するための軽量で人間が読み書きしやすい形式です。JSONは、テキストベースのデータ交換形式であり、データの構造を表現するためにオブジェクトと配列を使用します。フォーマットは、キーと値のペアを持つデータで表現します。

{“Devices”:[
 {“IPAddress”:”192.168.0.10″,
  “MACAddress”:”11-22-33-44-55-66″,
  “DeviceName”:”デバイス名1”,
  “Interval”:5,
  “NumOfAttempts”:10,

  “Configured”:false,
  “Started”:false
},
{“IPAddress”:”192.168.0.11″,
 ”MACAddress”:”AA-BB-CC-DD-EE-FF”,
 ”DeviceName”:”デバイス名2”,
 ”Interval”:5,
 ”NumOfAttempts”:10,

 ”Configured”:false,
 ”Started”:false
}
]}

WoLの設定をJSON形式で保存したときのファイルの中身です。ここでは見やすいように改行をしています。太文字の部分を見るとWoLの設定画面の内容そのものであることがわかります。

WoLアプリのソースコード

 GitHubでの公開方法を知らいないのでベタにコードを貼り付けてみました。まだ、デバッグが若干足らないように思いますので予めご了承ください。(汗)
コメントもあまり入っていません。コメントを入れると行数が増えるので今回は控えます。(汗)

using System;
using System.Drawing;
using System.Windows.Forms;

namespace wol
{
    public partial class Form_WoL : Form
    {
        public DeviceInfo[] deviceInfo = new DeviceInfo[]{
            new DeviceInfo{ DeviceName = "",
                IPAddress = "",
                MACAddress = "",
                Interval = 5,
                NumOfAttempts = 10,
                Configured = false,
                Started = false
            },
            new DeviceInfo{ DeviceName = "",
                IPAddress = "",
                MACAddress = "",
                Interval = 5,
                NumOfAttempts = 10,
                Configured = false,
                Started = false
            }
        };
        public DeviceManager deviceManager = new DeviceManager();
        private Form_Setting Setting;
        Timer timer;

        public Form_WoL()
        {
            InitializeComponent();

            //フォームの定時更新イベントハンドラの登録とタイマー開始
            timer = new Timer();
            timer.Tick += new EventHandler(RefreshForm);
            timer.Interval = 1000;
            timer.Start();
            
            toolStripStatusLabel_WoL.Text = "";
            button_SendWoL1.ForeColor = Color.White;    //ボタンテキスト色
            button_SendWoL2.ForeColor = Color.White;
            SetStatusColor();

            Setting = new Form_Setting(this);
            SetStatusColor();
            label_DeviceName1.Text = deviceInfo[0].DeviceName;
            label_DeviceName2.Text = deviceInfo[1].DeviceName;
        }

        private void ToolStripStatusLabel_setting_Click(object sender, EventArgs e)
        {
            Setting.ShowDialog();
            if (Setting.DialogResult == DialogResult.OK)
            {
                label_DeviceName1.Text = deviceInfo[0].DeviceName;
                label_DeviceName2.Text = deviceInfo[1].DeviceName;
                SetStatusColor();
            }
            else
            {
                SetStatusColor();
            }
        }

        private void Button_SendWoL1_Click(object sender, EventArgs e)
        {
            Send(deviceInfo[0]);
        }

        private void Button_SendWoL2_Click(object sender, EventArgs e)
        {
            Send(deviceInfo[1]);
        }

        private void Send(DeviceInfo deviceInfo)
        {
            if (deviceInfo.Configured && !deviceInfo.Started)
            {
                WakeOnLanAndAlive(deviceInfo);
            }
            else if (deviceInfo.Started)
            {
                Alive(deviceInfo);
                if (deviceInfo.Started)
                {
                    MessageBox.Show($"{deviceInfo.DeviceName}は、既に起動しています。","情報",MessageBoxButtons.OK,MessageBoxIcon.Information);
                }
            }
            else
            {
                MessageBox.Show($"{deviceInfo.DeviceName}は、未設定です。設定を行ってください。","案内",MessageBoxButtons.OK,MessageBoxIcon.Warning);
            }
        }

        private void WakeOnLanAndAlive(DeviceInfo deviceInfo)
        {
            toolStripStatusLabel_WoL.Text = "";

            string mac = deviceInfo.MACAddress;
            if (string.IsNullOrEmpty(mac))
            {
                return;
            }
            else
            {
                deviceManager.WakeOnLan(mac);
                MessageBox.Show("Wake-on-LANパケットを送信しました。\n起動を確認します。","情報",MessageBoxButtons.OK,MessageBoxIcon.Information);
            }

            Alive(deviceInfo);
        }

        private async void Alive(DeviceInfo deviceInfo)
        {
            string ip = deviceInfo.IPAddress;
            int maxAttempts = deviceInfo.NumOfAttempts; // 最大試行回数
            int intervalSeconds = deviceInfo.Interval;  // ピンク送信間隔(秒)
            bool success = await deviceManager.CheckComputerStatusAsync(ip, maxAttempts, intervalSeconds, status => this.Invoke((MethodInvoker)(() => UpdateUI(status))));
            if (!success)
            {
                MessageBox.Show("タイムアウトしました。コンピューターは起動していない可能性があります。","案内",MessageBoxButtons.OK,MessageBoxIcon.Warning);
                toolStripStatusLabel_WoL.Text = "確認終了";
            }
            else
            {
                deviceInfo.Started = true;
                toolStripStatusLabel_WoL.Text = "起動済";
            }
        }

        private void UpdateUI(string status)
        {
            toolStripStatusLabel_WoL.Text = status;
        }

        //イベント処理
        private void RefreshForm(object sender, EventArgs e)
        {
            SetStatusColor();
        }

        //状態色の設定
        private void SetStatusColor()
        {
            if (!deviceInfo[0].Configured && !deviceInfo[0].Started)
            {
                button_SendWoL1.BackColor = Define.NOT_SET_COLOR;
                button_SendWoL1.Text = "未設定";
            }
            else if(deviceInfo[0].Configured && !deviceInfo[0].Started)
            {
                button_SendWoL1.BackColor = Define.CONFIGURED_COLOR;
                button_SendWoL1.Text = "送信";
            }
            else if (deviceInfo[0].Started)
            {
                button_SendWoL1.BackColor = Define.STARTED_COLOR;
                button_SendWoL1.Text = "起動済";
            }
            if (!deviceInfo[1].Configured && !deviceInfo[1].Started)
            {
                button_SendWoL2.BackColor = Define.NOT_SET_COLOR;
                button_SendWoL2.Text = "未設定";
            }
            else if (deviceInfo[1].Configured && !deviceInfo[1].Started)
            {
                button_SendWoL2.BackColor = Define.CONFIGURED_COLOR;
                button_SendWoL2.Text = "送信";
            }
            else if (deviceInfo[1].Started)
            {
                button_SendWoL2.BackColor = Define.STARTED_COLOR;
                button_SendWoL2.Text = "起動済";
            }
        }
    }
}

 Form_WoL.csは、WoLアプリのメイン画面のコードです。

using System;
using System.IO;
using System.Windows.Forms;

namespace wol
{
    public partial class Form_Setting : Form
    {
        Form_WoL WoL;

        DeviceManager manager;
        DeviceInfoList dviList = null;
        string fileName = "wolconfig.json";
        string filePath = "";

        public Form_Setting(Form_WoL form_WoL)
        {
            WoL = form_WoL;
            manager = WoL.deviceManager;

            InitializeComponent();

            //実行モジュールの直下のパスを設定する
            filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, fileName);
            if (File.Exists(filePath))
            {
                //JSONファイルを読みだして、デイバス情報を設定する
                dviList = manager.LoadDeviceInfoList(filePath);
                if(dviList.Devices.Count > 0 && dviList.Devices[0].Configured)
                {
                    textBox_DeviceName1.Text = dviList.Devices[0].DeviceName;
                    textBox_IP1.Text = dviList.Devices[0].IPAddress;
                    textBox_MAC1.Text = dviList.Devices[0].MACAddress;
                    numericUpDown_Interval.Value = dviList.Devices[0].Interval;
                    numericUpDown_NumOfAttempts.Value = dviList.Devices[0].NumOfAttempts;
                    WoL.deviceInfo[0].Configured = true;
                }
                if (dviList.Devices.Count > 1 && dviList.Devices[1].Configured)
                {
                    textBox_DeviceName2.Text = dviList.Devices[1].DeviceName;
                    textBox_IP2.Text = dviList.Devices[1].IPAddress;
                    textBox_MAC2.Text = dviList.Devices[1].MACAddress;
                    WoL.deviceInfo[1].Configured = true;
                }
            }

            //現在値を設定する
            WoL.deviceInfo[0].DeviceName = textBox_DeviceName1.Text;
            WoL.deviceInfo[0].MACAddress = textBox_MAC1.Text;
            WoL.deviceInfo[0].IPAddress = textBox_IP1.Text;
            WoL.deviceInfo[0].Interval = (int)numericUpDown_Interval.Value;
            WoL.deviceInfo[0].NumOfAttempts = (int)numericUpDown_NumOfAttempts.Value;
            WoL.deviceInfo[1].DeviceName = textBox_DeviceName2.Text;
            WoL.deviceInfo[1].MACAddress = textBox_MAC2.Text;
            WoL.deviceInfo[1].IPAddress = textBox_IP2.Text;

            toolStripStatusLabel_GetDeviceInfo.Text = "";
        }

        private void Button_OK_Click(object sender, EventArgs e)
        {
            //デバイス情報を設定する
            if(WoL.deviceInfo[0].Configured)
            {
                WoL.deviceInfo[0].DeviceName = textBox_DeviceName1.Text;
                WoL.deviceInfo[0].MACAddress = textBox_MAC1.Text;
                WoL.deviceInfo[0].IPAddress = textBox_IP1.Text;
                WoL.deviceInfo[0].Interval = (int)numericUpDown_Interval.Value;
                WoL.deviceInfo[0].NumOfAttempts = (int)numericUpDown_NumOfAttempts.Value;
            }

            if (WoL.deviceInfo[1].Configured)
            {
                WoL.deviceInfo[1].DeviceName = textBox_DeviceName2.Text;
                WoL.deviceInfo[1].MACAddress = textBox_MAC2.Text;
                WoL.deviceInfo[1].IPAddress = textBox_IP2.Text;
                WoL.deviceInfo[1].Interval = (int)numericUpDown_Interval.Value;
                WoL.deviceInfo[1].NumOfAttempts = (int)numericUpDown_NumOfAttempts.Value;
            }

            //JSONファイルに保存する
            DeviceInfoList dil = new DeviceInfoList();
            for(int i = 0; i < 2 ; i++)
            {
                DeviceInfo di = new DeviceInfo();
                di = WoL.deviceInfo[i];
                dil.Devices.Add(di);
            }
            //デバイス情報を保存する
            manager.SaveDeviceInfoList(dil, filePath);

            //画面を閉じる
            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void Button_Cancel_Click(object sender, EventArgs e)
        {
            //元に戻す
            textBox_DeviceName1.Text = WoL.deviceInfo[0].DeviceName;
            textBox_MAC1.Text = WoL.deviceInfo[0].MACAddress;
            textBox_IP1.Text = WoL.deviceInfo[0].IPAddress;
            numericUpDown_Interval.Value = WoL.deviceInfo[0].Interval;
            numericUpDown_NumOfAttempts.Value = WoL.deviceInfo[0].NumOfAttempts;
            textBox_DeviceName2.Text = WoL.deviceInfo[1].DeviceName;
            textBox_MAC2.Text = WoL.deviceInfo[1].MACAddress;
            textBox_IP2.Text = WoL.deviceInfo[1].IPAddress;

            //画面を閉じる
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }

        private void Button1_GetDeviceInfo_Click(object sender, EventArgs e)
        {
            // デバイス情報を生成
            var deviceInfoList = manager.GenerateDeviceInfoList();

            textBox_DeviceName1.Text = deviceInfoList.Devices[0].DeviceName;
            textBox_IP1.Text = deviceInfoList.Devices[0].IPAddress;
            textBox_MAC1.Text = deviceInfoList.Devices[0].MACAddress;
            WoL.deviceInfo[0].Configured = true;

            toolStripStatusLabel_GetDeviceInfo.Text = "デバイス1情報を取得しました。";
        }

        private void Button2_GetDeviceInfo_Click(object sender, EventArgs e)
        {
            // デバイス情報を生成
            var deviceInfoList = manager.GenerateDeviceInfoList();

            textBox_DeviceName2.Text = deviceInfoList.Devices[0].DeviceName;
            textBox_IP2.Text = deviceInfoList.Devices[0].IPAddress;
            textBox_MAC2.Text = deviceInfoList.Devices[0].MACAddress;
            WoL.deviceInfo[0].Configured = true;

            toolStripStatusLabel_GetDeviceInfo.Text = "デバイス2情報を取得しました。";
        }

        private void TextBox_MAC1_TextChanged(object sender, EventArgs e)
        {
            if (WoL.deviceInfo[0].Started) WoL.deviceInfo[0].Started = false;
            WoL.deviceInfo[0].Configured = true;
        }

        private void textBox_IP1_TextChanged(object sender, EventArgs e)
        {
            if (WoL.deviceInfo[0].Started) WoL.deviceInfo[0].Started = false;
            WoL.deviceInfo[0].Configured = true;
        }

        private void textBox_DeviceName1_TextChanged(object sender, EventArgs e)
        {
            if (WoL.deviceInfo[0].Started) WoL.deviceInfo[0].Started = false;
            WoL.deviceInfo[0].Configured = true;
        }

        private void textBox_DeviceName2_TextChanged(object sender, EventArgs e)
        {
            if (WoL.deviceInfo[1].Started) WoL.deviceInfo[1].Started = false;
            WoL.deviceInfo[1].Configured = true;
        }

        private void textBox_MAC2_TextChanged(object sender, EventArgs e)
        {
            if (WoL.deviceInfo[1].Started) WoL.deviceInfo[1].Started = false;
            WoL.deviceInfo[1].Configured = true;
        }

        private void textBox_IP2_TextChanged(object sender, EventArgs e)
        {
            if (WoL.deviceInfo[1].Started) WoL.deviceInfo[1].Started = false;
            WoL.deviceInfo[1].Configured = true;
        }
    }
}

 Form_Setting.csは、WoLの設定画面のコードです。

using System;
using System.IO;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace wol
{
    public class DeviceInfo
    {
        public string IPAddress { get; set; }
        public string MACAddress { get; set; }
        public string DeviceName { get; set; }
        public int Interval { get; set; }
        public int NumOfAttempts { get; set; }
        public bool Configured { get; set; }
        public bool Started { get; set; }
    }

    public class DeviceInfoList
    {
        public List<DeviceInfo> Devices { get; set; }

        public DeviceInfoList()
        {
            Devices = new List<DeviceInfo>();
        }
    }

    public class DeviceManager
    {
        public void SaveDeviceInfoList(DeviceInfoList deviceInfoList, string filePath)
        {
            string json = JsonConvert.SerializeObject(deviceInfoList);
            File.WriteAllText(filePath, json);
        }

        public DeviceInfoList LoadDeviceInfoList(string filePath)
        {
            if (!File.Exists(filePath))
                throw new FileNotFoundException("ファイルが見つかりません。", filePath);

            string json = File.ReadAllText(filePath);
            return JsonConvert.DeserializeObject<DeviceInfoList>(json);
        }

        public DeviceInfoList GenerateDeviceInfoList()
        {
            var deviceList = new DeviceInfoList();

            var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();

            foreach (var nic in networkInterfaces)
            {
                if (nic.OperationalStatus == OperationalStatus.Up && !nic.Description.ToLower().Contains("virtual"))
                {
                    string ipAddress = "";
                    foreach (var address in nic.GetIPProperties().UnicastAddresses)
                    {
                        if (address.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {
                            ipAddress = address.Address.ToString();
                            break;
                        }
                    }

                    string macAddress = nic.GetPhysicalAddress().ToString();
                    macAddress = FormatMACAddress(macAddress); // MACアドレスをフォーマット

                    string deviceName = Environment.MachineName;

                    if (!string.IsNullOrEmpty(macAddress))
                    {
                        //MACアドレスがあるものだけ登録する
                        deviceList.Devices.Add(new DeviceInfo
                        {
                            IPAddress = ipAddress,
                            MACAddress = macAddress,
                            DeviceName = deviceName
                        });
                    }
                }
            }
            return deviceList;
        }

        private string FormatMACAddress(string macAddress)
        {
            return string.Join("-", SplitEveryNCharacters(macAddress, 2));
        }

        private IEnumerable<string> SplitEveryNCharacters(string str, int n)
        {
            for (int i = 0; i < str.Length; i += n)
            {
                yield return str.Substring(i, Math.Min(n, str.Length - i));
            }
        }

        //Wake on Lanマジックパケット送信
        public void WakeOnLan(string macAddress)
        {
            // MACアドレスをバイト配列に変換
            byte[] macBytes = new byte[6];
            string[] macAddressParts = macAddress.Split('-');
            for (int i = 0; i < 6; i++)
            {
                macBytes[i] = Convert.ToByte(macAddressParts[i], 16);
            }

            // マジックパケットを構築
            byte[] magicPacket = new byte[102];
            for (int i = 0; i < 6; i++)
            {
                magicPacket[i] = 0xFF;
            }
            for (int i = 6; i < 102; i += 6)
            {
                Array.Copy(macBytes, 0, magicPacket, i, 6);
            }
            
            // Wake-on-LANパケットを送信
            using (UdpClient client = new UdpClient())
            {
                client.Connect(IPAddress.Broadcast, 9); // ポート9にブロードキャストで接続
                client.Send(magicPacket, magicPacket.Length);
            }
        }

        //Pingによるデバイスの生存確認を行う
        public async Task<bool> CheckComputerStatusAsync(string ipAddress, int maxAttempts, int intervalSeconds, Action<string> updateStatusLabel)
        {
            int attempts = 0;
            bool success = false;

            while (!success && attempts < maxAttempts)
            {
                attempts++;
                updateStatusLabel($"起動確認中...[試行 {attempts}/{maxAttempts}]");

                success = await CheckIfAliveAsync(ipAddress);
                //success = false;
                if (!success)
                {
                    await Task.Delay(intervalSeconds * 1000);
                }
            }

            return success;
        }

        private async Task<bool> CheckIfAliveAsync(string ipAddress)
        {
            try
            {
                Ping ping = new Ping();
                PingReply reply = await ping.SendPingAsync(ipAddress);
                return reply.Status == IPStatus.Success;
            }
            catch (PingException)
            {
                return false;
            }
        }
    }
}

 DeviceManager.csは、Wake on LanとPingの処理コードです。また、ここでJSON形式ファイルの保存と読み込みも行っています。
 JSON形式ファイルの操作ライブラリとして、NuGetの「Newtonsoft.JSON」ライブラリをインストールしています。

using System;
using System.Drawing;

namespace wol
{
    static class Define
    {
        public static readonly Color NOT_SET_COLOR = Color.DarkRed;
        public static readonly Color CONFIGURED_COLOR = Color.Orange;
        public static readonly Color STARTED_COLOR = Color.Green;
    }
}

 Define.csは状態に対する色の定義をしています。ここで色を管理しているので、後でも好きな色に変更できます。
あと、画面があれば作成できるので、Form画面の定義コードは割愛しています。

Windowsのファイアウォールの設定

 さて、WoLアプリの動作確認をしていてハマったところがあったので記載します。パソコン起動の「死活確認」のためにPingコマンドを使っていますが、ノートPCからデスクトップPCにPingが通らないことが判明しました。逆も同様デスクトップPCからノートPCにもPingが通りませんでした。

 原因は、WindowsのファイアウォールでPingがブロックされていたからです。

 Windowsのファイアウォールの設定は、「設定」の「プライバシーとセキュリティ」をクリックして、右画面の「Windowsセキュリティ」をクリックします。

 右画面の「ファイアウォールとネットワーク保護」をクリックします。

 (アクティブ)と表示されているネットワークが、現在使われているネットワークになります。
ここでは、「パブリックネットワーク(アクティブ)」です。これをクリックします。

 「Microsoft Defenderファイアウォール」が①のところで「オン」になっていることがわかります。ファイアウォールが有効になっていることがわかります。

 Pingが通らないのが、ファイアウォールが原因かどうかの切り分けのために、一時的にファイアウォールを「オフ」にしました。

 ファイアウォールをオフにしたとたんPingが通るようになりました。これで、原因がファイアウォールということがわかりました。
 ちなみに、Pingコマンドに「/t」をつけるとPingが連続して実行されるようになります。止めるときは、Ctrl+C(同時に”Ctrl”キーと”C”キー)を押します。

 では、ファイアウォールを常時オフにしてよいのかというと、セキュリティの保護リスクが高くなってしまいます。

 そこで、ファイアウォールを常時オンにしておいて、Pingだけ通すようにすればリスクは低く抑えることができます。

Pingの応答のみファイアウォールに許可する

 Pingの応答のみをファイアウォールに許可するように設定します。

 「設定」>「プライバシーとセキュリティ」>「Windowsセキュリティ」>「ファイアウォールとネットワーク保護」を順にクリックして「ファイアウォールとネットワーク保護」の画面を開きます。画面下方にある「詳細設定」をクリックします。

 「セキュリティが強化されたWindows Defender ファイアウォール」画面が表示されます。画面中央の下方にある「受信の規則」をクリックします。

 画面中央に「受信の規則」に規則の一覧が表示されます。非常にたくさんある中から「ファイルとプリンターの共有(エコー要求-ICMPv4受信)」を探します。2つあることがわかりますが、ここではリモートアドレスの列が「ローカルサブネット」のものを選択します。これは家などのローカルエリアネットワークに限定するために選択しています。

 「ファイルとプリンターの共有(エコー要求-ICMPv4受信)」を選択して、マウスの右クリックメニューの「規則の有効化」をクリックします。

 ちなみに、ICMP(Internet Control Message Protocol)は、ネットワーク上での通信状態を監視し、通信エラーを検出するためのプロトコルです。Ping(Ping.exe)は、ICMPメッセージを使用してネットワークデバイス間の接続性をテストするためのツールです。具体的に言うと、Pingツールは、ICMP Echoリクエストメッセージを送信し、対象となるホストやデバイスからの応答を待ちます。この応答によって、対象デバイスが正常に通信可能かどうかが確認されます。

 有効の列が「いいえ」から「はい」に変わります。これでPingが許可されます。

 有効にした瞬間からPingの応答が返るようになります。
あと、もう少しセキュリティ保護のリスクを低くするために、この許可はプライベートネットワークに限定するのが安全です。

 「ファイルとプリンターの共有(エコー要求-ICMPv4受信)」を選択して、マウスの右クリックメニューの「プロパティ」をクリックします。

 プロパティ画面の「詳細設定」タブを開きます。赤枠のプロファイルには、「プライベート」と「パブリック」にチェックが付いています。このままでは外部ネットワークからのPingに対して応答してしまい、パソコン起動していることを教えてしまうことになります。

 そこで、他のパソコンとの共有(エコー要求)を禁止しておくために「パブリック」のみチェックします。つまり「プライベート」のチェックを外して「OK」をクリックします。これで、家庭内のネットワークに限定することができます。
 (ネットワーク)プロファイルの設定というのは利用環境を設定することを意味します。つまり、「パブリック」と指定した場合、「パブリック」環境で利用するという意味になり、他の(外部の)パソコンからの共有を禁止する動きになります。逆に、「プライベート」環境で利用するにした場合、安全な環境になるので他の(内部の)パソコンからの共有を許可する動きになります。

まとめ

 今回、Wake on Lanアプリを自作しました。ところがアプリを実行したところPingによるパソコンの「死活状態」を確認できないことが判明しました。原因は、Windowsのファイアウォールのブロックによるものでした。ファイアウォールの有効を維持して、Pingの応答のみを有効にすることで解決しました。

タイトルとURLをコピーしました