// Ping_Project.cpp : Defines the entry point for the console application.
//
#include
#include "stdafx.h"
#include
#include
#pragma comment(lib,"WS2_32.lib")
char szDestIP[]="119.147.15.11";
int checksum(USHORT* buff, int size);
int recSize=0;
BOOL HandPacket(char * Packet, SOCKADDR_IN sockFrom);
#define PROTO_ICMP 1
#define PROTO_IGMP 2
#define PROTO_TCP 6
#define PROTO_UDP 17
typedef struct _IPHeader // 20字节的IP头
{
UCHAR iphVerLen; // 版本号和头长度(各占4位)
UCHAR ipTOS; // 服务类型
USHORT ipLength; // 封包总长度,即整个IP报的长度
USHORT ipID; // 封包标识,惟一标识发送的每一个数据报
USHORT ipFlags; // 标志
UCHAR ipTTL; // 生存时间,就是TTL
UCHAR ipProtocol; // 协议,可能是TCP、UDP、ICMP等
USHORT ipChecksum; // 校验和
ULONG ipSource; // 源IP地址
ULONG ipDestination; // 目标IP地址
} IPHeader, *PIPHeader;
typedef struct ICMPHeader
{
unsigned char icmp_type;
unsigned char icmp_code;
unsigned short icmp_checksum;
//回显头
unsigned short icmd_id;
unsigned short icmp_sequence;
unsigned long icmp_timestamp;
} ICMPH;
int main(int argc, char* argv[])
{
printf("%d,%d/r/n",sizeof(IPHeader),sizeof(ICMPH));
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2,1),&wsaData) != 0)
;
SOCKET sRaw =socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
SOCKADDR_IN dest;
char sendBuf[sizeof(ICMPHeader)+32];
dest.sin_family = AF_INET;
dest.sin_port = htons(0);
dest.sin_addr.S_un.S_addr = inet_addr(szDestIP);
ICMPHeader *icmpHeader =(ICMPHeader*)sendBuf;
ZeroMemory(icmpHeader, sizeof(ICMPHeader));
icmpHeader->icmp_code = 0;
icmpHeader->icmp_type = 8;
icmpHeader->icmp_checksum = 0;
icmpHeader->icmd_id = (unsigned short)GetCurrentProcessId();
int count=0;
char recBuff[1024];
SOCKADDR_IN from;
int nLen = sizeof(from);
int nRet=0;
while(1)
{
count++;
if (count==4)
{
break;
}
icmpHeader->icmp_code = 0;
icmpHeader->icmp_type = 8;
icmpHeader->icmd_id = (unsigned short)GetCurrentProcessId();
icmpHeader->icmp_sequence =count;
icmpHeader->icmp_timestamp =GetTickCount();
icmpHeader->icmp_checksum =0;//有必要设置为0再算
icmpHeader->icmp_checksum =checksum((USHORT*)sendBuf, sizeof(sendBuf));
sendto(sRaw, sendBuf, sizeof(sendBuf), 0, (SOCKADDR*)&dest, sizeof(dest));
if(nRet == SOCKET_ERROR)
{
printf(" sendto() failed: %d /n", ::WSAGetLastError());
// return -1;
continue;
}
ZeroMemory(recBuff, 1024);
recSize=nRet =recvfrom(sRaw, recBuff, 1024, 0, (SOCKADDR*)&from, &nLen);
if (nRet == SOCKET_ERROR)
{
if (WSAGetLastError()==WSAETIMEDOUT)
{
printf("request time out!/r/n");
return 1;
}
printf(" recvfrom() failed: %d /n", ::WSAGetLastError());
// return -1;
continue;
}
if(nRet < sizeof(IPHeader) + sizeof(ICMPHeader))
{
printf(" Too few bytes from %s /n", ::inet_ntoa(from.sin_addr));
}
HandPacket((char*)recBuff, from);
// Sleep(11);
}
WSACleanup();
return 0;
}
///////////////////////////////////////////////////
int checksum(USHORT* buff, int size)
{
/*
unsigned long cksum = 0;
while(size>1)
{
cksum += *buff++;
size -= sizeof(USHORT);
}
// 是奇数
if(size)
{
cksum += *(UCHAR*)buff;
}
// 将32位的chsum高16位和低16位相加,然后取反
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (USHORT)(~cksum);
*/
int checksum=0;
while(size>1)
{
checksum+=*(buff++);
size-=2;
}
if (size)
{
checksum+=*(UCHAR*)buff;
}
checksum = (checksum>>16)+(checksum&0xffff);
checksum+=checksum>>16;
return ~checksum;
}
BOOL HandPacket(char * Packet, SOCKADDR_IN sockFrom)
{
IPHeader* ipHder=(IPHeader*)Packet;
ICMPHeader *icmphder=(ICMPHeader*)(Packet+sizeof(IPHeader));
if (icmphder->icmd_id!=GetCurrentProcessId())
{
printf("someone else's packet");
return TRUE;
}
if (icmphder->icmp_type!=0)
{
printf("not echo type icmpPacket");
return TRUE;
}
int nTick=GetTickCount();
printf("Reply %d bytes from %s:", strlen((char*)icmphder+sizeof(ICMPHeader)), inet_ntoa(sockFrom.sin_addr));
printf(" icmp_seq=%d. TTL=%d", icmphder->icmp_sequence,ipHder->ipTTL);
printf(" time: %dms Protocol:%d", nTick - icmphder->icmp_timestamp, ipHder->ipProtocol);
printf(" /n");
// printf(" ip: %d /r/n", ipHder->ipSource);
return TRUE;
}
本文来自优快云博客,转载请标明出处:http://blog.youkuaiyun.com/vincent_1011/archive/2009/08/25/4480347.aspx#