Windows系统ping命令的c++实现

// 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(bytessin_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;ksin_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;nh_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;i0)        
                {            
                    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

Windows系统ping命令的c++实现_第1张图片

你可能感兴趣的:(windows,c++,ping)