//ICMP.DLL を使った ping
//使い方
// Ping*p;
// p=new Ping();
// int r = p->ping("www.google.co.jp");
//
//戻り値が 0 ならばping成功
//0 以外なら失敗
//
//大量のpingを複数のターゲットに向けて送信するときは、
//複数のオブジェクトを作成してスレッドにてpingを実行しても正しく動くはずです。
#pragma comment(lib, "wsock32.lib")
#include <winsock2.h>
HANDLE hIOMutexPing = CreateMutex (NULL, FALSE, NULL);
class Ping{
public:
int RTT;
int TTL;
int ping(char*hostname)
{
typedef struct {
unsigned char Ttl; // Time To Live
unsigned char Tos; // Type Of Service
unsigned char Flags; // IP header flags
unsigned char OptionsSize; // Size in bytes of options data
unsigned char *OptionsData; // Pointer to options data
} IP_OPTION_INFORMATION, * PIP_OPTION_INFORMATION;
typedef struct {
DWORD Address; // Replying address
unsigned long Status; // Reply status
unsigned long RoundTripTime; // RTT in milliseconds
unsigned short DataSize; // Echo data size
unsigned short Reserved; // Reserved for system use
void *Data; // Pointer to the echo data
IP_OPTION_INFORMATION Options;// Reply options
} IP_ECHO_REPLY, * PIP_ECHO_REPLY;
WaitForSingleObject( hIOMutexPing, INFINITE );
WSAData wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0){
ReleaseMutex( hIOMutexPing);
return 1;
}
//ホスト名のIPアドレスを調べます。
HOSTENT*phe = gethostbyname(hostname);
if(phe == NULL){
ReleaseMutex( hIOMutexPing);
return 2;
}
HOSTENT pHost=*phe;
WSACleanup();
ReleaseMutex( hIOMutexPing);
//ICMP.DLLのロード
HINSTANCE hIcmp = LoadLibrary("ICMP.DLL");
if (hIcmp == 0) return 3;
//DLLを関数ポインタに接続します。
typedef HANDLE (WINAPI* pfnHV)(VOID);
typedef BOOL (WINAPI* pfnBH)(HANDLE);
typedef DWORD (WINAPI* pfnDHDPWPipPDD)(HANDLE, DWORD, LPVOID, WORD, PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD);
pfnHV pIcmpCreateFile;
pfnBH pIcmpCloseHandle;
pfnDHDPWPipPDD pIcmpSendEcho;
pIcmpCreateFile = (pfnHV)GetProcAddress(hIcmp,"IcmpCreateFile");
pIcmpCloseHandle = (pfnBH)GetProcAddress(hIcmp,"IcmpCloseHandle");
pIcmpSendEcho = (pfnDHDPWPipPDD)GetProcAddress(hIcmp,"IcmpSendEcho");
if ((pIcmpCreateFile == 0) || (pIcmpCloseHandle == 0) || (pIcmpSendEcho == 0)) return 4;
//開始
HANDLE hIP = pIcmpCreateFile();
if (hIP == INVALID_HANDLE_VALUE) return 5;
//パケットの生成
char acPingBuffer[64];
memset(acPingBuffer, '\xAA', sizeof(acPingBuffer));
PIP_ECHO_REPLY pIpe = (PIP_ECHO_REPLY)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,sizeof(IP_ECHO_REPLY) + sizeof(acPingBuffer));
if (pIpe == 0) return 6;
pIpe->Data = acPingBuffer;
pIpe->DataSize = sizeof(acPingBuffer);
//送受信
DWORD dwStatus = pIcmpSendEcho(hIP,*((DWORD*)pHost.h_addr_list[0]),acPingBuffer,sizeof(acPingBuffer),NULL,pIpe,sizeof(IP_ECHO_REPLY) + sizeof(acPingBuffer),5000);
//終了
GlobalFree(pIpe);
FreeLibrary(hIcmp);
if (dwStatus != 0) {
//Ping成功
RTT=int(pIpe->RoundTripTime);
TTL=int(pIpe->Options.Ttl);
return 0;
}else{
//失敗
return -1;
}
}
};
▲トップページ
>
Windows と C++