现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

VC判断目标主机是否存活,模拟系统的ping

2014-06-17 06:45 工业·编程 ⁄ 共 9291字 ⁄ 字号 暂无评论

<windows网络编程>第13章的例子,PS:有防火墙则无效.

//   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   <winsock2.h>  
  #include   <ws2tcpip.h>  
  #include   <stdio.h>  
  #include   <stdlib.h>  
   
  #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   <host>   [data   size]/n");  
          printf("               -r                       record   route/n");  
          printf("                 host                 remote   machine   to   ping/n");  
          printf("                 datasize         can   be   up   to   1KB/n");  
          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   <   (ipopt->ptr   /   4)   -   1;   i++)  
          {  
                  inaddr.S_un.S_addr   =   ipopt->addr[i];  
                  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/n",   inet_ntoa(inaddr),   host->h_name);  
                  else  
                          printf("(%-15s)/n",   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     <   iphdrlen   +   ICMP_MIN)    
          {  
                  printf("Too   few   bytes   from   %s/n",    
                          inet_ntoa(from->sin_addr));  
          }  
          icmphdr   =   (IcmpHeader*)(buf   +   iphdrlen);  
   
          if   (icmphdr->i_type   !=   ICMP_ECHOREPLY)    
          {  
                  printf("nonecho   type   %d   recvd/n",   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!/n");  
                  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("/n");  
   
          icmpcount++;  
          return;  
  }  
   
  void   ValidateArgs(int   argc,   char   **argv)  
  {  
          int  i;  
   
          bRecordRoute   =   FALSE;  
          lpdest   =   NULL;  
          datasize   =   DEF_PACKET_SIZE;  
           
          for(i   =   1;   i   <   argc;   i++)  
          {  
                  if   ((argv[i][0]   ==   '-')   ||   (argv[i][0]   ==   '/'))  
                  {  
                          switch   (tolower(argv[i][1]))  
                          {  
                                  case   'r':                 //   Record   route   option  
                                          bRecordRoute   =   TRUE;  
                                          break;  
                                  default:  
                                          usage(argv[0]);  
                                          break;  
                          }  
                  }  
                  else   if   (isdigit(argv[i][0]))  
                          datasize   =   atoi(argv[i]);  
                  else  
                          lpdest   =   argv[i];  
          }  
  }  

给我留言

留言无头像?