15,447
社区成员




#include"Ping.h"int main(int argc,char *argv[]){//erro:return-1,no err:return 0 if(argc==1) { usageinfo(argv[0]); return -1; } BOOL bRecordRout =FALSE; SOCKET hSocket =INVALID_SOCKET; SOCKADDR_IN dstSin; SOCKADDR_IN fromSin; IP_OPT_HEADER ipOptHeader; char* plcmData =NULL; char* pRecvData =NULL; char* lpDstIp =NULL; int datasize =DEF_PACKET_SIZE; int ret; int rcvNum; for(int i=1;i<argc;i++) { if(strchr(argv[i],'-')){ switch(tolower(argv[i][1])){ case'r': bRecordRout=TRUE; break; } } else if(strchr(argv[i],'.')){ int l=strlen(argv[i]); if(l<7||l>15) usageinfo(argv[0]); else lpDstIp=argv[i]; } } //initiate winsock // WSADATA wsaData; WORD wVer=MAKEWORD(2,2); if(WSAStartup(wVer,&wsaData)!=0){ printf("WSAStarup Erro!\n"); return -1; //err,return -1, } //createsocket handle // hSocket=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED); if(hSocket==INVALID_SOCKET) { printf("WSASocket Erro,Code:%d",WSAGetLastError()); WSACleanup(); return -1; } //set ip option header(record router) if(bRecordRout) { ZeroMemory(&ipOptHeader,sizeof(ipOptHeader)); ipOptHeader.code=IP_RECORD_ROUTER; ipOptHeader.len=39; ipOptHeader.ptr=4; if((ret=setsockopt(hSocket,IPPROTO_IP,IP_OPTIONS,(char*)&ipOptHeader,sizeof(ipOptHeader)))==SOCKET_ERROR){ printf("setsockopt(IP_OPTIONS)error,code:%d",WSAGetLastError()); WSACleanup(); closesocket(hSocket); return -1; } } //set socket recv and send timeout; int timeout=1000; if ((ret=setsockopt(hSocket,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout)))==SOCKET_ERROR) { printf("setsockopt(SO_RCVTIMEO)error,code:%d",WSAGetLastError()); WSACleanup(); closesocket(hSocket); return -1; } if ((ret=setsockopt(hSocket,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout)))==SOCKET_ERROR) { printf("setsockopt(SO_SNDTIMEO)error,code:%d",WSAGetLastError()); WSACleanup(); return -1; } pIcmpData=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET_SIZE); pRecvData=(char*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,MAX_PACKET_SIZE); if(pIcmpData==NULL||pRecvData==NULL) { printf("HeapAlloc Error\n"); WSACleanup(); return -1; } datasize+=sizeof(ICMP_HEADER); ZeroMemory(&dstSin,sizeof(dstSin)); dstSin.sin_family=AF_INET; dstSin.sin_addr.s_addr=inet_addr(lpDstIp); FillIcmpData(pIcmpData,datasize); printf("Ping %s with %d bytes of data\n",inet_ntoa(dstSin.sin_addr),datasize); int count=0; int seq=0; rcvNum=0; while(1) { count++; if(count==5) break; ((PICMP_HEADER)pIcmpData)->checksum=0; ((PICMP_HEADER)pIcmpData)->seq=seq++; ((PICMP_HEADER)pIcmpData)->timestamp=GetTickCount(); ((PICMP_HEADER)pIcmpData)->checksum=CheckSum((USHORT*)pIcmpData,datasize); if((ret=sendto(hSocket,pIcmpData,datasize,0,(LPSOCKADDR)&dstSin,sizeof(dstSin)==SOCKET_ERROR))) { if(WSAGetLastError()==WSAETIMEDOUT) { printf("time out.\n"); continue; } else { printf("sendto error,code:%d",WSAGetLastError()); closesocket(hSocket); WSACleanup(); return -1; } } int fromLen=sizeof(fromSin); if((ret=recvfrom(hSocket,pRecvData,MAX_PACKET_SIZE,0,(sockaddr*)&fromSin,&fromLen))==SOCKET_ERROR) { if(WSAGetLastError()==WSAETIMEDOUT) { printf("time out.\n"); continue; } printf("recvfrom fail!\n"); closesocket(hSocket); WSACleanup(); return -1; } rcvNum++; DecodeIcmpHeader(pRecvData,ret,&fromSin); } printf("\n Ping Statistics for:%s\n",lpDstIp); printf("\t Send= %d, Recieved= %d,Lost= %d (%d%%loss)",4,rcvNum,4-rcvNum,(4-rcvNum)/4*100); if(hSocket!=INVALID_SOCKET) closesocket(hSocket); HeapFree(GetProcessHeap(),0,pIcmpData); HeapFree(GetProcessHeap(),0,pRecvData); WSACleanup(); return 0;}void usageinfo(char *progname){ printf("Ping tool,by blode(blode@peoplemail.com.cn\n)"); printf("usage:ping[-r]<host ip>[-d][data size])\n"); printf("\t-r:\trecord router\n"); printf("\thost ip:\thost ip to ping\n"); printf("\t-d:\tuse data size option\n"); printf("\tdata size:\tdata size to ping(<=1024)\n");}void FillIcmpData(char *icmp_data,int size){ ICMP_HEADER *icmpHdr; icmpHdr=(PICMP_HEADER)icmp_data; icmpHdr->checksum=0; icmpHdr->code=0; icmpHdr->id=(unsigned short)GetCurrentProcessId(); icmpHdr->seq=0; icmpHdr->type=ICMP_ECHO; icmpHdr->timestamp=0;}USHORT CheckSum(USHORT *buf,int size){ //check sum funtion USHORT cksum=0; while(size>1) { cksum+=*buf++; size-=sizeof(USHORT); } if(size) cksum+=*buf++; cksum=(cksum>>16)+(cksum&0xffff); cksum+=(cksum>>16); return(USHORT)(-cksum);}void DecodeIcmpHeader(char *buf,int ret,LPSOCKADDR_IN lpSin){ ICMP_HEADER *icmpHdr; IP_HEADER *ipHdr; int ipHdrLen; static int first=0; DWORD tick=GetTickCount(); ipHdr=(IP_HEADER*)buf; ipHdrLen=ipHdr->h_len*4; if(ipHdrLen==60&&!first) DecodeIpHeader(buf,ret); icmpHdr=(ICMP_HEADER*)(buf+ipHdrLen); if(icmpHdr->type!=ICMP_ECHOREPLY){ printf("no echo reply %d recved\n",icmpHdr->type); return; } if(icmpHdr->id!=(USHORT)GetCurrentProcessId()){ printf("someone else's packet!\n"); return; } printf("Reply from:%s",inet_ntoa(lpSin->sin_addr)); printf("\tbytes:%d icmp seq:%d TTL=128",ret,icmpHdr->seq); printf(" time:%dms\n",tick-icmpHdr->timestamp); first++; return;}void DecodeIpHeader(char *buf,int bytes){ IP_OPT_HEADER *ipOptHdr; IN_ADDR in; ipOptHdr=(IP_OPT_HEADER*)(buf+20); printf("Record Router:"); for(int i=0;i<(ipOptHdr->ptr/4)-1;i++){ in.S_un.S_addr=ipOptHdr->addr[i]; printf("\t%-15s\n",inet_ntoa(in)); }}