#include <windows.h>
#include <winsock.h>
#include <stdio.h>
#include <string.h>
//定义IP信息的数据格式
typedef struct tagIPINFO()
{ u_char Ttl; // 生存时间
u_char Tos; // 服务类型
u_char IPFlags; // IP flags
u_char OptSize; // Size of options data
u_char FAR *Options; // Options data buffer
}IPINFO, *PIPINFO;
//定义ICMP信息的数据格式
typedef struct tagICMPECHO
{
u_long Source; // 源地址
u_long Status;
u_long RTTime; // 往返时间
u_short DataSize; // 回发数据大小
u_short Reserved;
void FAR *pData; //存储回发数据
IPINFO ipInfo;
}ICMPECHO, *PICMPECHO;
// ICMP.DLL载入的函数指针
HANDLE (WINAPI *pIcmpCreateFile)(VOID);
BOOL (WINAPI *pIcmpCloseHandle)(HANDLE);
DWORD (WINAPI *pIcmpSendEcho)
(HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD);
//主函数
void main(int argc, char **argv)
{
WSADATA wsaData;
ICMPECHO icmpEcho;
HANDLE hndlIcmp; // 加载 ICMP.DLL得到的句柄
HANDLE hndlFile; // IcmpCreateFile()的句柄
LPHOSTENT pHost; // Pointer to host entry structure
struct in_addr iaDest; // 网络地址结构
DWORD *dwAddress; // IP地址
IPINFO ipInfo; // IP 信息结构
int nRet;
DWORD dwRet;
int x;
// 检查输入参数
if (argc != 2)
{
fprintf(stderr,"\nSyntax: pingi HostNameOrIPAddress\n");
return;
}
// 动态载入 ICMP.DLL
hndlIcmp = LoadLibrary("ICMP.DLL");
if (hndlIcmp == NULL)
{
fprintf(stderr,"\nCould not load ICMP.DLL\n");
return;
}
// 获得 ICMP函数指针
pIcmpCreateFile = (HANDLE (WINAPI *)(void))
GetProcAddress(hndlIcmp,"IcmpCreateFile");
pIcmpCloseHandle = (BOOL (WINAPI *)(HANDLE))
GetProcAddress(hndlIcmp,"IcmpCloseHandle");
pIcmpSendEcho = (DWORD (WINAPI *)
(HANDLE,DWORD,LPVOID,WORD,PIPINFO,LPVOID,DWORD,DWORD))
GetProcAddress(hndlIcmp,"IcmpSendEcho");
//检查所有的ICMP函数指针
if (pIcmpCreateFile == NULL ||
pIcmpCloseHandle == NULL ||
pIcmpSendEcho == NULL)
{
fprintf(stderr,"\nError getting ICMP proc address\n");
FreeLibrary(hndlIcmp);/*释放动态连接库*/
return;
}
// 初始化 WinSock
nRet = WSAStartup(0x0101, &wsaData );
if (nRet)
{
fprintf(stderr,"\nWSAStartup() error: %d\n", nRet);
WSACleanup();
FreeLibrary(hndlIcmp);
return;
}
// 检查WinSock 版本
if (0x0101 != wsaData.wVersion)
{
fprintf(stderr,"\nWinSock version 1.1 not supported\n");
WSACleanup();
FreeLibrary(hndlIcmp);
return;
}
// 查看连接目标
iaDest.s_addr = inet_addr(argv[1]);/*检查输入参数是否为一网络地址*/
if (iaDest.s_addr == INADDR_NONE)
pHost = gethostbyname(argv[1]);/*得到主机的ip和主机名*/
else
pHost = gethostbyaddr((const char *)&iaDest,
sizeof(struct in_addr), AF_INET);
if (pHost == NULL)
{
fprintf(stderr, "\n%s not found\n", argv[1]);
WSACleanup();
FreeLibrary(hndlIcmp);
return;
}
// 输出ping提示
printf("\nPinging %s [%s]", pHost->h_name,
inet_ntoa((*(LPIN_ADDR)pHost->h_addr_list[0])));
// 复制IP 地址
dwAddress = (DWORD *)(*pHost->h_addr_list);
// 得到一个 ICMP 回显句柄
hndlFile = pIcmpCreateFile();
for (x = 0; x < 4; x++)
{
// 设置一些默认值
ipInfo.Ttl = 255;
ipInfo.Tos = 0;
ipInfo.IPFlags = 0;
ipInfo.OptSize = 0;
ipInfo.Options = NULL;
//icmpEcho.ipInfo.Ttl = 256;
// ICMP 回显请求
dwRet = pIcmpSendEcho(
hndlFile, // 从IcmpCreateFile()函数得到的句柄
*dwAddress, // 目标 IP 地址
NULL,
0,
&ipInfo,
&icmpEcho, // 回显缓存区
sizeof(struct tagICMPECHO),
5000); // 等待时间(微秒)
// 输出结果
iaDest.s_addr = icmpEcho.Source;
printf("\nReply from %s Time=%ldms TTL=%d",/*打印被测试主机名,往返时间,生存时间*/
inet_ntoa(iaDest),
icmpEcho.RTTime,
icmpEcho.ipInfo.Ttl);
if (icmpEcho.Status)
{
printf("\nError: icmpEcho.Status=%ld",
icmpEcho.Status);
break;
}
}
printf("\n");
// 关闭回显句柄
pIcmpCloseHandle(hndlFile);
FreeLibrary(hndlIcmp);
WSACleanup();
}
评论0