IP ヘルパーの ICMP 関数の使用方法

WinSock 及び IP Helper 関数等では低レベルな機能を利用できるため、非常に柔軟に様々な状況に対応することが可能です。

しかし、低レベルであるが故に、パワフルであることのトレードオフとして、一から色々と実装しなければならず面倒だったりします。

IP Helper 関数群に分類される API として、IP アドレスデータの変換系の API やユーティリティの API がある他、 ARP や ICMP などのプロトコルをサポートするための API もあります。

ここでは ICMP Echo、すなわち Ping を簡単に利用するための IP Helper 関数をみてみましょう。

エラー処理等はかなり端折ってます。assert でチェックしているのみですので、その点ご了承くださいませ。

ICMP 関数の使い方

ICMP 関数で Echo Request を送信して Reply を受け取る手順は次の通りです。

  1. IP アドレスの準備 (IPAddr への変換)
  2. バッファの準備
  3. ICMP ハンドルをオープン
  4. IcmpSendEcho で Echo Request を送信して受信 (ここは同期処理)
  5. 必要に応じて結果の確認
  6. バッファの解放
  7. ICMP ハンドルを閉じる

この手順を実装すると次のようになります。

#include "stdafx.h"

static char* REQDATA = "abcdefghijklmnop";

int main(int argc, char* argv[])
{
	IPAddr ipaddr;
	HANDLE hIcmp = NULL;
	DWORD ret;
	char* pReply = NULL;
	DWORD cbReply = 0;
	DWORD cbRequest = strlen(REQDATA);

	// Destination Address
	ipaddr = inet_addr("127.0.0.1");
	
	// Reply Buffer
	cbReply = sizeof(ICMP_ECHO_REPLY) + cbRequest;
	pReply = (char*) malloc(cbReply);
	assert(pReply);

	// Sending Icmp Request
	hIcmp = IcmpCreateFile();
	assert( INVALID_HANDLE_VALUE != hIcmp );

	ret = IcmpSendEcho(
		hIcmp,
		ipaddr,
		REQDATA,
		cbRequest,
		NULL,
		pReply,
		cbReply,
		5000);

	if(ret){
		PICMP_ECHO_REPLY p = (PICMP_ECHO_REPLY) pReply;
		printf("Status: %d\n", p->Status);
		printf("Round Trip Time: %d\n", p->RoundTripTime);
		printf("Data Size: %d\n", p->DataSize);
		PrintHexDump(p->DataSize, (PBYTE) p->Data);
	}

	free(pReply);
	IcmpCloseHandle(hIcmp);

	return 0;
}

珍しく Visual Studio で試したのでインクルードしているファイルが atdafx.h なんてなってますが、 その中で、assert.h、WinSock2.h、IPHlpApi.h、IcmpAPI.h をインクルードしています。

また、ビルドの設定で ws_win32.lib と iphlpapi.lib をリンクしています。

IP Helper 関数の利用

これを実行すると、ICMP Echo が確認できるはずです。試すときは IP アドレスを適当に変えてください。

念のためネットワークモニタでパケットをとると、確かに 16 バイトの abcd...nop というデータが送られ、それが送り返されたことがわかります。

IP Helper 関数の利用

ちなみに参考のため、コマンドラインから ping コマンドを用いて一度だけ、16 バイトのデータを送るには次のようにします。

> ping -n 1 -l 16 127.0.0.1

Linux ではオプションが少し違って次の通り。

$ ping -c 1 -s 16 127.0.0.1

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説