当前位置:文档之家› Ping程序的设计与实现

Ping程序的设计与实现

Ping程序的设计与实现Ping的基本实现原理请参考以下文档:/view/e0769dc69ec3d5bbfd0a7476.html;/view/9ee3583143323968011c9213.html;初学者读代码请先百度:socket(),setsockopt(),HeapAlloc()等函数。

使用说明:1、找到\Debug\ping.exe (即生成的可执行文件的目录);(Ping是工程名)2、开始->运行->cmd进入命令提示符模式;3、cd \Debug\ping.exe;然后输入参数即可。

Ping程序源码(无注释)//Ping.h#define WIN32_LEAN_AND_MEAN#include<windows.h>#include<winsock2.h>#include<ws2tcpip.h>#include<stdio.h>#include<stdlib.h>typedef struct tagIP_HEADER{unsigned int h_len:4;unsigned int ver:4;unsigned char tos;unsigned short total_len;unsigned short ident;unsigned short frag_floags;unsigned char ttl;unsigned char protocol;unsigned short checksum;unsigned int sourceip;unsigned int destip;}IP_HEADER,*PIP_HEADER;typedef struct tagIP_OPT_HEADER{unsigned char code;unsigned char len;unsigned char ptr;unsigned long addr[9];}IP_OPT_HEADER,*PIP_OPT_HEADER;typedef struct tagICMP_HEADER{unsigned char type;unsigned char code;unsigned short checksum;unsigned short id;unsigned short seq;unsigned long timestamp;}ICMP_HEADER,*PICMP_HEADER;#define DEF_PACKET_SIZE 32#define MAX_PACKET_SIZE 1024#define ICMP_ECHO 8#define ICMP_ECHOREPL Y 0#define IP_RECORD_ROUTER 7void usageinfo(char *progname);void FillIcmpData(char *icmp_data,int size);USHORT CheckSum(USHORT *buf,int size);void DecodeIcmpHeader(char *buf,int ret,LPSOCKADDR_IN lpSin); void DecodeIpHeader(char *buf,int bytes);//Ping.cpp#include<stdio.h>#include"Ping.h"#pragma comment(lib,"ws2_32")int main(int argc,char *argv[]){if(argc==1){usageinfo(argv[0]);return -1;}BOOL bRecordRout =FALSE;SOCKET hSocket =INV ALID_SOCKET;SOCKADDR_IN dstSin;SOCKADDR_IN fromSin;IP_OPT_HEADER ipOptHeader;char* pIcmpData = 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;case 'd':datasize=atoi(argv[i+1]);i=argc+1;break;}}else if(strchr(argv[i],'.')){int l=strlen(argv[i]);if(l<7||l>15)usageinfo(argv[0]);elselpDstIp=argv[i];}}WSADATA wsaData;WORD wVer=MAKEWORD(2,2);if(WSAStartup(wVer,&wsaData)!=0){printf("WSAStartup Error!\n");return -1;}hSocket=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,NULL,0,WSA_FLAG_OVERLAPPED);if(hSocket==INV ALID_SOCKET){printf("WSASocket Error,Code:%d",WSAGetLastError());WSACleanup();return -1;}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(ipOptH eader)))==SOCKET_ERROR){printf("setsockopt(IP_OPTIONS)error,code:%d",WSAGetLastError());WSACleanup();closesocket(hSocket);return -1;}}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)))==S OCKET_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,&from Len))==SOCKET_ERROR){if(WSAGetLastError()==WSAETIMEDOUT){printf("time out.\n");continue;}printf("recvform fail!\n");closesocket(hSocket);WSACleanup();return -1;}rcvNum++;DecodeIcmpHeader(pRecvData,ret,&fromSin);}printf("\n Ping Statistics for :%s\n",lpDstIp);printf("\t Send=%d Received=%d,Lost=%d(%d%%loss)",4,rcvNum,4-rcvNum,(4-rcvNum)/4*100);if(hSocket!=INV ALID_SOCKET)closesocket(hSocket);HeapFree(GetProcessHeap(),0,pIcmpData);HeapFree(GetProcessHeap(),0,pRecvData);WSACleanup();return 0;}void usageinfo(char *progname){printf("Pingtool,byblode(********************.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){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_ECHOREPL Y){printf("no echo reply %d recved\n",icmpHdr->type);return ;}if(icmpHdr->id!=(USHORT)GetCurrentProcessId()){printf("someone else's packet!\n");return;}printf("Reply form: %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));}}。

相关主题