操作系统

Ping程序源码
作者 ghostzhu 2006年01月05日 00:48

    发信人: matrix (矩阵), 信区: NetPrg

    标 题: ping程序源代码

    发信站: 牡丹园 (Mon Jul 22 09:33:59 2002) , 站内信件

    // Module Name: Ping.c

    //

    // Description:

    // This sample illustrates how an ICMP ping app can be written

    // using the SOCK_RAW socket type and IPPROTO_ICMP protocol.

    // By creating a raw socket, the underlying layer does not change

    // the protocol header so that when we submit the ICMP header

    // nothing is changed so that the receiving end will see an

    // ICMP packet. Additionally, we use the record route IP option

    // to get a round trip path to the endpoint. Note that the size

    // of the IP option header that records the route is limited to

    // nine IP addresses.

    //

    // Compile:

    // cl -o Ping Ping.c ws2_32.lib /Zp1

    //

    // Command Line Options/Parameters:

    // Ping [host] [packet-size]

    //

    // host String name of host to ping

    // packet-size Integer size of packet to send

    // (smaller than 1024 bytes)

    //

    //#pragma pack(1)

    #define WIN32_LEAN_AND_MEAN

    #include

    #include

    #include

    #include

    #define IP_RECORD_ROUTE 0x7

    //

    // IP header structure

    //

    typedef struct _iphdr

    {

     unsigned int h_len:4; // Length of the header

     unsigned int 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; // Time to live

     unsigned char proto; // Protocol (TCP, UDP etc)

     unsigned short checksum; // IP checksum

     unsigned int sourceIP;

     unsigned int destIP;

    } IpHeader;

    #define ICMP_ECHO 8

    #define ICMP_ECHOREPLY 0

    #define ICMP_MIN 8 // Minimum 8-byte ICMP packet (header)

    //

    // ICMP header structure

    //

    typedef struct _icmphdr

    {

     BYTE i_type;

     BYTE i_code; // Type sub code

     USHORT i_cksum;

     USHORT i_id;

     USHORT i_seq;

     // This is not the standard header, but we reserve space for time

     ULONG timestamp;

    } IcmpHeader;

    //

    // IP option header - use with socket option IP_OPTIONS

    //

    typedef struct _ipoptionhdr

    {

     unsigned char code; // Option type

     unsigned char len; // Length of option hdr

     unsigned char ptr; // Offset into options

     unsigned long addr[9]; // List of IP addrs

    } IpOptionHeader;

    #define DEF_PACKET_SIZE 32 // Default packet size

    #define MAX_PACKET 1024 // Max ICMP packet size

    #define MAX_IP_HDR_SIZE 60 // Max IP header size w/options

    BOOL bRecordRoute;

    int datasize;

    char *lpdest;

    //

    // Function: usage

    //

    // Description:

    // Print usage information

    //

    void usage(char *progname)

    {

     printf("usage: ping -r [data size]

    ");

     printf(" -r record route

    ");

     printf(" host remote machine to ping

    ");

     printf(" datasize can be up to 1KB

    ");

     ExitProcess(-1);

    }

    //

    // Function: FillICMPData

    //

    // Description:

    // Helper function to fill in various fields for our ICMP request

    //

    void FillICMPData(char *icmp_data, int datasize)

    {

     IcmpHeader *icmp_hdr = NULL;

     char *datapart = NULL;

     icmp_hdr = (IcmpHeader*)icmp_data;

     icmp_hdr->i_type = ICMP_ECHO; // Request an ICMP echo

     icmp_hdr->i_code = 0;

     icmp_hdr->i_id = (USHORT)GetCurrentProcessId();

     icmp_hdr->i_cksum = 0;

     icmp_hdr->i_seq = 0;

    

     datapart = icmp_data + sizeof(IcmpHeader);

     //

     // Place some junk in the buffer

     //

     memset(datapart, E , datasize - sizeof(IcmpHeader));

    }

    //

    // Function: checksum

    //

    // Description:

    // This function calculates the 16-bit one s complement sum

    // of the supplied buffer (ICMP) header

    //

    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);

    }

    //

    // Function: DecodeIPOptions

    //

    // Description:

    // If the IP option header is present, find the IP options

    // within the IP header and print the record route option

    // values

    //

    void DecodeIPOptions(char *buf, int bytes)

    {

     IpOptionHeader *ipopt = NULL;

     IN_ADDR inaddr;

     int i;

     HOSTENT *host = NULL;

     ipopt = (IpOptionHeader *)(buf + 20);

     printf("RR: ");

     for(i = 0; i ptr / 4) - 1; i++)

     {

     inaddr.S_un.S_addr = ipopt->addr;

     if (i != 0)

     printf(" ");

     host = gethostbyaddr((char *)&inaddr.S_un.S_addr,

     sizeof(inaddr.S_un.S_addr), AF_INET);

     if (host)

     printf("(%-15s) %s

    ", inet_ntoa(inaddr), host->h_name);

     else

     printf("(%-15s)

    ", inet_ntoa(inaddr));

     }

     return;

    }

    //

    // Function: DecodeICMPHeader

    //

    // Description:

    // The response is an IP packet. We must decode the IP header to

    // locate the ICMP data.

    //

    void DecodeICMPHeader(char *buf, int bytes,

     struct sockaddr_in *from)

    {

     IpHeader *iphdr = NULL;

     IcmpHeader *icmphdr = NULL;

     unsigned short iphdrlen;

     DWORD tick;

     static int icmpcount = 0;

     iphdr = (IpHeader *)buf;

     // Number of 32-bit words * 4 = bytes

     iphdrlen = iphdr->h_len * 4;

     tick = GetTickCount();

     if ((iphdrlen == MAX_IP_HDR_SIZE) && (!icmpcount))

     DecodeIPOptions(buf, bytes);

     if (bytes sin_addr));

     }

     icmphdr = (IcmpHeader*)(buf + iphdrlen);

     if (icmphdr->i_type != ICMP_ECHOREPLY)

     {

     printf("nonecho type %d recvd

    ", icmphdr->i_type);

     return;

     }

     // Make sure this is an ICMP reply to something we sent!

     //

     if (icmphdr->i_id != (USHORT)GetCurrentProcessId())

     {

     printf("someone else s packet!

    ");

     return ;

     }

     printf("%d bytes from %s:", bytes, inet_ntoa(from->sin_addr));

     printf(" icmp_seq = %d. ", icmphdr->i_seq);

     printf(" time: %d ms", tick - icmphdr->timestamp);

     printf("

    ");

     icmpcount++;

     return;

    }

    void ValidateArgs(int argc, char **argv)

    {

     int i;

     bRecordRoute = FALSE;

     lpdest = NULL;

     datasize = DEF_PACKET_SIZE;

    

     for(i = 1; i h_addr, hp->h_length);

     dest.sin_family = hp->h_addrtype;

     printf("dest.sin_addr = %s

    ", inet_ntoa(dest.sin_addr));

     }

     else

     {

     printf("gethostbyname() failed: %d

    ",

     WSAGetLastError());

     return -1;

     }

     }

     //

     // Create the ICMP packet

     //

     datasize += sizeof(IcmpHeader);

     icmp_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,

     MAX_PACKET);

     recvbuf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,

     MAX_PACKET);

     if (!icmp_data)

     {

     printf("HeapAlloc() failed: %d

    ", GetLastError());

     return -1;

     }

     memset(icmp_data,0,MAX_PACKET);

     FillICMPData(icmp_data,datasize);

     //

     // Start sending/receiving ICMP packets

     //

     while(1)

     {

     static int nCount = 0;

     int bwrote;

    

     if (nCount++ == 4)

     break;

    

     ((IcmpHeader*)icmp_data)->i_cksum = 0;

     ((IcmpHeader*)icmp_data)->timestamp = GetTickCount();

     ((IcmpHeader*)icmp_data)->i_seq = seq_no++;

     ((IcmpHeader*)icmp_data)->i_cksum =

     checksum((USHORT*)icmp_data, datasize);

     bwrote = sendto(sockRaw, icmp_data, datasize, 0,

     (struct sockaddr*)&dest, sizeof(dest));

     if (bwrote == SOCKET_ERROR)

     {

     if (WSAGetLastError() == WSAETIMEDOUT)

     {

     printf("timed out

    ");

     continue;

     }

     printf("sendto() failed: %d

    ", WSAGetLastError());

     return -1;

     }

     if (bwrote

    

    本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/10957/showart_65458.html

Ping程序源码

Ping程序源码

长按识别二维码 进入IT168查看全文

请长按保存图片
{{data.thematic.text}}