- // ping.cpp : 定义控制台应用程序的入口点。
- //
-
- #include
- #include
- #include
-
- #define ICMP_ECHO 8
- #define ICMP_ECHOREPLY 0
-
- /* The IP header */
- typedef struct iphdr
- {
- unsigned char h_len:4; // length of the header
- unsigned char version:4; // Version of IP
- unsigned char tos; // Type of service
- unsigned short total_len; // total length of the packet
- unsigned short ident; // unique identifier
- unsigned short frag_and_flags; // flags
- unsigned char ttl;
- unsigned char proto; // protocol (TCP, UDP etc)
- unsigned short checksum; // IP checksum
- unsigned int sourceIP;
- unsigned int destIP;
- }IpHeader;
-
- /* ICMP header */
- typedef struct _ihdr
- {
- BYTE i_type;
- BYTE i_code; /* type sub code */
- USHORT i_cksum;
- USHORT i_id;
- USHORT i_seq; /* This is not the std header, but we reserve space for time */
- ULONG timestamp;
- }IcmpHeader;
-
- #define STATUS_FAILED 0xFFFF
- #define DEF_PACKET_SIZE 32
- #define MAX_PACKET 1024
-
- /* The response is an IP packet. We must decode the IP header to locate the ICMP data */
- void decode_resp(char *buf, int bytes,struct sockaddr_in *from)
- {
- IpHeader *iphdr;
- IcmpHeader *icmphdr;
- unsigned short iphdrlen;
-
- iphdr=(IpHeader*)buf;
- iphdrlen=sizeof(IpHeader)+sizeof(IcmpHeader);
-
- if(bytes
- {
- printf("Too few bytes from %s\n",inet_ntoa(from->sin_addr));
- }
-
- icmphdr=(IcmpHeader*)(buf+sizeof(IpHeader));
- if(icmphdr->i_type!=ICMP_ECHOREPLY)
- {
- fprintf(stderr,"non-echo type %d recvd\n",icmphdr->i_type); return;
- }
-
- if(icmphdr->i_id!=(USHORT)GetCurrentProcessId())
- {
- fprintf(stderr,"someone else's packet!\n"); return ;
- }
-
- int correct=0;
- for(int k=0;k
- {
- if(*(buf+iphdrlen+k)=='E')
- {
- correct++;
- }
- }
-
- printf("来自 %s 的回复: 字节=%d 时间=%dms TTL=%d\n",\
- inet_ntoa(from->sin_addr),correct,GetTickCount()-icmphdr->timestamp,iphdr->ttl);
- }
-
- USHORT checksum(USHORT *buffer, int size)
- {
- unsigned long cksum=0;
-
- while(size>1)
- {
- cksum+=*buffer++;
- size-=sizeof(USHORT);
- }
-
- if(size)
- {
- cksum+=*(UCHAR*)buffer;
- }
-
- cksum=(cksum>>16)+(cksum&0xffff);
- cksum+=(cksum>>16);
-
- return (USHORT)(~cksum);
- }
-
- /* Helper function to fill in various stuff in our ICMP request. */
- void fill_icmp_data(char *icmp_data, int datasize)
- {
- char *datapart=NULL;
- IcmpHeader *icmp_hdr=NULL;
- icmp_hdr=(IcmpHeader*)icmp_data;
- icmp_hdr->i_type=ICMP_ECHO;
- icmp_hdr->i_code=0;
- icmp_hdr->i_id=(USHORT)GetCurrentProcessId();
- icmp_hdr->i_cksum=0;
- icmp_hdr->i_seq++;
- icmp_hdr->timestamp=GetTickCount();
- datapart=icmp_data+sizeof(IcmpHeader); // Place some junk in the buffer.
- memset(datapart,'E',datasize-sizeof(IcmpHeader));
- icmp_hdr->i_cksum=checksum((USHORT*)icmp_data,datasize);
- }
-
- int main(int argc, char *argv[])
- {
- int count=1;
- int error=-1;
- int datasize=0;
- int timeout=3000;
- struct sockaddr_in addrServer;
- struct hostent *phostent=NULL;
- int destlen=sizeof(addrServer);
- char *dest_ip=NULL;
- char icmp_data[MAX_PACKET];
- char recvbuf[MAX_PACKET];
- unsigned int addr=0;
- char srcIP[MAX_PATH]="0.0.0.0";
- char dstIP[MAX_PATH]="127.0.0.1";
-
- for(int n=1;n
- {
- if(!strcmp(argv[n],"-S"))
- {
- n++;strcpy_s(srcIP,argv[n++]);
- }
- else if(!strcmp(argv[n],"-n"))
- {
- n++;count=atoi(argv[n++]);
- }
- else
- {
- strcpy_s(dstIP,argv[n++]);
- }
- }
-
- WSADATA wsaData={0};
- if(WSAStartup(MAKEWORD(1,1),&wsaData)!=0)
- {
- printf("WSA startup error\n");
- ExitProcess(STATUS_FAILED);
- }
-
- SOCKET sockClient=WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, NULL, 0,0);
- if(sockClient==INVALID_SOCKET)
- {
- printf("WSA socket error\n");
- ExitProcess(STATUS_FAILED);
- }
-
- sockaddr_in addrClient;
- addrClient.sin_addr.S_un.S_addr=inet_addr(srcIP);
-
- addrClient.sin_family=AF_INET;
- addrClient.sin_port=htons(0);
-
- error=bind(sockClient,(SOCKADDR *)&addrClient,sizeof(addrClient));
- if(error)
- {
- closesocket(sockClient);
- printf("bind client error\n");
- return WSACleanup();
- }
-
- unsigned long ul=true;
- error=ioctlsocket(sockClient,FIONBIO,(unsigned long*)&ul);
- if(error)
- {
- closesocket(sockClient);
- printf("set ioctlsocket error\n");
- return WSACleanup();
- }
-
- error=setsockopt(sockClient,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout, sizeof(timeout));
- if(error==SOCKET_ERROR)
- {
- fprintf(stderr,"failed to set recv timeout: %d\n",WSAGetLastError());
- ExitProcess(STATUS_FAILED);
- }
-
- error=setsockopt(sockClient,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout, sizeof(timeout));
- if(error==SOCKET_ERROR)
- {
- fprintf(stderr,"failed to set send timeout: %d\n",WSAGetLastError());
- ExitProcess(STATUS_FAILED);
- }
-
- memset(&addrServer,0,sizeof(addrServer));
- phostent=gethostbyname(dstIP);
- if(!phostent)
- {
- addr=inet_addr(dstIP);
- }
-
- if((!phostent)&&(addr==INADDR_NONE))
- {
- fprintf(stderr,"Unable to resolve host %s\n",dstIP);
- ExitProcess(STATUS_FAILED);
- }
-
- if(phostent!=NULL)
- {
- memcpy(&(addrServer.sin_addr),phostent->h_addr,phostent->h_length);
- }
- else
- {
- addrServer.sin_addr.s_addr=addr;
- }
-
- if(phostent)
- {
- addrServer.sin_family=phostent->h_addrtype;
- }
- else
- {
- addrServer.sin_family=AF_INET;
- dest_ip=inet_ntoa(addrServer.sin_addr);
- }
-
- datasize=DEF_PACKET_SIZE;
- datasize+=sizeof(IcmpHeader);
- memset(icmp_data,0,MAX_PACKET);
-
- for(int i=0;i
- {
- fill_icmp_data(icmp_data,datasize);
- int num=sendto(sockClient,icmp_data,datasize,0,(struct sockaddr*)&addrServer, sizeof(addrServer));
- if(num==SOCKET_ERROR)
- {
- error=WSAGetLastError();
- if(error==WSAETIMEDOUT)
- {
- fprintf(stderr,"errorcode=%d\n",error);
- continue;
- }
- }
- if(num
- {
- fprintf(stdout,"Write %d bytes\n",num);
- }
-
- timeval tm;
- int len=sizeof(int);
- fd_set set;
-
- for(int k=0;k<3;k++)
- {
- num=recvfrom(sockClient,recvbuf,MAX_PACKET,0,(struct sockaddr*)&addrServer, &destlen);
- if(num!=SOCKET_ERROR)
- {
- break;
- }
-
- if(num==SOCKET_ERROR)
- {
- Sleep(1);
- tm.tv_sec=0;
- tm.tv_usec=1;
- FD_ZERO(&set);
- FD_SET(sockClient,&set);
- if(select(sockClient,NULL,&set,NULL,&tm)>0)
- {
- getsockopt(sockClient,SOL_SOCKET,SO_ERROR,(char*)&error,&len);
- }
- }
- }
-
- if(num!=SOCKET_ERROR)
- {
- decode_resp(recvbuf,num,&addrServer);
- }
- else
- {
- printf("Can not find host %s\n",dstIP);
- }
- if(i>0)
- {
- Sleep(1000);
- }
- }
-
- closesocket(sockClient);
- WSACleanup();
-
- return 0;
- }
编译命令如下:
g++ -std=c++2a -o ping.exe ping.cpp -lws2_32
-
相关阅读:
神经网络处理器设计原理,神经网络控制系统设计
SCRUM产品负责人(CSPO)认证培训课程
JSON数据和解析
docker打包部署自己的应用
Sentinel整合OpenFeign
【Vue】Router 方法使用
git 查漏补缺
[C++](8)模板的初步了解
justjavac:从辍学到成为Deno核心代码贡献者,我的十年编程生涯
python3 交叉编译环境搭建
-
原文地址:https://blog.csdn.net/princewwj/article/details/133302486