Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a714b275f | ||
|
|
d141744adb | ||
|
|
e1cdf8e1d3 | ||
|
|
d862dd962b | ||
|
|
5c68d6f338 | ||
|
|
a2ac5d0fae | ||
|
|
b01f282727 | ||
|
|
0ab66f80de | ||
|
|
741236e576 | ||
|
|
9fca2a141b | ||
|
|
9ee22bd46a | ||
|
|
f55397336b | ||
|
|
82722a31fe | ||
|
|
4aad0b2c14 | ||
|
|
fb5f5779cc | ||
|
|
a0252f6e79 | ||
|
|
3dee903b41 | ||
|
|
7e55f0b073 | ||
|
|
8daad08e1d | ||
|
|
b7343ed256 | ||
|
|
ecba31b2dd | ||
|
|
28eea9c273 | ||
|
|
121bea1d24 | ||
|
|
5d6db6f08d | ||
|
|
543d22122d | ||
|
|
70a29a11af | ||
|
|
b0e09ce6fe | ||
|
|
6400ffb339 | ||
|
|
98d44d02bb | ||
|
|
69fff78ca4 | ||
|
|
5b6784a4ea | ||
|
|
25dc120355 | ||
|
|
f906225fbd | ||
|
|
3e29f0631c | ||
|
|
10d0a54c07 | ||
|
|
ad4ca1609d | ||
|
|
e0edbf28fc | ||
|
|
1c85a422c1 | ||
|
|
86cfc7cf74 | ||
|
|
fd020977b5 | ||
|
|
81c96c0807 |
@@ -1,3 +1,4 @@
|
||||
.*.swp
|
||||
*.tar.gz
|
||||
*~
|
||||
.deps
|
||||
|
||||
@@ -1,3 +1,34 @@
|
||||
2013-11-04 David Schweikert <david@schweikert.ch>
|
||||
* Version 3.7
|
||||
* Allow running as non-root on Mac OS X by using non-privileged ICMP (#7)
|
||||
* Remove unnecessary IPv6 socket options
|
||||
* Fix again compatibility issue with FreeBSD (Shawn Chu)
|
||||
* Fix fping hanging forever on permanent sendto failure (Shawn Chu)
|
||||
* Fix duplicate echo reply packets causing early stop in count mode
|
||||
(reported by Ramon Schwammberger, #53)
|
||||
|
||||
2013-10-10 David Schweikert <david@schweikert.ch>
|
||||
* Version 3.6
|
||||
* Fix loop issue after 65536 pings (reported by Peter Folk and GBert, #12)
|
||||
* Minimum ping data size is now 0
|
||||
* Removed setsockopt IPV6_CHECKSUM, which shouldn't be set and breaks
|
||||
compiling on Solaris (reported by Juergen Arndt)
|
||||
* Fix wrong min RTT value with -Q option (reported by Alexander Ivanov, #51)
|
||||
|
||||
2013-05-22 David Schweikert <david@schweikert.ch>
|
||||
* Version 3.5
|
||||
* Fix sprint_tm buffer size crash (reported by Japheth Cleaver)
|
||||
* Addded -D flag to print timestamps (Toke Høiland-Jørgensen)
|
||||
* Fix fping6 build on OS X 10.8 (unknown contributor)
|
||||
* Fix compatibility issue with FreeBSD (Alexandre Raynaud, Jason Harris, #39)
|
||||
* Fping.spec: fix setuid permissions and provides fping6 (Marcus Vinicius Ferreira)
|
||||
* Re-create configure script with autoconf 2.69 for aarch64 support (Chuck Anderson, #45)
|
||||
|
||||
2012-09-04 David Schweikert <david@schweikert.ch>
|
||||
* Version 3.4
|
||||
* Revert "Output statistics to stdout instead of stderr", because it breaks
|
||||
tools assuming the output goes to stderr
|
||||
|
||||
2012-08-19 David Schweikert <david@schweikert.ch>
|
||||
* Version 3.3
|
||||
* Do not output icmp errors with -q (#1)
|
||||
|
||||
@@ -9,7 +9,11 @@ Current maintainer:
|
||||
David Schweikert <david@schweikert.ch>
|
||||
|
||||
Website:
|
||||
http://www.fping.org/
|
||||
http://fping.org/
|
||||
|
||||
Mailing-list:
|
||||
https://groups.google.com/group/fping-users
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
@@ -27,6 +31,7 @@ If you want to install fping from source, proceed as follows:
|
||||
4. Have a look at the fping(8) manual for usage help
|
||||
(fping -h will also give a minimal help output)
|
||||
|
||||
|
||||
IPv6 support
|
||||
------------
|
||||
You can can compile fping with support for IPv6 addresses. A separate binary
|
||||
@@ -38,6 +43,7 @@ is used for that, called fping6. To build it, use ./configure --enable-ipv6
|
||||
# make install
|
||||
# sudo setcap cap_net_raw+ep /usr/local/bin/fping*
|
||||
|
||||
|
||||
Credits
|
||||
-------
|
||||
Original author: Roland Schemers (schemers@stanford.edu)
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ dnl Process this file with autoconf to produce a configure script.
|
||||
dnl Minimum Autoconf version required.
|
||||
AC_PREREQ(2.59)
|
||||
|
||||
AC_INIT([fping],[3.3])
|
||||
AC_INIT([fping],[3.7])
|
||||
|
||||
dnl make ipv4 and ipv6 options
|
||||
AC_ARG_ENABLE([ipv4],
|
||||
|
||||
+34
-7
@@ -1,10 +1,10 @@
|
||||
Summary: send ICMP echo probes to multiple hosts
|
||||
Name: fping
|
||||
Version: 3.2
|
||||
Version: 3.4
|
||||
Release: 1
|
||||
License: MIT
|
||||
Group: Applications/System
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
Source0: http://fping.org/dist/%{name}-%{version}.tar.gz
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
|
||||
|
||||
%description
|
||||
@@ -18,29 +18,56 @@ statistics.
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
%configure
|
||||
|
||||
if [ ! -f ./configure ] ; then
|
||||
./autogen.sh
|
||||
fi
|
||||
|
||||
# fping
|
||||
%configure --enable-ipv4
|
||||
make
|
||||
|
||||
# fping6
|
||||
%configure --enable-ipv6
|
||||
make
|
||||
%{__mv} -f src/fping src/fping6
|
||||
|
||||
%install
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make DESTDIR=$RPM_BUILD_ROOT install
|
||||
|
||||
# fping6
|
||||
%{__install} -Dp -m4755 src/fping6 %{buildroot}%{_sbindir}/fping6
|
||||
%{__ln_s} -f fping.8 %{buildroot}%{_mandir}/man8/fping6.8
|
||||
|
||||
%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
/usr/sbin/fping
|
||||
%attr(4755, root, root) /usr/sbin/fping
|
||||
%attr(4755, root, root) /usr/sbin/fping6
|
||||
%doc README COPYING ChangeLog
|
||||
/usr/share/man/man8/fping.8.gz
|
||||
/usr/share/man/man8/fping6.8.gz
|
||||
|
||||
%post
|
||||
if [ -x /usr/sbin/setcap ]; then
|
||||
/usr/sbin/setcap cap_net_raw+ep /usr/sbin/fping
|
||||
else
|
||||
chmod 1777 /usr/sbin/fping
|
||||
/bin/chmod 0755 /usr/sbin/fping*
|
||||
/usr/sbin/setcap cap_net_raw+ep /usr/sbin/fping*
|
||||
fi
|
||||
|
||||
%changelog
|
||||
* Mon Dec 24 2012 Marcus Vinicius Ferreira <ferreira.mv@gmail.com>
|
||||
- Missing './configure' script when cloning from master.
|
||||
- Making 'fping6'.
|
||||
- Fix setuid permission to 'rwsr-xr-x'.
|
||||
- doc files.
|
||||
- Replacing setuid permission if 'setcap' is present on post-install.
|
||||
- Using 'http://fping.org/dist/' for release source distributions.
|
||||
|
||||
* Mon Jul 16 2012 Stephen Schaefer <sschaefer@acm.org>
|
||||
- Initial build
|
||||
|
||||
# vim:ft=spec:
|
||||
|
||||
|
||||
+3
-3
@@ -8,10 +8,10 @@ if IPV6
|
||||
man_MANS += fping6.8
|
||||
endif
|
||||
|
||||
EXTRA_DIST = $(man_MANS) fping.pod README.1992
|
||||
EXTRA_DIST = fping.8 fping6.8 fping.pod README.1992
|
||||
|
||||
fping.8: fping.pod
|
||||
pod2man -c "" -s 8 -r "fping $(VERSION)" $< >$@
|
||||
pod2man -c "" -s 8 -r "fping" $< >$@
|
||||
|
||||
fping6.8: fping.pod
|
||||
pod2man -c "" -s 8 -r "fping $(VERSION)" -n fping6 $< >$@
|
||||
pod2man -c "" -s 8 -r "fping" -n fping6 $< >$@
|
||||
|
||||
@@ -77,6 +77,11 @@ C<-> indicating that no response was received to the fourth request.
|
||||
Use DNS to lookup address of return ping packet. This allows you to give fping
|
||||
a list of IP addresses as input and print hostnames in the output.
|
||||
|
||||
=item B<-D>
|
||||
|
||||
Add Unix timestamps in front of output lines generated with in looping or counting
|
||||
modes (B<-l>, B<-c>, or B<-C>).
|
||||
|
||||
=item B<-e>
|
||||
|
||||
Show elapsed (round-trip) time of packets.
|
||||
|
||||
+2
-2
@@ -9,8 +9,8 @@ endif
|
||||
|
||||
sbin_PROGRAMS = ${prog}
|
||||
|
||||
fping_SOURCES = fping.c options.h
|
||||
fping_SOURCES = fping.c seqmap.c socket.c socket4.c fping.h options.h seqmap.h
|
||||
fping_DEPENDENCIES = ../config.h
|
||||
fping6_SOURCES = fping.c options.h
|
||||
fping6_SOURCES = fping.c seqmap.c socket.c socket6.c fping.h options.h seqmap.h
|
||||
fping6_DEPENDENCIES = ../config.h
|
||||
fping6_CFLAGS = $(AM_CFLAGS) -DIPV6
|
||||
|
||||
+159
-270
@@ -35,6 +35,9 @@ extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#include "fping.h"
|
||||
#include "options.h"
|
||||
|
||||
/* if compiling for Windows, use this separate set
|
||||
(too difficult to ifdef all the autoconf defines) */
|
||||
#ifdef WIN32
|
||||
@@ -54,9 +57,8 @@ extern "C"
|
||||
#include <getopt.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "seqmap.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@@ -95,8 +97,6 @@ extern "C"
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include "options.h"
|
||||
|
||||
/*** externals ***/
|
||||
|
||||
extern char *optarg;
|
||||
@@ -113,16 +113,7 @@ extern int h_errno;
|
||||
|
||||
/*** Ping packet defines ***/
|
||||
|
||||
/* data added after ICMP header for our nefarious purposes */
|
||||
|
||||
typedef struct ping_data
|
||||
{
|
||||
int ping_count; /* counts up to -c count or 1 */
|
||||
struct timeval ping_ts; /* time sent */
|
||||
|
||||
} PING_DATA;
|
||||
|
||||
#define MIN_PING_DATA sizeof( PING_DATA )
|
||||
#define MIN_PING_DATA 0
|
||||
#define MAX_IP_PACKET 65536 /* (theoretical) max IP packet size */
|
||||
#define SIZE_IP_HDR 20
|
||||
#ifndef IPV6
|
||||
@@ -201,13 +192,6 @@ char *icmp_unreach_str[16] =
|
||||
};
|
||||
|
||||
#define ICMP_UNREACH_MAXTYPE 15
|
||||
#ifndef IPV6
|
||||
#define FPING_SOCKADDR struct sockaddr_in
|
||||
#define FPING_ICMPHDR struct icmp
|
||||
#else
|
||||
#define FPING_SOCKADDR struct sockaddr_in6
|
||||
#define FPING_ICMPHDR struct icmp6_hdr
|
||||
#endif
|
||||
|
||||
/* entry used to keep track of each host we are pinging */
|
||||
|
||||
@@ -233,10 +217,12 @@ typedef struct host_entry
|
||||
unsigned char waiting; /* waiting for response */
|
||||
struct timeval last_send_time; /* time of last packet sent */
|
||||
int num_sent; /* number of ping packets sent */
|
||||
int num_recv; /* number of pings received */
|
||||
int num_recv; /* number of pings received (duplicates ignored) */
|
||||
int num_recv_total; /* number of pings received, including duplicates */
|
||||
int max_reply; /* longest response time */
|
||||
int min_reply; /* shortest response time */
|
||||
int total_time; /* sum of response times */
|
||||
/* _i -> splits (reset on every report interval) */
|
||||
int num_sent_i; /* number of ping packets sent */
|
||||
int num_recv_i; /* number of pings received */
|
||||
int max_reply_i; /* longest response time */
|
||||
@@ -285,13 +271,12 @@ struct in6_addr src_addr;
|
||||
|
||||
/* global stats */
|
||||
long max_reply = 0;
|
||||
long min_reply = 1000000;
|
||||
long min_reply = 0;
|
||||
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 */
|
||||
@@ -313,6 +298,7 @@ int verbose_flag, quiet_flag, stats_flag, unreachable_flag, alive_flag;
|
||||
int elapsed_flag, version_flag, count_flag, loop_flag;
|
||||
int per_recv_flag, report_all_rtts_flag, name_flag, addr_flag, backoff_flag;
|
||||
int multif_flag;
|
||||
int timestamp_flag = 0;
|
||||
#if defined( DEBUG ) || defined( _DEBUG )
|
||||
int randomly_lose_flag, sent_times_flag, trace_flag, print_per_system_flag;
|
||||
int lose_factor;
|
||||
@@ -374,124 +360,26 @@ void print_warning(char *fmt, ...);
|
||||
int main( int argc, char **argv )
|
||||
{
|
||||
int c, i, n;
|
||||
#ifdef IPV6
|
||||
int opton = 1;
|
||||
#endif
|
||||
struct protoent *proto;
|
||||
char *buf;
|
||||
uid_t uid;
|
||||
int tos = 0;
|
||||
|
||||
#ifndef IPV6
|
||||
struct sockaddr_in sa;
|
||||
#else
|
||||
struct sockaddr_in6 sa;
|
||||
#endif
|
||||
int tos = 0;
|
||||
HOST_ENTRY *cursor;
|
||||
|
||||
prog = argv[0];
|
||||
s = open_ping_socket();
|
||||
|
||||
/* confirm that ICMP is available on this machine */
|
||||
#ifndef IPV6
|
||||
if( ( proto = getprotobyname( "icmp" ) ) == NULL )
|
||||
#else
|
||||
if( ( proto = getprotobyname( "ipv6-icmp" ) ) == NULL )
|
||||
#endif
|
||||
crash_and_burn( "icmp: unknown protocol" );
|
||||
|
||||
/* create raw socket for ICMP calls (ping) */
|
||||
#ifndef IPV6
|
||||
s = socket( AF_INET, SOCK_RAW, proto->p_proto );
|
||||
#else
|
||||
s = socket( AF_INET6, SOCK_RAW, proto->p_proto );
|
||||
#endif
|
||||
|
||||
if( s < 0 )
|
||||
errno_crash_and_burn( "can't create raw socket (must run as root?)" );
|
||||
|
||||
#ifdef IPV6
|
||||
/*
|
||||
* 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)");
|
||||
#else /* old adv. API */
|
||||
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)");
|
||||
#else /* old adv. API */
|
||||
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)");
|
||||
#endif
|
||||
#ifdef 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)");
|
||||
#endif
|
||||
#ifndef USE_SIN6_SCOPE_ID
|
||||
#ifdef 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)");
|
||||
#endif
|
||||
#endif /* USE_SIN6_SCOPE_ID */
|
||||
#ifdef 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)");
|
||||
#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)");
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if( ( uid = getuid() ) )
|
||||
{
|
||||
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:H:i:p:f:r:c:b:C:Q:B:S:I:T:O:" ) ) != EOF )
|
||||
while( ( c = getopt( argc, argv, "gedhlmnqusaAvDz:t:H:i:p:f:r:c:b:C:Q:B:S:I:T:O:" ) ) != EOF )
|
||||
{
|
||||
switch( c )
|
||||
{
|
||||
@@ -533,7 +421,9 @@ int main( int argc, char **argv )
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
if( !( ping_data_size = ( unsigned int )atoi( optarg ) ) )
|
||||
errno = 0;
|
||||
ping_data_size = (unsigned int) strtol(optarg, (char **)NULL, 10);
|
||||
if( errno )
|
||||
usage(1);
|
||||
|
||||
break;
|
||||
@@ -582,6 +472,10 @@ int main( int argc, char **argv )
|
||||
stats_flag = 1;
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
timestamp_flag = 1;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
loop_flag = 1;
|
||||
backoff_flag = 0;
|
||||
@@ -683,7 +577,7 @@ int main( int argc, char **argv )
|
||||
|
||||
/* validate various option settings */
|
||||
|
||||
if (ttl < 0 || ttl > 255) {
|
||||
if (ttl > 255) {
|
||||
fprintf(stderr, "ping: ttl %u out of range\n", ttl);
|
||||
usage(1);
|
||||
}
|
||||
@@ -901,20 +795,8 @@ int main( int argc, char **argv )
|
||||
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;
|
||||
#else
|
||||
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" );
|
||||
if(src_addr_present) {
|
||||
socket_set_src_addr(s, src_addr);
|
||||
}
|
||||
|
||||
/* allocate array to hold outstanding ping requests */
|
||||
@@ -967,6 +849,8 @@ int main( int argc, char **argv )
|
||||
srandom( start_time.tv_usec );
|
||||
#endif /* DEBUG || _DEBUG */
|
||||
|
||||
seqmap_init();
|
||||
|
||||
/* main loop */
|
||||
main_loop();
|
||||
|
||||
@@ -1142,7 +1026,7 @@ void main_loop()
|
||||
ev_enqueue(h);
|
||||
}
|
||||
/* Count mode: schedule timeout after last ping */
|
||||
else if(count_flag && count_flag && h->num_sent >= count) {
|
||||
else if(count_flag && h->num_sent >= count) {
|
||||
h->ev_type = EV_TYPE_TIMEOUT;
|
||||
h->ev_time.tv_sec = last_send_time.tv_sec;
|
||||
h->ev_time.tv_usec = last_send_time.tv_usec;
|
||||
@@ -1305,39 +1189,39 @@ void print_per_system_stats( void )
|
||||
fflush( stdout );
|
||||
|
||||
if( verbose_flag || per_recv_flag )
|
||||
fprintf( stdout, "\n" );
|
||||
fprintf( stderr, "\n" );
|
||||
|
||||
for( i = 0; i < num_hosts; i++ )
|
||||
{
|
||||
h = table[i];
|
||||
fprintf( stdout, "%s%s :", h->host, h->pad );
|
||||
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( stdout, " %d.%02d", resp / 100, resp % 100 );
|
||||
fprintf( stderr, " %d.%02d", resp / 100, resp % 100 );
|
||||
else
|
||||
fprintf( stdout, " -" );
|
||||
fprintf( stderr, " -" );
|
||||
|
||||
}/* FOR */
|
||||
|
||||
fprintf( stdout, "\n" );
|
||||
fprintf( stderr, "\n" );
|
||||
|
||||
}/* IF */
|
||||
else
|
||||
{
|
||||
if( h->num_recv <= h->num_sent )
|
||||
{
|
||||
fprintf( stdout, " xmt/rcv/%%loss = %d/%d/%d%%",
|
||||
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( stdout, " xmt/rcv/%%return = %d/%d/%d%%",
|
||||
fprintf( stderr, " xmt/rcv/%%return = %d/%d/%d%%",
|
||||
h->num_sent, h->num_recv,
|
||||
( ( h->num_recv * 100 ) / h->num_sent ) );
|
||||
|
||||
@@ -1346,13 +1230,13 @@ void print_per_system_stats( void )
|
||||
if( h->num_recv )
|
||||
{
|
||||
avg = h->total_time / h->num_recv;
|
||||
fprintf( stdout, ", min/avg/max = %s", sprint_tm( h->min_reply ) );
|
||||
fprintf( stdout, "/%s", sprint_tm( avg ) );
|
||||
fprintf( stdout, "/%s", sprint_tm( h->max_reply ) );
|
||||
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(stdout, "\n");
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
}/* ELSE */
|
||||
|
||||
@@ -1362,11 +1246,11 @@ void print_per_system_stats( void )
|
||||
for( j = 0; j < h->num_sent; j++ )
|
||||
{
|
||||
if( ( resp = h->sent_times[j] ) >= 0 )
|
||||
fprintf( stdout, " %s", sprint_tm( resp ) );
|
||||
fprintf( stderr, " %s", sprint_tm( resp ) );
|
||||
else
|
||||
fprintf( stdout, " -" );
|
||||
fprintf( stderr, " -" );
|
||||
|
||||
fprintf( stdout, "\n" );
|
||||
fprintf( stderr, "\n" );
|
||||
|
||||
}/* FOR */
|
||||
}/* IF */
|
||||
@@ -1409,27 +1293,27 @@ void print_per_system_splits( void )
|
||||
fflush( stdout );
|
||||
|
||||
if( verbose_flag || per_recv_flag )
|
||||
fprintf( stdout, "\n" );
|
||||
fprintf( stderr, "\n" );
|
||||
|
||||
curr_tm = localtime( ( time_t* )¤t_time.tv_sec );
|
||||
fprintf( stdout, "[%2.2d:%2.2d:%2.2d]\n", curr_tm->tm_hour,
|
||||
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( stdout, "%s%s :", h->host, h->pad );
|
||||
fprintf( stderr, "%s%s :", h->host, h->pad );
|
||||
|
||||
if( h->num_recv_i <= h->num_sent_i )
|
||||
{
|
||||
fprintf( stdout, " xmt/rcv/%%loss = %d/%d/%d%%",
|
||||
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( stdout, " xmt/rcv/%%return = %d/%d/%d%%",
|
||||
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 );
|
||||
|
||||
@@ -1438,13 +1322,13 @@ void print_per_system_splits( void )
|
||||
if( h->num_recv_i )
|
||||
{
|
||||
avg = h->total_time_i / h->num_recv_i;
|
||||
fprintf( stdout, ", min/avg/max = %s", sprint_tm( h->min_reply_i ) );
|
||||
fprintf( stdout, "/%s", sprint_tm( avg ) );
|
||||
fprintf( stdout, "/%s", sprint_tm( h->max_reply_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( stdout, "\n" );
|
||||
fprintf( stderr, "\n" );
|
||||
h->num_sent_i = h->num_recv_i = h->max_reply_i =
|
||||
h->min_reply_i = h->total_time_i = 0;
|
||||
|
||||
@@ -1471,17 +1355,17 @@ void print_per_system_splits( void )
|
||||
void print_global_stats( void )
|
||||
{
|
||||
fflush( stdout );
|
||||
fprintf( stdout, "\n" );
|
||||
fprintf( stdout, " %7d targets\n", num_hosts );
|
||||
fprintf( stdout, " %7d alive\n", num_alive );
|
||||
fprintf( stdout, " %7d unreachable\n" ,num_unreachable );
|
||||
fprintf( stdout, " %7d unknown addresses\n", num_noaddress );
|
||||
fprintf( stdout, "\n" );
|
||||
fprintf( stdout, " %7d timeouts (waiting for response)\n", num_timeout );
|
||||
fprintf( stdout, " %7d ICMP Echos sent\n", num_pingsent );
|
||||
fprintf( stdout, " %7d ICMP Echo Replies received\n", num_pingreceived );
|
||||
fprintf( stdout, " %7d other ICMP received\n", num_othericmprcvd );
|
||||
fprintf( stdout, "\n" );
|
||||
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 )
|
||||
{
|
||||
@@ -1492,13 +1376,13 @@ void print_global_stats( void )
|
||||
|
||||
}/* IF */
|
||||
|
||||
fprintf( stdout, " %s ms (min round trip time)\n", sprint_tm( min_reply ) );
|
||||
fprintf( stdout, " %s ms (avg round trip time)\n",
|
||||
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( stdout, " %s ms (max round trip time)\n", sprint_tm( max_reply ) );
|
||||
fprintf( stdout, " %.3f sec (elapsed real time)\n",
|
||||
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( stdout, "\n" );
|
||||
fprintf( stderr, "\n" );
|
||||
|
||||
} /* print_global_stats() */
|
||||
|
||||
@@ -1525,7 +1409,6 @@ int send_ping( int s, HOST_ENTRY *h )
|
||||
{
|
||||
char *buffer;
|
||||
FPING_ICMPHDR *icp;
|
||||
PING_DATA *pdp;
|
||||
int n;
|
||||
int myseq;
|
||||
|
||||
@@ -1537,8 +1420,7 @@ int send_ping( int s, HOST_ENTRY *h )
|
||||
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;
|
||||
myseq = seqmap_add(h->i, h->num_sent, &h->last_send_time);
|
||||
|
||||
#ifndef IPV6
|
||||
icp->icmp_type = ICMP_ECHO;
|
||||
@@ -1547,10 +1429,6 @@ int send_ping( int s, HOST_ENTRY *h )
|
||||
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;
|
||||
|
||||
icp->icmp_cksum = in_cksum( ( unsigned short* )icp, ping_pkt_size );
|
||||
#else
|
||||
icp->icmp6_type = ICMP6_ECHO_REQUEST;
|
||||
@@ -1558,10 +1436,6 @@ int send_ping( int s, HOST_ENTRY *h )
|
||||
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;
|
||||
|
||||
icp->icmp6_cksum = 0; // The IPv6 stack calculates the checksum for us...
|
||||
#endif
|
||||
#if defined(DEBUG) || defined(_DEBUG)
|
||||
@@ -1572,8 +1446,12 @@ int send_ping( int s, HOST_ENTRY *h )
|
||||
n = sendto( s, buffer, ping_pkt_size, 0,
|
||||
( struct sockaddr* )&h->saddr, sizeof( FPING_SOCKADDR ) );
|
||||
|
||||
if( n < 0 || n != ping_pkt_size )
|
||||
{
|
||||
if(
|
||||
(n < 0 || n != ping_pkt_size)
|
||||
#if defined( EHOSTDOWN )
|
||||
&& errno != EHOSTDOWN
|
||||
#endif
|
||||
) {
|
||||
if( verbose_flag || unreachable_flag )
|
||||
{
|
||||
printf( "%s", h->host );
|
||||
@@ -1586,7 +1464,9 @@ int send_ping( int s, HOST_ENTRY *h )
|
||||
|
||||
h->num_sent++;
|
||||
h->num_sent_i++;
|
||||
h->waiting++;
|
||||
num_pingsent++;
|
||||
last_send_time = h->last_send_time;
|
||||
free( buffer );
|
||||
return(1);
|
||||
}
|
||||
@@ -1638,7 +1518,8 @@ int wait_for_reply(long wait_time)
|
||||
HOST_ENTRY *h;
|
||||
long this_reply;
|
||||
int this_count;
|
||||
struct timeval sent_time;
|
||||
struct timeval *sent_time;
|
||||
SEQMAP_VALUE *seqmap_value;
|
||||
|
||||
result = recvfrom_wto( s, buffer, sizeof(buffer), &response_addr, wait_time );
|
||||
|
||||
@@ -1684,6 +1565,8 @@ int wait_for_reply(long wait_time)
|
||||
return( 1 ); /* too short */
|
||||
}/* IF */
|
||||
|
||||
gettimeofday( ¤t_time, &tz );
|
||||
|
||||
icp = ( FPING_ICMPHDR* )( buffer + hlen );
|
||||
#ifndef IPV6
|
||||
if( icp->icmp_type != ICMP_ECHOREPLY )
|
||||
@@ -1704,54 +1587,51 @@ int wait_for_reply(long wait_time)
|
||||
#endif
|
||||
return 1; /* packet received, but not the one we are looking for! */
|
||||
|
||||
#ifndef IPV6
|
||||
seqmap_value = seqmap_fetch(ntohs(icp->icmp_seq), ¤t_time);
|
||||
#else
|
||||
seqmap_value = seqmap_fetch(ntohs(icp->icmp6_seq), ¤t_time);
|
||||
#endif
|
||||
if(seqmap_value == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
num_pingreceived++;
|
||||
|
||||
#ifndef IPV6
|
||||
if( ntohs(icp->icmp_seq) > max_seq_sent )
|
||||
#else
|
||||
if( ntohs(icp->icmp6_seq) > max_seq_sent )
|
||||
#endif
|
||||
return( 1 ); /* packet received, don't worry about it anymore */
|
||||
|
||||
#ifndef IPV6
|
||||
n = ntohs(icp->icmp_seq) % num_hosts;
|
||||
#else
|
||||
n = ntohs(icp->icmp6_seq) % num_hosts;
|
||||
#endif
|
||||
n = seqmap_value->host_nr;
|
||||
h = table[n];
|
||||
sent_time = &seqmap_value->ping_ts;
|
||||
this_count = seqmap_value->ping_count;
|
||||
this_reply = timeval_diff( ¤t_time, sent_time );
|
||||
|
||||
if( h->resp_times[this_count] == RESP_WAITING )
|
||||
{
|
||||
/* only for non-duplicates: */
|
||||
h->waiting = 0;
|
||||
h->timeout = timeout;
|
||||
h->num_recv++;
|
||||
h->num_recv_i++;
|
||||
|
||||
if( !max_reply || this_reply > max_reply ) max_reply = this_reply;
|
||||
if( !min_reply || this_reply < min_reply ) min_reply = this_reply;
|
||||
if( !h->max_reply || this_reply > h->max_reply ) h->max_reply = this_reply;
|
||||
if( !h->min_reply || this_reply < h->min_reply ) h->min_reply = this_reply;
|
||||
if( !h->max_reply_i || this_reply > h->max_reply_i ) h->max_reply_i = this_reply;
|
||||
if( !h->min_reply_i || 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++;
|
||||
}
|
||||
|
||||
/* 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 ) );
|
||||
#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 ) );
|
||||
#endif
|
||||
h->num_recv_total++;
|
||||
|
||||
#if defined( DEBUG ) || defined( _DEBUG )
|
||||
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 )
|
||||
{
|
||||
@@ -1822,6 +1702,11 @@ int wait_for_reply(long wait_time)
|
||||
|
||||
if( per_recv_flag )
|
||||
{
|
||||
if(timestamp_flag) {
|
||||
printf("[%lu.%06lu] ",
|
||||
(unsigned long)current_time.tv_sec,
|
||||
(unsigned long)current_time.tv_usec);
|
||||
}
|
||||
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 ) );
|
||||
@@ -1836,7 +1721,7 @@ int wait_for_reply(long wait_time)
|
||||
else
|
||||
{
|
||||
printf( "%d%% return)",
|
||||
( h->num_recv * 100 ) / h->num_sent );
|
||||
( h->num_recv_total * 100 ) / h->num_sent );
|
||||
|
||||
}/* ELSE */
|
||||
#ifndef IPV6
|
||||
@@ -1887,6 +1772,7 @@ int handle_random_icmp( FPING_ICMPHDR *p, int psize, FPING_SOCKADDR *addr )
|
||||
FPING_ICMPHDR *sent_icmp;
|
||||
unsigned char *c;
|
||||
HOST_ENTRY *h;
|
||||
SEQMAP_VALUE *seqmap_value;
|
||||
#ifdef IPV6
|
||||
char addr_ascii[INET6_ADDRSTRLEN];
|
||||
inet_ntop(addr->sin6_family, &addr->sin6_addr, addr_ascii, INET6_ADDRSTRLEN);
|
||||
@@ -1903,14 +1789,14 @@ int handle_random_icmp( FPING_ICMPHDR *p, int psize, FPING_SOCKADDR *addr )
|
||||
sent_icmp = ( FPING_ICMPHDR* )( c + 28 );
|
||||
|
||||
#ifndef IPV6
|
||||
sent_icmp = ( struct icmp* )( c + 28 );
|
||||
seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), ¤t_time);
|
||||
|
||||
if( ( sent_icmp->icmp_type == ICMP_ECHO ) &&
|
||||
( ntohs(sent_icmp->icmp_id) == ident ) &&
|
||||
( ntohs(sent_icmp->icmp_seq) <= ( n_short )max_seq_sent ) )
|
||||
( seqmap_value != NULL ) )
|
||||
{
|
||||
/* this is a response to a ping we sent */
|
||||
h = table[ntohs(sent_icmp->icmp_seq) % num_hosts];
|
||||
h = table[seqmap_value->host_nr];
|
||||
|
||||
if( p->icmp_code > ICMP_UNREACH_MAXTYPE )
|
||||
{
|
||||
@@ -1918,9 +1804,11 @@ int handle_random_icmp( FPING_ICMPHDR *p, int psize, FPING_SOCKADDR *addr )
|
||||
inet_ntoa( addr->sin_addr ), h->host );
|
||||
|
||||
#else
|
||||
seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp6_seq), ¤t_time);
|
||||
|
||||
if( ( sent_icmp->icmp6_type == ICMP_ECHO ) &&
|
||||
( ntohs(sent_icmp->icmp6_id) == ident ) &&
|
||||
( ntohs(sent_icmp->icmp6_seq) <= ( n_short )max_seq_sent ) )
|
||||
( seqmap_value != NULL ) )
|
||||
{
|
||||
/* this is a response to a ping we sent */
|
||||
h = table[ntohs(sent_icmp->icmp6_seq) % num_hosts];
|
||||
@@ -1961,21 +1849,25 @@ int handle_random_icmp( FPING_ICMPHDR *p, int psize, FPING_SOCKADDR *addr )
|
||||
case ICMP_PARAMPROB:
|
||||
sent_icmp = ( FPING_ICMPHDR* )( c + 28 );
|
||||
#ifndef IPV6
|
||||
seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), ¤t_time);
|
||||
|
||||
if( ( sent_icmp->icmp_type == ICMP_ECHO ) &&
|
||||
( ntohs(sent_icmp->icmp_id) == ident ) &&
|
||||
( ntohs(sent_icmp->icmp_seq) <= ( n_short )max_seq_sent ) )
|
||||
( seqmap_value != NULL ) )
|
||||
{
|
||||
/* this is a response to a ping we sent */
|
||||
h = table[ntohs(sent_icmp->icmp_seq) % num_hosts];
|
||||
h = table[seqmap_value->host_nr];
|
||||
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 ) );
|
||||
#else
|
||||
seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp6_seq), ¤t_time);
|
||||
|
||||
if( ( sent_icmp->icmp6_type == ICMP_ECHO ) &&
|
||||
( ntohs(sent_icmp->icmp6_id) == ident ) &&
|
||||
( ntohs(sent_icmp->icmp6_seq) <= ( n_short )max_seq_sent ) )
|
||||
( seqmap_value != NULL ) )
|
||||
{
|
||||
/* this is a response to a ping we sent */
|
||||
h = table[ntohs(sent_icmp->icmp6_seq) % num_hosts];
|
||||
@@ -2305,7 +2197,7 @@ void add_addr( char *name, char *host, FPING_SOCKADDR *ipaddr )
|
||||
#endif
|
||||
p->timeout = timeout;
|
||||
p->running = 1;
|
||||
p->min_reply = 10000000;
|
||||
p->min_reply = 0;
|
||||
|
||||
if( strlen( p->host ) > max_hostname_len )
|
||||
max_hostname_len = strlen( p->host );
|
||||
@@ -2534,36 +2426,32 @@ char * sprint_tm( int t )
|
||||
{
|
||||
static char buf[10];
|
||||
|
||||
/* <= 0.99 ms */
|
||||
if( t < 100 )
|
||||
{
|
||||
if( t < 0 ) {
|
||||
/* negative (unexpected) */
|
||||
sprintf( buf, "%.2g", (double) t / 100 );
|
||||
}
|
||||
else if( t < 100 ) {
|
||||
/* <= 0.99 ms */
|
||||
sprintf( buf, "0.%02d", t );
|
||||
return( buf );
|
||||
|
||||
}/* IF */
|
||||
|
||||
/* 1.00 - 9.99 ms */
|
||||
if( t < 1000 )
|
||||
{
|
||||
}
|
||||
else if( t < 1000 ) {
|
||||
/* 1.00 - 9.99 ms */
|
||||
sprintf( buf, "%d.%02d", t / 100, t % 100 );
|
||||
return( buf );
|
||||
|
||||
}/* IF */
|
||||
|
||||
/* 10.0 - 99.9 ms */
|
||||
if( t < 10000 )
|
||||
{
|
||||
}
|
||||
else if( t < 10000 ) {
|
||||
/* 10.0 - 99.9 ms */
|
||||
sprintf( buf, "%d.%d", t / 100, ( t % 100 ) / 10 );
|
||||
return( buf );
|
||||
|
||||
}/* IF */
|
||||
|
||||
/* >= 100 ms */
|
||||
sprintf( buf, "%d", t / 100 );
|
||||
}
|
||||
else if( t < 100000000 ) {
|
||||
/* 100 - 1'000'000 ms */
|
||||
sprintf( buf, "%d", t / 100 );
|
||||
}
|
||||
else {
|
||||
sprintf( buf, "%.2e", (double) (t / 100) );
|
||||
}
|
||||
|
||||
return( buf );
|
||||
|
||||
} /* sprint_tm() */
|
||||
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
|
||||
@@ -2809,6 +2697,7 @@ void usage(int is_error)
|
||||
fprintf(out, " -B f set exponential backoff factor to f\n" );
|
||||
fprintf(out, " -c n count of pings to send to each target (default %d)\n", count );
|
||||
fprintf(out, " -C n same as -c, report results in verbose format\n" );
|
||||
fprintf(out, " -D print timestamp before each output line\n" );
|
||||
fprintf(out, " -e show elapsed time on return packets\n" );
|
||||
fprintf(out, " -f file read list of targets from a file ( - means stdin) (only if no -g specified)\n" );
|
||||
fprintf(out, " -g generate target list (only if no -f specified)\n" );
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
#ifndef _FPING_H
|
||||
#define _FPING_H
|
||||
|
||||
#define __APPLE_USE_RFC_3542 1
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifndef IPV6
|
||||
#define FPING_SOCKADDR struct sockaddr_in
|
||||
#define FPING_INADDR struct in_addr
|
||||
#define FPING_ICMPHDR struct icmp
|
||||
#else
|
||||
#define FPING_SOCKADDR struct sockaddr_in6
|
||||
#define FPING_INADDR struct in6_addr
|
||||
#define FPING_ICMPHDR struct icmp6_hdr
|
||||
#endif
|
||||
|
||||
/* fping.c */
|
||||
void crash_and_burn( char *message );
|
||||
void errno_crash_and_burn( char *message );
|
||||
|
||||
/* socket.c */
|
||||
int open_ping_socket();
|
||||
void socket_set_src_addr(int s, FPING_INADDR src_addr);
|
||||
|
||||
#endif
|
||||
+119
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* fping: fast-ping, file-ping, favorite-ping, funky-ping
|
||||
*
|
||||
* Ping a list of target hosts in a round robin fashion.
|
||||
* A better ping overall.
|
||||
*
|
||||
* fping website: http://www.fping.org
|
||||
*
|
||||
* Current maintainer of fping: David Schweikert
|
||||
* Please send suggestions and patches to: david@schweikert.ch
|
||||
*
|
||||
*
|
||||
* Original author: Roland Schemers <schemers@stanford.edu>
|
||||
* IPv6 Support: Jeroen Massar <jeroen@unfix.org / jeroen@ipng.nl>
|
||||
* Improved main loop: David Schweikert <david@schweikert.ch>
|
||||
* Debian Merge, TOS settings: Tobi Oetiker <tobi@oetiker.ch>
|
||||
* Bugfixes, byte order & senseful seq.-numbers: Stephan Fuhrmann (stephan.fuhrmann AT 1und1.de)
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Stanford University. The name of the University may not be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* seqmap.c: implementation of a mapping between sequence number and (host, ping_nr)
|
||||
* we can't just use ping_nr*host_count + host_nr, because it can
|
||||
* overflow the 16 bit of the icmp header field. See also:
|
||||
* https://github.com/schweikert/fping/issues/48
|
||||
*/
|
||||
|
||||
#include "seqmap.h"
|
||||
#include "options.h"
|
||||
#include "limits.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* description of the data structure used:
|
||||
*
|
||||
* - we assume that no more than SEQMAP_MAXSEQ (65535) pings are sent in
|
||||
* the timeout interval (SEQMAP_TIMEOUT_IN_S)
|
||||
* - we store the values in an array with SEQMAP_MAXSEQ elements
|
||||
* - current sequence number % SEQMAP_MAXSEQ gives the current index
|
||||
* - when entering a value, we check that the current entry is expired
|
||||
*/
|
||||
|
||||
static SEQMAP_VALUE *seqmap_map = NULL;
|
||||
static unsigned int seqmap_next_id = 0;
|
||||
static SEQMAP_VALUE *seqmap_free_list;
|
||||
|
||||
#define SEQMAP_TIMEOUT_IN_S 10
|
||||
#define SEQMAP_UNASSIGNED_HOST_NR UINT_MAX
|
||||
|
||||
void seqmap_init()
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
seqmap_map = calloc(SEQMAP_MAXSEQ, sizeof(SEQMAP_VALUE));
|
||||
if(seqmap_map == NULL) {
|
||||
perror("malloc error (can't allocate seqmap_map)");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, struct timeval *now)
|
||||
{
|
||||
unsigned int current_id;
|
||||
SEQMAP_VALUE *next_value;
|
||||
|
||||
if(!seqmap_map) {
|
||||
fprintf(stderr, "fping internal error: seqmap not initialized.\n");
|
||||
exit(4);
|
||||
}
|
||||
|
||||
/* check if expired (note that unused seqmap values will have fields set to
|
||||
* 0, so will be seen as expired */
|
||||
next_value = &seqmap_map[seqmap_next_id];
|
||||
if(next_value->ping_ts.tv_sec != 0 && (now->tv_sec - next_value->ping_ts.tv_sec) < SEQMAP_TIMEOUT_IN_S) {
|
||||
fprintf(stderr, "fping error: not enough sequence numbers available! (expire_timeout=%d, host_nr=%d, ping_count=%d, seqmap_next_id=%d)\n",
|
||||
SEQMAP_TIMEOUT_IN_S, host_nr, ping_count, seqmap_next_id);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
/* store the value */
|
||||
next_value->host_nr = host_nr;
|
||||
next_value->ping_count = ping_count;
|
||||
next_value->ping_ts.tv_sec = now->tv_sec;
|
||||
next_value->ping_ts.tv_usec = now->tv_usec;
|
||||
|
||||
/* increase next id */
|
||||
current_id = seqmap_next_id;
|
||||
seqmap_next_id = (seqmap_next_id + 1) % SEQMAP_MAXSEQ;
|
||||
|
||||
return current_id;
|
||||
}
|
||||
|
||||
SEQMAP_VALUE *seqmap_fetch(unsigned int id, struct timeval *now)
|
||||
{
|
||||
SEQMAP_VALUE *value;
|
||||
|
||||
if(id > SEQMAP_MAXSEQ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
value = &seqmap_map[id];
|
||||
|
||||
/* verify that value is not expired */
|
||||
if(now->tv_sec - value->ping_ts.tv_sec >= SEQMAP_TIMEOUT_IN_S) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef SEQMAP_H
|
||||
#define SEQMAP_H
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
typedef struct seqmap_value
|
||||
{
|
||||
unsigned int host_nr;
|
||||
unsigned int ping_count;
|
||||
struct timeval ping_ts;
|
||||
|
||||
} SEQMAP_VALUE;
|
||||
|
||||
#define SEQMAP_MAXSEQ 65535
|
||||
|
||||
void seqmap_init();
|
||||
unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, struct timeval *now);
|
||||
SEQMAP_VALUE *seqmap_fetch(unsigned int id, struct timeval *now);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* fping: fast-ping, file-ping, favorite-ping, funky-ping
|
||||
*
|
||||
* Ping a list of target hosts in a round robin fashion.
|
||||
* A better ping overall.
|
||||
*
|
||||
* fping website: http://www.fping.org
|
||||
*
|
||||
* Current maintainer of fping: David Schweikert
|
||||
* Please send suggestions and patches to: david@schweikert.ch
|
||||
*
|
||||
*
|
||||
* Original author: Roland Schemers <schemers@stanford.edu>
|
||||
* IPv6 Support: Jeroen Massar <jeroen@unfix.org / jeroen@ipng.nl>
|
||||
* Improved main loop: David Schweikert <david@schweikert.ch>
|
||||
* Debian Merge, TOS settings: Tobi Oetiker <tobi@oetiker.ch>
|
||||
* Bugfixes, byte order & senseful seq.-numbers: Stephan Fuhrmann (stephan.fuhrmann AT 1und1.de)
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Stanford University. The name of the University may not be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "fping.h"
|
||||
#include "config.h"
|
||||
|
||||
int open_ping_socket_ipv4();
|
||||
int open_ping_socket_ipv6();
|
||||
void socket_set_src_addr_ipv4(int s, FPING_INADDR src_addr);
|
||||
void socket_set_src_addr_ipv6(int s, FPING_INADDR src_addr);
|
||||
|
||||
int open_ping_socket()
|
||||
{
|
||||
#ifndef IPV6
|
||||
return open_ping_socket_ipv4();
|
||||
#else
|
||||
return open_ping_socket_ipv6();
|
||||
#endif
|
||||
}
|
||||
|
||||
void socket_set_src_addr(int s, FPING_INADDR src_addr)
|
||||
{
|
||||
#ifndef IPV6
|
||||
socket_set_src_addr_ipv4(s, src_addr);
|
||||
#else
|
||||
socket_set_src_addr_ipv6(s, src_addr);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* fping: fast-ping, file-ping, favorite-ping, funky-ping
|
||||
*
|
||||
* Ping a list of target hosts in a round robin fashion.
|
||||
* A better ping overall.
|
||||
*
|
||||
* fping website: http://www.fping.org
|
||||
*
|
||||
* Current maintainer of fping: David Schweikert
|
||||
* Please send suggestions and patches to: david@schweikert.ch
|
||||
*
|
||||
*
|
||||
* Original author: Roland Schemers <schemers@stanford.edu>
|
||||
* IPv6 Support: Jeroen Massar <jeroen@unfix.org / jeroen@ipng.nl>
|
||||
* Improved main loop: David Schweikert <david@schweikert.ch>
|
||||
* Debian Merge, TOS settings: Tobi Oetiker <tobi@oetiker.ch>
|
||||
* Bugfixes, byte order & senseful seq.-numbers: Stephan Fuhrmann (stephan.fuhrmann AT 1und1.de)
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Stanford University. The name of the University may not be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "fping.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
int open_ping_socket_ipv4()
|
||||
{
|
||||
struct protoent *proto;
|
||||
int s;
|
||||
|
||||
/* confirm that ICMP is available on this machine */
|
||||
if( ( proto = getprotobyname( "icmp" ) ) == NULL )
|
||||
crash_and_burn( "icmp: unknown protocol" );
|
||||
|
||||
/* create raw socket for ICMP calls (ping) */
|
||||
s = socket( AF_INET, SOCK_RAW, proto->p_proto );
|
||||
if( s < 0 ) {
|
||||
/* try non-privileged icmp (works on Mac OSX without privileges, for example) */
|
||||
s = socket( AF_INET, SOCK_DGRAM, proto->p_proto );
|
||||
if( s < 0 ) {
|
||||
errno_crash_and_burn( "can't create socket (must run as root?)" );
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void socket_set_src_addr_ipv4(int s, FPING_INADDR src_addr)
|
||||
{
|
||||
struct sockaddr_in sa;
|
||||
memset( &sa, 0, sizeof( sa ) );
|
||||
sa.sin_family = AF_INET;
|
||||
sa.sin_addr = src_addr;
|
||||
|
||||
if ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 )
|
||||
errno_crash_and_burn( "cannot bind source address" );
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* fping: fast-ping, file-ping, favorite-ping, funky-ping
|
||||
*
|
||||
* Ping a list of target hosts in a round robin fashion.
|
||||
* A better ping overall.
|
||||
*
|
||||
* fping website: http://www.fping.org
|
||||
*
|
||||
* Current maintainer of fping: David Schweikert
|
||||
* Please send suggestions and patches to: david@schweikert.ch
|
||||
*
|
||||
*
|
||||
* Original author: Roland Schemers <schemers@stanford.edu>
|
||||
* IPv6 Support: Jeroen Massar <jeroen@unfix.org / jeroen@ipng.nl>
|
||||
* Improved main loop: David Schweikert <david@schweikert.ch>
|
||||
* Debian Merge, TOS settings: Tobi Oetiker <tobi@oetiker.ch>
|
||||
* Bugfixes, byte order & senseful seq.-numbers: Stephan Fuhrmann (stephan.fuhrmann AT 1und1.de)
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by Stanford University. The name of the University may not be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "fping.h"
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
int open_ping_socket_ipv6()
|
||||
{
|
||||
struct protoent *proto;
|
||||
int opton = 1;
|
||||
int s;
|
||||
|
||||
/* confirm that ICMP is available on this machine */
|
||||
if( ( proto = getprotobyname( "ipv6-icmp" ) ) == NULL )
|
||||
crash_and_burn( "icmp: unknown protocol" );
|
||||
|
||||
/* create raw socket for ICMP calls (ping) */
|
||||
s = socket( AF_INET6, SOCK_RAW, proto->p_proto );
|
||||
if( s < 0 ) {
|
||||
/* try non-privileged icmp (works on Mac OSX without privileges, for example) */
|
||||
s = socket( AF_INET6, SOCK_DGRAM, proto->p_proto );
|
||||
if( s < 0 ) {
|
||||
errno_crash_and_burn( "can't create raw socket (must run as root?)" );
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void socket_set_src_addr_ipv6(int s, FPING_INADDR src_addr)
|
||||
{
|
||||
struct sockaddr_in6 sa;
|
||||
memset( &sa, 0, sizeof( sa ) );
|
||||
sa.sin6_family = AF_INET6;
|
||||
sa.sin6_addr = src_addr;
|
||||
|
||||
if ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 )
|
||||
errno_crash_and_burn( "cannot bind source address" );
|
||||
}
|
||||
Reference in New Issue
Block a user