* 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.org
*
* Current maintainer of fping: David Schweikert
/*** Constants ***/
-#define EMAIL "david@schweikert.ch"
+#define EMAIL "david@schweikert.ch"
/*** Ping packet defines ***/
} 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 MIN_PING_DATA sizeof( PING_DATA )
+#define MAX_IP_PACKET 65536 /* (theoretical) max IP packet size */
+#define SIZE_IP_HDR 20
#ifndef IPV6
-#define SIZE_ICMP_HDR ICMP_MINLEN /* from ip_icmp.h */
+#define SIZE_ICMP_HDR ICMP_MINLEN /* from ip_icmp.h */
#else
-#define SIZE_ICMP_HDR sizeof(FPING_ICMPHDR)
+#define SIZE_ICMP_HDR sizeof(FPING_ICMPHDR)
#endif
-#define MAX_PING_DATA ( MAX_IP_PACKET - SIZE_IP_HDR - SIZE_ICMP_HDR )
+#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 )
+#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
+#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
+#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
+#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 */
+ "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 */
+ "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
+#define ICMP_UNREACH_MAXTYPE 15
#ifndef IPV6
-#define FPING_SOCKADDR struct sockaddr_in
-#define FPING_ICMPHDR struct icmp
+#define FPING_SOCKADDR struct sockaddr_in
+#define FPING_ICMPHDR struct icmp
#else
-#define FPING_SOCKADDR struct sockaddr_in6
-#define FPING_ICMPHDR struct icmp6_hdr
+#define FPING_SOCKADDR struct sockaddr_in6
+#define FPING_ICMPHDR struct icmp6_hdr
#endif
/* entry used to keep track of each host we are pinging */
typedef struct host_entry
{
- /* Each host can have an event attached: either the next time that a ping needs
- * to be sent, or the timeout, if the last ping was sent */
- struct host_entry *ev_prev; /* double linked list for the event-queue */
- struct host_entry *ev_next; /* double linked list for the event-queue */
- struct timeval ev_time; /* time, after which this event should happen */
- int ev_type; /* event type */
+ /* Each host can have an event attached: either the next time that a ping needs
+ * to be sent, or the timeout, if the last ping was sent */
+ struct host_entry *ev_prev; /* double linked list for the event-queue */
+ struct host_entry *ev_next; /* double linked list for the event-queue */
+ struct timeval ev_time; /* time, after which this event should happen */
+ int ev_type; /* event type */
int i; /* index into array */
char *name; /* name as given by user */
/*** 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 *rrlist = NULL; /* linked list of hosts be pinged */
+HOST_ENTRY **table = NULL; /* array of pointers to items in the list */
/* event queue (ev): This, together with the ev_next / ev_prev elements are used
* to track the next event happening for each host. This can be either a new ping
HOST_ENTRY *ev_last;
char *prog;
-int ident; /* our pid */
-int s; /* socket */
+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 */
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 max_seq_sent = 0; /* maximum sequence number sent so far */
-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) */
+int num_jobs = 0; /* number of hosts still to do */
+int num_hosts; /* total number of hosts */
+int max_seq_sent = 0; /* maximum sequence number sent so far */
+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 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 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 lose_factor;
#endif /* DEBUG || _DEBUG */
-char *filename = NULL; /* file containing hosts to ping */
+char *filename = NULL; /* file containing hosts to ping */
/*** forward declarations ***/
int main( int argc, char **argv )
#endif /* _NO_PROTO */
{
- int c, i, n;
+ int c, i, n;
#ifdef IPV6
- int opton = 1;
+ int opton = 1;
#endif
- struct protoent *proto;
- char *buf;
- uid_t uid;
+ struct protoent *proto;
+ char *buf;
+ uid_t uid;
int tos = 0;
#ifndef IPV6
- struct sockaddr_in sa;
+ struct sockaddr_in sa;
#else
- struct sockaddr_in6 sa;
+ struct sockaddr_in6 sa;
#endif
- HOST_ENTRY *cursor;
+ HOST_ENTRY *cursor;
- /* check if we are root */
+ /* check if we are root */
- if( geteuid() )
- {
- fprintf( stderr,
- "This program can only be run by root, or it must be setuid root.\n" );
+ if( geteuid() )
+ {
+ fprintf( stderr,
+ "This program can only be run by root, or it must be setuid root.\n" );
- exit( 3 );
+ exit( 3 );
- }/* IF */
+ }/* IF */
- /* confirm that ICMP is available on this machine */
+ /* confirm that ICMP is available on this machine */
#ifndef IPV6
- if( ( proto = getprotobyname( "icmp" ) ) == NULL )
+ if( ( proto = getprotobyname( "icmp" ) ) == NULL )
#else
- if( ( proto = getprotobyname( "ipv6-icmp" ) ) == NULL )
+ if( ( proto = getprotobyname( "ipv6-icmp" ) ) == NULL )
#endif
- crash_and_burn( "icmp: unknown protocol" );
+ crash_and_burn( "icmp: unknown protocol" );
- /* create raw socket for ICMP calls (ping) */
+ /* create raw socket for ICMP calls (ping) */
#ifndef IPV6
- s = socket( AF_INET, SOCK_RAW, proto->p_proto );
+ s = socket( AF_INET, SOCK_RAW, proto->p_proto );
#else
- s = socket( AF_INET6, SOCK_RAW, proto->p_proto );
+ s = socket( AF_INET6, SOCK_RAW, proto->p_proto );
#endif
- if( s < 0 )
- errno_crash_and_burn( "can't create raw socket" );
+ if( s < 0 )
+ errno_crash_and_burn( "can't create raw socket" );
#ifdef IPV6
- /*
- * let the kernel pass extension headers of incoming packets,
- * for privileged socket options
- */
+ /*
+ * let the kernel pass extension headers of incoming packets,
+ * for privileged socket options
+ */
#ifdef IPV6_RECVHOPOPTS
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton,
- sizeof(opton)))
- err(1, "setsockopt(IPV6_RECVHOPOPTS)");
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_RECVHOPOPTS)");
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPOPTS, &opton,
- sizeof(opton)))
- err(1, "setsockopt(IPV6_HOPOPTS)");
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPOPTS, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_HOPOPTS)");
#endif
#ifdef IPV6_RECVDSTOPTS
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton,
- sizeof(opton)))
- err(1, "setsockopt(IPV6_RECVDSTOPTS)");
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVDSTOPTS, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_RECVDSTOPTS)");
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_DSTOPTS, &opton,
- sizeof(opton)))
- err(1, "setsockopt(IPV6_DSTOPTS)");
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_DSTOPTS, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_DSTOPTS)");
#endif
#ifdef IPV6_RECVRTHDRDSTOPTS
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton,
- sizeof(opton)))
- err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)");
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDRDSTOPTS, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_RECVRTHDRDSTOPTS)");
#endif
#ifdef IPV6_RECVRTHDR
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton,
- sizeof(opton)))
- err(1, "setsockopt(IPV6_RECVRTHDR)");
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVRTHDR, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_RECVRTHDR)");
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, &opton,
- sizeof(opton)))
- err(1, "setsockopt(IPV6_RTHDR)");
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_RTHDR, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_RTHDR)");
#endif
#ifndef USE_SIN6_SCOPE_ID
#ifdef IPV6_RECVPKTINFO
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &opton,
- sizeof(opton)))
- err(1, "setsockopt(IPV6_RECVPKTINFO)");
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_RECVPKTINFO)");
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &opton,
- sizeof(opton)))
- err(1, "setsockopt(IPV6_PKTINFO)");
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_PKTINFO, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_PKTINFO)");
#endif
#endif /* USE_SIN6_SCOPE_ID */
#ifdef IPV6_RECVHOPLIMIT
- if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &opton,
- sizeof(opton)))
- err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_RECVHOPLIMIT)");
#else /* old adv. API */
- if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPLIMIT, &opton,
- sizeof(opton)))
- err(1, "setsockopt(IPV6_HOPLIMIT)");
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_HOPLIMIT, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(IPV6_HOPLIMIT)");
#endif
#ifdef IPV6_CHECKSUM
#ifndef SOL_RAW
#define SOL_RAW IPPROTO_IPV6
#endif
- opton = 2;
- if (setsockopt(s, SOL_RAW, IPV6_CHECKSUM, &opton,
- sizeof(opton)))
- err(1, "setsockopt(SOL_RAW,IPV6_CHECKSUM)");
+ opton = 2;
+ if (setsockopt(s, SOL_RAW, IPV6_CHECKSUM, &opton,
+ sizeof(opton)))
+ err(1, "setsockopt(SOL_RAW,IPV6_CHECKSUM)");
#endif
#endif
- 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:S:I:T:O:" ) ) != EOF )
- {
- switch( c )
- {
- case 't':
- if( !( timeout = ( u_int )atoi( optarg ) * 100 ) )
- usage();
-
- break;
-
- case 'r':
- if( ( retry = ( u_int )atoi( optarg ) ) < 0 )
- 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( ( 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:S:I:T:O:" ) ) != EOF )
+ {
+ switch( c )
+ {
+ case 't':
+ if( !( timeout = ( u_int )atoi( optarg ) * 100 ) )
+ usage();
+
+ break;
+
+ case 'r':
+ if( ( retry = ( u_int )atoi( optarg ) ) < 0 )
+ 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;
+ case 'z':
+ if( ! ( debugging = ( u_int )atoi( optarg ) ) )
+ usage();
+
+ break;
#endif /* DEBUG || _DEBUG */
- case 'v':
- printf( "%s: Version %s\n", argv[0], VERSION);
- printf( "%s: comments to %s\n", argv[0], EMAIL );
- exit( 0 );
+ case 'v':
+ printf( "%s: Version %s\n", argv[0], VERSION);
+ printf( "%s: comments to %s\n", argv[0], EMAIL );
+ exit( 0 );
- case 'f':
+ case 'f':
#ifdef ENABLE_F_OPTION
- filename = optarg;
- generate_flag = 0;
- break;
+ 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( 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;
+ }/* IF */
+ else
+ {
+ filename = optarg;
+ generate_flag = 0;
- }/* ELSE */
+ }/* ELSE */
- break;
+ 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;
+ case 'g':
+ /* use IP list generation */
+ /* mutually exclusive with using file input or command line targets */
+ generate_flag = 1;
+ break;
- case 'S':
+ case 'S':
#ifndef IPV6
- if( ! inet_pton( AF_INET, optarg, &src_addr ) )
+ if( ! inet_pton( AF_INET, optarg, &src_addr ) )
#else
- if( ! inet_pton( AF_INET6, optarg, &src_addr ) )
+ if( ! inet_pton( AF_INET6, optarg, &src_addr ) )
#endif
- usage();
- src_addr_present = 1;
- break;
+ usage();
+ src_addr_present = 1;
+ break;
- case 'I':
+ case 'I':
#ifdef SO_BINDTODEVICE
- if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, optarg,
- strlen(optarg)))
- perror("binding to specific interface (SO_BINTODEVICE)");
+ if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, optarg,
+ strlen(optarg)))
+ perror("binding to specific interface (SO_BINTODEVICE)");
#else
printf( "%s: cant bind to a particular net interface since SO_BINDTODEVICE is not supported on your os.\n", argv[0] );
exit(3);;
#endif
- break;
+ break;
- case 'T':
- if ( ! ( select_time = ( u_int )atoi( optarg ) * 100 ) )
- usage();
- break;
+ case 'T':
+ if ( ! ( select_time = ( u_int )atoi( optarg ) * 100 ) )
+ usage();
+ break;
case 'O':
if (sscanf(optarg,"%i",&tos)){
if ( setsockopt(s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))) {
}
}
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 %lu 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();
-
- }/* IF */
-
- if( alive_flag || unreachable_flag )
- verbose_flag = 0;
-
- if( count_flag )
- {
- if( verbose_flag )
- per_recv_flag = 1;
+ 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 %lu and %u\n",
+ prog, ping_data_size, MIN_PING_DATA, MAX_PING_DATA );
+ usage();
- alive_flag = unreachable_flag = verbose_flag = 0;
+ }/* 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 */
-
- if( loop_flag )
- {
- if( !report_interval )
- per_recv_flag = 1;
-
- alive_flag = unreachable_flag = verbose_flag = 0;
+ if( count > MAX_COUNT )
+ {
+ fprintf( stderr, "%s: count %u not valid, must be less than %u\n",
+ prog, count, MAX_COUNT );
+ usage();
+
+ }/* 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 */
+
+ if( loop_flag )
+ {
+ if( !report_interval )
+ per_recv_flag = 1;
+
+ alive_flag = unreachable_flag = verbose_flag = 0;
- trials = ( count > retry + 1 ) ? count : retry + 1;
+ }/* 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_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 */
+ 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, sizeof(line), 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;
-
- /* 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 );
-
- /* set the source address */
-
- if( src_addr_present )
- {
- memset( &sa, 0, sizeof( sa ) );
+ /* 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, sizeof(line), 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;
+
+ /* 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 );
+
+ /* set the source address */
+
+ if( src_addr_present )
+ {
+ memset( &sa, 0, sizeof( sa ) );
#ifndef IPV6
- sa.sin_family = AF_INET;
- sa.sin_addr = src_addr;
+ sa.sin_family = AF_INET;
+ sa.sin_addr = src_addr;
#else
- sa.sin6_family = AF_INET6;
- sa.sin6_addr = src_addr;
+ sa.sin6_family = AF_INET6;
+ sa.sin6_addr = src_addr;
#endif
- if ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 )
- errno_crash_and_burn( "cannot bind source address" );
- }
-
- /* 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 = ev_first;
-
- 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->ev_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 ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 )
+ errno_crash_and_burn( "cannot bind source address" );
+ }
+
+ /* 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 = ev_first;
+
+ 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->ev_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 );
+ if( randomly_lose_flag )
+ srandom( start_time.tv_usec );
#endif /* DEBUG || _DEBUG */
- /* main loop */
- main_loop();
-
- finish();
+ /* main loop */
+ main_loop();
+
+ finish();
- return 0;
+ return 0;
} /* main() */
void main_loop()
{
- u_int lt;
- long wait_time;
- HOST_ENTRY *h;
-
- while(ev_first) {
- /* Any event that can be processed now ? */
- if(ev_first->ev_time.tv_sec < current_time.tv_sec ||
- (ev_first->ev_time.tv_sec == current_time.tv_sec &&
- ev_first->ev_time.tv_usec < current_time.tv_usec))
- {
- /* Event type: ping */
- if(ev_first->ev_type == EV_TYPE_PING) {
- /* Make sure that we don't ping more than once every "interval" */
- lt = timeval_diff( ¤t_time, &last_send_time );
- if(lt < interval) goto wait_for_reply;
-
- /* Dequeue the event */
- h = ev_dequeue();
-
- /* Send the ping */
- if(!send_ping(s, h)) goto wait_for_reply;
-
- /* Check what needs to be done next */
- if(!loop_flag && !count_flag) {
- /* Normal mode: schedule retry */
- if(h->waiting < retry + 1) {
- h->ev_type = EV_TYPE_PING;
- h->ev_time.tv_sec = current_time.tv_sec;
- h->ev_time.tv_usec = current_time.tv_usec;
- timeval_add(&h->ev_time, h->timeout);
- ev_enqueue(h);
-
- if(backoff_flag) {
- h->timeout *= backoff;
- }
- }
- /* Normal mode: schedule timeout for last retry */
- else {
- h->ev_type = EV_TYPE_TIMEOUT;
- h->ev_time.tv_sec = current_time.tv_sec;
- h->ev_time.tv_usec = current_time.tv_usec;
- timeval_add(&h->ev_time, h->timeout);
- ev_enqueue(h);
- }
- }
- /* Loop and count mode: schedule next ping */
- else if(loop_flag || (count_flag && h->num_sent < count))
- {
- h->ev_type = EV_TYPE_PING;
- h->ev_time.tv_sec = current_time.tv_sec;
- h->ev_time.tv_usec = current_time.tv_usec;
- timeval_add(&h->ev_time, perhost_interval);
- ev_enqueue(h);
- }
- /* Count mode: schedule timeout after last ping */
- else if(count_flag && count_flag && h->num_sent >= count) {
- h->ev_type = EV_TYPE_TIMEOUT;
- h->ev_time.tv_sec = current_time.tv_sec;
- h->ev_time.tv_usec = current_time.tv_usec;
- timeval_add(&h->ev_time, h->timeout);
- ev_enqueue(h);
- }
- }
- else if(ev_first->ev_type == EV_TYPE_TIMEOUT) {
- num_timeout++;
- remove_job(ev_first);
- }
- }
-
- wait_for_reply:
-
- /* When can we expect the next event? */
- if(ev_first) {
- if(ev_first->ev_time.tv_sec == 0) {
- wait_time = interval;
- }
- else {
- wait_time = timeval_diff(&ev_first->ev_time, ¤t_time);
- if(wait_time < (long) interval) {
- wait_time = interval;
- }
- }
+ u_int lt;
+ long wait_time;
+ HOST_ENTRY *h;
+
+ while(ev_first) {
+ /* Any event that can be processed now ? */
+ if(ev_first->ev_time.tv_sec < current_time.tv_sec ||
+ (ev_first->ev_time.tv_sec == current_time.tv_sec &&
+ ev_first->ev_time.tv_usec < current_time.tv_usec))
+ {
+ /* Event type: ping */
+ if(ev_first->ev_type == EV_TYPE_PING) {
+ /* Make sure that we don't ping more than once every "interval" */
+ lt = timeval_diff( ¤t_time, &last_send_time );
+ if(lt < interval) goto wait_for_reply;
+
+ /* Dequeue the event */
+ h = ev_dequeue();
+
+ /* Send the ping */
+ if(!send_ping(s, h)) goto wait_for_reply;
+
+ /* Check what needs to be done next */
+ if(!loop_flag && !count_flag) {
+ /* Normal mode: schedule retry */
+ if(h->waiting < retry + 1) {
+ h->ev_type = EV_TYPE_PING;
+ h->ev_time.tv_sec = current_time.tv_sec;
+ h->ev_time.tv_usec = current_time.tv_usec;
+ timeval_add(&h->ev_time, h->timeout);
+ ev_enqueue(h);
+
+ if(backoff_flag) {
+ h->timeout *= backoff;
+ }
+ }
+ /* Normal mode: schedule timeout for last retry */
+ else {
+ h->ev_type = EV_TYPE_TIMEOUT;
+ h->ev_time.tv_sec = current_time.tv_sec;
+ h->ev_time.tv_usec = current_time.tv_usec;
+ timeval_add(&h->ev_time, h->timeout);
+ ev_enqueue(h);
+ }
+ }
+ /* Loop and count mode: schedule next ping */
+ else if(loop_flag || (count_flag && h->num_sent < count))
+ {
+ h->ev_type = EV_TYPE_PING;
+ h->ev_time.tv_sec = current_time.tv_sec;
+ h->ev_time.tv_usec = current_time.tv_usec;
+ timeval_add(&h->ev_time, perhost_interval);
+ ev_enqueue(h);
+ }
+ /* Count mode: schedule timeout after last ping */
+ else if(count_flag && count_flag && h->num_sent >= count) {
+ h->ev_type = EV_TYPE_TIMEOUT;
+ h->ev_time.tv_sec = current_time.tv_sec;
+ h->ev_time.tv_usec = current_time.tv_usec;
+ timeval_add(&h->ev_time, h->timeout);
+ ev_enqueue(h);
+ }
+ }
+ else if(ev_first->ev_type == EV_TYPE_TIMEOUT) {
+ num_timeout++;
+ remove_job(ev_first);
+ }
+ }
+
+ wait_for_reply:
+
+ /* When can we expect the next event? */
+ if(ev_first) {
+ if(ev_first->ev_time.tv_sec == 0) {
+ wait_time = interval;
+ }
+ else {
+ wait_time = timeval_diff(&ev_first->ev_time, ¤t_time);
+ if(wait_time < (long) interval) {
+ wait_time = interval;
+ }
+ }
#if defined( DEBUG ) || defined( _DEBUG )
- if( trace_flag ) {
- fprintf(stderr, "next event in %d ms (%s)\n", wait_time / 100, ev_first->host);
- }
+ if( trace_flag ) {
+ fprintf(stderr, "next event in %d ms (%s)\n", wait_time / 100, ev_first->host);
+ }
#endif
- }
- else {
- wait_time = interval;
- }
-
- /* Receive replies */
- /* (this is what sleeps during each loop iteration) */
- if(wait_for_reply(wait_time)) {
- while(wait_for_reply(0)); /* process other replies in the queue */
- }
-
- gettimeofday( ¤t_time, &tz );
-
- /* Print report */
- if( report_interval && ( loop_flag || count_flag ) &&
- ( timeval_diff ( ¤t_time, &last_report_time ) > report_interval ) )
- {
- print_per_system_splits();
- last_report_time = current_time;
- }
- }
+ }
+ else {
+ wait_time = interval;
+ }
+
+ /* Receive replies */
+ /* (this is what sleeps during each loop iteration) */
+ if(wait_for_reply(wait_time)) {
+ while(wait_for_reply(0)); /* process other replies in the queue */
+ }
+
+ gettimeofday( ¤t_time, &tz );
+
+ /* Print report */
+ if( report_interval && ( loop_flag || count_flag ) &&
+ ( timeval_diff ( ¤t_time, &last_report_time ) > report_interval ) )
+ {
+ print_per_system_splits();
+ last_report_time = current_time;
+ }
+ }
}
/************************************************************
void 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();
+ 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();
+ else if( print_per_system_flag )
+ print_per_system_stats();
#endif /* DEBUG || _DEBUG */
- if( stats_flag )
- print_global_stats();
+ if( stats_flag )
+ print_global_stats();
- if( num_noaddress )
- exit( 2 );
- else if( num_alive != num_hosts )
- exit( 1 );
-
- exit(0);
+ if( num_noaddress )
+ exit( 2 );
+ else if( num_alive != num_hosts )
+ exit( 1 );
+
+ exit(0);
} /* finish() */
void print_per_system_stats( void )
#endif /* _NO_PROTO */
{
- int i, j, 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 */
+ int i, j, 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 */
+ 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 */
+ }/* FOR */
- free( buf );
+ free( buf );
} /* print_per_system_stats() */
void print_per_system_splits( void )
#endif /* _NO_PROTO */
{
- int i, avg;
- HOST_ENTRY *h;
- char *buf;
- int bufsize;
- struct tm *curr_tm;
-
- 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" );
-
- curr_tm = localtime( ( time_t* )¤t_time.tv_sec );
- fprintf( stderr, "[%2.2d:%2.2d:%2.2d]\n", curr_tm->tm_hour,
- curr_tm->tm_min, curr_tm->tm_sec );
-
- for( i = 0; i < num_hosts; i++ )
- {
- h = table[i];
- fprintf( stderr, "%s%s :", h->host, h->pad );
-
- if( h->num_recv_i <= h->num_sent_i )
- {
- fprintf( stderr, " xmt/rcv/%%loss = %d/%d/%d%%",
- h->num_sent_i, h->num_recv_i, h->num_sent_i > 0 ?
- ( ( h->num_sent_i - h->num_recv_i ) * 100 ) / h->num_sent_i : 0 );
-
- }/* IF */
- else
- {
- fprintf( stderr, " xmt/rcv/%%return = %d/%d/%d%%",
- h->num_sent_i, h->num_recv_i, h->num_sent_i > 0 ?
- ( ( h->num_recv_i * 100 ) / h->num_sent_i ) : 0 );
-
- }/* ELSE */
-
- if( h->num_recv_i )
- {
- avg = h->total_time_i / h->num_recv_i;
- fprintf( stderr, ", min/avg/max = %s", sprint_tm( h->min_reply_i ) );
- fprintf( stderr, "/%s", sprint_tm( avg ) );
- fprintf( stderr, "/%s", sprint_tm( h->max_reply_i ) );
-
- }/* IF */
-
- fprintf( stderr, "\n" );
- h->num_sent_i = h->num_recv_i = h->max_reply_i =
- h->min_reply_i = h->total_time_i = 0;
-
- }/* FOR */
-
- free( buf );
+ int i, avg;
+ HOST_ENTRY *h;
+ char *buf;
+ int bufsize;
+ struct tm *curr_tm;
+
+ 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" );
+
+ curr_tm = localtime( ( time_t* )¤t_time.tv_sec );
+ fprintf( stderr, "[%2.2d:%2.2d:%2.2d]\n", curr_tm->tm_hour,
+ curr_tm->tm_min, curr_tm->tm_sec );
+
+ for( i = 0; i < num_hosts; i++ )
+ {
+ h = table[i];
+ fprintf( stderr, "%s%s :", h->host, h->pad );
+
+ if( h->num_recv_i <= h->num_sent_i )
+ {
+ fprintf( stderr, " xmt/rcv/%%loss = %d/%d/%d%%",
+ h->num_sent_i, h->num_recv_i, h->num_sent_i > 0 ?
+ ( ( h->num_sent_i - h->num_recv_i ) * 100 ) / h->num_sent_i : 0 );
+
+ }/* IF */
+ else
+ {
+ fprintf( stderr, " xmt/rcv/%%return = %d/%d/%d%%",
+ h->num_sent_i, h->num_recv_i, h->num_sent_i > 0 ?
+ ( ( h->num_recv_i * 100 ) / h->num_sent_i ) : 0 );
+
+ }/* ELSE */
+
+ if( h->num_recv_i )
+ {
+ avg = h->total_time_i / h->num_recv_i;
+ fprintf( stderr, ", min/avg/max = %s", sprint_tm( h->min_reply_i ) );
+ fprintf( stderr, "/%s", sprint_tm( avg ) );
+ fprintf( stderr, "/%s", sprint_tm( h->max_reply_i ) );
+
+ }/* IF */
+
+ fprintf( stderr, "\n" );
+ h->num_sent_i = h->num_recv_i = h->max_reply_i =
+ h->min_reply_i = h->total_time_i = 0;
+
+ }/* FOR */
+
+ free( buf );
} /* print_per_system_splits() */
void print_global_stats( void )
#endif /* _NO_PROTO */
{
- fflush( stdout );
- fprintf( stderr, "\n" );
- fprintf( stderr, " %7d targets\n", num_hosts );
- fprintf( stderr, " %7d alive\n", num_alive );
- fprintf( stderr, " %7d unreachable\n" ,num_unreachable );
- fprintf( stderr, " %7d unknown addresses\n", num_noaddress );
- fprintf( stderr, "\n" );
- fprintf( stderr, " %7d timeouts (waiting for response)\n", num_timeout );
- fprintf( stderr, " %7d ICMP Echos sent\n", num_pingsent );
- fprintf( stderr, " %7d ICMP Echo Replies received\n", num_pingreceived );
- fprintf( stderr, " %7d other ICMP received\n", num_othericmprcvd );
- fprintf( stderr, "\n" );
-
- if( total_replies == 0 )
- {
- min_reply = 0;
- max_reply = 0;
- total_replies = 1;
- sum_replies = 0;
-
- }/* IF */
-
- fprintf( stderr, " %s ms (min round trip time)\n", sprint_tm( min_reply ) );
- fprintf( stderr, " %s ms (avg round trip time)\n",
- sprint_tm( ( int )( sum_replies / total_replies ) ) );
- fprintf( stderr, " %s ms (max round trip time)\n", sprint_tm( max_reply ) );
- fprintf( stderr, " %12.3f sec (elapsed real time)\n",
- timeval_diff( &end_time, &start_time ) / 100000.0 );
- fprintf( stderr, "\n" );
+ fflush( stdout );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, " %7d targets\n", num_hosts );
+ fprintf( stderr, " %7d alive\n", num_alive );
+ fprintf( stderr, " %7d unreachable\n" ,num_unreachable );
+ fprintf( stderr, " %7d unknown addresses\n", num_noaddress );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, " %7d timeouts (waiting for response)\n", num_timeout );
+ fprintf( stderr, " %7d ICMP Echos sent\n", num_pingsent );
+ fprintf( stderr, " %7d ICMP Echo Replies received\n", num_pingreceived );
+ fprintf( stderr, " %7d other ICMP received\n", num_othericmprcvd );
+ fprintf( stderr, "\n" );
+
+ if( total_replies == 0 )
+ {
+ min_reply = 0;
+ max_reply = 0;
+ total_replies = 1;
+ sum_replies = 0;
+
+ }/* IF */
+
+ fprintf( stderr, " %s ms (min round trip time)\n", sprint_tm( min_reply ) );
+ fprintf( stderr, " %s ms (avg round trip time)\n",
+ sprint_tm( ( int )( sum_replies / total_replies ) ) );
+ fprintf( stderr, " %s ms (max round trip time)\n", sprint_tm( max_reply ) );
+ fprintf( stderr, " %12.3f sec (elapsed real time)\n",
+ timeval_diff( &end_time, &start_time ) / 100000.0 );
+ fprintf( stderr, "\n" );
} /* print_global_stats() */
int send_ping( int s, HOST_ENTRY *h )
#endif /* _NO_PROTO */
{
- char *buffer;
- FPING_ICMPHDR *icp;
- PING_DATA *pdp;
- int n;
+ char *buffer;
+ FPING_ICMPHDR *icp;
+ PING_DATA *pdp;
+ int n;
int myseq;
- buffer = ( char* )malloc( ( size_t )ping_pkt_size );
- if( !buffer )
- crash_and_burn( "can't malloc ping packet" );
-
- memset( buffer, 0, ping_pkt_size * sizeof( char ) );
- icp = ( FPING_ICMPHDR* )buffer;
+ buffer = ( char* )malloc( ( size_t )ping_pkt_size );
+ if( !buffer )
+ crash_and_burn( "can't malloc ping packet" );
+
+ memset( buffer, 0, ping_pkt_size * sizeof( char ) );
+ icp = ( FPING_ICMPHDR* )buffer;
- gettimeofday( &h->last_send_time, &tz );
- myseq = h->num_sent * num_hosts + h->i;
- max_seq_sent = myseq > max_seq_sent ? myseq : max_seq_sent;
+ gettimeofday( &h->last_send_time, &tz );
+ myseq = h->num_sent * num_hosts + h->i;
+ max_seq_sent = myseq > max_seq_sent ? myseq : max_seq_sent;
#ifndef IPV6
- icp->icmp_type = ICMP_ECHO;
- icp->icmp_code = 0;
- icp->icmp_cksum = 0;
- icp->icmp_seq = htons(myseq);
- icp->icmp_id = htons(ident);
+ icp->icmp_type = ICMP_ECHO;
+ icp->icmp_code = 0;
+ icp->icmp_cksum = 0;
+ icp->icmp_seq = htons(myseq);
+ icp->icmp_id = htons(ident);
- pdp = ( PING_DATA* )( buffer + SIZE_ICMP_HDR );
- pdp->ping_ts = h->last_send_time;
- pdp->ping_count = h->num_sent;
+ pdp = ( PING_DATA* )( buffer + SIZE_ICMP_HDR );
+ pdp->ping_ts = h->last_send_time;
+ pdp->ping_count = h->num_sent;
- icp->icmp_cksum = in_cksum( ( u_short* )icp, ping_pkt_size );
+ icp->icmp_cksum = in_cksum( ( u_short* )icp, ping_pkt_size );
#else
- icp->icmp6_type = ICMP6_ECHO_REQUEST;
- icp->icmp6_code = 0;
- icp->icmp6_seq = htons(myseq);
- icp->icmp6_id = htons(ident);
+ icp->icmp6_type = ICMP6_ECHO_REQUEST;
+ icp->icmp6_code = 0;
+ icp->icmp6_seq = htons(myseq);
+ icp->icmp6_id = htons(ident);
- pdp = ( PING_DATA* )( buffer + SIZE_ICMP_HDR );
- pdp->ping_ts = h->last_send_time;
- pdp->ping_count = h->num_sent;
+ pdp = ( PING_DATA* )( buffer + SIZE_ICMP_HDR );
+ pdp->ping_ts = h->last_send_time;
+ pdp->ping_count = h->num_sent;
- icp->icmp6_cksum = 0; // The IPv6 stack calculates the checksum for us...
+ icp->icmp6_cksum = 0; // The IPv6 stack calculates the checksum for us...
#endif
#if defined(DEBUG) || defined(_DEBUG)
- if( trace_flag )
- printf( "sending [%d] to %s\n", h->num_sent, h->host );
+ if( trace_flag )
+ printf( "sending [%d] to %s\n", h->num_sent, h->host );
#endif /* DEBUG || _DEBUG */
- n = sendto( s, buffer, ping_pkt_size, 0,
- ( struct sockaddr* )&h->saddr, sizeof( FPING_SOCKADDR ) );
-
- if( n < 0 || n != ping_pkt_size )
- {
- if( verbose_flag || unreachable_flag )
- {
- printf( "%s", h->host );
- if( verbose_flag )
- printf( " error while sending ping: %s\n", strerror( errno ) );
-
- printf( "\n" );
-
- }/* IF */
-
- num_unreachable++;
- remove_job( h );
- free( buffer );
- return(0);
- }
-
- /* mark this trial as outstanding */
- if( !loop_flag )
- h->resp_times[h->num_sent] = RESP_WAITING;
+ n = sendto( s, buffer, ping_pkt_size, 0,
+ ( struct sockaddr* )&h->saddr, sizeof( FPING_SOCKADDR ) );
+
+ if( n < 0 || n != ping_pkt_size )
+ {
+ if( verbose_flag || unreachable_flag )
+ {
+ printf( "%s", h->host );
+ if( verbose_flag )
+ printf( " error while sending ping: %s\n", strerror( errno ) );
+
+ printf( "\n" );
+
+ }/* IF */
+
+ num_unreachable++;
+ remove_job( h );
+ free( buffer );
+ return(0);
+ }
+
+ /* mark this trial as outstanding */
+ if( !loop_flag )
+ h->resp_times[h->num_sent] = RESP_WAITING;
#if defined( DEBUG ) || defined( _DEBUG )
- if( sent_times_flag )
- h->sent_times[h->num_sent] = timeval_diff( &h->last_send_time, &start_time );
+ if( sent_times_flag )
+ h->sent_times[h->num_sent] = timeval_diff( &h->last_send_time, &start_time );
#endif /* DEBUG || _DEBUG */
- h->num_sent++;
- h->num_sent_i++;
- h->waiting++;
- num_pingsent++;
- last_send_time = h->last_send_time;
-
- free( buffer );
- return(1);
+ h->num_sent++;
+ h->num_sent_i++;
+ h->waiting++;
+ num_pingsent++;
+ last_send_time = h->last_send_time;
+
+ free( buffer );
+ return(1);
}
int wait_for_reply(u_int wait_time)
#endif
{
- int result;
- static char buffer[4096];
- FPING_SOCKADDR response_addr;
- struct ip *ip;
- int hlen = 0;
- FPING_ICMPHDR *icp;
- int n, avg;
- HOST_ENTRY *h;
- long this_reply;
- int this_count;
- struct timeval sent_time;
-
- result = recvfrom_wto( s, buffer, sizeof(buffer), &response_addr, wait_time );
-
- if( result < 0 )
- return 0; /* timeout */
+ int result;
+ static char buffer[4096];
+ FPING_SOCKADDR response_addr;
+ struct ip *ip;
+ int hlen = 0;
+ FPING_ICMPHDR *icp;
+ int n, avg;
+ HOST_ENTRY *h;
+ long this_reply;
+ int this_count;
+ struct timeval sent_time;
+
+ result = recvfrom_wto( s, buffer, sizeof(buffer), &response_addr, wait_time );
+
+ if( result < 0 )
+ return 0; /* timeout */
#if defined( DEBUG ) || defined( _DEBUG )
- if( randomly_lose_flag )
- {
- if( ( random() & 0x07 ) <= lose_factor )
- return 0;
+ if( randomly_lose_flag )
+ {
+ if( ( random() & 0x07 ) <= lose_factor )
+ return 0;
- }/* IF */
+ }/* IF */
#endif /* DEBUG || _DEBUG */
- ip = ( struct ip* )buffer;
+ ip = ( struct ip* )buffer;
#ifndef IPV6
#if defined( __alpha__ ) && __STDC__ && !defined( __GLIBC__ )
- /* The alpha headers are decidedly broken.
- * Using an ANSI compiler, it provides ip_vhl instead of ip_hl and
- * ip_v. So, to get ip_hl, we mask off the bottom four bits.
- */
- hlen = ( ip->ip_vhl & 0x0F ) << 2;
+ /* The alpha headers are decidedly broken.
+ * Using an ANSI compiler, it provides ip_vhl instead of ip_hl and
+ * ip_v. So, to get ip_hl, we mask off the bottom four bits.
+ */
+ hlen = ( ip->ip_vhl & 0x0F ) << 2;
#else
- hlen = ip->ip_hl << 2;
+ hlen = ip->ip_hl << 2;
#endif /* defined(__alpha__) && __STDC__ */
- if( result < hlen + ICMP_MINLEN )
+ if( result < hlen + ICMP_MINLEN )
#else
- if( result < sizeof(FPING_ICMPHDR) )
+ if( result < sizeof(FPING_ICMPHDR) )
#endif
- {
- if( verbose_flag )
- {
+ {
+ if( verbose_flag )
+ {
#ifndef IPV6
- printf( "received packet too short for ICMP (%d bytes from %s)\n", result,
- inet_ntoa( response_addr.sin_addr ) );
-#else
- char buf[INET6_ADDRSTRLEN];
- inet_ntop(response_addr.sin6_family, &response_addr.sin6_addr, buf, INET6_ADDRSTRLEN);
- printf( "received packet too short for ICMP (%d bytes from %s)\n", result, buf);
+ printf( "received packet too short for ICMP (%d bytes from %s)\n", result,
+ inet_ntoa( response_addr.sin_addr ) );
+#else
+ char buf[INET6_ADDRSTRLEN];
+ inet_ntop(response_addr.sin6_family, &response_addr.sin6_addr, buf, INET6_ADDRSTRLEN);
+ printf( "received packet too short for ICMP (%d bytes from %s)\n", result, buf);
#endif
- }
- return( 1 ); /* too short */
- }/* IF */
+ }
+ return( 1 ); /* too short */
+ }/* IF */
- icp = ( FPING_ICMPHDR* )( buffer + hlen );
+ icp = ( FPING_ICMPHDR* )( buffer + hlen );
#ifndef IPV6
- if( icp->icmp_type != ICMP_ECHOREPLY )
+ if( icp->icmp_type != ICMP_ECHOREPLY )
#else
- if( icp->icmp6_type != ICMP6_ECHO_REPLY )
+ if( icp->icmp6_type != ICMP6_ECHO_REPLY )
#endif
- {
- /* handle some problem */
- if( handle_random_icmp( icp, result, &response_addr ) )
- num_othericmprcvd++;
- return 1;
- }/* IF */
+ {
+ /* handle some problem */
+ if( handle_random_icmp( icp, result, &response_addr ) )
+ num_othericmprcvd++;
+ return 1;
+ }/* IF */
#ifndef IPV6
- if( ntohs(icp->icmp_id) != ident )
+ if( ntohs(icp->icmp_id) != ident )
#else
- if( ntohs(icp->icmp6_id) != ident )
+ if( ntohs(icp->icmp6_id) != ident )
#endif
- return 1; /* packet received, but not the one we are looking for! */
+ return 1; /* packet received, but not the one we are looking for! */
- num_pingreceived++;
+ num_pingreceived++;
#ifndef IPV6
- if( ntohs(icp->icmp_seq) > max_seq_sent )
+ if( ntohs(icp->icmp_seq) > max_seq_sent )
#else
- if( ntohs(icp->icmp6_seq) > max_seq_sent )
+ if( ntohs(icp->icmp6_seq) > max_seq_sent )
#endif
- return( 1 ); /* packet received, don't worry about it anymore */
+ return( 1 ); /* packet received, don't worry about it anymore */
#ifndef IPV6
- n = ntohs(icp->icmp_seq) % num_hosts;
+ n = ntohs(icp->icmp_seq) % num_hosts;
#else
- n = ntohs(icp->icmp6_seq) % num_hosts;
+ n = ntohs(icp->icmp6_seq) % num_hosts;
#endif
- h = table[n];
+ h = table[n];
- /* received ping is cool, so process it */
- gettimeofday( ¤t_time, &tz );
- h->waiting = 0;
- h->timeout = timeout;
- h->num_recv++;
- h->num_recv_i++;
+ /* received ping is cool, so process it */
+ gettimeofday( ¤t_time, &tz );
+ h->waiting = 0;
+ h->timeout = timeout;
+ h->num_recv++;
+ h->num_recv_i++;
#ifndef IPV6
- memcpy( &sent_time, icp->icmp_data + offsetof( PING_DATA, ping_ts ), sizeof( sent_time ) );
- memcpy( &this_count, icp->icmp_data, sizeof( this_count ) );
+ memcpy( &sent_time, icp->icmp_data + offsetof( PING_DATA, ping_ts ), sizeof( sent_time ) );
+ memcpy( &this_count, icp->icmp_data, sizeof( this_count ) );
#else
- memcpy( &sent_time, ((char *)icp->icmp6_data32)+4+offsetof(PING_DATA, ping_ts), sizeof( sent_time ) );
- memcpy( &this_count, ((char *)icp->icmp6_data32)+4, sizeof( this_count ) );
+ memcpy( &sent_time, ((char *)icp->icmp6_data32)+4+offsetof(PING_DATA, ping_ts), sizeof( sent_time ) );
+ memcpy( &this_count, ((char *)icp->icmp6_data32)+4, sizeof( this_count ) );
#endif
#if defined( DEBUG ) || defined( _DEBUG )
- if( trace_flag )
- printf( "received [%d] from %s\n", this_count, h->host );
+ if( trace_flag )
+ printf( "received [%d] from %s\n", this_count, h->host );
#endif /* DEBUG || _DEBUG */
- this_reply = timeval_diff( ¤t_time, &sent_time );
- if( this_reply > max_reply ) max_reply = this_reply;
- if( this_reply < min_reply ) min_reply = this_reply;
- if( this_reply > h->max_reply ) h->max_reply = this_reply;
- if( this_reply < h->min_reply ) h->min_reply = this_reply;
- if( this_reply > h->max_reply_i ) h->max_reply_i = this_reply;
- if( this_reply < h->min_reply_i ) h->min_reply_i = this_reply;
- sum_replies += this_reply;
- h->total_time += this_reply;
- h->total_time_i += this_reply;
- total_replies++;
-
- /* note reply time in array, probably */
- if( !loop_flag )
- {
- if( ( this_count >= 0 ) && ( this_count < trials ) )
- {
- if( h->resp_times[this_count] != RESP_WAITING )
- {
- if( !per_recv_flag )
- {
- fprintf( stderr, "%s : duplicate for [%d], %d bytes, %s ms",
- h->host, this_count, result, sprint_tm( this_reply ) );
+ this_reply = timeval_diff( ¤t_time, &sent_time );
+ if( this_reply > max_reply ) max_reply = this_reply;
+ if( this_reply < min_reply ) min_reply = this_reply;
+ if( this_reply > h->max_reply ) h->max_reply = this_reply;
+ if( this_reply < h->min_reply ) h->min_reply = this_reply;
+ if( this_reply > h->max_reply_i ) h->max_reply_i = this_reply;
+ if( this_reply < h->min_reply_i ) h->min_reply_i = this_reply;
+ sum_replies += this_reply;
+ h->total_time += this_reply;
+ h->total_time_i += this_reply;
+ total_replies++;
+
+ /* note reply time in array, probably */
+ if( !loop_flag )
+ {
+ if( ( this_count >= 0 ) && ( this_count < trials ) )
+ {
+ if( h->resp_times[this_count] != RESP_WAITING )
+ {
+ if( !per_recv_flag )
+ {
+ fprintf( stderr, "%s : duplicate for [%d], %d bytes, %s ms",
+ h->host, this_count, result, sprint_tm( this_reply ) );
#ifndef IPV6
- if( response_addr.sin_addr.s_addr != h->saddr.sin_addr.s_addr )
- fprintf( stderr, " [<- %s]", inet_ntoa( response_addr.sin_addr ) );
+ if( response_addr.sin_addr.s_addr != h->saddr.sin_addr.s_addr )
+ fprintf( stderr, " [<- %s]", inet_ntoa( response_addr.sin_addr ) );
#else
- if(memcmp(&response_addr.sin6_addr, &h->saddr.sin6_addr, sizeof(response_addr.sin6_addr)))
- {
- char buf[INET6_ADDRSTRLEN];
- inet_ntop(response_addr.sin6_family, &response_addr.sin6_addr, buf, INET6_ADDRSTRLEN);
-
- fprintf( stderr, " [<- %s]", buf);
- }
-#endif
- fprintf( stderr, "\n" );
-
- }/* IF */
- }/* IF */
- else
- h->resp_times[this_count] = this_reply;
-
- }/* IF */
- else
- {
- /* count is out of bounds?? */
- fprintf( stderr, "%s : duplicate for [%d], %d bytes, %s ms\n",
- h->host, this_count, result, sprint_tm( this_reply ) );
-
- }/* ELSE */
- }/* IF */
-
- if( h->num_recv == 1 )
- {
- num_alive++;
- if( verbose_flag || alive_flag )
- {
- printf( "%s", h->host );
-
- if( verbose_flag )
- printf( " is alive" );
-
- if( elapsed_flag )
- printf( " (%s ms)", sprint_tm( this_reply ) );
+ if(memcmp(&response_addr.sin6_addr, &h->saddr.sin6_addr, sizeof(response_addr.sin6_addr)))
+ {
+ char buf[INET6_ADDRSTRLEN];
+ inet_ntop(response_addr.sin6_family, &response_addr.sin6_addr, buf, INET6_ADDRSTRLEN);
+
+ fprintf( stderr, " [<- %s]", buf);
+ }
+#endif
+ fprintf( stderr, "\n" );
+
+ }/* IF */
+ }/* IF */
+ else
+ h->resp_times[this_count] = this_reply;
+
+ }/* IF */
+ else
+ {
+ /* count is out of bounds?? */
+ fprintf( stderr, "%s : duplicate for [%d], %d bytes, %s ms\n",
+ h->host, this_count, result, sprint_tm( this_reply ) );
+
+ }/* ELSE */
+ }/* IF */
+
+ if( h->num_recv == 1 )
+ {
+ num_alive++;
+ if( verbose_flag || alive_flag )
+ {
+ printf( "%s", h->host );
+
+ if( verbose_flag )
+ printf( " is alive" );
+
+ if( elapsed_flag )
+ printf( " (%s ms)", sprint_tm( this_reply ) );
#ifndef IPV6
- if( response_addr.sin_addr.s_addr != h->saddr.sin_addr.s_addr )
- printf( " [<- %s]", inet_ntoa( response_addr.sin_addr ) );
+ if( response_addr.sin_addr.s_addr != h->saddr.sin_addr.s_addr )
+ printf( " [<- %s]", inet_ntoa( response_addr.sin_addr ) );
#else
- if(memcmp(&response_addr.sin6_addr, &h->saddr.sin6_addr, sizeof(response_addr.sin6_addr)))
- {
- char buf[INET6_ADDRSTRLEN];
- inet_ntop(response_addr.sin6_family, &response_addr.sin6_addr, buf, INET6_ADDRSTRLEN);
- fprintf( stderr, " [<- %s]", buf);
- }
+ if(memcmp(&response_addr.sin6_addr, &h->saddr.sin6_addr, sizeof(response_addr.sin6_addr)))
+ {
+ char buf[INET6_ADDRSTRLEN];
+ inet_ntop(response_addr.sin6_family, &response_addr.sin6_addr, buf, INET6_ADDRSTRLEN);
+ fprintf( stderr, " [<- %s]", buf);
+ }
#endif
- printf( "\n" );
-
- }/* IF */
- }/* IF */
-
- if( per_recv_flag )
- {
- avg = h->total_time / h->num_recv;
- printf( "%s%s : [%d], %d bytes, %s ms",
- h->host, h->pad, this_count, result, sprint_tm( this_reply ) );
- printf( " (%s avg, ", sprint_tm( avg ) );
+ printf( "\n" );
+
+ }/* IF */
+ }/* IF */
+
+ if( per_recv_flag )
+ {
+ avg = h->total_time / h->num_recv;
+ printf( "%s%s : [%d], %d bytes, %s ms",
+ h->host, h->pad, this_count, result, sprint_tm( this_reply ) );
+ printf( " (%s avg, ", sprint_tm( avg ) );
- if( h->num_recv <= h->num_sent )
- {
- printf( "%d%% loss)",
- ( ( h->num_sent - h->num_recv ) * 100 ) / h->num_sent );
-
- }/* IF */
- else
- {
- printf( "%d%% return)",
- ( h->num_recv * 100 ) / h->num_sent );
-
- }/* ELSE */
+ if( h->num_recv <= h->num_sent )
+ {
+ printf( "%d%% loss)",
+ ( ( h->num_sent - h->num_recv ) * 100 ) / h->num_sent );
+
+ }/* IF */
+ else
+ {
+ printf( "%d%% return)",
+ ( h->num_recv * 100 ) / h->num_sent );
+
+ }/* ELSE */
#ifndef IPV6
- if( response_addr.sin_addr.s_addr != h->saddr.sin_addr.s_addr )
- printf( " [<- %s]", inet_ntoa( response_addr.sin_addr ) );
+ if( response_addr.sin_addr.s_addr != h->saddr.sin_addr.s_addr )
+ printf( " [<- %s]", inet_ntoa( response_addr.sin_addr ) );
#else
- if(memcmp(&response_addr.sin6_addr, &h->saddr.sin6_addr, sizeof(response_addr.sin6_addr)))
- {
- char buf[INET6_ADDRSTRLEN];
- inet_ntop(response_addr.sin6_family, &response_addr.sin6_addr, buf, INET6_ADDRSTRLEN);
- fprintf( stderr, " [<- %s]", buf);
- }
+ if(memcmp(&response_addr.sin6_addr, &h->saddr.sin6_addr, sizeof(response_addr.sin6_addr)))
+ {
+ char buf[INET6_ADDRSTRLEN];
+ inet_ntop(response_addr.sin6_family, &response_addr.sin6_addr, buf, INET6_ADDRSTRLEN);
+ fprintf( stderr, " [<- %s]", buf);
+ }
#endif
-
- printf( "\n" );
-
- }/* IF */
-
- /* remove this job, if we are done */
- if((count_flag && h->num_recv >= count) ||
- (!loop_flag && !count_flag && h->num_recv))
- {
- remove_job(h);
- }
-
- fflush( stdout );
- return num_jobs;
+
+ printf( "\n" );
+
+ }/* IF */
+
+ /* remove this job, if we are done */
+ if((count_flag && h->num_recv >= count) ||
+ (!loop_flag && !count_flag && h->num_recv))
+ {
+ remove_job(h);
+ }
+
+ fflush( stdout );
+ return num_jobs;
} /* wait_for_reply() */
int handle_random_icmp( FPING_ICMPHDR *p, int psize, FPING_SOCKADDR *addr )
#endif /* _NO_PROTO */
{
- FPING_ICMPHDR *sent_icmp;
- u_char *c;
- HOST_ENTRY *h;
+ FPING_ICMPHDR *sent_icmp;
+ u_char *c;
+ HOST_ENTRY *h;
#ifdef IPV6
- char addr_ascii[INET6_ADDRSTRLEN];
- inet_ntop(addr->sin6_family, &addr->sin6_addr, addr_ascii, INET6_ADDRSTRLEN);
+ char addr_ascii[INET6_ADDRSTRLEN];
+ inet_ntop(addr->sin6_family, &addr->sin6_addr, addr_ascii, INET6_ADDRSTRLEN);
#endif
- c = ( u_char* )p;
+ c = ( u_char* )p;
#ifndef IPV6
- switch( p->icmp_type )
+ switch( p->icmp_type )
#else
- switch( p->icmp6_type )
+ switch( p->icmp6_type )
#endif
- {
- case ICMP_UNREACH:
- sent_icmp = ( FPING_ICMPHDR* )( c + 28 );
-
+ {
+ case ICMP_UNREACH:
+ sent_icmp = ( FPING_ICMPHDR* )( c + 28 );
+
#ifndef IPV6
- sent_icmp = ( struct icmp* )( c + 28 );
-
- if( ( sent_icmp->icmp_type == ICMP_ECHO ) &&
- ( ntohs(sent_icmp->icmp_id) == ident ) &&
- ( ntohs(sent_icmp->icmp_seq) <= ( n_short )max_seq_sent ) )
- {
- /* this is a response to a ping we sent */
- h = table[ntohs(sent_icmp->icmp_seq) % num_hosts];
-
- if( p->icmp_code > ICMP_UNREACH_MAXTYPE )
- {
- fprintf( stderr, "ICMP Unreachable (Invalid Code) from %s for ICMP Echo sent to %s",
- inet_ntoa( addr->sin_addr ), h->host );
+ sent_icmp = ( struct icmp* )( c + 28 );
+
+ if( ( sent_icmp->icmp_type == ICMP_ECHO ) &&
+ ( ntohs(sent_icmp->icmp_id) == ident ) &&
+ ( ntohs(sent_icmp->icmp_seq) <= ( n_short )max_seq_sent ) )
+ {
+ /* this is a response to a ping we sent */
+ h = table[ntohs(sent_icmp->icmp_seq) % num_hosts];
+
+ if( p->icmp_code > ICMP_UNREACH_MAXTYPE )
+ {
+ fprintf( stderr, "ICMP Unreachable (Invalid Code) from %s for ICMP Echo sent to %s",
+ inet_ntoa( addr->sin_addr ), h->host );
#else
- if( ( sent_icmp->icmp6_type == ICMP_ECHO ) &&
- ( ntohs(sent_icmp->icmp6_id) == ident ) &&
- ( ntohs(sent_icmp->icmp6_seq) <= ( n_short )max_seq_sent ) )
- {
- /* this is a response to a ping we sent */
- h = table[ntohs(sent_icmp->icmp6_seq) % num_hosts];
-
- if( p->icmp6_code > ICMP_UNREACH_MAXTYPE )
- {
- fprintf( stderr, "ICMP Unreachable (Invalid Code) from %s for ICMP Echo sent to %s",
- addr_ascii, h->host );
+ if( ( sent_icmp->icmp6_type == ICMP_ECHO ) &&
+ ( ntohs(sent_icmp->icmp6_id) == ident ) &&
+ ( ntohs(sent_icmp->icmp6_seq) <= ( n_short )max_seq_sent ) )
+ {
+ /* this is a response to a ping we sent */
+ h = table[ntohs(sent_icmp->icmp6_seq) % num_hosts];
+
+ if( p->icmp6_code > ICMP_UNREACH_MAXTYPE )
+ {
+ fprintf( stderr, "ICMP Unreachable (Invalid Code) from %s for ICMP Echo sent to %s",
+ addr_ascii, h->host );
#endif
- }/* IF */
- else
- {
- fprintf( stderr, "%s from %s for ICMP Echo sent to %s",
+ }/* IF */
+ else
+ {
+ fprintf( stderr, "%s from %s for ICMP Echo sent to %s",
#ifndef IPV6
- icmp_unreach_str[p->icmp_code], inet_ntoa( addr->sin_addr ), h->host );
+ icmp_unreach_str[p->icmp_code], inet_ntoa( addr->sin_addr ), h->host );
#else
- icmp_unreach_str[p->icmp6_code], addr_ascii, h->host );
+ icmp_unreach_str[p->icmp6_code], addr_ascii, h->host );
#endif
-
- }/* ELSE */
+
+ }/* ELSE */
- if( inet_addr( h->host ) == -1 )
+ if( inet_addr( h->host ) == -1 )
#ifndef IPV6
- fprintf( stderr, " (%s)", inet_ntoa( h->saddr.sin_addr ) );
+ fprintf( stderr, " (%s)", inet_ntoa( h->saddr.sin_addr ) );
#else
- fprintf( stderr, " (%s)", addr_ascii);
+ fprintf( stderr, " (%s)", addr_ascii);
#endif
-
- fprintf( stderr, "\n" );
-
- }/* IF */
-
- return 1;
-
- case ICMP_SOURCEQUENCH:
- case ICMP_REDIRECT:
- case ICMP_TIMXCEED:
- case ICMP_PARAMPROB:
- sent_icmp = ( FPING_ICMPHDR* )( c + 28 );
+
+ fprintf( stderr, "\n" );
+
+ }/* IF */
+
+ return 1;
+
+ case ICMP_SOURCEQUENCH:
+ case ICMP_REDIRECT:
+ case ICMP_TIMXCEED:
+ case ICMP_PARAMPROB:
+ sent_icmp = ( FPING_ICMPHDR* )( c + 28 );
#ifndef IPV6
- if( ( sent_icmp->icmp_type == ICMP_ECHO ) &&
- ( ntohs(sent_icmp->icmp_id) == ident ) &&
- ( ntohs(sent_icmp->icmp_seq) <= ( n_short )max_seq_sent ) )
- {
- /* this is a response to a ping we sent */
- h = table[ntohs(sent_icmp->icmp_seq) % num_hosts];
- fprintf( stderr, "%s from %s for ICMP Echo sent to %s",
- icmp_type_str[p->icmp_type], inet_ntoa( addr->sin_addr ), h->host );
+ if( ( sent_icmp->icmp_type == ICMP_ECHO ) &&
+ ( ntohs(sent_icmp->icmp_id) == ident ) &&
+ ( ntohs(sent_icmp->icmp_seq) <= ( n_short )max_seq_sent ) )
+ {
+ /* this is a response to a ping we sent */
+ h = table[ntohs(sent_icmp->icmp_seq) % num_hosts];
+ fprintf( stderr, "%s from %s for ICMP Echo sent to %s",
+ icmp_type_str[p->icmp_type], inet_ntoa( addr->sin_addr ), h->host );
- if( inet_addr( h->host ) == -1 )
- fprintf( stderr, " (%s)", inet_ntoa( h->saddr.sin_addr ) );
+ if( inet_addr( h->host ) == -1 )
+ fprintf( stderr, " (%s)", inet_ntoa( h->saddr.sin_addr ) );
#else
- if( ( sent_icmp->icmp6_type == ICMP_ECHO ) &&
- ( ntohs(sent_icmp->icmp6_id) == ident ) &&
- ( ntohs(sent_icmp->icmp6_seq) <= ( n_short )max_seq_sent ) )
- {
- /* this is a response to a ping we sent */
- h = table[ntohs(sent_icmp->icmp6_seq) % num_hosts];
- fprintf( stderr, "%s from %s for ICMP Echo sent to %s",
- icmp_type_str[p->icmp6_type], addr_ascii, h->host );
+ if( ( sent_icmp->icmp6_type == ICMP_ECHO ) &&
+ ( ntohs(sent_icmp->icmp6_id) == ident ) &&
+ ( ntohs(sent_icmp->icmp6_seq) <= ( n_short )max_seq_sent ) )
+ {
+ /* this is a response to a ping we sent */
+ h = table[ntohs(sent_icmp->icmp6_seq) % num_hosts];
+ fprintf( stderr, "%s from %s for ICMP Echo sent to %s",
+ icmp_type_str[p->icmp6_type], addr_ascii, h->host );
- if( inet_addr( h->host ) == -1 )
- fprintf( stderr, " (%s)", addr_ascii );
+ if( inet_addr( h->host ) == -1 )
+ fprintf( stderr, " (%s)", addr_ascii );
#endif
- fprintf( stderr, "\n" );
-
- }/* IF */
-
- return 2;
-
- /* no way to tell whether any of these are sent due to our ping */
- /* or not (shouldn't be, of course), so just discard */
- case ICMP_TSTAMP:
- case ICMP_TSTAMPREPLY:
- case ICMP_IREQ:
- case ICMP_IREQREPLY:
- case ICMP_MASKREQ:
- case ICMP_MASKREPLY:
- default:
- return 0;
-
- }/* SWITCH */
+ fprintf( stderr, "\n" );
+
+ }/* IF */
+
+ return 2;
+
+ /* no way to tell whether any of these are sent due to our ping */
+ /* or not (shouldn't be, of course), so just discard */
+ case ICMP_TSTAMP:
+ case ICMP_TSTAMPREPLY:
+ case ICMP_IREQ:
+ case ICMP_IREQREPLY:
+ case ICMP_MASKREQ:
+ case ICMP_MASKREPLY:
+ default:
+ return 0;
+
+ }/* SWITCH */
} /* handle_random_icmp() */
int in_cksum( u_short *p, int n )
#endif /* _NO_PROTO */
{
- register u_short answer;
- register long sum = 0;
- u_short odd_byte = 0;
-
- while( n > 1 )
- {
- sum += *p++;
- n -= 2;
-
- }/* WHILE */
-
-
- /* mop up an odd byte, if necessary */
- if( n == 1 )
- {
- *( u_char* )( &odd_byte ) = *( u_char* )p;
- sum += odd_byte;
-
- }/* IF */
-
- sum = ( sum >> 16 ) + ( sum & 0xffff ); /* add hi 16 to low 16 */
- sum += ( sum >> 16 ); /* add carry */
- answer = ~sum; /* ones-complement, truncate*/
-
- return ( answer );
+ register u_short answer;
+ register long sum = 0;
+ u_short odd_byte = 0;
+
+ while( n > 1 )
+ {
+ sum += *p++;
+ n -= 2;
+
+ }/* WHILE */
+
+
+ /* mop up an odd byte, if necessary */
+ if( n == 1 )
+ {
+ *( u_char* )( &odd_byte ) = *( u_char* )p;
+ sum += odd_byte;
+
+ }/* IF */
+
+ sum = ( sum >> 16 ) + ( sum & 0xffff ); /* add hi 16 to low 16 */
+ sum += ( sum >> 16 ); /* add carry */
+ answer = ~sum; /* ones-complement, truncate*/
+
+ return ( answer );
} /* in_cksum() */
#endif /* _NO_PROTO */
{
#ifndef IPV6
- struct hostent *host_ent;
- u_int ipaddress;
- struct in_addr *ipa = ( struct in_addr* )&ipaddress;
- struct in_addr *host_add;
- char *nm;
- int i = 0;
-
- if( ( ipaddress = inet_addr( name ) ) != -1 )
- {
- /* input name is an IP addr, go with it */
- if( name_flag )
- {
- if( addr_flag )
- add_addr( name, na_cat( get_host_by_address( *ipa ), *ipa ), *ipa );
- else
- {
- nm = cpystr( get_host_by_address( *ipa ) );
- add_addr( name, nm, *ipa );
-
- }/* ELSE */
- }/* IF */
- else
- add_addr( name, name, *ipa );
-
- return;
-
- }/* IF */
-
- /* input name is not an IP addr, maybe it's a host name */
- host_ent = gethostbyname( name );
- if( host_ent == NULL )
- {
- if( h_errno == TRY_AGAIN )
- {
- u_sleep( DNS_TIMEOUT );
- host_ent = gethostbyname( name );
-
- }/* IF */
-
- if( host_ent == NULL )
- {
+ struct hostent *host_ent;
+ u_int ipaddress;
+ struct in_addr *ipa = ( struct in_addr* )&ipaddress;
+ struct in_addr *host_add;
+ char *nm;
+ int i = 0;
+
+ if( ( ipaddress = inet_addr( name ) ) != -1 )
+ {
+ /* input name is an IP addr, go with it */
+ if( name_flag )
+ {
+ if( addr_flag )
+ add_addr( name, na_cat( get_host_by_address( *ipa ), *ipa ), *ipa );
+ else
+ {
+ nm = cpystr( get_host_by_address( *ipa ) );
+ add_addr( name, nm, *ipa );
+
+ }/* ELSE */
+ }/* IF */
+ else
+ add_addr( name, name, *ipa );
+
+ return;
+
+ }/* IF */
+
+ /* input name is not an IP addr, maybe it's a host name */
+ host_ent = gethostbyname( name );
+ if( host_ent == NULL )
+ {
+ if( h_errno == TRY_AGAIN )
+ {
+ u_sleep( DNS_TIMEOUT );
+ host_ent = gethostbyname( name );
+
+ }/* IF */
+
+ if( host_ent == NULL )
+ {
#ifdef NIS_GROUPS
- /* maybe it's the name of a NIS netgroup */
- char *machine, *user_ignored, *domain_ignored;
- setnetgrent( name );
- if( getnetgrent( &machine, &user_ignored, &domain_ignored ) == 0 )
- {
- endnetgrent();
- if( !quiet_flag )
- fprintf( stderr, "%s address not found\n", name );
-
- num_noaddress++;
- return;
-
- }/* IF */
- else
- add_name( cpystr( machine ) );
-
- while( getnetgrent( &machine, &user_ignored, &domain_ignored ) )
- add_name( cpystr( machine ) );
+ /* maybe it's the name of a NIS netgroup */
+ char *machine, *user_ignored, *domain_ignored;
+ setnetgrent( name );
+ if( getnetgrent( &machine, &user_ignored, &domain_ignored ) == 0 )
+ {
+ endnetgrent();
+ if( !quiet_flag )
+ fprintf( stderr, "%s address not found\n", name );
+
+ num_noaddress++;
+ return;
+
+ }/* IF */
+ else
+ add_name( cpystr( machine ) );
+
+ while( getnetgrent( &machine, &user_ignored, &domain_ignored ) )
+ add_name( cpystr( machine ) );
- endnetgrent();
- return;
+ endnetgrent();
+ return;
#else
- if( !quiet_flag )
- fprintf( stderr, "%s address not found\n", name );
-
- num_noaddress++;
- return ;
+ if( !quiet_flag )
+ fprintf( stderr, "%s address not found\n", name );
+
+ num_noaddress++;
+ return ;
#endif /* NIS_GROUPS */
- }/* IF */
- }/* IF */
+ }/* IF */
+ }/* IF */
- host_add = ( struct in_addr* )*( host_ent->h_addr_list );
- if( host_add == NULL )
- {
- if( !quiet_flag )
- fprintf( stderr, "%s has no address data\n", name );
-
- num_noaddress++;
- return;
-
- }/* IF */
- else
- {
- /* it is indeed a hostname with a real address */
- while( host_add )
- {
- if( name_flag && addr_flag )
- add_addr( name, na_cat( name, *host_add ), *host_add );
- else if( addr_flag )
- {
- nm = cpystr( inet_ntoa( *host_add ) );
- add_addr( name, nm, *host_add );
- }/* ELSE IF */
- else
- add_addr( name, name, *host_add );
-
- if( !multif_flag )
- break;
-
- host_add = ( struct in_addr* )( host_ent->h_addr_list[++i] );
-
- }/* WHILE */
- }/* ELSE */
+ host_add = ( struct in_addr* )*( host_ent->h_addr_list );
+ if( host_add == NULL )
+ {
+ if( !quiet_flag )
+ fprintf( stderr, "%s has no address data\n", name );
+
+ num_noaddress++;
+ return;
+
+ }/* IF */
+ else
+ {
+ /* it is indeed a hostname with a real address */
+ while( host_add )
+ {
+ if( name_flag && addr_flag )
+ add_addr( name, na_cat( name, *host_add ), *host_add );
+ else if( addr_flag )
+ {
+ nm = cpystr( inet_ntoa( *host_add ) );
+ add_addr( name, nm, *host_add );
+ }/* ELSE IF */
+ else
+ add_addr( name, name, *host_add );
+
+ if( !multif_flag )
+ break;
+
+ host_add = ( struct in_addr* )( host_ent->h_addr_list[++i] );
+
+ }/* WHILE */
+ }/* ELSE */
#else
- FPING_SOCKADDR dst;
- struct addrinfo *res, hints;
- int ret_ga;
- char *hostname;
- size_t len;
-
- /* getaddrinfo */
- bzero(&hints, sizeof(struct addrinfo));
- hints.ai_flags = name_flag ? AI_CANONNAME : 0;
- hints.ai_family = AF_INET6;
- hints.ai_socktype = SOCK_RAW;
- hints.ai_protocol = IPPROTO_ICMPV6;
-
- ret_ga = getaddrinfo(name, NULL, &hints, &res);
- if (ret_ga) {
- if(!quiet_flag)
- warnx("%s", gai_strerror(ret_ga));
- num_noaddress++;
- return;
- }
- if (res->ai_canonname) hostname = res->ai_canonname;
- else hostname = name;
- if (!res->ai_addr) {
- if(!quiet_flag)
- warnx("getaddrinfo failed");
- num_noaddress++;
- return;
- }
- len = res->ai_addrlen;
- if (len > sizeof(FPING_SOCKADDR)) len = sizeof(FPING_SOCKADDR);
- (void)memcpy(&dst, res->ai_addr, len);
- add_addr(name, name, &dst);
+ FPING_SOCKADDR dst;
+ struct addrinfo *res, hints;
+ int ret_ga;
+ char *hostname;
+ size_t len;
+
+ /* getaddrinfo */
+ bzero(&hints, sizeof(struct addrinfo));
+ hints.ai_flags = name_flag ? AI_CANONNAME : 0;
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_RAW;
+ hints.ai_protocol = IPPROTO_ICMPV6;
+
+ ret_ga = getaddrinfo(name, NULL, &hints, &res);
+ if (ret_ga) {
+ if(!quiet_flag)
+ warnx("%s", gai_strerror(ret_ga));
+ num_noaddress++;
+ return;
+ }
+ if (res->ai_canonname) hostname = res->ai_canonname;
+ else hostname = name;
+ if (!res->ai_addr) {
+ if(!quiet_flag)
+ warnx("getaddrinfo failed");
+ num_noaddress++;
+ return;
+ }
+ len = res->ai_addrlen;
+ if (len > sizeof(FPING_SOCKADDR)) len = sizeof(FPING_SOCKADDR);
+ (void)memcpy(&dst, res->ai_addr, len);
+ add_addr(name, name, &dst);
#endif
} /* add_name() */
char *na_cat( char *name, struct in_addr ipaddr )
#endif /* _NO_PROTO */
{
- char *nm, *as;
+ char *nm, *as;
- as = inet_ntoa( ipaddr );
- nm = ( char* )malloc( strlen( name ) + strlen( as ) + 4 );
+ as = inet_ntoa( ipaddr );
+ nm = ( char* )malloc( strlen( name ) + strlen( as ) + 4 );
- if( !nm )
- crash_and_burn( "can't allocate some space for a string" );
-
- strcpy( nm, name );
- strcat( nm, " (" );
- strcat( nm, as );
- strcat( nm, ")" );
+ if( !nm )
+ crash_and_burn( "can't allocate some space for a string" );
+
+ strcpy( nm, name );
+ strcat( nm, " (" );
+ strcat( nm, as );
+ strcat( nm, ")" );
- return( nm );
+ return( nm );
} /* na_cat() */
#endif
#endif /* _NO_PROTO */
{
- HOST_ENTRY *p;
- int n, *i;
+ HOST_ENTRY *p;
+ int n, *i;
- p = ( HOST_ENTRY* )malloc( sizeof( HOST_ENTRY ) );
- if( !p )
- crash_and_burn( "can't allocate HOST_ENTRY" );
+ p = ( HOST_ENTRY* )malloc( sizeof( HOST_ENTRY ) );
+ if( !p )
+ crash_and_burn( "can't allocate HOST_ENTRY" );
- memset( ( char* ) p, 0, sizeof( HOST_ENTRY ) );
+ memset( ( char* ) p, 0, sizeof( HOST_ENTRY ) );
- p->name = name;
- p->host = host;
+ p->name = name;
+ p->host = host;
#ifndef IPV6
- p->saddr.sin_family = AF_INET;
- p->saddr.sin_addr = ipaddr;
+ p->saddr.sin_family = AF_INET;
+ p->saddr.sin_addr = ipaddr;
#else
- p->saddr.sin6_family = AF_INET6;
- (void)memcpy(&p->saddr, ipaddr, sizeof(FPING_SOCKADDR));
+ p->saddr.sin6_family = AF_INET6;
+ (void)memcpy(&p->saddr, ipaddr, sizeof(FPING_SOCKADDR));
#endif
- p->timeout = timeout;
- p->running = 1;
- p->min_reply = 10000000;
-
- if( strlen( p->host ) > max_hostname_len )
- max_hostname_len = strlen( p->host );
-
- /* array for response time results */
- if( !loop_flag )
- {
- i = ( int* )malloc( trials * sizeof( int ) );
- if( !i )
- crash_and_burn( "can't allocate resp_times array" );
-
- for( n = 1; n < trials; n++ )
- i[n] = RESP_UNUSED;
-
- p->resp_times = i;
-
- }/* IF */
+ p->timeout = timeout;
+ p->running = 1;
+ p->min_reply = 10000000;
+
+ if( strlen( p->host ) > max_hostname_len )
+ max_hostname_len = strlen( p->host );
+
+ /* array for response time results */
+ if( !loop_flag )
+ {
+ i = ( int* )malloc( trials * sizeof( int ) );
+ if( !i )
+ crash_and_burn( "can't allocate resp_times array" );
+
+ for( n = 1; n < trials; n++ )
+ i[n] = RESP_UNUSED;
+
+ p->resp_times = i;
+
+ }/* IF */
#if defined( DEBUG ) || defined( _DEBUG )
- /* likewise for sent times */
- if( sent_times_flag )
- {
- i = ( int* )malloc( trials * sizeof( int ) );
- if( !i )
- crash_and_burn( "can't allocate sent_times array" );
+ /* likewise for sent times */
+ if( sent_times_flag )
+ {
+ i = ( int* )malloc( trials * sizeof( int ) );
+ if( !i )
+ crash_and_burn( "can't allocate sent_times array" );
+
+ for( n = 1; n < trials; n++ )
+ i[n] = RESP_UNUSED;
+
+ p->sent_times = i;
- for( n = 1; n < trials; n++ )
- i[n] = RESP_UNUSED;
-
- p->sent_times = i;
-
- }/* IF */
+ }/* IF */
#endif /* DEBUG || _DEBUG */
- /* schedule first ping */
- p->ev_type = EV_TYPE_PING;
- p->ev_time.tv_sec = 0;
- p->ev_time.tv_usec = 0;
- ev_enqueue(p);
+ /* schedule first ping */
+ p->ev_type = EV_TYPE_PING;
+ p->ev_time.tv_sec = 0;
+ p->ev_time.tv_usec = 0;
+ ev_enqueue(p);
- num_hosts++;
+ num_hosts++;
} /* add_addr() */
#endif /* _NO_PROTO */
{
#if defined( DEBUG ) || defined( _DEBUG )
- if( trace_flag )
- printf( "removing job for %s\n", h->host );
+ if( trace_flag )
+ printf( "removing job for %s\n", h->host );
#endif /* DEBUG || _DEBUG */
- h->running = 0;
- h->waiting = 0;
- --num_jobs;
+ h->running = 0;
+ h->waiting = 0;
+ --num_jobs;
- ev_remove(h);
+ ev_remove(h);
} /* remove_job() */
char *get_host_by_address( struct in_addr in )
#endif /* _NO_PROTO */
{
- struct hostent *h;
+ struct hostent *h;
#ifndef IPV6
- h = gethostbyaddr( ( char* )&in, sizeof( struct in_addr ),AF_INET );
+ h = gethostbyaddr( ( char* )&in, sizeof( struct in_addr ),AF_INET );
#else
- h = gethostbyaddr( ( char* )&in, sizeof( FPING_SOCKADDR ),AF_INET6 );
+ h = gethostbyaddr( ( char* )&in, sizeof( FPING_SOCKADDR ),AF_INET6 );
#endif
-
- if( h == NULL || h->h_name == NULL )
- return inet_ntoa( in );
- else
- return ( char* )h->h_name;
+
+ if( h == NULL || h->h_name == NULL )
+ return inet_ntoa( in );
+ else
+ return ( char* )h->h_name;
} /* get_host_by_address() */
char *cpystr( char *string )
#endif /* _NO_PROTO */
{
- char *dst;
-
- if( string )
- {
- dst = ( char* )malloc( 1 + strlen( string ) );
- if( !dst )
- crash_and_burn( "can't allocate some space for a string" );
-
- strcpy( dst, string );
- return dst;
-
- }/* IF */
- else
- return NULL;
+ char *dst;
+
+ if( string )
+ {
+ dst = ( char* )malloc( 1 + strlen( string ) );
+ if( !dst )
+ crash_and_burn( "can't allocate some space for a string" );
+
+ strcpy( dst, string );
+ return dst;
+
+ }/* IF */
+ else
+ return NULL;
} /* cpystr() */
void crash_and_burn( char *message )
#endif /* _NO_PROTO */
{
- if( verbose_flag )
- fprintf( stderr, "%s: %s\n", prog, message );
-
- exit( 4 );
+ if( verbose_flag )
+ fprintf( stderr, "%s: %s\n", prog, message );
+
+ exit( 4 );
} /* crash_and_burn() */
void errno_crash_and_burn( char *message )
#endif /* _NO_PROTO */
{
- if( verbose_flag )
- fprintf( stderr, "%s: %s : %s\n", prog, message, strerror( errno ) );
+ if( verbose_flag )
+ fprintf( stderr, "%s: %s : %s\n", prog, message, strerror( errno ) );
- exit( 4 );
+ exit( 4 );
} /* errno_crash_and_burn() */
long timeval_diff( struct timeval *a, struct timeval *b )
#endif /* _NO_PROTO */
{
- long sec_diff = a->tv_sec - b->tv_sec;
- if(sec_diff > 100) {
- /* For such large differences, we don't really care about the microseconds... */
- return sec_diff * 100000;
- }
- else {
- return (sec_diff * 1000000 + a->tv_usec - b->tv_usec) / 10;
- }
+ long sec_diff = a->tv_sec - b->tv_sec;
+ if(sec_diff > 100) {
+ /* For such large differences, we don't really care about the microseconds... */
+ return sec_diff * 100000;
+ }
+ else {
+ return (sec_diff * 1000000 + a->tv_usec - b->tv_usec) / 10;
+ }
} /* timeval_diff() */
/************************************************************
*************************************************************/
void timeval_add(struct timeval *a, long t_10u)
{
- t_10u *= 10;
- a->tv_sec += (t_10u + a->tv_usec) / 1000000;
- a->tv_usec = (t_10u + a->tv_usec) % 1000000;
+ t_10u *= 10;
+ a->tv_sec += (t_10u + a->tv_usec) / 1000000;
+ a->tv_usec = (t_10u + a->tv_usec) % 1000000;
}
/************************************************************
char * sprint_tm( int t )
#endif /* _NO_PROTO */
{
- static char buf[10];
-
- /* <= 0.99 ms */
- if( t < 100 )
- {
- sprintf( buf, "0.%02d", t );
- return( buf );
-
- }/* IF */
-
- /* 1.00 - 9.99 ms */
- if( t < 1000 )
- {
- sprintf( buf, "%d.%02d", t / 100, t % 100 );
- return( buf );
-
- }/* IF */
-
- /* 10.0 - 99.9 ms */
- if( t < 10000 )
- {
- sprintf( buf, "%d.%d", t / 100, ( t % 100 ) / 10 );
- return( buf );
-
- }/* IF */
+ static char buf[10];
+
+ /* <= 0.99 ms */
+ if( t < 100 )
+ {
+ sprintf( buf, "0.%02d", t );
+ return( buf );
+
+ }/* IF */
+
+ /* 1.00 - 9.99 ms */
+ if( t < 1000 )
+ {
+ sprintf( buf, "%d.%02d", t / 100, t % 100 );
+ return( buf );
+
+ }/* IF */
+
+ /* 10.0 - 99.9 ms */
+ if( t < 10000 )
+ {
+ sprintf( buf, "%d.%d", t / 100, ( t % 100 ) / 10 );
+ return( buf );
+
+ }/* IF */
- /* >= 100 ms */
- sprintf( buf, "%d", t / 100 );
- return( buf );
+ /* >= 100 ms */
+ sprintf( buf, "%d", t / 100 );
+ return( buf );
} /* sprint_tm() */
void u_sleep( int u_sec )
#endif /* _NO_PROTO */
{
- int nfound;
- struct timeval to;
- fd_set readset, writeset;
+ int nfound;
+ struct timeval to;
+ fd_set readset, writeset;
- to.tv_sec = u_sec / 1000000;
- to.tv_usec = u_sec - ( to.tv_sec * 1000000 );
+ to.tv_sec = u_sec / 1000000;
+ to.tv_usec = u_sec - ( to.tv_sec * 1000000 );
- FD_ZERO( &readset );
- FD_ZERO( &writeset );
- nfound = select( 0, &readset, &writeset, NULL, &to );
- if( nfound < 0 )
- errno_crash_and_burn( "select" );
+ FD_ZERO( &readset );
+ FD_ZERO( &writeset );
+ nfound = select( 0, &readset, &writeset, NULL, &to );
+ if( nfound < 0 )
+ errno_crash_and_burn( "select" );
- return;
+ return;
} /* u_sleep() */
#endif /* _NO_PROTO */
{
unsigned int slen;
- int nfound, n;
- struct timeval to;
- fd_set readset, writeset;
+ int nfound, n;
+ struct timeval to;
+ fd_set readset, writeset;
- to.tv_sec = 0;
- to.tv_usec = timo * 10;
+ to.tv_sec = 0;
+ to.tv_usec = timo * 10;
- FD_ZERO( &readset );
- FD_ZERO( &writeset );
- FD_SET( s, &readset );
- nfound = select( s + 1, &readset, &writeset, NULL, &to );
- if( nfound < 0 )
- errno_crash_and_burn( "select" );
+ FD_ZERO( &readset );
+ FD_ZERO( &writeset );
+ FD_SET( s, &readset );
+ nfound = select( s + 1, &readset, &writeset, NULL, &to );
+ if( nfound < 0 )
+ errno_crash_and_burn( "select" );
- if( nfound == 0 )
- return -1; /* timeout */
+ if( nfound == 0 )
+ return -1; /* timeout */
#ifndef IPV6
- slen = sizeof( struct sockaddr );
+ slen = sizeof( struct sockaddr );
#else
- slen = sizeof( FPING_SOCKADDR );
+ slen = sizeof( FPING_SOCKADDR );
#endif
- n = recvfrom( s, buf, len, 0, (struct sockaddr *)saddr, &slen );
- if( n < 0 )
- errno_crash_and_burn( "recvfrom" );
-
- return n;
+ n = recvfrom( s, buf, len, 0, (struct sockaddr *)saddr, &slen );
+ if( n < 0 )
+ errno_crash_and_burn( "recvfrom" );
+
+ return n;
} /* recvfrom_wto() */
*************************************************************/
void ev_enqueue(HOST_ENTRY *h)
{
- HOST_ENTRY *i;
- HOST_ENTRY *i_prev;
+ HOST_ENTRY *i;
+ HOST_ENTRY *i_prev;
#if defined( DEBUG ) || defined( _DEBUG )
- if( trace_flag ) {
- long st = timeval_diff(&h->ev_time, ¤t_time);
- fprintf(stderr, "Enqueue: host=%s, when=%d ms (%d, %d)\n", h->host, st/100, h->ev_time.tv_sec, h->ev_time.tv_usec);
- }
+ if( trace_flag ) {
+ long st = timeval_diff(&h->ev_time, ¤t_time);
+ fprintf(stderr, "Enqueue: host=%s, when=%d ms (%d, %d)\n", h->host, st/100, h->ev_time.tv_sec, h->ev_time.tv_usec);
+ }
#endif
/* Empty list */
- if(ev_last == NULL) {
- h->ev_next = NULL;
- h->ev_prev = NULL;
- ev_first = h;
- ev_last = h;
- return;
- }
-
- /* Insert on tail? */
- if(h->ev_time.tv_sec > ev_last->ev_time.tv_sec ||
+ if(ev_last == NULL) {
+ h->ev_next = NULL;
+ h->ev_prev = NULL;
+ ev_first = h;
+ ev_last = h;
+ return;
+ }
+
+ /* Insert on tail? */
+ if(h->ev_time.tv_sec > ev_last->ev_time.tv_sec ||
(h->ev_time.tv_sec == ev_last->ev_time.tv_sec &&
- h->ev_time.tv_usec >= ev_last->ev_time.tv_usec))
- {
- h->ev_next = NULL;
- h->ev_prev = ev_last;
- ev_last->ev_next = h;
- ev_last = h;
- return;
- }
-
- /* Find insertion point */
- i = ev_last;
- while(1) {
- i_prev = i->ev_prev;
- if(i_prev == NULL ||
- h->ev_time.tv_sec > i_prev->ev_time.tv_sec ||
+ h->ev_time.tv_usec >= ev_last->ev_time.tv_usec))
+ {
+ h->ev_next = NULL;
+ h->ev_prev = ev_last;
+ ev_last->ev_next = h;
+ ev_last = h;
+ return;
+ }
+
+ /* Find insertion point */
+ i = ev_last;
+ while(1) {
+ i_prev = i->ev_prev;
+ if(i_prev == NULL ||
+ h->ev_time.tv_sec > i_prev->ev_time.tv_sec ||
(h->ev_time.tv_sec == i_prev->ev_time.tv_sec &&
- h->ev_time.tv_usec >= i_prev->ev_time.tv_usec))
- {
- h->ev_prev = i_prev;
- h->ev_next = i;
- i->ev_prev = h;
- if(i_prev != NULL) {
- i_prev->ev_next = h;
- }
- else {
- ev_first = h;
- }
- return;
- }
- i = i_prev;
- }
+ h->ev_time.tv_usec >= i_prev->ev_time.tv_usec))
+ {
+ h->ev_prev = i_prev;
+ h->ev_next = i;
+ i->ev_prev = h;
+ if(i_prev != NULL) {
+ i_prev->ev_next = h;
+ }
+ else {
+ ev_first = h;
+ }
+ return;
+ }
+ i = i_prev;
+ }
}
/************************************************************
*************************************************************/
HOST_ENTRY *ev_dequeue()
{
- HOST_ENTRY *dequeued;
+ HOST_ENTRY *dequeued;
- if(ev_first == NULL) {
- return NULL;
- }
- dequeued = ev_first;
- ev_remove(dequeued);
+ if(ev_first == NULL) {
+ return NULL;
+ }
+ dequeued = ev_first;
+ ev_remove(dequeued);
- return dequeued;
+ return dequeued;
}
/************************************************************
*************************************************************/
void ev_remove(HOST_ENTRY *h)
{
- if(ev_first == h) {
- ev_first = h->ev_next;
- }
- if(ev_last == h) {
- ev_last = h->ev_prev;
- }
- if(h->ev_prev) {
- h->ev_prev->ev_next = h->ev_next;
- }
- if(h->ev_next) {
- h->ev_next->ev_prev = h->ev_prev;
- }
+ if(ev_first == h) {
+ ev_first = h->ev_next;
+ }
+ if(ev_last == h) {
+ ev_last = h->ev_prev;
+ }
+ if(h->ev_prev) {
+ h->ev_prev->ev_next = h->ev_next;
+ }
+ if(h->ev_next) {
+ h->ev_next->ev_prev = h->ev_prev;
+ }
}
void usage( void )
#endif /* _NO_PROTO */
{
- fprintf( stderr, "\n" );
- fprintf( stderr, "Usage: %s [options] [targets...]\n", prog );
- fprintf( stderr, " -a show targets that are alive\n" );
- fprintf( stderr, " -A show targets by address\n" );
- fprintf( stderr, " -b n amount of ping data to send, in bytes (default %d)\n", ping_data_size );
- fprintf( stderr, " -B f set exponential backoff factor to f\n" );
- fprintf( stderr, " -c n count of pings to send to each target (default %d)\n", count );
- fprintf( stderr, " -C n same as -c, report results in verbose format\n" );
- fprintf( stderr, " -e show elapsed time on return packets\n" );
- fprintf( stderr, " -f file read list of targets from a file ( - means stdin) (only if no -g specified)\n" );
- fprintf( stderr, " -g generate target list (only if no -f specified)\n" );
- fprintf( stderr, " (specify the start and end IP in the target list, or supply a IP netmask)\n" );
+ fprintf( stderr, "\n" );
+ fprintf( stderr, "Usage: %s [options] [targets...]\n", prog );
+ fprintf( stderr, " -a show targets that are alive\n" );
+ fprintf( stderr, " -A show targets by address\n" );
+ fprintf( stderr, " -b n amount of ping data to send, in bytes (default %d)\n", ping_data_size );
+ fprintf( stderr, " -B f set exponential backoff factor to f\n" );
+ fprintf( stderr, " -c n count of pings to send to each target (default %d)\n", count );
+ fprintf( stderr, " -C n same as -c, report results in verbose format\n" );
+ fprintf( stderr, " -e show elapsed time on return packets\n" );
+ fprintf( stderr, " -f file read list of targets from a file ( - means stdin) (only if no -g specified)\n" );
+ fprintf( stderr, " -g generate target list (only if no -f specified)\n" );
+ fprintf( stderr, " (specify the start and end IP in the target list, or supply a IP netmask)\n" );
fprintf( stderr, " (ex. %s -g 192.168.1.0 192.168.1.255 or %s -g 192.168.1.0/24)\n", prog, prog );
- fprintf( stderr, " -i n interval between sending ping packets (in millisec) (default %d)\n", interval / 100 );
- fprintf( stderr, " -l loop sending pings forever\n" );
- fprintf( stderr, " -m ping multiple interfaces on target host\n" );
- fprintf( stderr, " -n show targets by name (-d is equivalent)\n" );
- fprintf( stderr, " -p n interval between ping packets to one target (in millisec)\n" );
- fprintf( stderr, " (in looping and counting modes, default %d)\n", perhost_interval / 100 );
- fprintf( stderr, " -q quiet (don't show per-target/per-ping results)\n" );
- fprintf( stderr, " -Q n same as -q, but show summary every n seconds\n" );
- fprintf( stderr, " -r n number of retries (default %d)\n", DEFAULT_RETRY );
- fprintf( stderr, " -s print final stats\n" );
+ fprintf( stderr, " -i n interval between sending ping packets (in millisec) (default %d)\n", interval / 100 );
+ fprintf( stderr, " -l loop sending pings forever\n" );
+ fprintf( stderr, " -m ping multiple interfaces on target host\n" );
+ fprintf( stderr, " -n show targets by name (-d is equivalent)\n" );
+ fprintf( stderr, " -p n interval between ping packets to one target (in millisec)\n" );
+ fprintf( stderr, " (in looping and counting modes, default %d)\n", perhost_interval / 100 );
+ fprintf( stderr, " -q quiet (don't show per-target/per-ping results)\n" );
+ fprintf( stderr, " -Q n same as -q, but show summary every n seconds\n" );
+ fprintf( stderr, " -r n number of retries (default %d)\n", DEFAULT_RETRY );
+ fprintf( stderr, " -s print final stats\n" );
#ifdef SO_BINDTODEVICE
fprintf( stderr, " -I if bind to a particular interface\n");
#endif
- fprintf( stderr, " -S addr set source address\n" );
- fprintf( stderr, " -t n individual target initial timeout (in millisec) (default %d)\n", timeout / 100 );
- fprintf( stderr, " -T n set select timeout (default %d)\n", select_time / 100 );
- fprintf( stderr, " -u show targets that are unreachable\n" );
- fprintf( stderr, " -O n set the type of service (tos) flag on the ICMP packets\n" );
- fprintf( stderr, " -v show version\n" );
+ fprintf( stderr, " -S addr set source address\n" );
+ fprintf( stderr, " -t n individual target initial timeout (in millisec) (default %d)\n", timeout / 100 );
+ fprintf( stderr, " -T n set select timeout (default %d)\n", select_time / 100 );
+ fprintf( stderr, " -u show targets that are unreachable\n" );
+ fprintf( stderr, " -O n set the type of service (tos) flag on the ICMP packets\n" );
+ fprintf( stderr, " -v show version\n" );
- fprintf( stderr, " targets list of targets to check (if no -f specified)\n" );
- fprintf( stderr, "\n");
- exit( 3 );
+ fprintf( stderr, " targets list of targets to check (if no -f specified)\n" );
+ fprintf( stderr, "\n");
+ exit( 3 );
} /* usage() */