透析ICMP协议(三): 牛刀初试之一 应用篇ping(ICMP.dll)

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

透析ICMP协议(三): 牛刀初试之一

应用篇ping(ICMP.dll)

===============================

这篇文章出自:http://tangentsoft.net/wskfaq/examples/dllping.html

翻译: bugfree/CSDN, 对原始代码加了些注释

平台: VC6 Windows XP

原理简介:

--------

这个例子演示了应用微软的ICMP.DLL怎样"ping"另一台机器. 这个DLL是没有文档话的发送ICMP回送包API接口, 也称为"pings," 就像潜水员对声纳信号的术语一样. 这段代码出自一个被一个名叫MarkG的家伙的GUI程序, 他的网页已经消失了.

ICMP.DLL API 现在在Windows平台上与微软的Winsocks工作的很好, 但是微软说更好的产品一出来他们将替换它. 微软说这个自从Windows 95时代就在用, 这些功能在在Windows 2000上仍然存在.

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

更详细的ICMP.DLL API的信息到sockets.com的ICMP API网页获取.

具体实现:

--------

// 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"

==================ping的实现部分==================

int doit(int argc, char* argv[])

{//[bugfree] 建议将这个argc和argv的处理拿到main函数中

// 检查命令行参数

if (argc < 2) {

cerr << "usage: ping <host>" << endl;

return 1;

}

// 装载ICMP.DLL连接库

HINSTANCE hIcmp = LoadLibrary("ICMP.DLL");

if (hIcmp == 0) {

cerr << "Unable to locate ICMP.DLL!" << endl;

return 2;

}

// 查找给定机器的IP地址信息

struct hostent* phe;

if ((phe = gethostbyname(argv[1])) == 0) {

cerr << "Could not find IP address for " << argv[1] << endl;

return 3;

}

// 定义函数三个指针类型

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;

//从ICMP.DLL中得到函数入口地址

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;

}

// 打开ping服务

HANDLE hIP = pIcmpCreateFile();

if (hIP == INVALID_HANDLE_VALUE) {

cerr << "Unable to open ping service." << endl;

return 5;

}

// 构造ping数据包

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);

// 发送ping数据包

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;

}

// 关闭,回收资源

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

//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;

链接:

-------

我的其它文章,<<透析ICMP协议>>, 和其它文章参见:

http://www.csdn.net/develop/author/netauthor/bugfree/

联系方式:

-------

zhangliangsd@hotmail.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航