登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

秒大刀 博客

好好学习 天天向上

 
 
 

日志

 
 
 
 

Ping: ICMP.DLL Method  

2007-11-18 00:20:01|  分类: C/C++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

This example shows how to "ping" another machine using Microsoft's ICMP.DLL. This DLL is an undocumented API for sending ICMP echo packets, also called "pings," after the submariner's term for sonar signals. The code was derived from a GUI program developed by a guy named MarkG, whose web page has disappeared. If anyone knows where he is these days, I'd like to refer them to his page.

The ICMP.DLL API works fine and is present on all current Windows boxes with Microsoft Winsocks, but Microsoft says they'll replace it as soon as something better comes along. Microsoft's been saying this since the Windows 95 days, however, yet this functionality still exists in Windows 2000.

For more information on the ICMP.DLL API, check out sockets.com's ICMP API page.

By the way, you might be wondering why the program has to load the ICMP.DLL manually and get the procedure addresses manually. I'm not sure of the reasons, but I spent an hour trying to get import libraries and DEF files to work.


dllping.cpp

// Borland C++ 5.0: bcc32.cpp ping.cpp  // Visual C++ 5.0:  cl ping.cpp wsock32.lib  //  // This sample program is hereby placed in the public domain.    #include <iostream.h>  #include <winsock.h>  #include <windowsx.h>  #include "icmpdefs.h"    int doit(int argc, char* argv[])  {      // Check for correct command-line args      if (argc < 2) {          cerr << "usage: ping <host>" << endl;          return 1;      }            // Load the ICMP.DLL      HINSTANCE hIcmp = LoadLibrary("ICMP.DLL");      if (hIcmp == 0) {          cerr << "Unable to locate ICMP.DLL!" << endl;          return 2;      }        // Look up an IP address for the given host name      struct hostent* phe;      if ((phe = gethostbyname(argv[1])) == 0) {          cerr << "Could not find IP address for " << argv[1] << endl;          return 3;      }        // Get handles to the functions inside ICMP.DLL that we'll need      typedef HANDLE (WINAPI* pfnHV)(VOID);      typedef BOOL (WINAPI* pfnBH)(HANDLE);      typedef DWORD (WINAPI* pfnDHDPWPipPDD)(HANDLE, DWORD, LPVOID, WORD,              PIP_OPTION_INFORMATION, LPVOID, DWORD, DWORD); // evil, no?      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)) {          cerr << "Failed to get proc addr for function." << endl;          return 4;      }        // Open the ping service      HANDLE hIP = pIcmpCreateFile();      if (hIP == INVALID_HANDLE_VALUE) {          cerr << "Unable to open ping service." << endl;          return 5;      }           // Build ping packet      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) {          cerr << "Failed to allocate global ping packet buffer." << endl;          return 6;      }      pIpe->Data = acPingBuffer;      pIpe->DataSize = sizeof(acPingBuffer);              // Send the ping packet      DWORD dwStatus = pIcmpSendEcho(hIP, *((DWORD*)phe->h_addr_list[0]),               acPingBuffer, sizeof(acPingBuffer), NULL, pIpe,               sizeof(IP_ECHO_REPLY) + sizeof(acPingBuffer), 5000);      if (dwStatus != 0) {          cout << "Addr: " <<                  int(LOBYTE(LOWORD(pIpe->Address))) << "." <<                  int(HIBYTE(LOWORD(pIpe->Address))) << "." <<                  int(LOBYTE(HIWORD(pIpe->Address))) << "." <<                  int(HIBYTE(HIWORD(pIpe->Address))) << ", " <<                  "RTT: " << int(pIpe->RoundTripTime) << "ms, " <<                  "TTL: " << int(pIpe->Options.Ttl) << endl;      }      else {          cerr << "Error obtaining info from ping packet." << endl;      }        // Shut down...      GlobalFree(pIpe);      FreeLibrary(hIcmp);      return 0;  }    int main(int argc, char* argv[])  {      WSAData wsaData;      if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {          return 255;      }        int retval = doit(argc, argv);        WSACleanup();      return retval;  }      

icmpdefs.h

// Structures required to use functions in ICMP.DLL    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;
  评论这张
 
阅读(1135)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018