123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- #pragma once
- #include "StdAfx.h"
- #include "MyPingip.h"
- //#include <iphlpapi.h>
- //#pragma comment (lib , "Iphlpapi.lib")
- #pragma comment (lib , "wsock32.lib")
- #pragma warning(disable : 4996)
- #define WM_MSG_STATUS WM_USER + 100
- CMyPingip::CMyPingip(void)
- {
- }
- CMyPingip::~CMyPingip(void)
- {
- }
- bool CMyPingip::PingFunction(LPCSTR pstrHost)
- {
- UINT nRetries = 5;
- int nLostConnectCnt = 0;
- bool bRet = true;
- WSADATA wsaData;
- WORD wVersionRequested;
- wVersionRequested = MAKEWORD( 2, 0 );
- if(WSAStartup(wVersionRequested ,&wsaData) != 0)
- {
- return false;
- }
- SOCKET rawSocket;
- UINT nLoop;
- int nRet;
- struct sockaddr_in saDest;
- struct sockaddr_in saSrc;
- DWORD dwTimeSent;
- DWORD dwElapsed;
- u_char cTTL;
- //创建一个Raw套接字
- rawSocket = socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
- if (rawSocket == SOCKET_ERROR)
- {
- //PRINTA_INFO(pLog, "Create Socket Error – WSAError: %ld", WSAGetLastError());
- return false;
- }
- //获得主机信息
- //lpHost = gethostbyname(pstrHost);
- //构造目标套接字地址信息
- saDest.sin_addr.s_addr = inet_addr(pstrHost)/**((u_long FAR *)(lpHost->h_addr))*/;
- saDest.sin_family = AF_INET;
- saDest.sin_port = 0;
- //ping
- for (nLoop = 0; nLoop < nRetries; nLoop++)
- {
- //发送ICMP回应请求
- SendEchoRequest(rawSocket, &saDest);
- nRet = WaitForEchoReply(rawSocket);
- if (!nRet) //没有回应,不再一个IP段
- {
- //PRINTA_INFO(pLog, "Request Timed Out");
- nLostConnectCnt++;
- }
- else //在一个IP段,回应正确或者回应不可达
- {
- dwTimeSent = RecvEchoReply(rawSocket,&saSrc,&cTTL); //获得回应
- LPCSTR strIp = inet_ntoa(saSrc.sin_addr);
- if (strcmp(strIp,pstrHost)==0 )
- {
- dwElapsed = GetTickCount()-dwTimeSent; //计算时间
- //PRINTA_INFO(pLog, "Reply from: %s: bytes=%d time=%d ms TTL=%d", strIp, REQ_DATASIZE, dwElapsed, cTTL);
- }
- else
- {
- nLostConnectCnt++;
- //PRINTA_INFO(pLog, "Reply from: %s: Destination host unreachable", strIp);
- }
- }
- }
- nRet = closesocket(rawSocket);
- if (nRet == SOCKET_ERROR)
- {
- //PRINTA_INFO(pLog, "Close Socket Error – WSAError: %ld", WSAGetLastError());
- }
- WSACleanup();
- if (nLostConnectCnt>=3)
- {
- bRet = false;
- }
- return bRet;
- }
- //发送ICMPECHO数据包请求
- int CMyPingip::SendEchoRequest(SOCKET s,LPSOCKADDR_IN lpstToAddr)
- {
- static ECHOREQUEST echo;
- static int nId = 1;
- static int nSeq = 1;
- int nRet;
- //构造回应请求
- echo.icmpHdr.Type = 8;
- echo.icmpHdr.Code = 0;
- echo.icmpHdr.Checksum = 0;
- echo.icmpHdr.ID = nId++;
- echo.icmpHdr.Seq = nSeq++;
- for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
- {
- echo.cData[nRet] = ' ' + nRet;
- }
- //保存发送时间
- echo.dwTime = GetTickCount();
- echo.icmpHdr.Checksum = in_cksum((u_short *)&echo,sizeof(ECHOREQUEST));
- //发送请求
- nRet = sendto(s, (LPSTR)&echo, sizeof(ECHOREQUEST), 0, (LPSOCKADDR)lpstToAddr, sizeof(SOCKADDR_IN));
- if (nRet == SOCKET_ERROR)
- {
- //CString strMsg;
- //strMsg.Format("发送数据时发生错误 – WSAError: %ld",WSAGetLastError());
- //发送报错信息
- //SendMessage(m_hWnd,WM_MSG_STATUS,0,(LPARAM) AllocBuffer(strMsg));
- }
- return (nRet);
- }
- //接收ICMPECHO数据包回应
- DWORD CMyPingip::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)
- {
- //CString strMsg;
- //strMsg.Format("接收数据时发生错误 – WSAError: %ld",WSAGetLastError());
- //发送报错信息
- //SendMessage(m_hWnd,WM_MSG_STATUS,0,(LPARAM) AllocBuffer(strMsg));
- }
- //返回发送的时间
- *pTTL = echoReply.iphdr.TTL;
- return(echoReply.echorequest.dwTime);
- }
- //等待回应
- int CMyPingip::WaitForEchoReply(SOCKET s)
- {
- struct timeval Time;
- fd_set fds;
- fds.fd_count = 1;
- fds.fd_array[0] = s;
- Time.tv_sec = 1;
- Time.tv_usec = 0;
- return(select(1,&fds,NULL,NULL,&Time));
- }
- //转换地址
- u_short CMyPingip::in_cksum(u_short *addr,int len)
- {
- int nleft = len;
- u_short *n = addr;
- u_short answer;
- int sum = 0;
- while(nleft > 1)
- {
- sum += *n++;
- nleft -= 2;
- }
- if(nleft == 1)
- {
- u_short u = 0;
- *(u_char *)(&u) = *(u_char *)n;
- sum += u;
- }
- sum = (sum >> 16) + (sum & 0xffff);
- sum += (sum >> 16);
- answer = ~sum;
- return (answer);
- }
|