#include <iostream>
#include <windows.h>
using namespace std;#define MAX_ICMP_PACKET_SIZE 1024
#define MAXBFRSIZE 2048
#define MAX_HOPS 30typedef SOCKET* LPSOCKET;
typedef in_addr* LPINADDR;typedef struct _IpHeader
{
unsigned int HeaderLength:4; //IP首部长度
unsigned int Version:4; //IP的版本
unsigned int TypeOfService; //服务类型
unsigned short TotalLength; //总的数据包大小
unsigned short Identification; //特殊标识符
unsigned char TTL; //Time To Live
unsigned char Protocol; //协议类型(TCP,UDP等)
unsigned short CheckSum; //校验和
unsigned int sourceIPAddress; //源地址
unsigned int destIPAddress; //目的地址
}IpHeader;typedef IpHeader FAR* LPIpHeader;#define IpHeaderLength sizeof(IpHeader)typedef struct _IcmpHeader
{
unsigned char IcmpType; //ICMP报文类型
unsigned char IcmpCode; //ICMP代码
unsigned short IcmpCheckSum; //校验和
unsigned short IcmpId; //标识符
unsigned short IcmpSeq; //序列号
unsigned long IcmpTimestamp; //时间戳,非标准字段
}IcmpHeader;typedef IcmpHeader FAR* LPIcmpHeader;#define IcmpHeaderLength sizeof(IcmpHeader)#define MAX_PACKET 2000 + IcmpHeaderLength
#define ICMP_ECHO 8
#define ICMP_ECHOREPLY 0
#define ICMP_MIN 8 //最小为8字节的icmp包(仅包头)int main()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;

wVersionRequested = MAKEWORD( 2, 2 );

err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) 
{   
return err;
}

if ( LOBYTE( wsaData.wVersion ) != 2 ||
        HIBYTE( wsaData.wVersion ) != 2 ) 
{
WSACleanup();
return -1; 
} cout << "ping " << endl;
string strIp = "";
// cin >> strIp; SOCKET s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
if(s == INVALID_SOCKET)
{
cout << "Create Socket Error!" << endl;
} SOCKADDR_IN addrDest;
ZeroMemory(&addrDest, sizeof(addrDest)); addrDest.sin_addr.s_addr = inet_addr("127.0.0.1");
addrDest.sin_family = AF_INET;
addrDest.sin_port = htons(0); char *buffer = new char[sizeof(IcmpHeader)+ 32];
IcmpHeader* icmp = (IcmpHeader *)(buffer);
// ZeroMemory(&icmp, sizeof(icmp));
icmp->IcmpType = 8;//回显请求类型
icmp->IcmpCode = 0;
icmp->IcmpId = GetCurrentProcessId();
icmp->IcmpCheckSum = 0;
icmp->IcmpSeq = 0;
icmp->IcmpTimestamp = GetTickCount(); memset(&icmp[sizeof(IcmpHeader)], '@', 32); //计算校验和
unsigned long ulSum = 0;
unsigned short* pBuffer = (unsigned short*)(&icmp);
int nSize = sizeof(icmp);
for(int nIndex = 0; nSize > 1; nSize -= sizeof(short int), ++nIndex)
ulSum += pBuffer[nIndex]; if(nSize != 0)
{
ulSum += pBuffer[nIndex];
} ulSum = (ulSum >> 16) + (ulSum & 0xFFFF);
ulSum += (ulSum >> 16); icmp->IcmpCheckSum = (unsigned short)(~ulSum);
//发送ICMP数据报
int nSendResult = sendto(s, buffer, sizeof(IcmpHeader) + 32, 0, (sockaddr*)(&addrDest), sizeof(addrDest)); if(nSendResult == SOCKET_ERROR)
{
cout << GetLastError() << endl;
}// Sleep(5000); char *pRecvBuf = new char[MAX_ICMP_PACKET_SIZE]; sockaddr_in addrSend;
ZeroMemory(&addrSend, sizeof(addrSend)); addrSend.sin_family = AF_INET;
addrSend.sin_addr.s_addr = htonl(INADDR_ANY);
addrSend.sin_port = htons(0); int nAddrSend = sizeof(addrSend);// bind(s, (sockaddr*)&addrSend, sizeof(addrSend)); UINT nRecvLength = recvfrom(s, pRecvBuf, MAX_ICMP_PACKET_SIZE, 0, (sockaddr*)(&addrSend), &nAddrSend); IcmpHeader *icmpRecv = (IcmpHeader*)pRecvBuf; cout << icmpRecv->IcmpTimestamp; WSACleanup();
return 0;
}