⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ping.c

📁 ping代码的封装
💻 C
字号:
/** * PING module * * Copyright (C) 2001 Jeffrey Fulmer <jdfulmer@armstrong.com> * This file is part of LIBPING * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */#include <ping.h>#include <util.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#include <pthread.h>#include <stdlib.h>#define  MAXPACKET   65535#define  PKTSIZE     64 #define  HDRLEN      ICMP_MINLEN#define  DATALEN     (PKTSIZE-HDRLEN)#define  MAXDATA     (MAXPKT-HDRLEN-TIMLEN)#define  DEF_TIMEOUT 5#include "private.h"voidJOEfreeprotoent( struct protoent *p ){  char **a;  free( p->p_name );  if( p->p_aliases != NULL ){    for( a = p->p_aliases; *a != NULL; a++ ){      free( *a );    }  }  free( p );}voidJOEfreehostent( struct hostent *h ){  char **p;  free( h->h_name );  if( h->h_aliases != NULL ){    for( p = h->h_aliases; *p != NULL; ++p )      free( *p );    free( h->h_aliases );  }  if( h->h_addr_list != NULL ){    for( p = h->h_addr_list; *p != NULL; ++p )      free( *p );    free (h->h_addr_list);  }  free( h );}static int in_checksum( u_short *buf, int len ){  register long sum = 0;  u_short  answer = 0;  while( len > 1 ){    sum += *buf++;    len -= 2;  }  if( len == 1 ){    *( u_char* )( &answer ) = *( u_char* )buf;    sum += answer;  }  sum = ( sum >> 16 ) + ( sum & 0xffff );  sum += ( sum >> 16 );       answer = ~sum;       return ( answer );} static intsend_ping( const char *host, struct sockaddr_in *taddr, struct ping_priv * datum ){  int len;  int ss;  unsigned char buf[ HDRLEN + DATALEN ];  const  proto_buf_len = 1024;  char   proto_buf[proto_buf_len];  struct protoent *proto = NULL;  struct protoent proto_datum;  struct hostent  *hp = NULL;  struct hostent  hent;  int herrno;  char hbf[9000];#if defined(_AIX)  char *aixbuf;  char *probuf;  int  rc;#endif/*_AIX*/  struct icmp     *icp;  unsigned short  last;  len = HDRLEN + DATALEN;#if defined(__GLIBC__)  /* for systems using GNU libc */  getprotobyname_r("icmp", &proto_datum, proto_buf, proto_buf_len, &proto);  if(( gethostbyname_r( host, &hent, hbf, sizeof(hbf), &hp, &herrno ) < 0 )){    hp = NULL;  }#elif defined(sun)  /* Solaris 5++ */  proto = getprotobyname_r("icmp", &proto_datum, proto_buf, proto_buf_len);  hp    = gethostbyname_r( host, &hent, hbf, sizeof(hbf), &herrno );#elif defined(_AIX)  aixbuf = (char*)xmalloc( 9000 );  probuf = (char*)xmalloc( 9000 );  rc  = getprotobyname_r( "icmp", &proto,                        ( struct protoent_data *)(probuf + sizeof( struct protoent)));  rc  = gethostbyname_r ( host, (struct hostent *)aixbuf,                        (struct hostent_data *)(aixbuf + sizeof(struct hostent)));  hp = (struct hostent*)aixbuf;#elif ( defined(hpux) || defined(__osf__) )  proto  = getprotobyname( "icmp" );   hp     = gethostbyname( host );  herrno = h_errno;#else  /* simply hoping that get*byname is thread-safe */  proto  = getprotobyname( "icmp" );   hp     = gethostbyname( host );  herrno = h_errno;#endif/*OS SPECIFICS*/    if( proto == NULL ) {    return -1;  }  if(hp != NULL ){    memcpy( &taddr->sin_addr, hp->h_addr_list[0], sizeof( taddr->sin_addr ));    taddr->sin_port = 0;    taddr->sin_family = AF_INET;  }  else if( inet_aton( host, &taddr->sin_addr ) == 0 ){    return -1;  }  last = ntohl( taddr->sin_addr.s_addr ) & 0xFF;  if(( last == 0x00 ) || ( last == 0xFF )){    return -1;  }  if(( datum->sock = socket( AF_INET, SOCK_RAW, proto->p_proto )) < 0 ){#ifdef  DEBUG  perror( "sock" );#endif/*DEBUG*/    return -2;  }  icp = (struct icmp *)buf;  icp->icmp_type  = ICMP_ECHO;  icp->icmp_code  = 0;  icp->icmp_cksum = 0;  icp->icmp_id    = getpid() & 0xFFFF;  icp->icmp_cksum = in_checksum((u_short *)icp, len );  if(( ss = sendto( datum->sock, buf, sizeof( buf ), 0,      (struct sockaddr*)taddr, sizeof( *taddr ))) < 0 ){#ifdef  DEBUG  perror( "sock" );#endif/*DEBUG*/    return -2;  }  if( ss != len ){#ifdef  DEBUG  perror( "malformed packet" );#endif/*DEBUG*/    return -2;  }#if defined(_AIX)  free( aixbuf );  free( probuf );#endif   /* JOEfreeprotoent( proto ); */  /* JOEfreeprotoent( &proto_datum ); */  /* JOEfreehostent( hp ); */  /* JOEfreehostent( &hent ); */  return 0;}static int recv_ping( struct sockaddr_in *taddr, struct ping_priv * datum ){  int response;  int len;  int from;  int nf, cc;  unsigned char buf[ HDRLEN + DATALEN ];  struct ip          *ip;  struct icmp        *icp;  struct sockaddr_in faddr;  struct timeval to;  fd_set readset;  to.tv_sec = datum->timo / 100000;  to.tv_usec = ( datum->timo - ( to.tv_sec * 100000 ) ) * 10;  FD_ZERO( &readset );  FD_SET( datum->sock, &readset );  /* we use select to see if there is any activity     on the socket.  If not, then we've requested an     unreachable network and we'll time out here. */  if(( nf = select( datum->sock + 1, &readset, NULL, NULL, &to )) < 0 ){    datum->rrt = -4;#ifdef  DEBUG    perror( "select" );#endif/*DEBUG*/        return 0;  }  if( nf == 0 ){     return -1;   }  len = HDRLEN + DATALEN;  from = sizeof( faddr );   cc = recvfrom( datum->sock, buf, len, 0, (struct sockaddr*)&faddr, &from );  if( cc < 0 ){    datum->rrt = -4;#ifdef  DEBUG    perror( "recvfrom" );#endif/*DEBUG*/        return 0;  }  icp = (struct icmp *)(buf + HDRLEN + DATALEN );  if( faddr.sin_addr.s_addr != taddr->sin_addr.s_addr ){    return 1;  }  /*****  if( icp->icmp_id   != ( getpid() & 0xFFFF )){    printf( "id: %d\n",  icp->icmp_id );    return 1;   }  *****/  return 0;}int myping( const char *hostname, int t , struct ping_priv * datum){  int to;  int err;  int rrt;  struct sockaddr_in sa;  struct timeval mytime;   datum->ident = getpid() & 0xFFFF;  if( t == 0 ) datum->timo = 2;   else         datum->timo = t;  datum->rrt = 0;    (void) gettimeofday( &mytime, (struct timezone *)NULL);   if(( err = send_ping( hostname, &sa, datum)) < 0 ){    close( datum->sock );    return err;  }  do {    rrt = elapsed_time( &mytime );    if (datum->rrt < 0)      return 0;    datum->rrt = rrt;    if (datum->rrt > datum->timo * 1000 ) {      close( datum->sock );      return 0;    }  } while( recv_ping( &sa, datum ));  close( datum->sock );    return 1;}intpinghost( const char *hostname ){  struct ping_priv datum = ping_priv_default();  return myping( hostname, 0, &datum );}intpingthost( const char *hostname, int t ){  struct ping_priv datum = ping_priv_default();  return myping( hostname, t, &datum );}inttpinghost( const char *hostname ){  int ret;  struct ping_priv datum = ping_priv_default();  ret = myping( hostname, 0, &datum );  if(ret > 0 )    ret = datum.rrt;  return ret;} inttpingthost( const char *hostname, int t ){  int ret;  struct ping_priv datum = ping_priv_default();  ret = myping( hostname, t, &datum );  if(ret > 0 )    ret = datum.rrt;  return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -