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

📄 ping.c

📁 判断网络上某个TCP/IP主机是否可以连通的C函数库
💻 C
字号:
#include "./include.h"char usage[]="Usage:Ping [-drv] host [datasize] [npackets]\n";char hnamebuf[MAXHOSTNAMELEN];char *pname;main(argc, argv)int argc;char **argv;{	int sockoption, on;	char *destdotaddr ;	struct protoent *proto; 	/*--- include in netdb.h ---*/	struct hostent  *host;	extern void sig_finish();	extern void sig_alarm();	on=1;	ntransmitted = 0;	npackets = 0 ;	timing = 0;	verbose = 0 ;	pname = argv[0];	// pin	argc --;	argv++;	sockoption = 0;	while( argc > 0 && *argv[0] == '-' ) {		while(*++argv[0]) switch( *argv[0]) {			case 'd':				sockoption |= SO_DEBUG;				break;			case 'r':				sockoption |= SO_DONTROUTE;				break;			case 'v':				verbose ++;				break;		}		argc --; argv ++;	}	if ( argc < 1 ) err_sys( usage ) ;	/*---------------------------------------	**  struct sockaddr_in {	**	short sin_family;	**	u_short sin_port;	**	struct in_addr sin_addr ;	**	char sin_zero[8];	**	}	**  struct in_addr {	**	u_long          s_addr;	**	};	**-------------------------------------*/	bzero( (char *) &dest, sizeof( dest ) );	dest.sin_family = AF_INET;	if( (dest.sin_addr.s_addr=inet_addr(argv[0]) ) != INADDR_NONE ) {		/*------ 格式: 130.150.160.1 -------*/		strcpy( hnamebuf, argv[0] );		hostname = hnamebuf ; 		destdotaddr = NULL;	} 	else {		/*------ 格式: lsd01 ---------------*/	/*----------  struct hostent (netdb.h)-----------------	**struct hostent {	**	char    *h_name;	official name of host	**	char    **h_aliases;	alias list	**	int     h_addrtype;	host address type	**	int     h_length;	length of address	**	char    **h_addr_list;	list of addresses from name server	**      #define	h_addr	h_addr_list[0]	**--------------------------------------------*/		if ( ( host=gethostbyname( argv[0] )) == NULL ) {			err_quit( "主机名(%s)出错 \n", argv[0] );		}		dest.sin_family = host->h_addrtype;		bcopy( host->h_addr, (caddr_t)&dest.sin_addr,host->h_length);		hostname = host->h_name;		/*--- inet_ntoa 将LONG地址转换成130.150.160.10 ----*/		destdotaddr = (char *)inet_ntoa( dest.sin_addr.s_addr );	}	if ( argc >= 2 ) datalen = atoi( argv[1] );	else		 datalen = DEF_DATALEN;	packsize = datalen + SIZE_ICMP_HDR ;	if ( packsize > MAXPACKET ) 		err_quit( "ICMP包大小不能大于%d\n" ,MAXPACKET-SIZE_ICMP_HDR);	if ( datalen >= SIZE_TIME_DATA ) timing = 1;	if ( argc > 2 ) npackets = atoi ( argv[2] );	ident = getpid() & 0xffff;		/* why & 0xffff ? */	/*--------------------(include in dbnet.h)----------------	**struct protoent {	**	char           *p_name;		official protocol name 	**	char          **p_aliases;	alias list 	**	int             p_proto;	protocol # 	**-----------------------------------------------------*/	if ( (proto=getprotobyname( "icmp" ) ) == NULL )		err_sys( "ICMP PROTO IS NOT CREATE! " );	if ( ( sockfd == socket( AF_INET, SOCK_RAW, proto->p_proto ) ) < 0 )		err_sys( "不能创建SOCKET!" );	if ( sockoption & SO_DEBUG ) 		if ( setsockopt( sockfd, SOL_SOCKET, SO_DEBUG, &on, 			sizeof(on) ) < 0 ) 			err_sys( "设置SO_DEBUG出错\n" ) ;	if( sockoption & SO_DONTROUTE ) 		if ( setsockopt( sockfd, SOL_SOCKET, SO_DONTROUTE, &on, 			sizeof(on) ) < 0 ) 			err_sys( "设置SO_DONTROUTE出错\n" ) ;	/*-------- 输出提示信息 -----------*/	printf( "PING %s", hostname );			if ( destdotaddr) 	//格式lsd01		printf( "(%s)", destdotaddr); 	printf( ":%d 字节\n" , datalen );			tmin = 99999999;	/*	setlinebuf( stdout ) ;	*/	signal ( SIGINT, sig_finish );	signal ( SIGALRM,sig_alarm );	sig_alarm ();	recv_ping();}/***	时间信号处理***/void sig_alarm(){	int waittime;	extern void sig_finish();	send_ping();	if ( npackets == 0 || ntransmitted < npackets ) 		alarm(1);	else {		npackets = 1;		if ( nreceived ) {			waittime = 2 * tmax /1000;			if ( waittime == 0 ) waittime = 1;		}else {			waittime = MAXWAIT ;			signal ( SIGALRM, sig_finish );			alarm ( waittime );		}		return ;	}}/***	每隔一个时间片发送ICMP包***/send_ping(){	register int i;	register struct icmp *icp;	register u_char *uptr;	/*--- ICMP 包头 ----*/	/* struct icmp {	**	u_char 	icmp_type ;		**	u_char  icmp_code ;	**	u_short icmp_chksum;     包检查大小	**	u_short icmp_id ;	**	u_short icmp_seq;	**	char 	icmp_data[1];	 经常放时间 	*/	icp = (struct icmp *) sendpack;   /* u_char sendpack[MAXPACKET]; */	icp->icmp_type = ICMP_ECHO;	icp->icmp_code = 0;	icp->icmp_cksum = 0;	icp->icmp_id = ident;	icp->icmp_seq = ntransmitted ++;		if ( timing ) 		/**----- datalen >= SIZE_TIME_DATA ) ----------**/		/**--------放时间于icmp_data[SIZE_TIME_DATA]---**/		gettimeofday( (struct timeval *) &sendpack[SIZE_ICMP_HDR],				(struct tiemzone *) 0 );	/**--- 填充ICMP包从SIZE_ICMP_HDR+SIZE_TIME_DATA(def=16)起(def=56)个 --*/	uptr = &sendpack[SIZE_ICMP_HDR+SIZE_TIME_DATA];	for ( i = SIZE_TIME_DATA; i< datalen; i++ )		*uptr++ = i;	icp->icmp_cksum=in_chksum( icp, packsize );	i = sendto( sockfd, sendpack , packsize , 0, (struct sockaddr *)&dest,		sizeof( dest ) );	if ( i < 0 || i != packsize ) {		if ( i < 0 ) {			err_sys( "sendto error " ) ;		}		else err_quit( "wrote %s %d bytes , return = %d\n", 				hostname , packsize , i ) ;	}}/***	得出ICMP包大小的校验值****/int in_chksum( ptr, nbytes ) u_short *ptr ;int nbytes ;{	register long sum;	u_short       oddbyte;	register u_short answer;	sum = 0 ;	/***------ 两位一次检查 ------**/	while( nbytes>1 ) {		sum+=*ptr++;		nbytes-=2;	}	if ( nbytes == 1 ) {		/**----- 剩下最后一位,加上 -------**/		oddbyte= 0;		*((u_char *)&oddbyte )  =*(u_char *)ptr ;		sum+=oddbyte;	}		sum=(sum>>16) + (sum&0xffff);	sum += ( sum>>16 );	answer = -sum;		/** turn to 16 bits **/	return ( answer ) ;}/***	接收返回信息*/recv_ping(){	register int n;	int 	fromlen;	struct sockaddr_in from ;	extern void sig_finish();	for ( ;; ) {		fromlen = sizeof( from );		if ( ( n = recvfrom ( sockfd, recvpack, sizeof( recvpack ) , 			0 , (struct sockaddr *)&from, &fromlen ) ) < 0 ) {			if ( errno == EINTR )  /** 因为ALARM调用会引起						   NORMAL中断       */				continue;			printf( "errno=%d,errstr=%s, 接收数据出错!",				errno, sys_errlist[errno] ) ; 			continue;		}		pr_pack( recvpack, n, &from ) ;		if ( npackets &&  nreceived >=npackets ) 			sig_finish();	}}pr_pack( buf, cc, from ) char *buf;int cc; struct sockaddr_in *from ;{	int i, iphdrlen, triptime;	struct ip *ip;	register struct icmp *icp;	long *lp;	struct timeval tv;	char *pr_type();	from->sin_addr.s_addr = ntohl( from->sin_addr.s_addr ) ;	if ( timing ) 		gettimeofday( &tv, ( struct timezone *)0 ) ;	ip = (struct ip *)buf ;	iphdrlen = ip->ip_hl<<2;	if ( cc < iphdrlen + ICMP_MINLEN ) {		if ( verbose ) 			printf( "包太小 (%d bytes ) from %s\n", cc, 				inet_ntoa( ntohl( from->sin_addr.s_addr ) ));			return ;	} 	cc-=iphdrlen ;	icp = ( struct icmp *) ( buf + iphdrlen ) ;	if ( icp->icmp_type != ICMP_ECHOREPLY ) {	}}char *pr_type(){}void sig_finish(){	alarm(0);	exit(0);}err_sys(s)char *s;{	if ( errno > 0 && errno <sys_nerr ) 		printf( "errno=%d:%s. %s\n", errno, sys_errlist[errno], s );	else printf( "errno=%d:%s\n", errno, s );	exit(0);}/****/err_quit( s, parm )char *s;char **parm ;{	printf( s, parm ); 	exit(0);}

⌨️ 快捷键说明

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