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

📄 fping.c

📁 mysql+ha. 实现高可用性 http://code.google.com/p/mysql-master-master/
💻 C
📖 第 1 页 / 共 4 页
字号:
/*  * fping: fast-ping, file-ping, favorite-ping, funky-ping * *   Ping a list of target hosts in a round robin fashion. *   A better ping overall. * * VIEWING NOTES: *  * This file was formatted with tab indents at a tab stop of 4. * * It is highly recommended that your editor is set to this * tab stop setting for viewing and editing. * * fping website:  http://www.fping.com * * * * Current maintainers of fping: * * ZeroHype Technologies Inc. (http://www.zerohype.com) * Suggestions and patches, please email noc@zerohype.com * * * * Original author:  Roland Schemers  <schemers@stanford.edu>  * * * * RCS header information no longer used.  It has been moved to the * ChangeLog file. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by Stanford University.  The name of the University may not be used  * to endorse or promote products derived from this software without  * specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */#ifndef _NO_PROTO#if !__STDC__ && !defined( __cplusplus ) && !defined( FUNCPROTO ) \                                                 && !defined( _POSIX_SOURCE )#define _NO_PROTO#endif /* __STDC__ */#endif /* _NO_PROTO */#ifdef __cplusplusextern "C"{#endif /* __cplusplus *//* if compiling for Windows, use this separate set  (too difficult to ifdef all the autoconf defines) */#ifdef WIN32/*** Windows includes ***/#else/*** autoconf includes ***/#include <config.h>#include <stdio.h>#include <errno.h>#include <time.h>#include <signal.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif /* HAVE_UNISTD_H */#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif /* HAVE_STDLIB_H */#include <string.h>#include <stddef.h>#include <sys/types.h>#include <sys/time.h>#include <sys/socket.h>#if HAVE_SYS_FILE_H#include <sys/file.h>#endif /* HAVE_SYS_FILE_H */#include <netinet/in_systm.h>#include <netinet/in.h>/* Linux has bizarre ip.h and ip_icmp.h */#if defined( __linux__ )#include "linux.h"#else#include <netinet/ip.h>#include <netinet/ip_icmp.h>#endif /* defined(__linux__) */#include <arpa/inet.h>#include <netdb.h>/* RS6000 has sys/select.h */#ifdef HAVE_SYS_SELECT_H#include <sys/select.h>#endif /* HAVE_SYS_SELECT_H */#endif /* WIN32 */#include "options.h"/*** externals ***/extern char *optarg;extern int optind,opterr;extern int h_errno;#ifdef __cplusplus}#endif /* __cplusplus *//*** Constants ***/#define REV_DATE	"2001/01/25 11:25:04"#define EMAIL		"noc@zerohype.com"/*** Ping packet defines ***//* data added after ICMP header for our nefarious purposes */typedef struct ping_data{     int                  ping_count;         /* counts up to -c count or 1 */     struct timeval       ping_ts;            /* time sent */} PING_DATA;#define MIN_PING_DATA	sizeof( PING_DATA )#define	MAX_IP_PACKET	65536	/* (theoretical) max IP packet size */#define SIZE_IP_HDR		20#define SIZE_ICMP_HDR	ICMP_MINLEN		/* from ip_icmp.h */#define MAX_PING_DATA	( MAX_IP_PACKET - SIZE_IP_HDR - SIZE_ICMP_HDR )/* sized so as to be like traditional ping */#define DEFAULT_PING_DATA_SIZE	( MIN_PING_DATA + 44 ) /* maxima and minima */#define MAX_COUNT				10000#define MIN_INTERVAL			10		/* in millisec */#define MIN_PERHOST_INTERVAL	20		/* in millisec */#define MIN_TIMEOUT				50		/* in millisec */#define MAX_RETRY				20/* response time array flags */#define RESP_WAITING	-1#define RESP_UNUSED		-2/* debugging flags */#if defined( DEBUG ) || defined( _DEBUG )#define DBG_TRACE				1#define DBG_SENT_TIMES			2#define DBG_RANDOM_LOSE_FEW		4#define DBG_RANDOM_LOSE_MANY	8#define DBG_PRINT_PER_SYSTEM	16#define DBG_REPORT_ALL_RTTS		32#endif /* DEBUG || _DEBUG *//* Long names for ICMP packet types */char *icmp_type_str[19] ={	"ICMP Echo Reply",			/* 0 */	"",	"",	"ICMP Unreachable",			/* 3 */	"ICMP Source Quench",		/* 4 */	"ICMP Redirect",			/* 5 */	"",	"",	"ICMP Echo",				/* 8 */	"",	"",	"ICMP Time Exceeded",		/* 11 */	"ICMP Paramter Problem",	/* 12 */	"ICMP Timestamp Request",	/* 13 */	"ICMP Timestamp Reply",		/* 14 */	"ICMP Information Request",	/* 15 */	"ICMP Information Reply",	/* 16 */	"ICMP Mask Request",		/* 17 */	"ICMP Mask Reply"			/* 18 */};char *icmp_unreach_str[16] ={	"ICMP Network Unreachable",										/* 0 */	"ICMP Host Unreachable",										/* 1 */	"ICMP Protocol Unreachable",									/* 2 */	"ICMP Port Unreachable",										/* 3 */	"ICMP Unreachable (Fragmentation Needed)",						/* 4 */	"ICMP Unreachable (Source Route Failed)",						/* 5 */	"ICMP Unreachable (Destination Network Unknown)",				/* 6 */	"ICMP Unreachable (Destination Host Unknown)",					/* 7 */	"ICMP Unreachable (Source Host Isolated)",						/* 8 */	"ICMP Unreachable (Communication with Network Prohibited)",		/* 9 */	"ICMP Unreachable (Communication with Host Prohibited)",		/* 10 */	"ICMP Unreachable (Network Unreachable For Type Of Service)",	/* 11 */	"ICMP Unreachable (Host Unreachable For Type Of Service)",		/* 12 */	"ICMP Unreachable (Communication Administratively Prohibited)",	/* 13 */	"ICMP Unreachable (Host Precedence Violation)",					/* 14 */	"ICMP Unreachable (Precedence cutoff in effect)"				/* 15 */};#define	ICMP_UNREACH_MAXTYPE	15/* entry used to keep track of each host we are pinging */typedef struct host_entry{     struct host_entry    *prev,*next;        /* doubly linked list */     int                  i;                  /* index into array */     char                 *name;              /* name as given by user */     char                 *host;              /* text description of host */     char                 *pad;               /* pad to align print names */     struct sockaddr_in   saddr;              /* internet address */     int                  timeout;            /* time to wait for response */     u_char               running;            /* unset when through sending */     u_char               waiting;            /* waiting for response */     struct timeval       last_send_time;     /* time of last packet sent */     int                  num_sent;           /* number of ping packets sent */     int                  num_recv;           /* number of pings received */     int                  max_reply;          /* longest response time */     int                  min_reply;          /* shortest response time */     int                  total_time;         /* sum of response times */     int                  num_sent_i;         /* number of ping packets sent */     int                  num_recv_i;         /* number of pings received */     int                  max_reply_i;        /* longest response time */     int                  min_reply_i;        /* shortest response time */     int                  total_time_i;       /* sum of response times */     int                  *resp_times;        /* individual response times */#if defined( DEBUG ) || defined( _DEBUG )     int                  *sent_times;        /* per-sent-ping timestamp */#endif /* DEBUG || _DEBUG */} HOST_ENTRY;/*** globals ***/HOST_ENTRY *rrlist = NULL;	/* linked list of hosts be pinged */HOST_ENTRY **table = NULL;	/* array of pointers to items in the list */HOST_ENTRY *cursor;char *prog;int ident;					/* our pid */int s;						/* socket */u_int debugging = 0;/* times get *100 because all times are calculated in 10 usec units, not ms */u_int retry = DEFAULT_RETRY;u_int timeout = DEFAULT_TIMEOUT * 100; u_int interval = DEFAULT_INTERVAL * 100;u_int perhost_interval = DEFAULT_PERHOST_INTERVAL * 100;float backoff = DEFAULT_BACKOFF_FACTOR;u_int select_time = DEFAULT_SELECT_TIME * 100;u_int ping_data_size = DEFAULT_PING_DATA_SIZE;u_int ping_pkt_size;u_int count = 1;u_int trials;u_int report_interval = 0;/* global stats */long max_reply = 0;long min_reply = 1000000;int total_replies = 0;double sum_replies = 0;int max_hostname_len = 0;int num_jobs = 0;					/* number of hosts still to do */int num_hosts;						/* total number of hosts */int num_alive = 0,					/* total number alive */    num_unreachable = 0,			/* total number unreachable */    num_noaddress = 0;				/* total number of addresses not found */int num_timeout = 0,				/* number of times select timed out */    num_pingsent = 0,				/* total pings sent */    num_pingreceived = 0,			/* total pings received */    num_othericmprcvd = 0;			/* total non-echo-reply ICMP received */struct timeval current_time;		/* current time (pseudo) */struct timeval start_time; struct timeval end_time;struct timeval last_send_time;		/* time last ping was sent */struct timeval last_report_time;	/* time last report was printed */struct timezone tz;/* switches */int generate_flag = 0;				/* flag for IP list generation */int verbose_flag, quiet_flag, stats_flag, unreachable_flag, alive_flag;int elapsed_flag, version_flag, count_flag, loop_flag;int per_recv_flag, report_all_rtts_flag, name_flag, addr_flag, backoff_flag;int multif_flag;#if defined( DEBUG ) || defined( _DEBUG )int randomly_lose_flag, sent_times_flag, trace_flag, print_per_system_flag;int lose_factor;#endif /* DEBUG || _DEBUG */char *filename = NULL;				/* file containing hosts to ping *//*** forward declarations ***/#ifdef _NO_PROTOvoid add_name();void add_addr();char *na_cat();char *cpystr();void crash_and_burn();void errno_crash_and_burn();char *get_host_by_address();int in_cksum();void u_sleep();int recvfrom_wto ();void remove_job();void send_ping();void usage();int wait_for_reply();long timeval_diff();void print_per_system_stats();void print_per_system_splits();void print_global_stats();void finish();int handle_random_icmp();char *sprint_tm();#elsevoid add_name( char *name );void add_addr( char *name, char *host, struct in_addr ipaddr );char *na_cat( char *name, struct in_addr ipaddr );char *cpystr( char *string );void crash_and_burn( char *message );void errno_crash_and_burn( char *message );char *get_host_by_address( struct in_addr in );int in_cksum( u_short *p, int n );void u_sleep( int u_sec );int recvfrom_wto ( int s, char *buf, int len, struct sockaddr *saddr, int timo );void remove_job( HOST_ENTRY *h );void send_ping( int s, HOST_ENTRY *h );long timeval_diff( struct timeval *a, struct timeval *b );void usage( void );int wait_for_reply( void );void print_per_system_stats( void );void print_per_system_splits( void );void print_global_stats( void );void finish();int handle_random_icmp( struct icmp *p, int psize, struct sockaddr_in *addr );char *sprint_tm( int t );#endif /* _NO_PROTO *//*** function definitions ***//************************************************************  Function: main*************************************************************  Inputs:  int argc, char** argv  Description:    Main program entry point************************************************************/#ifdef _NO_PROTOint main( argc, argv )int argc; char **argv;#elseint main( int argc, char **argv )#endif /* _NO_PROTO */{	int c, i, n;	u_int lt, ht;	int advance;	struct protoent *proto;	char *buf;	uid_t uid;	/* check if we are root */	if( geteuid() )	{		fprintf( stderr,			"This program can only be run by root, or it must be setuid root.\n" );		exit( 3 );	}/* IF */	/* confirm that ICMP is available on this machine */	if( ( proto = getprotobyname( "icmp" ) ) == NULL ) 		crash_and_burn( "icmp: unknown protocol" );	/* create raw socket for ICMP calls (ping) */	s = socket( AF_INET, SOCK_RAW, proto->p_proto );	if( s < 0 )		errno_crash_and_burn( "can't create raw socket" );	if( ( uid = getuid() ) )	{		seteuid( getuid() );	}/* IF */	prog = argv[0];	ident = getpid() & 0xFFFF;	verbose_flag = 1;	backoff_flag = 1;	opterr = 1;	/* get command line options */	while( ( c = getopt( argc, argv, "gedhlmnqusaAvz:t:i:p:f:r:c:b:C:Q:B:" ) ) != EOF )	{		switch( c )		{		case 't':			if( !( timeout = ( u_int )atoi( optarg ) * 100 ) )				usage();			break;				case 'r':			if( !( retry = ( u_int )atoi( optarg ) ) )				usage();			break;				case 'i':			if( !( interval = ( u_int )atoi( optarg ) * 100 ) )				usage();			break;		case 'p':			if( !( perhost_interval = ( u_int )atoi( optarg ) * 100 ) )				usage();			break;		case 'c':			if( !( count = ( u_int )atoi( optarg ) ) )				usage();						count_flag = 1;			break;				case 'C':			if( !( count = ( u_int )atoi( optarg ) ) )				usage();						count_flag = 1;			report_all_rtts_flag = 1;			break;		case 'b':			if( !( ping_data_size = ( u_int )atoi( optarg ) ) )				usage();						break;		case 'h':			usage();			break;		case 'q':			verbose_flag = 0;			quiet_flag = 1;			break;		case 'Q':			verbose_flag = 0;			quiet_flag = 1;			if( !( report_interval = ( u_int )atoi( optarg ) * 100000 ) )				usage();						break;		case 'e':			elapsed_flag = 1;			break;		case 'm':			multif_flag = 1;			break;		case 'd': 		case 'n':			name_flag = 1;			break;		case 'A':			addr_flag = 1;			break;		case 'B':			if( !( backoff = atof( optarg ) ) )				usage();						break;		case 's':			stats_flag = 1;			break;		case 'l':			loop_flag = 1;			backoff_flag = 0;			break;		case 'u':			unreachable_flag = 1;			break;		case 'a':			alive_flag = 1;			break;#if defined( DEBUG ) || defined( _DEBUG )		case 'z':			if( ! ( debugging = ( u_int )atoi( optarg ) ) )				usage();						break;#endif /* DEBUG || _DEBUG */		case 'v':			printf( "%s: Version %s $Date: %s $\n", argv[0], VERSION, REV_DATE );			printf( "%s: comments to %s\n", argv[0], EMAIL );			exit( 0 );		case 'f': #ifdef ENABLE_F_OPTION			filename = optarg;			generate_flag = 0;			break;#else			if( getuid() )			{				printf( "%s: this option can only be used by root.\n", argv[0] );				printf( "%s: fping will read from stdin by default.\n", argv[0] );				exit( 3 );			}/* IF */			else			{				filename = optarg;				generate_flag = 0;			}/* ELSE */			break;#endif /* ENABLE_F_OPTION */		case 'g':			/* use IP list generation */			/* mutually exclusive with using file input or command line targets */			generate_flag = 1;			break;		default:			usage();			break;		}/* SWITCH */	}/* WHILE */	/* validate various option settings */	if( unreachable_flag && alive_flag )	{		fprintf( stderr, "%s: specify only one of a, u\n", argv[0] );		usage();	}/* IF */	if( count_flag && loop_flag )	{		fprintf( stderr, "%s: specify only one of c, l\n", argv[0] );		usage();		}/* IF */		if( ( interval < MIN_INTERVAL * 100 ||			perhost_interval < MIN_PERHOST_INTERVAL * 100 || 			retry > MAX_RETRY || 			timeout < MIN_TIMEOUT * 100 ) 		&& getuid() )	{		fprintf( stderr, "%s: these options are too risky for mere mortals.\n", prog );		fprintf( stderr, "%s: You need i >= %u, p >= %u, r < %u, and t >= %u\n",			prog, MIN_INTERVAL, MIN_PERHOST_INTERVAL, MAX_RETRY, MIN_TIMEOUT );		usage();	}/* IF */		if( ( ping_data_size > MAX_PING_DATA ) || ( ping_data_size < MIN_PING_DATA ) )	{		fprintf( stderr, "%s: data size %u not valid, must be between %u and %u\n",			prog, ping_data_size, MIN_PING_DATA, MAX_PING_DATA );		usage();		}/* IF */		if( ( backoff > MAX_BACKOFF_FACTOR ) || ( backoff < MIN_BACKOFF_FACTOR ) )	{		fprintf( stderr, "%s: backoff factor %.1f not valid, must be between %.1f and %.1f\n",			prog, backoff, MIN_BACKOFF_FACTOR, MAX_BACKOFF_FACTOR );		usage();		}/* IF */	if( count > MAX_COUNT )	{		fprintf( stderr, "%s: count %u not valid, must be less than %u\n",			prog, count, MAX_COUNT );	    usage();	

⌨️ 快捷键说明

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