Chinaunix首页 | 论坛 | 博客
  • 博客访问: 239488
  • 博文数量: 53
  • 博客积分: 3011
  • 博客等级: 中校
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-10 22:34
文章分类

全部博文(53)

文章存档

2010年(2)

2008年(11)

2007年(40)

我的朋友

分类: C/C++

2008-05-30 21:26:33

  //*******************************************************************
  // A ping program.
  // Copright by Hugo. 2006/03/20
  //*******************************************************************
  #include "stdio.h"
  #include "sys/types.h"
  #include "sys/socket.h"
  #include "netdb.h"
  #include "netinet/in.h"
  #include "netinet/in_systm.h"
  #include "sys/select.h"
  #include "sys/time.h"
  
  // IP Header -- RFC 791
  
  #define ICMP_ECHOREPLY 0
  #define ICMP_ECHO 8
  #define REQ_DATASIZE 32
  typedef struct tagIPHDR
  {
   u_char VIHL; // Version and IHL
   u_char TOS; // Type Of Service
   short TotLen; // Total Length
   short ID; // Identification
   short FlagOff; // Flags and Fragment Offset
   u_char TTL; // Time To Live
   u_char Protocol; // Protocol
   u_short Checksum; // Checksum
   struct in_addr iaSrc; // Internet Address - Source
   struct in_addr iaDst; // Internet Address - Destination
  }IPHDR, *PIPHDR;
  
  // ICMP Header - RFC 792
  typedef struct tagICMPHDR
  {
   u_char Type; // Type
   u_char Code; // Code
   u_short Checksum; // Checksum
   u_short ID; // Identification
   u_short Seq; // Sequence
   char Data; // Data
  }ICMPHDR, *PICMPHDR;
  
  // ICMP Echo Request
  typedef struct tagECHOREQUEST
  {
   ICMPHDR icmpHdr;
   struct timeval echoTime;
   char cData[REQ_DATASIZE];
  }ECHOREQUEST, *PECHOREQUEST;
  
  // ICMP Echo Reply
  typedef struct tagECHOREPLY
  {
   IPHDR ipHdr;
   ECHOREQUEST echoRequest;
   char cFiller[256];
  }ECHOREPLY, *PECHOREPLY;
  
  pid_t pid;
  void tv_sub(struct timeval *out,struct timeval *in);
  unsigned short checksum(unsigned short *buffer, int size);
  int WaitForEchoReply(int socket);
  int main(int argc, char **argv)
  {
   int sockfd;
   int nRet;
   struct sockaddr_in addrDest;
   struct hostent *Dest;
   float spenttime;
   if(argc != 2)
   {
   fprintf(stderr, "usage: %s hostname\n", argv[0]);
   exit(1);
   }
   if ((Dest=gethostbyname(argv[1])) == NULL)
   {
   /* get the host info */
   herror("gethostbyname");
   exit(1);
   }
   printf("Host name : %s\n", Dest->h_name);
  // printf("IP Address : %s\n",inet_ntoa(*((struct in_addr *)Dest->h_addr)));
   if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
   {
   perror("socket");
   exit(1);
   }
  
   addrDest.sin_addr = *((struct in_addr *)Dest->h_addr);
   addrDest.sin_family = AF_INET;
   bzero(&(addrDest.sin_zero), 8);
   ECHOREQUEST echoReq;
   echoReq.icmpHdr.Type = ICMP_ECHO;
   echoReq.icmpHdr.Code = 0;
   echoReq.icmpHdr.ID = getpid();
   int Seq = 0;
   for (nRet = 0; nRet < REQ_DATASIZE; nRet++)
   echoReq.cData[nRet] = ' '+nRet;
  
   while(1){
   echoReq.icmpHdr.Seq = Seq++;
  
   echoReq.icmpHdr.Checksum = 0;
   gettimeofday(&echoReq.echoTime,NULL);
   echoReq.icmpHdr.Checksum = checksum((unsigned short*)&echoReq, sizeof(struct tagECHOREQUEST));
    if (sendto(sockfd, (struct ECHOREQUEST*)&echoReq, sizeof(struct tagECHOREQUEST), 0, (struct sockaddr *)&addrDest, sizeof(addrDest)) < 0)
   {
   perror("sendto");
   exit(1);
   }
   if(WaitForEchoReply(sockfd) == -1)
   {
   perror("select");
   exit(1);
   }
   ECHOREPLY icmpRecv;
   int addr_len;
   addr_len = sizeof(struct sockaddr);
    if (recvfrom(sockfd, (struct ECHOREPLY*)&icmpRecv, sizeof(struct tagECHOREPLY), 0, (struct sockaddr *)&addrDest, &addr_len) < 0)
   {
   perror("sendto");
   }
   else if(icmpRecv.echoRequest.icmpHdr.Type == ICMP_ECHOREPLY)
   {
   gettimeofday(&icmpRecv.echoRequest.echoTime, NULL);
   tv_sub(&icmpRecv.echoRequest.echoTime, &echoReq.echoTime);
   spenttime=icmpRecv.echoRequest.echoTime.tv_sec*1000+icmpRecv.echoRequest.echoTime.tv_usec*0.001;
    printf("Reply from %s: Bytes=%d Id_seq = %d time=%4.3fms TTL=%d\n",Dest->h_name, sizeof(icmpRecv.echoRequest), icmpRecv.echoRequest.icmpHdr.Seq, spenttime,icmpRecv.ipHdr.TTL);
   sleep(1);
   }
   }
  }
  
  unsigned short checksum(unsigned short *buffer, int size)
  {
   unsigned long cksum=0;
  
   while(size >1)
   {
   cksum+=*buffer++;
   size -=sizeof(unsigned short);
   }
   if(size)
   {
   cksum += *(unsigned char*)buffer;
   }
  
   cksum = (cksum >> 16) + (cksum & 0xffff);
   cksum += (cksum >>16);
   return (unsigned short)(~cksum);
  }
  
  //Wait for echoRecv
  int WaitForEchoReply(int socket)
  {
   struct timeval Timeout;
   fd_set readfds;
   FD_ZERO(&readfds);
   FD_SET(socket, &readfds);
   Timeout.tv_sec = 1;
   Timeout.tv_usec = 0;
  
   return(select(socket+1, &readfds, NULL, NULL, &Timeout));
  }
  
  /*timeval*/
  void tv_sub(struct timeval *out,struct timeval *in)
  {
   if( (out->tv_usec-=in->tv_usec)<0)
   {
   --out->tv_sec;
   out->tv_usec+=1000000;
   }
   out->tv_sec-=in->tv_sec;
  }
  
阅读(1466) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~