📄 ping.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 + -