📄 fping.c
字号:
}/* IF */ if( alive_flag || unreachable_flag ) verbose_flag = 0; if( count_flag ) { if( verbose_flag ) per_recv_flag = 1; alive_flag = unreachable_flag = verbose_flag = 0; }/* IF */ if( loop_flag ) { if( !report_interval ) per_recv_flag = 1; alive_flag = unreachable_flag = verbose_flag = 0; }/* IF */ trials = ( count > retry + 1 ) ? count : retry + 1;#if defined( DEBUG ) || defined( _DEBUG ) if( debugging & DBG_TRACE ) trace_flag = 1; if( ( debugging & DBG_SENT_TIMES ) && !loop_flag ) sent_times_flag = 1; if( debugging & DBG_RANDOM_LOSE_FEW ) { randomly_lose_flag = 1; lose_factor = 1; /* ie, 1/4 */ }/* IF */ if( debugging & DBG_RANDOM_LOSE_MANY ) { randomly_lose_flag = 1; lose_factor = 5; /* ie, 3/4 */ }/* IF */ if( debugging & DBG_PRINT_PER_SYSTEM ) print_per_system_flag = 1; if( ( debugging & DBG_REPORT_ALL_RTTS ) && !loop_flag ) report_all_rtts_flag = 1; if( trace_flag ) { fprintf( stderr, "%s:\n count: %u, retry: %u, interval: %u\n", prog, count, retry, interval / 10 ); fprintf( stderr, " perhost_interval: %u, timeout: %u\n", perhost_interval / 10, timeout / 10 ); fprintf( stderr, " ping_data_size = %u, trials = %u\n", ping_data_size, trials ); if( verbose_flag ) fprintf( stderr, " verbose_flag set\n" ); if( multif_flag ) fprintf( stderr, " multif_flag set\n" ); if( name_flag ) fprintf( stderr, " name_flag set\n" ); if( addr_flag ) fprintf( stderr, " addr_flag set\n" ); if( stats_flag ) fprintf( stderr, " stats_flag set\n" ); if( unreachable_flag ) fprintf( stderr, " unreachable_flag set\n" ); if( alive_flag ) fprintf( stderr, " alive_flag set\n" ); if( elapsed_flag ) fprintf( stderr, " elapsed_flag set\n" ); if( version_flag ) fprintf( stderr, " version_flag set\n" ); if( count_flag ) fprintf( stderr, " count_flag set\n" ); if( loop_flag ) fprintf( stderr, " loop_flag set\n" ); if( backoff_flag ) fprintf( stderr, " backoff_flag set\n" ); if( per_recv_flag ) fprintf( stderr, " per_recv_flag set\n" ); if( report_all_rtts_flag ) fprintf( stderr, " report_all_rtts_flag set\n" ); if( randomly_lose_flag ) fprintf( stderr, " randomly_lose_flag set\n" ); if( sent_times_flag ) fprintf( stderr, " sent_times_flag set\n" ); if( print_per_system_flag ) fprintf( stderr, " print_per_system_flag set\n" ); }/* IF */#endif /* DEBUG || _DEBUG */ /* handle host names supplied on command line or in a file */ /* if the generate_flag is on, then generate the IP list */ argv = &argv[optind]; /* cover allowable conditions */ /* file and generate are mutually exclusive */ /* file and command line are mutually exclusive */ /* generate requires command line parameters beyond the switches */ if( ( *argv && filename ) || ( filename && generate_flag ) || ( generate_flag && !*argv ) ) usage(); /* if no conditions are specified, then assume input from stdin */ if( !*argv && !filename && !generate_flag ) filename = "-"; if( *argv && !generate_flag ) { while( *argv ) { add_name( *argv ); ++argv; }/* WHILE */ }/* IF */ else if( filename ) { FILE *ping_file; char line[132]; char host[132]; char *p; if( strcmp( filename, "-" ) == 0 ) ping_file = fdopen( 0, "r" ); else ping_file = fopen( filename, "r" ); if( !ping_file ) errno_crash_and_burn( "fopen" ); while( fgets( line, 132, ping_file ) ) { if( sscanf( line, "%s", host ) != 1 ) continue; if( ( !*host ) || ( host[0] == '#' ) ) /* magic to avoid comments */ continue; p = cpystr( host ); add_name( p ); }/* WHILE */ fclose( ping_file ); }/* ELSE IF */ else if( *argv && generate_flag ) { char* pStart; char* pEnd; char* pCopy; char* pTemp; struct in_addr sStart; struct in_addr sEnd; int iBits; int iBitpos; int iMask = 1; int failed = 0; unsigned long uTemp; /* two possible forms are allowed here */ pStart = *argv; argv++; /* IP mask is specified */ if( !*argv ) { pCopy = ( char* )malloc( sizeof( char ) * strlen( pStart ) + 1 ); if( pCopy ) { /* make a copy of the arg, so we don't damage the original */ strcpy( pCopy, pStart ); /* look for token '/' */ if( strtok( pCopy, "/" ) != NULL ) { /* if no token was found, the string should be unaltered */ if( strcmp( pCopy, pStart ) != 0 ) { /* convert it to the starting address */ if( inet_addr( pCopy ) != INADDR_NONE ) { sStart.s_addr = inet_addr( pCopy ); /* now find the bitmask */ pTemp = ( char* )pStart + strlen( pCopy ) + 1; /* get the bits */ iBits = 32 - atoi( pTemp ); if( ( iBits < 32 ) && ( iBits >= 0 ) ) { /* now make the end address */ for( iBitpos = 0; iBitpos < iBits; iBitpos++ ) iMask = iMask | 1 << iBitpos; sEnd.s_addr = sStart.s_addr | ntohl( iMask ); }/* IF */ else failed = 1; }/* IF */ else failed = 1; }/* IF */ else failed = 1; }/* IF */ else failed = 1; free( pCopy ); if( failed == 1 ) usage(); }/* IF */ else crash_and_burn( "Cannot malloc copy of input string" ); }/* IF */ else { /* IP start and end points are specified */ pEnd = *argv; /* parameters should be start and end ranges */ if( ( inet_addr( pStart ) != INADDR_NONE ) && ( inet_addr( pEnd ) != INADDR_NONE ) ) { sStart.s_addr = inet_addr( pStart ); sEnd.s_addr = inet_addr( pEnd ); }/* IF */ else usage(); }/* ELSE */ /* ensure that the end point is greater or equal to the start */ if( htonl( sEnd.s_addr ) >= htonl( sStart.s_addr ) ) { /* start and end points should be determined, so generate list */ unsigned int uiDiff; struct in_addr sTemp; int iCount; uiDiff = htonl( sEnd.s_addr ) - htonl( sStart.s_addr ) + 1; for( iCount = 0; iCount < uiDiff; iCount++ ) { sTemp.s_addr = sStart.s_addr + ntohl( iCount ); pTemp = cpystr( inet_ntoa( sTemp ) ); add_name( pTemp ); }/* FOR */ }/* IF */ else usage(); }/* ELSE IF */ else usage(); if( !num_hosts ) exit( 2 ); /* allocate array to hold outstanding ping requests */ table = ( HOST_ENTRY** )malloc( sizeof( HOST_ENTRY* ) * num_hosts ); if( !table ) crash_and_burn( "Can't malloc array of hosts" ); cursor = rrlist; for( num_jobs = 0; num_jobs < num_hosts; num_jobs++ ) { table[num_jobs] = cursor; cursor->i = num_jobs; /* as long as we're here, put this in so names print out nicely */ if( count_flag || loop_flag ) { n = max_hostname_len - strlen( cursor->host ); buf = ( char* ) malloc( n + 1 ); if( !buf ) crash_and_burn( "can't malloc host pad" ); for ( i = 0; i < n; i++ ) buf[i] = ' '; buf[n] = '\0'; cursor->pad = buf; }/* IF */ cursor=cursor->next; }/* FOR */ ping_pkt_size = ping_data_size + SIZE_ICMP_HDR; signal( SIGINT, finish ); gettimeofday( &start_time, &tz ); current_time = start_time; if( report_interval ) last_report_time = start_time; last_send_time.tv_sec = current_time.tv_sec - 10000;#if defined( DEBUG ) || defined( _DEBUG ) if( randomly_lose_flag ) srandom( start_time.tv_usec );#endif /* DEBUG || _DEBUG */ cursor = rrlist; advance = 0; /* main loop */ while( num_jobs ) { if( num_pingsent ) while( wait_for_reply() ); /* call wfr until we timeout */ if( cursor && advance ) cursor = cursor->next; gettimeofday( ¤t_time, &tz ); lt = timeval_diff( ¤t_time, &last_send_time ); ht = timeval_diff( ¤t_time, &cursor->last_send_time ); if( report_interval && ( loop_flag || count_flag ) && ( timeval_diff ( ¤t_time, &last_report_time ) > report_interval ) ) { print_per_system_splits(); gettimeofday( ¤t_time, &tz ); lt = timeval_diff( ¤t_time, &last_send_time ); ht = timeval_diff( ¤t_time, &cursor->last_send_time ); last_report_time = current_time; }/* IF */ advance = 1;#if defined( DEBUG ) || defined( _DEBUG ) if( trace_flag ) { printf( "main loop:\n [%s, wait/run/sent/recv/timeout = %u/%u/%u/%u/%u], jobs/lt/ht = %u/%u/%u\n", cursor->host, cursor->waiting, cursor->running, cursor->num_sent, cursor->num_recv, cursor->timeout, num_jobs, lt, ht ); }/* IF */#endif /* DEBUG || _DEBUG */ /* if it's OK to send while counting or looping or starting */ if( ( lt > interval ) && ( ht > perhost_interval ) ) { /* send if starting or looping */ if( ( cursor->num_sent == 0 ) || loop_flag ) { send_ping( s, cursor ); continue; }/* IF */ /* send if counting and count not exceeded */ if( count_flag ) { if( cursor->num_sent < count ) { send_ping( s, cursor ); continue; }/* IF */ }/* IF */ }/* IF */ /* is-it-alive mode, and timeout exceeded while waiting for a reply */ /* and we haven't exceeded our retries */ if( ( lt > interval ) && !count_flag && !loop_flag && !cursor->num_recv && ( ht > cursor->timeout ) && ( cursor->waiting < retry + 1 ) ) {#if defined( DEBUG ) || defined( _DEBUG ) if( trace_flag ) printf( "main loop: timeout for %s\n", cursor->host );#endif /* DEBUG || _DEBUG */ num_timeout++; /* try again */ if( backoff_flag ) cursor->timeout *= backoff; send_ping( s, cursor ); continue; }/* IF */ /* didn't send, can we remove? */#if defined( DEBUG ) || defined( _DEBUG ) if( trace_flag ) printf( "main loop: didn't send to %s\n", cursor->host );#endif /* DEBUG || _DEBUG */ /* never remove if looping */ if( loop_flag ) continue; /* remove if counting and count exceeded */ /* but allow time for the last one to come in */ if( count_flag ) { if( ( cursor->num_sent >= count ) && ( ht > cursor->timeout ) ) { remove_job( cursor ); continue; }/* IF */ }/* IF */ else { /* normal mode, and we got one */ if( cursor->num_recv ) { remove_job( cursor ); continue; }/* IF */ /* normal mode, and timeout exceeded while waiting for a reply */ /* and we've run out of retries, so node is unreachable */ if( ( ht > cursor->timeout ) && ( cursor->waiting >= retry + 1 ) ) {#if defined( DEBUG ) || defined( _DEBUG ) if( trace_flag ) printf( "main loop: timeout for %s\n", cursor->host );#endif /* DEBUG || _DEBUG */ num_timeout++; remove_job( cursor ); continue; }/* IF */ }/* ELSE */ /* could send to this host, so keep considering it */ if( ht > interval ) advance = 0; }/* WHILE */ finish();} /* main() *//************************************************************ Function: finish************************************************************* Inputs: void (none) Description: Main program clean up and exit point************************************************************/#ifdef _NO_PROTOvoid finish()#elsevoid finish()#endif /* _NO_PROTO */{ int i; HOST_ENTRY *h; gettimeofday( &end_time, &tz ); /* tot up unreachables */ for( i = 0; i < num_hosts; i++ ) { h = table[i]; if( !h->num_recv ) { num_unreachable++; if( verbose_flag || unreachable_flag ) { printf( "%s", h->host ); if( verbose_flag ) printf( " is unreachable" ); printf( "\n" ); }/* IF */ }/* IF */ }/* FOR */ if( count_flag || loop_flag ) print_per_system_stats();#if defined( DEBUG ) || defined( _DEBUG ) else if( print_per_system_flag ) print_per_system_stats();#endif /* DEBUG || _DEBUG */ if( stats_flag ) print_global_stats(); if( num_noaddress ) exit( 2 ); else if( num_alive != num_hosts ) exit( 1 ); exit(0);} /* finish() *//************************************************************ Function: print_per_system_stats************************************************************* Inputs: void (none) Description: ************************************************************/#ifdef _NO_PROTOvoid print_per_system_stats()#elsevoid print_per_system_stats( void )#endif /* _NO_PROTO */{ int i, j, k, avg; HOST_ENTRY *h; char *buf; int bufsize; int resp; bufsize = max_hostname_len + 1; buf = ( char* )malloc( bufsize ); if( !buf ) crash_and_burn( "can't malloc print buf" ); memset( buf, 0, bufsize ); fflush( stdout ); if( verbose_flag || per_recv_flag ) fprintf( stderr, "\n" ); for( i = 0; i < num_hosts; i++ ) { h = table[i]; fprintf( stderr, "%s%s :", h->host, h->pad ); if( report_all_rtts_flag ) { for( j = 0; j < h->num_sent; j++ ) { if( ( resp = h->resp_times[j] ) >= 0 ) fprintf( stderr, " %d.%02d", resp / 100, resp % 100 ); else fprintf( stderr, " -" ); }/* FOR */ fprintf( stderr, "\n" ); }/* IF */ else { if( h->num_recv <= h->num_sent ) { fprintf( stderr, " xmt/rcv/%%loss = %d/%d/%d%%", h->num_sent, h->num_recv, h->num_sent > 0 ? ( ( h->num_sent - h->num_recv ) * 100 ) / h->num_sent : 0 ); }/* IF */ else { fprintf( stderr, " xmt/rcv/%%return = %d/%d/%d%%", h->num_sent, h->num_recv, ( ( h->num_recv * 100 ) / h->num_sent ) ); }/* ELSE */ if( h->num_recv ) { avg = h->total_time / h->num_recv; fprintf( stderr, ", min/avg/max = %s", sprint_tm( h->min_reply ) ); fprintf( stderr, "/%s", sprint_tm( avg ) ); fprintf( stderr, "/%s", sprint_tm( h->max_reply ) ); }/* IF */ fprintf(stderr, "\n"); }/* ELSE */#if defined( DEBUG ) || defined( _DEBUG ) if( sent_times_flag ) { for( j = 0; j < h->num_sent; j++ ) { if( ( resp = h->sent_times[j] ) >= 0 ) fprintf( stderr, " %s", sprint_tm( resp ) ); else fprintf( stderr, " -" ); fprintf( stderr, "\n" ); }/* FOR */ }/* IF */#endif /* DEBUG || _DEBUG */ }/* FOR */ free( buf );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -