Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f36dddffd | ||
|
|
e042466b9a | ||
|
|
3aed2604bb | ||
|
|
609f4f17c4 | ||
|
|
4d6861c2c3 | ||
|
|
314b8debd9 | ||
|
|
fe12f0dbab | ||
|
|
a07e244a57 | ||
|
|
7b8899043d | ||
|
|
c4c3068bbb | ||
|
|
2b5d9ef795 | ||
|
|
e79444f09a | ||
|
|
b779e14db6 | ||
|
|
3aa530c2ff | ||
|
|
c9f276b3cd | ||
|
|
1d576326ba | ||
|
|
f35f4a8cc4 | ||
|
|
75101dd843 | ||
|
|
c1fe95f7b7 | ||
|
|
bdca2c4b07 | ||
|
|
ea026f3ba4 | ||
|
|
3ec68c8a3f | ||
|
|
9a5c6589b2 | ||
|
|
a7f351fb8e | ||
|
|
51cc41a2c1 | ||
|
|
d35f7072b5 | ||
|
|
ab006a5113 | ||
|
|
c524813889 | ||
|
|
86f0b1e380 | ||
|
|
d4e0a6c89b | ||
|
|
3cf9a8a3cd | ||
|
|
f65d335ecf | ||
|
|
c6f37022a4 | ||
|
|
c786c34334 | ||
|
|
cd21d0bb91 | ||
|
|
b359c0e7a3 | ||
|
|
9d71f4e809 | ||
|
|
af0446b046 | ||
|
|
930af0fc54 | ||
|
|
00e3384d5c | ||
|
|
6fa8c4c175 | ||
|
|
8cda80898e | ||
|
|
56c431df13 | ||
|
|
def79d3590 | ||
|
|
0990bf1c61 | ||
|
|
a6721ac2d2 | ||
|
|
49f24acda6 | ||
|
|
37158fe9fe | ||
|
|
86ecd82263 | ||
|
|
382ab64e5c | ||
|
|
3f37397c58 | ||
|
|
8bd200905d | ||
|
|
91130ebd28 | ||
|
|
358ac75c21 | ||
|
|
c5e7e911b0 | ||
|
|
e2705a01c1 | ||
|
|
d9506b335f | ||
|
|
782524e489 | ||
|
|
956b851d47 | ||
|
|
e27fd71935 | ||
|
|
4989d94eb7 | ||
|
|
ff44de71b1 | ||
|
|
e7ace04516 | ||
|
|
18aa33e13a | ||
|
|
71bf72527b | ||
|
|
e07a6e9dfc | ||
|
|
71616ec77e | ||
|
|
42574667d6 | ||
|
|
2604b40743 | ||
|
|
e39e24e933 | ||
|
|
bd768a44f8 | ||
|
|
e9daacdf81 | ||
|
|
2f9cd95bbd | ||
|
|
219dbd893d | ||
|
|
7dd45384e4 | ||
|
|
f9c68a6dc7 | ||
|
|
540057dfd9 | ||
|
|
fdddda1c22 | ||
|
|
a2ac03c210 | ||
|
|
3eccad8ee1 | ||
|
|
c6d311a7d4 | ||
|
|
5851422798 | ||
|
|
57595638ec | ||
|
|
801051eeec | ||
|
|
806ad042b8 | ||
|
|
5dc8afb265 | ||
|
|
f27a89d40d | ||
|
|
b973451021 | ||
|
|
63c73e0697 | ||
|
|
5dd8c5de50 | ||
|
|
0decb829d8 | ||
|
|
3e8eb6c613 | ||
|
|
85abf34b0a | ||
|
|
bda0744d2c | ||
|
|
d6808efd81 | ||
|
|
3a714b275f | ||
|
|
d141744adb | ||
|
|
e1cdf8e1d3 | ||
|
|
d862dd962b | ||
|
|
5c68d6f338 | ||
|
|
a2ac5d0fae | ||
|
|
b01f282727 | ||
|
|
0ab66f80de | ||
|
|
741236e576 | ||
|
|
9fca2a141b | ||
|
|
9ee22bd46a | ||
|
|
f55397336b | ||
|
|
82722a31fe | ||
|
|
4aad0b2c14 | ||
|
|
fb5f5779cc | ||
|
|
a0252f6e79 | ||
|
|
3dee903b41 | ||
|
|
7e55f0b073 | ||
|
|
8daad08e1d | ||
|
|
b7343ed256 |
@@ -1,10 +1,15 @@
|
||||
.*.swp
|
||||
*.tar.gz
|
||||
*~
|
||||
src/*.gcno
|
||||
src/*.gcda
|
||||
src/*.gcov
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
@@ -21,3 +26,4 @@ src/fping6
|
||||
stamp-h1
|
||||
doc/fping.8
|
||||
doc/fping6.8
|
||||
ci/build
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
# travis-ci.org configuration
|
||||
language: c
|
||||
env:
|
||||
global:
|
||||
- secure: "CoI8hwHH1yfQoQxIfWGRS0WfTyScox+5aJn0fDDgz2uKrrIxmBvIw/WKX8wcSiV6fLmLuwgNkKqSM3hdO4qaG+JxfWcuEiZZHm+kxSGMkWbGb/fvAI+gHg8ldKyYttcIX71O5rlZiC2QpNKQi2v18S6pI5p8eqnx7DYx4YrmguQ="
|
||||
compiler:
|
||||
- gcc
|
||||
before_install:
|
||||
- sudo apt-get install libcap2-bin
|
||||
install:
|
||||
- ci/build-1-autotools.sh
|
||||
- curl -L http://cpanmin.us | perl - --sudo App::cpanminus
|
||||
- cpanm --sudo Test::Command
|
||||
script:
|
||||
- ci/build-2-install.sh
|
||||
- env PATH=`pwd`/src:$PATH prove ci/test-*.pl
|
||||
- ci/test-tarball.sh
|
||||
after_success:
|
||||
- ci/coveralls.sh
|
||||
- ci/deploy-bintray.sh
|
||||
@@ -1,5 +1,9 @@
|
||||
|
||||
/*
|
||||
* 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,
|
||||
@@ -11,5 +15,3 @@
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,3 +1,43 @@
|
||||
2014-05-03 David Schweikert <david@schweikert.ch>
|
||||
* Version 3.10
|
||||
* Fix confusing error message with -g and IPv6 addresses (#58, reported by Axel Beckert)
|
||||
* Allow option '-f' also for non-root (since setuid privileges are dropped)
|
||||
* Do not retry twice DNS lookup on DNS lookup problem
|
||||
* Remove support for NIS groups
|
||||
* Better document -B backoff-factor and when it can be used (#33, Oleksiy Zagorskyi)
|
||||
* More tests added
|
||||
|
||||
2014-03-08 David Schweikert <david@schweikert.ch>
|
||||
* Version 3.9
|
||||
* Fix random output on socket error (reported by Aleksandrs Saveljevs, #56)
|
||||
* Support ppc64le architecture by including alpha libtool version
|
||||
(reported by Amit Kumar Gupta and Aravinda B Thunug)
|
||||
* Fix compilation problem on FreeBSD (#57)
|
||||
* Initial test suite and continous intergration (with travis-ci.org / coveralls.io)
|
||||
* Don't output usage information on error
|
||||
|
||||
2013-11-08 David Schweikert <david@schweikert.ch>
|
||||
* Version 3.8
|
||||
* Fix segmentation fault introduced in version 3.7 with loop mode (reported
|
||||
by Vlad Glagolev, #55)
|
||||
|
||||
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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -19,3 +19,6 @@ rm -f stamp-h1
|
||||
rm -f doc/Makefile.in
|
||||
rm -f src/Makefile.in
|
||||
rm -f doc/fping.8
|
||||
rm -f src/*.gcda
|
||||
rm -f src/*.gcno
|
||||
rm -f src/*.gcov
|
||||
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
AUTOCONF=http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz
|
||||
AUTOMAKE=http://ftp.gnu.org/gnu/automake/automake-1.14.1.tar.gz
|
||||
LIBTOOL=http://alpha.gnu.org/gnu/libtool/libtool-2.4.2.418.tar.gz
|
||||
PREFIX=$(pwd)/ci/build
|
||||
PATH=$(pwd)/ci/build/bin:$PATH
|
||||
|
||||
if [ ! -d ci ]; then
|
||||
echo "you must run this in the root fping directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# remove standard versions
|
||||
sudo apt-get remove -qq autoconf automake autotools-dev libtool
|
||||
|
||||
# prepare build environment
|
||||
cd ci
|
||||
rm -rf build
|
||||
mkdir -p build/src
|
||||
cd build/src
|
||||
|
||||
# autoconf
|
||||
(
|
||||
AUTOCONF_FILE=$(basename $AUTOCONF)
|
||||
AUTOCONF_DIR=$(echo $AUTOCONF_FILE | sed -e 's/\.tar.*//')
|
||||
wget $AUTOCONF
|
||||
tar xf $AUTOCONF_FILE
|
||||
cd $AUTOCONF_DIR
|
||||
./configure --prefix=$PREFIX
|
||||
make install
|
||||
)
|
||||
|
||||
# automake
|
||||
(
|
||||
AUTOMAKE_FILE=$(basename $AUTOMAKE)
|
||||
AUTOMAKE_DIR=$(echo $AUTOMAKE_FILE | sed -e 's/\.tar.*//')
|
||||
wget $AUTOMAKE
|
||||
tar xf $AUTOMAKE_FILE
|
||||
cd $AUTOMAKE_DIR
|
||||
./configure --prefix=$PREFIX
|
||||
make install
|
||||
)
|
||||
|
||||
# libtool
|
||||
(
|
||||
LIBTOOL_FILE=$(basename $LIBTOOL)
|
||||
LIBTOOL_DIR=$(echo $LIBTOOL_FILE | sed -e 's/\.tar.*//')
|
||||
wget $LIBTOOL
|
||||
tar xf $LIBTOOL_FILE
|
||||
cd $LIBTOOL_DIR
|
||||
./configure --prefix=$PREFIX
|
||||
make install
|
||||
)
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
PATH=$(pwd)/ci/build/bin:$PATH
|
||||
|
||||
if [ ! -d ci ]; then
|
||||
echo "you must run this in the root fping directory" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
autoreconf -i
|
||||
./configure --enable-ipv4 --enable-ipv6 --prefix=/opt/fping
|
||||
make CFLAGS="-g -fprofile-arcs -ftest-coverage"
|
||||
sudo setcap cap_net_raw+ep src/fping
|
||||
sudo setcap cap_net_raw+ep src/fping6
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -x
|
||||
|
||||
sudo pip install cpp-coveralls --use-mirrors
|
||||
|
||||
cd src
|
||||
|
||||
ls -l
|
||||
|
||||
gcov *.o
|
||||
cd ..
|
||||
coveralls --exclude ci --no-gcov
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
# upload to bintray.com/schweikert
|
||||
|
||||
set -e
|
||||
|
||||
# do this only for the gcc run
|
||||
if [ "$CC" != "gcc" ]; then
|
||||
echo "skipped upload because $CC != gcc"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# do this only for the master branch
|
||||
if [ "$TRAVIS_BRANCH" != "master" ]; then
|
||||
echo "skipped upload branch $TRAVIS_BRANCH isn't master"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
VERSION=$(ls fping-*.tar.gz | sed -e 's/^fping-//' | sed -e 's/\.tar\.gz$//')
|
||||
if [[ "$VERSION" =~ ^[0-9]+\.[0-9]+$ ]]; then
|
||||
REPO=release
|
||||
else
|
||||
REPO=beta
|
||||
fi
|
||||
curl -T fping-$VERSION.tar.gz -uschweikert:$BINTRAY_API_KEY https://api.bintray.com/content/schweikert/$REPO/fping/$VERSION/fping-$VERSION.tar.gz
|
||||
echo
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 9;
|
||||
|
||||
# ping 127.0.0.1
|
||||
my $cmd1 = Test::Command->new(cmd => "fping 127.0.0.1");
|
||||
$cmd1->exit_is_num(0);
|
||||
$cmd1->stdout_is_eq("127.0.0.1 is alive\n");
|
||||
$cmd1->stderr_is_eq("");
|
||||
|
||||
# ping ::1
|
||||
my $cmd2 = Test::Command->new(cmd => "fping6 ::1");
|
||||
$cmd2->exit_is_num(0);
|
||||
$cmd2->stdout_is_eq("::1 is alive\n");
|
||||
$cmd2->stderr_is_eq("");
|
||||
|
||||
# ping 3 times 127.0.0.1
|
||||
my $cmd3 = Test::Command->new(cmd => "fping -p 100 -C3 127.0.0.1");
|
||||
$cmd3->exit_is_num(0);
|
||||
$cmd3->stdout_like(qr{127\.0\.0\.1 : \[0\], 84 bytes, 0\.\d+ ms \(0\.\d+ avg, 0% loss\)
|
||||
127\.0\.0\.1 : \[1\], 84 bytes, 0\.\d+ ms \(0.\d+ avg, 0% loss\)
|
||||
127\.0\.0\.1 : \[2\], 84 bytes, 0\.\d+ ms \(0.\d+ avg, 0% loss\)
|
||||
});
|
||||
$cmd3->stderr_like(qr{127\.0\.0\.1 : 0\.\d+ 0\.\d+ 0\.\d+\n});
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 6;
|
||||
|
||||
# -u show targets that are unreachable
|
||||
# -v show version
|
||||
|
||||
# fping -u
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -r0 -u 8.8.0.0 127.0.0.1");
|
||||
$cmd->exit_is_num(1);
|
||||
$cmd->stdout_is_eq("8.8.0.0\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -v
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -v");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_like(qr{ping: Version 3\.\d+
|
||||
fping: comments to david\@schweikert\.ch
|
||||
});
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 6;
|
||||
|
||||
# run without privileges
|
||||
my $fping_bin = `which fping`; chomp $fping_bin;
|
||||
my $fping6_bin = `which fping6`; chomp $fping6_bin;
|
||||
system("cp $fping_bin /tmp/fping.copy; chmod +x /tmp/fping.copy");
|
||||
system("cp $fping6_bin /tmp/fping6.copy; chmod +x /tmp/fping6.copy");
|
||||
|
||||
# fping
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "/tmp/fping.copy 127.0.0.1");
|
||||
$cmd->exit_is_num(4);
|
||||
$cmd->stdout_is_eq("");
|
||||
$cmd->stderr_like(qr{\(null\): can't create socket \(must run as root\?\) : .*\n});
|
||||
}
|
||||
|
||||
# fping6
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "/tmp/fping6.copy ::1");
|
||||
$cmd->exit_is_num(4);
|
||||
$cmd->stdout_is_eq("");
|
||||
$cmd->stderr_like(qr{\(null\): can't create raw socket \(must run as root\?\) : .*\n});
|
||||
}
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 36;
|
||||
|
||||
for my $arg (qw(i b B c C H i O p Q r t)) {
|
||||
my $cmd = Test::Command->new(cmd => "fping -$arg xxx");
|
||||
$cmd->exit_is_num(1);
|
||||
$cmd->stdout_is_eq("");
|
||||
$cmd->stderr_like(qr{Usage:});
|
||||
}
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 6;
|
||||
|
||||
# fping
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping nosuchname.example.com");
|
||||
$cmd->exit_is_num(1);
|
||||
$cmd->stdout_is_eq("");
|
||||
$cmd->stderr_is_eq("nosuchname.example.com address not found\n");
|
||||
}
|
||||
|
||||
# fping6
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping6 nosuchname.example.com");
|
||||
$cmd->exit_is_num(1);
|
||||
$cmd->stdout_is_eq("");
|
||||
$cmd->stderr_is_eq("nosuchname.example.com: Name or service not known\n");
|
||||
}
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 3;
|
||||
|
||||
my $re_num = qr{\d+(?:\.\d+)?};
|
||||
|
||||
# fping
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -q -i 10 -p 20 -c 3 -t200 8.8.8.8 4.2.2.5 www.france-telecom.fr www.google.com");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("");
|
||||
$cmd->stderr_like(qr{8\.8\.8\.8\s*: xmt/rcv/%loss = [123]/3/\d+%, min/avg/max = $re_num/$re_num/$re_num
|
||||
4\.2\.2\.5\s*: xmt/rcv/%loss = [123]/3/\d+%, min/avg/max = $re_num/$re_num/$re_num
|
||||
www\.france-telecom\.fr\s*: xmt/rcv/%loss = [123]/3/\d+%, min/avg/max = $re_num/$re_num/$re_num
|
||||
www\.google\.com\s*: xmt/rcv/%loss = [123]/3/\d+%, min/avg/max = $re_num/$re_num/$re_num
|
||||
});
|
||||
}
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 9;
|
||||
|
||||
# fping -h
|
||||
my $cmd1 = Test::Command->new(cmd => "fping -h");
|
||||
$cmd1->exit_is_num(0);
|
||||
$cmd1->stdout_is_eq(<<END);
|
||||
|
||||
Usage: fping [options] [targets...]
|
||||
-a show targets that are alive
|
||||
-A show targets by address
|
||||
-b n amount of ping data to send, in bytes (default 56)
|
||||
-B f set exponential backoff factor to f
|
||||
-c n count of pings to send to each target (default 1)
|
||||
-C n same as -c, report results in verbose format
|
||||
-D print timestamp before each output line
|
||||
-e show elapsed time on return packets
|
||||
-f file read list of targets from a file ( - means stdin) (only if no -g specified)
|
||||
-g generate target list (only if no -f specified)
|
||||
(specify the start and end IP in the target list, or supply a IP netmask)
|
||||
(ex. fping -g 192.168.1.0 192.168.1.255 or fping -g 192.168.1.0/24)
|
||||
-H n Set the IP TTL value (Time To Live hops)
|
||||
-i n interval between sending ping packets (in millisec) (default 25)
|
||||
-I if bind to a particular interface
|
||||
-l loop sending pings forever
|
||||
-m ping multiple interfaces on target host
|
||||
-n show targets by name (-d is equivalent)
|
||||
-O n set the type of service (tos) flag on the ICMP packets
|
||||
-p n interval between ping packets to one target (in millisec)
|
||||
(in looping and counting modes, default 1000)
|
||||
-q quiet (don't show per-target/per-ping results)
|
||||
-Q n same as -q, but show summary every n seconds
|
||||
-r n number of retries (default 3)
|
||||
-s print final stats
|
||||
-S addr set source address
|
||||
-t n individual target initial timeout (in millisec) (default 500)
|
||||
-T n ignored (for compatibility with fping 2.4)
|
||||
-u show targets that are unreachable
|
||||
-v show version
|
||||
targets list of targets to check (if no -f specified)
|
||||
|
||||
END
|
||||
$cmd1->stderr_is_eq("");
|
||||
|
||||
# fping -v
|
||||
my $cmd2 = Test::Command->new(cmd => "fping -v");
|
||||
$cmd2->exit_is_num(0);
|
||||
$cmd2->stdout_like(qr{fping: Version \S+
|
||||
fping: comments to david\@schweikert\.ch\n});
|
||||
$cmd2->stderr_is_eq("");
|
||||
|
||||
# fping with unknown option
|
||||
my $cmd3 = Test::Command->new(cmd => "fping -Z");
|
||||
$cmd3->exit_is_num(1);
|
||||
$cmd3->stdout_is_eq("");
|
||||
$cmd3->stderr_is_eq("fping: invalid option -- 'Z'
|
||||
see 'fping -h' for usage information\n");
|
||||
Executable
+82
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 33;
|
||||
|
||||
# fping -i 9
|
||||
my $cmd1 = Test::Command->new(cmd => "fping -i 9 -T10 -g 127.0.0.1/29");
|
||||
$cmd1->exit_is_num(1);
|
||||
$cmd1->stdout_is_eq("");
|
||||
$cmd1->stderr_is_eq(<<END);
|
||||
fping: these options are too risky for mere mortals.
|
||||
fping: You need i >= 10, p >= 20, r < 20, and t >= 50
|
||||
END
|
||||
|
||||
# fping -p 15
|
||||
my $cmd2 = Test::Command->new(cmd => "fping -c3 -p 15 127.0.0.1");
|
||||
$cmd2->exit_is_num(1);
|
||||
$cmd2->stdout_is_eq("");
|
||||
$cmd2->stderr_is_eq(<<END);
|
||||
fping: these options are too risky for mere mortals.
|
||||
fping: You need i >= 10, p >= 20, r < 20, and t >= 50
|
||||
END
|
||||
|
||||
# fping -r 30
|
||||
my $cmd3 = Test::Command->new(cmd => "fping -r 30 127.0.0.1");
|
||||
$cmd3->exit_is_num(1);
|
||||
$cmd3->stdout_is_eq("");
|
||||
$cmd3->stderr_is_eq(<<END);
|
||||
fping: these options are too risky for mere mortals.
|
||||
fping: You need i >= 10, p >= 20, r < 20, and t >= 50
|
||||
END
|
||||
|
||||
# fping -t 40
|
||||
my $cmd4 = Test::Command->new(cmd => "fping -t 40 127.0.0.1");
|
||||
$cmd4->exit_is_num(1);
|
||||
$cmd4->stdout_is_eq("");
|
||||
$cmd4->stderr_is_eq(<<END);
|
||||
fping: these options are too risky for mere mortals.
|
||||
fping: You need i >= 10, p >= 20, r < 20, and t >= 50
|
||||
END
|
||||
|
||||
# fping -H 300
|
||||
my $cmd5 = Test::Command->new(cmd => "fping -H 300 127.0.0.1");
|
||||
$cmd5->exit_is_num(1);
|
||||
$cmd5->stdout_is_eq("");
|
||||
$cmd5->stderr_is_eq("ttl 300 out of range\n");
|
||||
|
||||
# fping -a -u
|
||||
my $cmd6 = Test::Command->new(cmd => "fping -a -u 127.0.0.1");
|
||||
$cmd6->exit_is_num(1);
|
||||
$cmd6->stdout_is_eq("");
|
||||
$cmd6->stderr_is_eq("fping: specify only one of a, u\n");
|
||||
|
||||
# fping -c -l
|
||||
my $cmd7 = Test::Command->new(cmd => "fping -c3 -l 127.0.0.1");
|
||||
$cmd7->exit_is_num(1);
|
||||
$cmd7->stdout_is_eq("");
|
||||
$cmd7->stderr_is_eq("fping: specify only one of c, l\n");
|
||||
|
||||
# fping -b 65509
|
||||
my $cmd8 = Test::Command->new(cmd => "fping -b 65509 127.0.0.1");
|
||||
$cmd8->exit_is_num(1);
|
||||
$cmd8->stdout_is_eq("");
|
||||
$cmd8->stderr_is_eq("fping: data size 65509 not valid, must be between 0 and 65508\n");
|
||||
|
||||
# fping -B 0.9
|
||||
my $cmd9 = Test::Command->new(cmd => "fping -B 0.9 127.0.0.1");
|
||||
$cmd9->exit_is_num(1);
|
||||
$cmd9->stdout_is_eq("");
|
||||
$cmd9->stderr_is_eq("fping: backoff factor 0.9 not valid, must be between 1.0 and 5.0\n");
|
||||
|
||||
# fping -B 0.9
|
||||
my $cmd10 = Test::Command->new(cmd => "fping -B 5.1 127.0.0.1");
|
||||
$cmd10->exit_is_num(1);
|
||||
$cmd10->stdout_is_eq("");
|
||||
$cmd10->stderr_is_eq("fping: backoff factor 5.1 not valid, must be between 1.0 and 5.0\n");
|
||||
|
||||
# fping -C 11000
|
||||
my $cmd11 = Test::Command->new(cmd => "fping -C 11000 127.0.0.1");
|
||||
$cmd11->exit_is_num(1);
|
||||
$cmd11->stdout_is_eq("");
|
||||
$cmd11->stderr_is_eq("fping: count 11000 not valid, must be less than 10000\n");
|
||||
|
||||
Executable
+63
@@ -0,0 +1,63 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 20;
|
||||
use Test::More;
|
||||
use Time::HiRes qw(gettimeofday tv_interval);
|
||||
|
||||
# -a show targets that are alive
|
||||
# -A show targets by address
|
||||
# -b n amount of ping data to send, in bytes (default 56)
|
||||
# -B f set exponential backoff factor to f
|
||||
|
||||
# fping -a
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -a 127.0.0.1 127.0.0.2");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1\n127.0.0.2\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -A
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -A localhost");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -A -n
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -A -n localhost");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("localhost (127.0.0.1) is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping6 -A -n
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping6 -n -A 2001:4860:4860::8888");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("google-public-dns-a.google.com (2001:4860:4860::8888) is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -b
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -b 1000 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -B
|
||||
{
|
||||
my $t0 = [gettimeofday];
|
||||
my $cmd = Test::Command->new(cmd => "fping -t 100 -r 3 -B 2 8.8.8.7");
|
||||
$cmd->exit_is_num(1);
|
||||
$cmd->stdout_is_eq("8.8.8.7 is unreachable\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
my $elapsed = tv_interval($t0);
|
||||
# 0.1 + 0.2 + 0.4 + 0.8 = 1.5
|
||||
cmp_ok($elapsed, '>=', 1.5);
|
||||
cmp_ok($elapsed, '<', 1.7);
|
||||
}
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 12;
|
||||
|
||||
# -c n count of pings to send to each target (default 1)
|
||||
# -C n same as -c, report results in verbose format
|
||||
# -D print timestamp before each output line
|
||||
# -e show elapsed time on return packets
|
||||
|
||||
# fping -c n
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -c 2 -p 100 localhost 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_like(qr{localhost : \[0\], 84 bytes, 0\.\d+ ms \(0\.\d+ avg, 0% loss\)
|
||||
127\.0\.0\.1 : \[0\], 84 bytes, 0\.\d+ ms \(0.\d+ avg, 0% loss\)
|
||||
localhost : \[1\], 84 bytes, 0\.\d+ ms \(0\.\d+ avg, 0% loss\)
|
||||
127\.0\.0\.1 : \[1\], 84 bytes, 0\.\d+ ms \(0\.\d+ avg, 0% loss\)
|
||||
});
|
||||
|
||||
$cmd->stderr_like(qr{localhost : xmt/rcv/%loss = 2/2/0%, min/avg/max = 0\.\d+/0\.\d+/0\.\d+
|
||||
127\.0\.0\.1 : xmt/rcv/%loss = 2/2/0%, min/avg/max = 0\.\d+/0\.\d+/0\.\d+
|
||||
});
|
||||
}
|
||||
|
||||
# fping -C n
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -C 2 -p 100 localhost 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_like(qr{localhost : \[0\], 84 bytes, 0\.\d+ ms \(0\.\d+ avg, 0% loss\)
|
||||
127\.0\.0\.1 : \[0\], 84 bytes, 0\.\d+ ms \(0.\d+ avg, 0% loss\)
|
||||
localhost : \[1\], 84 bytes, 0\.\d+ ms \(0\.\d+ avg, 0% loss\)
|
||||
127\.0\.0\.1 : \[1\], 84 bytes, 0\.\d+ ms \(0\.\d+ avg, 0% loss\)
|
||||
});
|
||||
|
||||
$cmd->stderr_like(qr{localhost : 0\.\d+ 0\.\d+
|
||||
127\.0\.0\.1 : 0\.\d+ 0\.\d+
|
||||
});
|
||||
}
|
||||
|
||||
# fping -D
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -D -c 2 -p 100 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_like(qr{\[\d{10}\.\d+\] 127\.0\.0\.1 : \[0\], 84 bytes, 0\.\d+ ms \(0.\d+ avg, 0% loss\)
|
||||
\[\d{10}\.\d+\] 127\.0\.0\.1 : \[1\], 84 bytes, 0\.\d+ ms \(0\.\d+ avg, 0% loss\)
|
||||
});
|
||||
|
||||
$cmd->stderr_like(qr{127\.0\.0\.1 : xmt/rcv/%loss = 2/2/0%, min/avg/max = 0\.\d+/0\.\d+/0\.\d+
|
||||
});
|
||||
}
|
||||
|
||||
# fping -e
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -e 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_like(qr{127\.0\.0\.1 is alive \(0\.\d+ ms\)
|
||||
});
|
||||
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 18;
|
||||
use File::Temp;
|
||||
|
||||
# -f file read list of targets from a file ( - means stdin) (only if no -g specified)
|
||||
# -g generate target list (only if no -f specified)
|
||||
# (specify the start and end IP in the target list, or supply a IP netmask)
|
||||
# (ex. ../src/fping -g 192.168.1.0 192.168.1.255 or ../src/fping -g 192.168.1.0/24)
|
||||
# -H n Set the IP TTL value (Time To Live hops)
|
||||
|
||||
my $tmpfile = File::Temp->new();
|
||||
print $tmpfile "127.0.0.1\n127.0.0.2\n";
|
||||
close($tmpfile);
|
||||
|
||||
# fping without option (-> equivalent to 'fping -f -')
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "cat ".$tmpfile->filename." | fping");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n127.0.0.2 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -f -
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "cat ".$tmpfile->filename." | fping -f -");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n127.0.0.2 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -f file
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -f ".$tmpfile->filename);
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n127.0.0.2 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -g (range)
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -g 127.0.0.1 127.0.0.5");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n127.0.0.2 is alive\n127.0.0.3 is alive\n127.0.0.4 is alive\n127.0.0.5 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -g (cidr)
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -g 127.0.0.1/30");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n127.0.0.2 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -H
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -H 1 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 7;
|
||||
|
||||
# -i n interval between sending ping packets (in millisec) (default 25)
|
||||
# -l loop sending pings forever
|
||||
# -m ping multiple interfaces on target host
|
||||
|
||||
# fping -i n
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -i 100 127.0.0.1 127.0.0.2");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n127.0.0.2 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -l
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => '(sleep 2; pkill fping)& fping -p 900 -l 127.0.0.1');
|
||||
$cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 84 bytes, 0\.\d+ ms \(0.\d+ avg, 0% loss\)
|
||||
127\.0\.0\.1 : \[1\], 84 bytes, 0\.\d+ ms \(0\.\d+ avg, 0% loss\)
|
||||
});
|
||||
}
|
||||
|
||||
# fping -m
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -m google-public-dns-a.google.com");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("google-public-dns-a.google.com is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 12;
|
||||
|
||||
# -n show targets by name (-d is equivalent)
|
||||
# -O n set the type of service (tos) flag on the ICMP packets
|
||||
# -p n interval between ping packets to one target (in millisec)
|
||||
# (in looping and counting modes, default 1000)
|
||||
# -q quiet (don't show per-target/per-ping results)
|
||||
# -Q n same as -q, but show summary every n seconds
|
||||
|
||||
# fping -n
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -n 8.8.8.8");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("google-public-dns-a.google.com is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -O
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -O 2 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -q
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -q -p 100 -c 3 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("");
|
||||
$cmd->stderr_like(qr{127\.0\.0\.1 : xmt/rcv/%loss = 3/3/0%, min/avg/max = 0\.\d+/0\.\d+/0\.\d+
|
||||
});
|
||||
}
|
||||
|
||||
# fping -Q
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -Q 1 -p 400 -c 4 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("");
|
||||
$cmd->stderr_like(qr{\[\d+:\d+:\d+\]
|
||||
127\.0\.0\.1 : xmt/rcv/%loss = 3/3/0%, min/avg/max = 0\.\d+/0\.\d+/0\.\d+
|
||||
127\.0\.0\.1 : xmt/rcv/%loss = 4/4/0%, min/avg/max = 0\.\d+/0\.\d+/0\.\d+
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 12;
|
||||
|
||||
# -r n number of retries (default 3)
|
||||
# -s print final stats
|
||||
# -S addr set source address
|
||||
# -t n individual target initial timeout (in millisec) (default 500)
|
||||
# -T n ignored (for compatibility with fping 2.4)
|
||||
|
||||
# fping -r tested in test-4-options-a-b.pl
|
||||
|
||||
# fping -s
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -s 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n");
|
||||
$cmd->stderr_like(qr{\s*
|
||||
\s*1 targets
|
||||
\s*1 alive
|
||||
\s*0 unreachable
|
||||
\s*0 unknown addresses
|
||||
\s*
|
||||
\s*0 timeouts \(waiting for response\)
|
||||
\s*1 ICMP Echos sent
|
||||
\s*1 ICMP Echo Replies received
|
||||
\s*0 other ICMP received
|
||||
|
||||
\s*0.\d+ ms \(min round trip time\)
|
||||
\s*0.\d+ ms \(avg round trip time\)
|
||||
\s*0.\d+ ms \(max round trip time\)
|
||||
\s*0.\d+ sec \(elapsed real time\)
|
||||
});
|
||||
}
|
||||
|
||||
# fping -s (no host reachable)
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -r0 -t100 -s 8.8.0.0");
|
||||
$cmd->exit_is_num(1);
|
||||
$cmd->stdout_is_eq("8.8.0.0 is unreachable\n");
|
||||
$cmd->stderr_like(qr{\s*
|
||||
\s*1 targets
|
||||
\s*0 alive
|
||||
\s*1 unreachable
|
||||
\s*0 unknown addresses
|
||||
\s*
|
||||
\s*1 timeouts \(waiting for response\)
|
||||
\s*1 ICMP Echos sent
|
||||
\s*0 ICMP Echo Replies received
|
||||
\s*0 other ICMP received
|
||||
|
||||
\s*0.\d+ ms \(min round trip time\)
|
||||
\s*0.\d+ ms \(avg round trip time\)
|
||||
\s*0.\d+ ms \(max round trip time\)
|
||||
\s*0.\d+ sec \(elapsed real time\)
|
||||
});
|
||||
}
|
||||
|
||||
# fping -S
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -S 127.0.0.1 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping6 -S
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping6 -S ::1 ::1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("::1 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -t tested in test-4-options-a-b.pl
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# regression testing for github issue #56
|
||||
|
||||
use Test::Command tests => 3;
|
||||
|
||||
my $cmd1 = Test::Command->new(cmd => "fping -t100 -p100 -C3 255.255.255.255");
|
||||
$cmd1->exit_is_num(1);
|
||||
$cmd1->stdout_is_eq("");
|
||||
$cmd1->stderr_is_eq("\n255.255.255.255 : - - -\n");
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
# regression testing for github issue #58
|
||||
|
||||
use Test::Command tests => 3;
|
||||
|
||||
my $cmd1 = Test::Command->new(cmd => "fping -a -g 2001:db8:120:4161::4/64");
|
||||
$cmd1->exit_is_num(1);
|
||||
$cmd1->stdout_is_eq("");
|
||||
$cmd1->stderr_is_eq("Error: -g works only with IPv4 addresses\n");
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
|
||||
# make sure that the .tar.gz file contains everything necessary
|
||||
# to build fping
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
make dist
|
||||
VERSION=$(ls fping-*.tar.gz | sed -e 's/^fping-//' | sed -e 's/\.tar\.gz$//')
|
||||
if [ -z "$VERSION" ]; then
|
||||
echo "tar.gz file not found." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# unarchive
|
||||
TMPDIR=$(mktemp -d --tmpdir=ci)
|
||||
cd $TMPDIR
|
||||
tar xf ../../fping-$VERSION.tar.gz
|
||||
DIRNAME=$(ls)
|
||||
|
||||
# build
|
||||
cd $DIRNAME
|
||||
./configure --enable-ipv4 --enable-ipv6 --prefix=/opt/fping
|
||||
make
|
||||
sudo make install
|
||||
+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.4])
|
||||
AC_INIT([fping],[3.10])
|
||||
|
||||
dnl make ipv4 and ipv6 options
|
||||
AC_ARG_ENABLE([ipv4],
|
||||
|
||||
+8
-5
@@ -49,10 +49,11 @@ number.
|
||||
|
||||
=item B<-B> I<n>
|
||||
|
||||
In the default mode, B<fping> sends several requests to a target before giving
|
||||
up, waiting longer for a reply on each successive request. This parameter is
|
||||
the value by which the wait time is multiplied on each successive request; it
|
||||
must be entered as a floating-point number (x.y). The default is 1.5.
|
||||
Backoff factor. In the default mode, B<fping> sends several requests to a
|
||||
target before giving up, waiting longer for a reply on each successive request.
|
||||
This parameter is the value by which the wait time (B<-t>) is multiplied on each
|
||||
successive request; it must be entered as a floating-point number (x.y). The
|
||||
default is 1.5.
|
||||
|
||||
=item B<-c> I<n>
|
||||
|
||||
@@ -165,7 +166,9 @@ Set the interface (requires SO_BINDTODEVICE support)
|
||||
|
||||
Initial target timeout in milliseconds (default 500). In the default mode, this
|
||||
is the amount of time that B<fping> waits for a response to its first request.
|
||||
Successive timeouts are multiplied by the backoff factor.
|
||||
Successive timeouts are multiplied by the backoff factor specified with B<-B>.
|
||||
Note that this option has no effect looping or counting modes (B<-l>, B<-c>, or
|
||||
B<-C>).
|
||||
|
||||
=item B<-T> I<n>
|
||||
|
||||
|
||||
+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
|
||||
|
||||
+131
-306
@@ -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,10 +57,8 @@ extern "C"
|
||||
#include <getopt.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#define __APPLE_USE_RFC_3542 1
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "seqmap.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
@@ -96,8 +97,6 @@ extern "C"
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include "options.h"
|
||||
|
||||
/*** externals ***/
|
||||
|
||||
extern char *optarg;
|
||||
@@ -114,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
|
||||
@@ -146,6 +136,7 @@ typedef struct ping_data
|
||||
/* response time array flags */
|
||||
#define RESP_WAITING -1
|
||||
#define RESP_UNUSED -2
|
||||
#define RESP_ERROR -3
|
||||
|
||||
/* debugging flags */
|
||||
#if defined( DEBUG ) || defined( _DEBUG )
|
||||
@@ -202,13 +193,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 */
|
||||
|
||||
@@ -234,10 +218,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 */
|
||||
@@ -286,13 +272,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 */
|
||||
@@ -376,117 +361,20 @@ 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;
|
||||
|
||||
s = open_ping_socket();
|
||||
|
||||
if((uid = getuid())) {
|
||||
/* drop privileges */
|
||||
setuid( getuid() );
|
||||
}
|
||||
|
||||
prog = argv[0];
|
||||
|
||||
/* 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() ) )
|
||||
{
|
||||
seteuid( getuid() );
|
||||
|
||||
}/* IF */
|
||||
|
||||
ident = getpid() & 0xFFFF;
|
||||
|
||||
verbose_flag = 1;
|
||||
backoff_flag = 1;
|
||||
opterr = 1;
|
||||
@@ -504,7 +392,8 @@ int main( int argc, char **argv )
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
retry = ( unsigned int )atoi( optarg );
|
||||
if (!sscanf(optarg,"%i",&retry))
|
||||
usage(1);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
@@ -535,7 +424,7 @@ int main( int argc, char **argv )
|
||||
break;
|
||||
|
||||
case 'b':
|
||||
if( !( ping_data_size = ( unsigned int )atoi( optarg ) ) )
|
||||
if (!sscanf(optarg,"%i",&ping_data_size))
|
||||
usage(1);
|
||||
|
||||
break;
|
||||
@@ -620,27 +509,8 @@ int main( int argc, char **argv )
|
||||
exit( 0 );
|
||||
|
||||
case 'f':
|
||||
#ifdef ENABLE_F_OPTION
|
||||
filename = optarg;
|
||||
generate_flag = 0;
|
||||
break;
|
||||
#else
|
||||
if( getuid() )
|
||||
{
|
||||
printf( "%s: this option can only be used by root.\n", argv[0] );
|
||||
printf( "%s: fping will read from stdin by default.\n", argv[0] );
|
||||
exit( 3 );
|
||||
|
||||
}/* IF */
|
||||
else
|
||||
{
|
||||
filename = optarg;
|
||||
generate_flag = 0;
|
||||
|
||||
}/* ELSE */
|
||||
|
||||
break;
|
||||
#endif /* ENABLE_F_OPTION */
|
||||
|
||||
case 'g':
|
||||
/* use IP list generation */
|
||||
@@ -679,9 +549,13 @@ int main( int argc, char **argv )
|
||||
perror("setting type of service octet IP_TOS");
|
||||
}
|
||||
}
|
||||
else {
|
||||
usage(1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage(1);
|
||||
fprintf(stderr, "see 'fping -h' for usage information\n");
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
}/* SWITCH */
|
||||
@@ -690,21 +564,21 @@ int main( int argc, char **argv )
|
||||
/* validate various option settings */
|
||||
|
||||
if (ttl > 255) {
|
||||
fprintf(stderr, "ping: ttl %u out of range\n", ttl);
|
||||
usage(1);
|
||||
fprintf(stderr, "ttl %u out of range\n", ttl);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if( unreachable_flag && alive_flag )
|
||||
{
|
||||
fprintf( stderr, "%s: specify only one of a, u\n", argv[0] );
|
||||
usage(1);
|
||||
exit(1);
|
||||
|
||||
}/* IF */
|
||||
|
||||
if( count_flag && loop_flag )
|
||||
{
|
||||
fprintf( stderr, "%s: specify only one of c, l\n", argv[0] );
|
||||
usage(1);
|
||||
exit(1);
|
||||
|
||||
}/* IF */
|
||||
|
||||
@@ -717,15 +591,14 @@ int main( int argc, char **argv )
|
||||
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(1);
|
||||
|
||||
exit(1);
|
||||
}/* IF */
|
||||
|
||||
if( ( ping_data_size > MAX_PING_DATA ) || ( ping_data_size < MIN_PING_DATA ) )
|
||||
{
|
||||
fprintf( stderr, "%s: data size %u not valid, must be between %u and %u\n",
|
||||
prog, ping_data_size, (unsigned int) MIN_PING_DATA, (unsigned int) MAX_PING_DATA );
|
||||
usage(1);
|
||||
exit(1);
|
||||
|
||||
}/* IF */
|
||||
|
||||
@@ -733,7 +606,7 @@ int main( int argc, char **argv )
|
||||
{
|
||||
fprintf( stderr, "%s: backoff factor %.1f not valid, must be between %.1f and %.1f\n",
|
||||
prog, backoff, MIN_BACKOFF_FACTOR, MAX_BACKOFF_FACTOR );
|
||||
usage(1);
|
||||
exit(1);
|
||||
|
||||
}/* IF */
|
||||
|
||||
@@ -741,7 +614,7 @@ int main( int argc, char **argv )
|
||||
{
|
||||
fprintf( stderr, "%s: count %u not valid, must be less than %u\n",
|
||||
prog, count, MAX_COUNT );
|
||||
usage(1);
|
||||
exit(1);
|
||||
|
||||
}/* IF */
|
||||
|
||||
@@ -905,22 +778,10 @@ int main( int argc, char **argv )
|
||||
}
|
||||
|
||||
if( !num_hosts )
|
||||
exit( 2 );
|
||||
exit(1);
|
||||
|
||||
/* 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 */
|
||||
@@ -973,6 +834,8 @@ int main( int argc, char **argv )
|
||||
srandom( start_time.tv_usec );
|
||||
#endif /* DEBUG || _DEBUG */
|
||||
|
||||
seqmap_init();
|
||||
|
||||
/* main loop */
|
||||
main_loop();
|
||||
|
||||
@@ -1001,10 +864,6 @@ void add_cidr(char *addr)
|
||||
*addr_end = '\0';
|
||||
mask_str = addr_end + 1;
|
||||
mask = atoi(mask_str);
|
||||
if(mask < 1 || mask > 30) {
|
||||
fprintf(stderr, "Error: netmask must be between 1 and 30 (is: %s)\n", mask_str);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/* parse address (IPv4 only) */
|
||||
memset(&addr_hints, 0, sizeof(struct addrinfo));
|
||||
@@ -1013,14 +872,20 @@ void add_cidr(char *addr)
|
||||
ret = getaddrinfo(addr, NULL, &addr_hints, &addr_res);
|
||||
if(ret) {
|
||||
fprintf(stderr, "Error: can't parse address %s: %s\n", addr, gai_strerror(ret));
|
||||
exit(2);
|
||||
exit(1);
|
||||
}
|
||||
if(addr_res->ai_family != AF_INET) {
|
||||
fprintf(stderr, "Error: -g works only with IPv4 addresses\n");
|
||||
exit(2);
|
||||
exit(1);
|
||||
}
|
||||
net_addr = ntohl(((struct sockaddr_in *) addr_res->ai_addr)->sin_addr.s_addr);
|
||||
|
||||
/* check mask */
|
||||
if(mask < 1 || mask > 30) {
|
||||
fprintf(stderr, "Error: netmask must be between 1 and 30 (is: %s)\n", mask_str);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* convert mask integer from 1 to 32 to a bitmask */
|
||||
bitmask = ((unsigned long) 0xFFFFFFFF) << (32-mask);
|
||||
|
||||
@@ -1055,11 +920,11 @@ void add_range(char *start, char *end)
|
||||
ret = getaddrinfo(start, NULL, &addr_hints, &addr_res);
|
||||
if(ret) {
|
||||
fprintf(stderr, "Error: can't parse address %s: %s\n", start, gai_strerror(ret));
|
||||
exit(2);
|
||||
exit(1);
|
||||
}
|
||||
if(addr_res->ai_family != AF_INET) {
|
||||
fprintf(stderr, "Error: -g works only with IPv4 addresses\n");
|
||||
exit(2);
|
||||
exit(1);
|
||||
}
|
||||
start_long = ntohl(((struct sockaddr_in *) addr_res->ai_addr)->sin_addr.s_addr);
|
||||
|
||||
@@ -1070,11 +935,11 @@ void add_range(char *start, char *end)
|
||||
ret = getaddrinfo(end, NULL, &addr_hints, &addr_res);
|
||||
if(ret) {
|
||||
fprintf(stderr, "Error: can't parse address %s: %s\n", end, gai_strerror(ret));
|
||||
exit(2);
|
||||
exit(1);
|
||||
}
|
||||
if(addr_res->ai_family != AF_INET) {
|
||||
fprintf(stderr, "Error: -g works only with IPv4 addresses\n");
|
||||
exit(2);
|
||||
exit(1);
|
||||
}
|
||||
end_long = ntohl(((struct sockaddr_in *) addr_res->ai_addr)->sin_addr.s_addr);
|
||||
|
||||
@@ -1113,7 +978,7 @@ void main_loop()
|
||||
|
||||
/* Send the ping */
|
||||
/*printf("Sending ping after %d ms\n", lt/100); */
|
||||
if(!send_ping(s, h)) goto wait_for_reply;
|
||||
send_ping(s, h);
|
||||
|
||||
/* Check what needs to be done next */
|
||||
if(!loop_flag && !count_flag) {
|
||||
@@ -1531,9 +1396,9 @@ int send_ping( int s, HOST_ENTRY *h )
|
||||
{
|
||||
char *buffer;
|
||||
FPING_ICMPHDR *icp;
|
||||
PING_DATA *pdp;
|
||||
int n;
|
||||
int myseq;
|
||||
int myseq;
|
||||
int ret = 1;
|
||||
|
||||
buffer = ( char* )malloc( ( size_t )ping_pkt_size );
|
||||
if( !buffer )
|
||||
@@ -1543,8 +1408,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;
|
||||
@@ -1553,10 +1417,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;
|
||||
@@ -1564,10 +1424,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)
|
||||
@@ -1578,47 +1434,44 @@ 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 )
|
||||
{
|
||||
if( verbose_flag || unreachable_flag ) {
|
||||
printf( "%s", h->host );
|
||||
if( verbose_flag )
|
||||
printf( " error while sending ping: %s\n", strerror( errno ) );
|
||||
|
||||
printf( "\n" );
|
||||
|
||||
}/* IF */
|
||||
}
|
||||
|
||||
h->num_sent++;
|
||||
h->num_sent_i++;
|
||||
num_pingsent++;
|
||||
free( buffer );
|
||||
return(1);
|
||||
}
|
||||
if( !loop_flag )
|
||||
h->resp_times[h->num_sent] = RESP_ERROR;
|
||||
|
||||
/* mark this trial as outstanding */
|
||||
if( !loop_flag )
|
||||
h->resp_times[h->num_sent] = RESP_WAITING;
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
/* 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 );
|
||||
#endif /* DEBUG || _DEBUG */
|
||||
if( sent_times_flag )
|
||||
h->sent_times[h->num_sent] = timeval_diff( &h->last_send_time, &start_time );
|
||||
#endif
|
||||
}
|
||||
|
||||
h->num_sent++;
|
||||
h->num_sent_i++;
|
||||
h->waiting++;
|
||||
num_pingsent++;
|
||||
last_send_time = h->last_send_time;
|
||||
|
||||
free( buffer );
|
||||
return(1);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
@@ -1649,7 +1502,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 );
|
||||
|
||||
@@ -1695,6 +1549,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 )
|
||||
@@ -1715,60 +1571,57 @@ 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( loop_flag || 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 )
|
||||
{
|
||||
if( ( this_count >= 0 ) && ( this_count < trials ) )
|
||||
{
|
||||
if( h->resp_times[this_count] != RESP_WAITING )
|
||||
if( h->resp_times[this_count] >= 0 )
|
||||
{
|
||||
if( !per_recv_flag )
|
||||
{
|
||||
@@ -1852,7 +1705,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
|
||||
@@ -1903,6 +1756,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);
|
||||
@@ -1919,14 +1773,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 )
|
||||
{
|
||||
@@ -1934,9 +1788,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];
|
||||
@@ -1977,21 +1833,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];
|
||||
@@ -2126,45 +1986,10 @@ void add_name( char *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();
|
||||
print_warning("%s address not found\n", name );
|
||||
|
||||
num_noaddress++;
|
||||
return;
|
||||
|
||||
}/* IF */
|
||||
else
|
||||
add_name(machine);
|
||||
|
||||
while( getnetgrent( &machine, &user_ignored, &domain_ignored ) )
|
||||
add_name(machine);
|
||||
|
||||
endnetgrent();
|
||||
return;
|
||||
#else
|
||||
print_warning("%s address not found\n", name );
|
||||
|
||||
num_noaddress++;
|
||||
return ;
|
||||
#endif /* NIS_GROUPS */
|
||||
}/* IF */
|
||||
}/* IF */
|
||||
}
|
||||
|
||||
if(host_ent->h_addrtype != AF_INET) {
|
||||
print_warning("%s: IPv6 address returned by gethostbyname (options inet6 in resolv.conf?)\n", name );
|
||||
@@ -2321,7 +2146,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 );
|
||||
@@ -2829,23 +2654,23 @@ void usage(int is_error)
|
||||
fprintf(out, " (ex. %s -g 192.168.1.0 192.168.1.255 or %s -g 192.168.1.0/24)\n", prog, prog );
|
||||
fprintf(out, " -H n Set the IP TTL value (Time To Live hops)\n");
|
||||
fprintf(out, " -i n interval between sending ping packets (in millisec) (default %d)\n", interval / 100 );
|
||||
#ifdef SO_BINDTODEVICE
|
||||
fprintf(out, " -I if bind to a particular interface\n");
|
||||
#endif
|
||||
fprintf(out, " -l loop sending pings forever\n" );
|
||||
fprintf(out, " -m ping multiple interfaces on target host\n" );
|
||||
fprintf(out, " -n show targets by name (-d is equivalent)\n" );
|
||||
fprintf(out, " -O n set the type of service (tos) flag on the ICMP packets\n" );
|
||||
fprintf(out, " -p n interval between ping packets to one target (in millisec)\n" );
|
||||
fprintf(out, " (in looping and counting modes, default %d)\n", perhost_interval / 100 );
|
||||
fprintf(out, " -q quiet (don't show per-target/per-ping results)\n" );
|
||||
fprintf(out, " -Q n same as -q, but show summary every n seconds\n" );
|
||||
fprintf(out, " -r n number of retries (default %d)\n", DEFAULT_RETRY );
|
||||
fprintf(out, " -s print final stats\n" );
|
||||
#ifdef SO_BINDTODEVICE
|
||||
fprintf(out, " -I if bind to a particular interface\n");
|
||||
#endif
|
||||
fprintf(out, " -S addr set source address\n" );
|
||||
fprintf(out, " -t n individual target initial timeout (in millisec) (default %d)\n", timeout / 100 );
|
||||
fprintf(out, " -T n ignored (for compatibility with fping 2.4)\n");
|
||||
fprintf(out, " -u show targets that are unreachable\n" );
|
||||
fprintf(out, " -O n set the type of service (tos) flag on the ICMP packets\n" );
|
||||
fprintf(out, " -v show version\n" );
|
||||
fprintf(out, " targets list of targets to check (if no -f specified)\n" );
|
||||
fprintf(out, "\n");
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
#ifndef _FPING_H
|
||||
#define _FPING_H
|
||||
|
||||
#define __APPLE_USE_RFC_3542 1
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.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
|
||||
@@ -49,6 +49,3 @@
|
||||
#ifndef DNS_TIMEOUT
|
||||
#define DNS_TIMEOUT 1000 /* time in micro_sec for dns retry */
|
||||
#endif
|
||||
|
||||
/* NIS_GROUPS allows input name to be an NIS netgroup name */
|
||||
/* #define NIS_GROUPS=1 */
|
||||
|
||||
+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