
最終更新日: 1999年 08月 26日 木曜日
今回は、ニュースグループで質問のあったPINGクラスを公開いたします。詳しい使用法などはいずれ
別の場所で公開予定になっていますので、ヘッダーやクラスの内部構造を理解できる方は使用してみて
ください。
このコードはWPINGおよびSCK99を作成するのに使用したコードをC++のクラスに変換したものです。

void OnKillfocusEdit1()
{
CString hostname;
CPing ping;
char hostaddr[4];
LPHOSTENT sHost;
{ // TimeOut
CString s;
m_edit2.GetWindowText(s);
ping.SetTimeOutTime(LPCTSTR(s));
}
m_edit1.GetWindowText(hostname);
if(hostname.GetLength()==0)return;
if(ping.GetHostName(hostname,hostname,hostaddr,&sHost)==TRUE){
int n;
m_edit1.SetWindowText(hostname);
m_add1.SetAddress( hostaddr[0],hostaddr[1],hostaddr[2],hostaddr[3]);
n = iplist.AddList(sHost);
while(1){
if(ping.GetHostName(hostname,hostname,hostaddr,&sHost)==FALSE)break;
if(iplist.Compare(n,sHost)==0)break;
int n2;
n2 = iplist.AddList(sHost);
break;
}
}else{
AfxMessageBox("サーバーIPアドレスが修得できませんでした");
return;
}
}

// // // Ping.h // #ifndef __PING_HDR__ #define __PING_HDR__ #include#pragma pack(1) #define ICMP_ECHOREPLY 0 #define ICMP_ECHOREQ 8 // IP Header -- RFC 791 typedef struct tagIPHDR { u_char VIHL; // Version and IHL u_char TOS; // Type Of Service short TotLen; // Total Length short ID; // Identification short FlagOff; // Flags and Fragment Offset u_char TTL; // Time To Live u_char Protocol; // Protocol u_short Checksum; // Checksum struct in_addr iaSrc; // Internet Address - Source struct in_addr iaDst; // Internet Address - Destination }IPHDR, *PIPHDR; // ICMP Header - RFC 792 typedef struct tagICMPHDR { u_char Type; // Type u_char Code; // Code u_short Checksum; // Checksum u_short ID; // Identification u_short Seq; // Sequence char Data; // Data }ICMPHDR, *PICMPHDR; #define REQ_DATASIZE 32 // Echo Request Data size // ICMP Echo Request typedef struct tagECHOREQUEST { ICMPHDR icmpHdr; DWORD dwTime; char cData[REQ_DATASIZE]; }ECHOREQUEST, *PECHOREQUEST; // ICMP Echo Reply typedef struct tagECHOREPLY { IPHDR ipHdr; ECHOREQUEST echoRequest; char cFiller[256]; }ECHOREPLY, *PECHOREPLY; #pragma pack() ///////////////////////////// class CPing : public CObject { public: CPing(); virtual ~CPing(); public: CString errstr; private: int timeout; private: u_short in_cksum(u_short *addr, int len); public: void ReportError (LPCTSTR s); int SendEchoRequest (SOCKET s,LPSOCKADDR_IN lpstToAddr); DWORD RecvEchoReply (SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL); int WaitForEchoReply (SOCKET s); public: int GetTimeOutTime(void); void SetTimeOutTime(int s); void SetTimeOutTime(LPCTSTR s); public: DWORD Ping(unsigned long addr,LPDWORD pdwElapsed=NULL,unsigned char * pcTTL=NULL); DWORD Ping(LPCSTR pstrHost,LPDWORD pdwElapsed=NULL,unsigned char* pTTL =NULL); BOOL GetHostName(LPCTSTR pstrHost,CString &hostname,char *hostaddr=NULL,LPHOSTENT* lpDesc=NULL); }; #endif // __PING_HDR__

#include "ping.h"
#pragma comment(lib, "wsock32.lib")
CPing::CPing(){
timeout = 5;
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(1, 1);
int nResult = WSAStartup(wVersionRequested, &wsaData);
if (nResult != 0)return ;
if (LOBYTE(wsaData.wVersion) != 1 || HIBYTE(wsaData.wVersion) != 1){
// Version Error Job
return ;
}
errstr="";
};
CPing::~CPing(){
WSACleanup();
};
int CPing::GetTimeOutTime(void){return timeout;};
void CPing::SetTimeOutTime(int s){timeout=s;};
void CPing::SetTimeOutTime(LPCTSTR s){
SetTimeOutTime(atoi(s));
};
void CPing::ReportError(LPCTSTR s){
errstr=s;
};
int CPing::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr) {
static ECHOREQUEST echoReq;
static nId = 1;
static nSeq = 1;
int nRet;
echoReq.icmpHdr.Type = ICMP_ECHOREQ;
echoReq.icmpHdr.Code = 0;
echoReq.icmpHdr.Checksum = 0;
echoReq.icmpHdr.ID = nId++;
echoReq.icmpHdr.Seq = nSeq++;
for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
echoReq.cData[nRet] = ' '+nRet;
echoReq.dwTime = GetTickCount();
echoReq.icmpHdr.Checksum = in_cksum((u_short *)&echoReq, sizeof(ECHOREQUEST));
nRet = sendto(s,(LPSTR)&echoReq, sizeof(ECHOREQUEST),
0,(LPSOCKADDR)lpstToAddr, sizeof(SOCKADDR_IN));
if (nRet == SOCKET_ERROR) ReportError("sendto()");
return (nRet);
};
DWORD CPing::RecvEchoReply(SOCKET s, LPSOCKADDR_IN lpsaFrom, u_char *pTTL) {
ECHOREPLY echoReply;
int nRet;
int nAddrLen = sizeof(struct sockaddr_in);
nRet = recvfrom(s,(LPSTR)&echoReply,sizeof(ECHOREPLY),0,(LPSOCKADDR)lpsaFrom,&nAddrLen);
if (nRet == SOCKET_ERROR) ReportError("recvfrom()");
*pTTL = echoReply.ipHdr.TTL;
return(echoReply.echoRequest.dwTime);
};
int CPing::WaitForEchoReply(SOCKET s){
struct timeval Timeout;
fd_set readfds;
readfds.fd_count = 1;
readfds.fd_array[0] = s;
Timeout.tv_sec = timeout;
Timeout.tv_usec = 0;
return(select(1, &readfds, NULL, NULL, &Timeout));
};
u_short CPing::in_cksum(u_short *addr, int len){
register int nleft = len;
register u_short *w = addr;
register u_short answer;
register int sum = 0;
while( nleft > 1 ) {
sum += *w++;
nleft -= 2;
}
if( nleft == 1 ) {
u_short u = 0;
*(u_char *)(&u) = *(u_char *)w ;
sum += u;
}
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
answer = ~sum;
return (answer);
};
/////////////////////////////////////////////////////////////
DWORD CPing::Ping(LPCSTR pstrHost,LPDWORD pdwElapsed,unsigned char * pcTTL){
SOCKET rawSocket;
LPHOSTENT lpHost;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
DWORD dwTimeSent;
DWORD dwElapsed;
u_char cTTL;
int nRet;
CString sbk,s;
//
*pcTTL = (unsigned char)-1;
*pdwElapsed = (DWORD)-1;
rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (rawSocket == SOCKET_ERROR)
{ReportError("socket()"); return -1; }
lpHost = gethostbyname(pstrHost);
if (lpHost == NULL){
char buf[80];
wsprintf(buf,"\nHost not found: %s\n", pstrHost);
ReportError(buf); return -1;
}
saDest.sin_addr.s_addr = *((u_long FAR *) (lpHost->h_addr));
saDest.sin_family = AF_INET;
saDest.sin_port = 0;
while(1){
SendEchoRequest(rawSocket, &saDest);
nRet = WaitForEchoReply(rawSocket);
if (nRet == SOCKET_ERROR){ ReportError("select()");break;}
if (!nRet){ ReportError("TimeOut"); break;}
dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL);
dwElapsed = GetTickCount() - dwTimeSent;
break;
}
nRet = closesocket(rawSocket);
if(pdwElapsed!=NULL)*pdwElapsed=dwElapsed;
if(pcTTL!=NULL)*pcTTL=cTTL;
if (nRet == SOCKET_ERROR) {ReportError("closesocket()"); return -1;}
return dwElapsed;
}
DWORD CPing::Ping(unsigned long addr,LPDWORD pdwElapsed,unsigned char * pcTTL){
SOCKET rawSocket;
struct sockaddr_in saDest;
struct sockaddr_in saSrc;
DWORD dwTimeSent;
DWORD dwElapsed =-1;
u_char cTTL=-1;
int nRet;
CString sbk,s;
//
*pcTTL = (unsigned char)-1;
*pdwElapsed = (DWORD)-1;
rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (rawSocket == SOCKET_ERROR) {ReportError("socket()"); return -1; }
saDest.sin_addr.s_addr = addr;
saDest.sin_family = AF_INET;
saDest.sin_port = 0;
while(1){
SendEchoRequest(rawSocket, &saDest);
nRet = WaitForEchoReply(rawSocket);
if (nRet == SOCKET_ERROR){ ReportError("select()");break;}
if (!nRet){ ReportError("TimeOut"); break;}
dwTimeSent = RecvEchoReply(rawSocket, &saSrc, &cTTL);
dwElapsed = GetTickCount() - dwTimeSent;
break;
}
nRet = closesocket(rawSocket);
if(pdwElapsed!=NULL)*pdwElapsed=dwElapsed;
if(pcTTL!=NULL)*pcTTL=cTTL;
if (nRet == SOCKET_ERROR) {ReportError("closesocket()"); return -1;}
return dwElapsed;
}
BOOL CPing::GetHostName(LPCTSTR pstrHost,CString &hostname,char *hostaddr,LPHOSTENT *lpDesc){
SOCKET rawSocket;
LPHOSTENT lpHost;
int nRet;
CString sbk,s;
rawSocket = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if (rawSocket == SOCKET_ERROR)
{ReportError("socket()"); return FALSE; }
lpHost = gethostbyname(pstrHost);
if (lpHost == NULL){
char buf[80];
wsprintf(buf,"\nHost not found: %s\n", pstrHost);
ReportError(buf); return FALSE;
}
if(lpHost->h_aliases!=NULL){
hostname = *lpHost->h_aliases;
if(hostname.GetLength()==0)hostname = lpHost->h_name;
}else hostname = lpHost->h_name;
if(lpDesc!=NULL)*lpDesc=lpHost;
if(hostaddr!=NULL){
for(int i=0;i<4;i++){
char *p = *lpHost->h_addr_list;
hostaddr[i] = p[i];
}
}
nRet = closesocket(rawSocket);
if (nRet == SOCKET_ERROR) {ReportError("closesocket()"); return FALSE;}
return TRUE;
}

Copyright (C) Kitaro 1999