IcmpSendEcho 实现 ping

 


#include 
#pragma comment(lib, "Ws2_32.lib")
#include 
#pragma comment(lib, "Iphlpapi.lib")

// Initialize Winsock
struct _tagWinSockInit_t
{
  _tagWinSockInit_t()
  {
    WSADATA wsaData;
    int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if( iResult != 0)
    {
      printf( "WSAStartup failed %u\n", iResult);
    }
  }
  ~_tagWinSockInit_t()
  {
    WSACleanup();
  }
}m_SockInit;

class CIcmpBase
{
protected:
  HANDLE m_hIcmp;

public:
  CIcmpBase()
  {
    m_hIcmp = IcmpCreateFile();
    if(m_hIcmp == INVALID_HANDLE_VALUE)
    {
      printf("IcmpCreateFile failed %u\n", GetLastError());
    }
  }
  virtual ~CIcmpBase()
  {
    if(m_hIcmp != INVALID_HANDLE_VALUE)
    {
      IcmpCloseHandle(m_hIcmp);
      m_hIcmp = INVALID_HANDLE_VALUE;
    }
  }

  //解析目标地址
  BOOL GetHostAddr(LPCSTR sHostName, IPAddr &dstIP)
  {
    BOOL bRet = FALSE;
    struct hostent *remoteHost = gethostbyname(sHostName);
    if(remoteHost)
    {
      dstIP = *(u_long *) remoteHost->h_addr_list[0];
      bRet = TRUE;
    }
    else
    {
      printf("gethostbyname(%s) failed %u\n", 
        sHostName, WSAGetLastError());      
    }
    return bRet;
  }
};

class CIcmpPing : public CIcmpBase
{
public:
  BOOL Ping(LPCSTR sHostName, DWORD dwTmOut=1000)
  {
    int iRet = 0;

    IPAddr dstIP = 0;
    char SendData[32] = {"Fill for test ICMP data"};
    char chAckData[256] = {0};
    ICMP_ECHO_REPLY *pEchoReply = (ICMP_ECHO_REPLY *)chAckData;
    DWORD dwEcho;
    in_addr inAddr;

    if(m_hIcmp != INVALID_HANDLE_VALUE && GetHostAddr(sHostName, dstIP))
    { 
      dwEcho = IcmpSendEcho(m_hIcmp, dstIP, &SendData, sizeof(SendData), 
        NULL, chAckData, sizeof(chAckData), dwTmOut);
      if(dwEcho)
      {
        //输出一些信息
        inAddr.s_addr = pEchoReply->Address;
        printf("Reply from %s: bytes=%d TTL=%d\n", 
          inet_ntoa(inAddr), pEchoReply->DataSize, 
          pEchoReply->Options.Ttl);
        iRet ++;
      }
      else
      {
        printf("IcmpSendEcho failed %u\n", GetLastError());
      }
    }
    return iRet;
  }
};

//测试用例

  CIcmpPing icmp;
  icmp.Ping("127.0.0.1");
  icmp.Ping("www.sina.com.cn");
  

//测试输出

Reply from 127.0.0.1: bytes=32 TTL=64
Reply from 202.102.94.124: bytes=32 TTL=56

你可能感兴趣的:(网络/安全)