Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
David Schweikert | a993bf5043 | 8 years ago |
David Schweikert | 7a5f9b29d2 | 8 years ago |
David Schweikert | 36030dce3b | 8 years ago |
David Schweikert | 08e5cabe45 | 8 years ago |
David Schweikert | b079eaf8d4 | 8 years ago |
@ -1,30 +0,0 @@
|
||||
.*.swp
|
||||
*.tar.gz
|
||||
*~
|
||||
src/*.gcno
|
||||
src/*.gcda
|
||||
src/*.gcov
|
||||
src/tags
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
compile
|
||||
config.guess
|
||||
config.h
|
||||
config.h.in
|
||||
config.log
|
||||
config.status
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
missing
|
||||
src/*.o
|
||||
src/fping
|
||||
src/fping6
|
||||
stamp-h1
|
||||
doc/fping.8
|
||||
doc/fping6.8
|
||||
ci/build
|
@ -1,108 +0,0 @@
|
||||
name: Test
|
||||
on: [push, pull_request]
|
||||
jobs:
|
||||
Test-Linux:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-20.04, ubuntu-22.04]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install libcap2-bin libtest-command-perl lcov
|
||||
sudo sysctl net.ipv4.ping_group_range='0 2147483647'
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
ci/build-1-autotools.sh
|
||||
ci/build-4-compile.sh
|
||||
ci/test-tarball.sh
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
set -ex
|
||||
PATH=`pwd`/src:$PATH
|
||||
# avoid pinging internet hosts because it doesn't
|
||||
# work with GitHub Actions being hosted in Azure.
|
||||
prove $(ls ci/test-*.pl|grep -v internet-hosts)
|
||||
ci/run-lcov.sh
|
||||
|
||||
- name: Coveralls
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
path-to-lcov: lcov.info
|
||||
flag-name: ${{ matrix.os }}
|
||||
parallel: true
|
||||
|
||||
|
||||
|
||||
Test-Mac:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew install automake lcov
|
||||
ci/build-2-test-command.sh
|
||||
ci/build-3-prepare-macos.sh
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
ci/build-4-compile.sh
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
set -ex
|
||||
PATH=`pwd`/src:$PATH
|
||||
export SKIP_IPV6=1
|
||||
prove $(ls ci/test-*.pl|grep -v internet-hosts)
|
||||
ci/run-lcov.sh
|
||||
|
||||
- name: Coveralls
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
path-to-lcov: lcov.info
|
||||
flag-name: macos
|
||||
parallel: true
|
||||
|
||||
Coveralls-Finish:
|
||||
needs: [Test-Linux, Test-Mac]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Coveralls
|
||||
uses: coverallsapp/github-action@master
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
parallel-finished: true
|
||||
|
||||
Release-Tarball:
|
||||
needs: [Test-Linux, Test-Mac]
|
||||
if: ${{ github.event_name == 'push' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install libcap2-bin libtest-command-perl
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
ci/build-1-autotools.sh
|
||||
ci/build-4-compile.sh
|
||||
ci/test-tarball.sh
|
||||
|
||||
- uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: dist
|
||||
path: fping-*.tar.gz
|
@ -1,98 +1,40 @@
|
||||
# travis-ci.org configuration
|
||||
#
|
||||
language: generic
|
||||
|
||||
os:
|
||||
- linux
|
||||
|
||||
dist:
|
||||
- trusty
|
||||
- xenial
|
||||
|
||||
sudo: required
|
||||
dist: trusty
|
||||
env:
|
||||
global:
|
||||
- secure: "CoI8hwHH1yfQoQxIfWGRS0WfTyScox+5aJn0fDDgz2uKrrIxmBvIw/WKX8wcSiV6fLmLuwgNkKqSM3hdO4qaG+JxfWcuEiZZHm+kxSGMkWbGb/fvAI+gHg8ldKyYttcIX71O5rlZiC2QpNKQi2v18S6pI5p8eqnx7DYx4YrmguQ="
|
||||
# The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
|
||||
# via the "travis encrypt" command using the project repo's public key
|
||||
- secure: "C9ZJ9LYnuowRdF4D66KLfquimvu8GtRGIafwvCcGYKReEy8phlBdFsHlybkMBNYJNTJSM0j6wyo1lKTVGHxmpQDimjR7kmxUtawbhuJ5qOCBtFqNVh9lRQi7hC4+UOhvRsIcbV8HAJM5u/5RxGOfXCePK3a2DtiYv1d2NHToZN8="
|
||||
|
||||
notifications:
|
||||
webhooks: https://coveralls.io/webhook
|
||||
|
||||
compiler:
|
||||
- gcc
|
||||
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
packages:
|
||||
- libcap2-bin
|
||||
- libtest-command-perl
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get install libcap2-bin
|
||||
#- sudo apt-get install traceroute
|
||||
#- traceroute google.com
|
||||
- echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
|
||||
install:
|
||||
- ci/build-1-autotools.sh
|
||||
- curl -L http://cpanmin.us | perl - --sudo App::cpanminus
|
||||
- cpanm --sudo Test::Command
|
||||
script:
|
||||
- ci/build-4-compile.sh
|
||||
- ci/run-tests.sh
|
||||
|
||||
- ci/build-2-install.sh
|
||||
- env PATH=`pwd`/src:$PATH prove ci/test-*.pl
|
||||
- ci/test-tarball.sh
|
||||
after_success:
|
||||
- ci/deploy-coveralls.sh
|
||||
|
||||
stages:
|
||||
- test
|
||||
- name: deploy
|
||||
if: branch = master OR branch = v4.x
|
||||
- name: coverity
|
||||
if: branch = master OR branch = coverity_scan
|
||||
|
||||
jobs:
|
||||
include:
|
||||
#### STAGE: test
|
||||
- stage: test
|
||||
name: test trusty
|
||||
os: linux
|
||||
dist: trusty
|
||||
env:
|
||||
- SKIP_IPV6=1
|
||||
install:
|
||||
- ci/build-1-autotools.sh
|
||||
|
||||
- name: test xenial
|
||||
os: linux
|
||||
dist: xenial
|
||||
env:
|
||||
- SKIP_IPV6=1
|
||||
|
||||
- name: test bionic
|
||||
os: linux
|
||||
dist: bionic
|
||||
env:
|
||||
- SKIP_IPV6=1
|
||||
|
||||
- name: test bionic lxd arm64
|
||||
os: linux
|
||||
dist: bionic
|
||||
arch: arm64
|
||||
|
||||
- name: test macos
|
||||
os: osx
|
||||
install:
|
||||
- ci/build-2-test-command.sh
|
||||
- ci/build-3-prepare-macos.sh
|
||||
env:
|
||||
- SKIP_IPV6=1
|
||||
|
||||
#### STAGE: deploy
|
||||
- stage: deploy
|
||||
name: deploy
|
||||
os: linux
|
||||
dist: xenial
|
||||
env:
|
||||
- SKIP_IPV6=1
|
||||
after_success:
|
||||
- ci/coveralls.sh
|
||||
- ci/deploy-bintray.sh
|
||||
|
||||
#### STAGE: coverity
|
||||
- stage: coverity
|
||||
name: coverity
|
||||
os: linux
|
||||
dist: xenial
|
||||
after_success:
|
||||
script:
|
||||
- ci/deploy-coverity.sh
|
||||
addons:
|
||||
coverity_scan:
|
||||
project:
|
||||
name: "schweikert/fping"
|
||||
description: "Build submitted via Travis CI"
|
||||
notification_email: david@schweikert.ch
|
||||
#build_command_prepend: "ci/build-2-install.sh"
|
||||
build_command: "ci/build-2-install.sh"
|
||||
branch_pattern: coverity_scan
|
||||
|
@ -1,35 +0,0 @@
|
||||
{
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug fping",
|
||||
"type": "cppdbg",
|
||||
"request": "launch",
|
||||
"program": "${workspaceFolder}/src/fping",
|
||||
"args": ["127.0.0.1"],
|
||||
"stopAtEntry": false,
|
||||
"cwd": "${workspaceFolder}",
|
||||
"environment": [],
|
||||
"externalConsole": false,
|
||||
"MIMode": "gdb",
|
||||
"setupCommands": [
|
||||
{
|
||||
"description": "Enable pretty-printing for gdb",
|
||||
"text": "-enable-pretty-printing",
|
||||
"ignoreFailures": true
|
||||
},
|
||||
{
|
||||
"description": "Set Disassembly Flavor to Intel",
|
||||
"text": "-gdb-set disassembly-flavor intel",
|
||||
"ignoreFailures": true
|
||||
}
|
||||
],
|
||||
"preLaunchTask": "build",
|
||||
"postDebugTask": "autoclean",
|
||||
"miDebuggerPath": "/usr/bin/gdb",
|
||||
"logging": {
|
||||
"engineLogging": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"version": "2.0.0"
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
{
|
||||
"tasks": [
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "autogen",
|
||||
"command": "./autogen.sh",
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "configure",
|
||||
"command": "./configure",
|
||||
"args": ["--enable-debug"],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"dependsOn": ["autogen"],
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "build",
|
||||
"command": "make",
|
||||
"args": ["CFLAGS=\"-g -O0\""],
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"dependsOn": ["configure"],
|
||||
"problemMatcher": ["$gcc"]
|
||||
},
|
||||
{
|
||||
"type": "shell",
|
||||
"label": "autoclean",
|
||||
"command": "./autoclean.sh",
|
||||
"problemMatcher": []
|
||||
}
|
||||
],
|
||||
"version": "2.0.0"
|
||||
}
|
@ -1,246 +0,0 @@
|
||||
fping 5.2 (2024-04-21)
|
||||
======================
|
||||
|
||||
## New features
|
||||
|
||||
- New option -X / --fast-reachable to exit immediately once N hosts have been
|
||||
found (#260, thanks @chriscray and @gsnw)
|
||||
|
||||
- New option -k / -fwmark to set Linux fwmark mask (#289, thanks @tomangert and
|
||||
@deepkv)
|
||||
|
||||
## Bugfixes and other changes
|
||||
|
||||
- Always output fatal error messages (#303, thanks @auerswal)
|
||||
- Fallback to SO\_TIMESTAMP if SO\_TIMESTAMPNS is not available (#279, thanks
|
||||
@gsnw)
|
||||
- Fix "not enough sequence numbers available" error on BSD-like systems (#307,
|
||||
thanks @cagney, @gsnw)
|
||||
- Fix running in unprivileged mode (#248, thanks @sfan5)
|
||||
- Fix build issue for NetBSD/alpha (#255, thanks @0-wiz-0)
|
||||
- Fix build issue for OpenBSD/alpha (#275, thanks @gsnw)
|
||||
- Fix build warning for long int usage (#258, thanks @gsnw)
|
||||
- Fix build error with musl libc (#263, thanks @kraj)
|
||||
- Fix to guard against division by zero (#293, thanks @auerswal)
|
||||
- Decouple -a/-u effects from -c (#298, thanks @auerswal)
|
||||
- Added contrib/Dockerfile (#224, thanks @darless)
|
||||
- Remove host from Netdata chart titles (#253, thanks @ilyam8)
|
||||
- Add additional tests (#292, #297, thanks @auerswal)
|
||||
- Update github action os images (#282, thanks @gsnw)
|
||||
- Fix Azure pipeline tests (#308, thanks @gsnw)
|
||||
- Various autoconf fixes (#286, #283, thanks @gsnw)
|
||||
- Extended configure script with --enable-debug and output cpu usage (#311,
|
||||
thanks @gsnw)
|
||||
- Documentation: Update Netdata website link (#257, thanks @ilyam8)
|
||||
- Documentation: fix description of --file option (#268, thanks @MohGeek)
|
||||
- Documentation: improve exit status description (#294, thanks @auerswal)
|
||||
- Documentation: move description of -i MSEC (#298, thanks @auerswal)
|
||||
- Documentation: improve help output for options -c and -C (#302, #auerswal)
|
||||
|
||||
|
||||
fping 5.1 (2022-02-06)
|
||||
======================
|
||||
|
||||
## Bugfixes and other changes
|
||||
|
||||
- Use setcap to specify specific files in fping.spec (#232, thanks @zdyxry)
|
||||
- Netdata: use host instead name as family label (#226, thanks @k0ste)
|
||||
- Netdata: use formatstring macro PRId64 (#229, thanks @gsnw)
|
||||
- Allow -4 option to be given multiple times (#215, thanks @normanr)
|
||||
- Documentation fix (#208, thanks @timgates42)
|
||||
- Retain privileges until after privileged setsockopt (#200, thanks @simetnicbr)
|
||||
- Set bind to source only when option is set (#198, thanks @dinoex)
|
||||
- Update Azure test pipeline (#197, thanks @gsnw)
|
||||
- Fix getnameinfo not called properly for IPv4 (#227, thanks @aafbsd)
|
||||
- Fixed wrong timestamp under Free- and OpenBSD and macOS (#217, thanks @gsnw)
|
||||
- Documentation updates (#240, thanks @auerswal)
|
||||
- Updated autotools (autoconf 2.71, automake 1.16.5, libtool 2.4.6)
|
||||
|
||||
|
||||
fping 5.0 (2020-08-05)
|
||||
======================
|
||||
|
||||
## Incompatible Changes
|
||||
|
||||
- In non-quiet loop and count mode, a line is printed for every lost packet
|
||||
(#175, thanks @kbucheli):
|
||||
|
||||
```
|
||||
$ fping -D -c2 8.8.8.8 8.8.8.7
|
||||
[1596092373.18423] 8.8.8.8 : [0], 64 bytes, 12.8 ms (12.8 avg, 0% loss)
|
||||
[1596092374.18223] 8.8.8.7 : [0], timed out (NaN avg, 100% loss)
|
||||
[1596092374.18424] 8.8.8.8 : [1], 64 bytes, 12.3 ms (12.5 avg, 0% loss)
|
||||
[1596092375.18344] 8.8.8.7 : [1], timed out (NaN avg, 100% loss)
|
||||
|
||||
8.8.8.8 : xmt/rcv/%loss = 2/2/0%, min/avg/max = 12.3/12.5/12.8
|
||||
8.8.8.7 : xmt/rcv/%loss = 2/0/100%
|
||||
```
|
||||
|
||||
- The returned size in bytes now always excludes the IP header, so if before it
|
||||
reported '84 bytes' e.g. when using 'fping -l', now it reports '64 bytes'.
|
||||
This is to make the reported size consistent with ping(8) from iputils and
|
||||
also with fping when pinging a IPv6 host (which never included the IPv6
|
||||
header size).
|
||||
|
||||
## New features
|
||||
|
||||
- The number of sent pings is only counted when the pings are received or have
|
||||
timed out, ensuring that the loss ratio will be always correct. This makes it
|
||||
possible, for example, to use loop mode (-l) with interval statistics (-Q)
|
||||
and a timeout larger than period, without having the issue that initially
|
||||
some pings would be reported as missing (#193)
|
||||
|
||||
- Improved precision of measurements from 10us to 1us (#136, thanks @tycho)
|
||||
|
||||
## Bugfixes and other changes
|
||||
|
||||
- The reported size of received packets is now always correct on Linux even for
|
||||
packets > 4096 bytes (#180)
|
||||
|
||||
- Travis CI automated testing now also macos testing and additional ubuntu
|
||||
distributions (#196)
|
||||
|
||||
fping 4.4 (2020-07-24)
|
||||
======================
|
||||
## Bugfixes and other changes
|
||||
|
||||
- Fix wrong ident used for normal (non-unprivileged) pings (#191, thanks @tycho)
|
||||
- Fix build with --disable-ipv6 (#187, thanks Polynomial-C)
|
||||
|
||||
fping 4.3 (2020-07-11)
|
||||
======================
|
||||
|
||||
## New features
|
||||
|
||||
- Linux unprivileged ping support (#173, thanks @tycho)
|
||||
- Add SIGQUIT summary support similar to ping (#185, thanks @laddp)
|
||||
|
||||
## Bugfixes and other changes
|
||||
|
||||
- Corrected long option name of -s to --stats (#148, thanks @wopfel)
|
||||
- Do not fail if using fping6 with -6 flag (#149, thanks @stromnet)
|
||||
- Fail if interface binding (-I) does not work (#162, thanks @kbucheli)
|
||||
- Fix using option -4 when fping is compiled IPv4-only (#154, thanks @pbhenson)
|
||||
- Add Azure pipeline test build (#153 and #170, thanks @gsnw)
|
||||
- GCC 10 compatibility fixes (#167 and #168, thanks @cranderson)
|
||||
- Macos build fix (#174, thanks @tycho)
|
||||
- Fix xmt stats in Netdata output (#172, thanks @vlvkobal)
|
||||
- Only increase num_alive if response is not a duplicate (#151, thanks @brownowski)
|
||||
- Use line buffering for stdout (#179, thanks @bg6cq)
|
||||
|
||||
fping 4.2 (2019-02-19)
|
||||
======================
|
||||
|
||||
## New features
|
||||
|
||||
- New option -x / --reachable to check if the number of reachable hosts is >= a certain
|
||||
number. Useful for example to implement connectivity-checks (#138, thanks @deepak0004)
|
||||
|
||||
## Bugfixes and other changes
|
||||
|
||||
- Allow decimal numbers for '-t', '-i', '-p', and '-Q'
|
||||
- Fix build with --disable-ipv6 (#134, thanks @Polynomial-C)
|
||||
- Fix hang with '-6', with ipv6 kernel module, but not loaded (#140, thanks @abelbeck)
|
||||
- Assume '-6' if the binary is named 'fping6' (this is mostly for special
|
||||
embedded-distro use cases, and not meant to be used generally in place of
|
||||
compiling IPv6-only binary or using '-6', see also the notes in #139, thanks
|
||||
abelbeck)
|
||||
- Get rid of warning "timeout (-t) value larger than period (-p) produces unexpected results"
|
||||
(#142, thanks @MrDragon1122)
|
||||
|
||||
|
||||
fping 4.1 (2018-09-17)
|
||||
======================
|
||||
|
||||
## Bugfixes and other changes
|
||||
|
||||
- Fix problem when socket fd is 0 (#125, thanks Ramón Novoa!)
|
||||
- Fix running on servers with disabled IPv6 (#118, thanks Simon Matter)
|
||||
- Allow running "fping -h" or "--help" even when raw socket can't be opened (#131, thanks @teto)
|
||||
- Fix build issue with FreeBSD and IPv6 (#132, thanks @gsnw)
|
||||
|
||||
fping 4.0 (2017-04-23)
|
||||
======================
|
||||
|
||||
## Incompatible Changes
|
||||
|
||||
##### fping and fping6 unification
|
||||
|
||||
fping and fping6 are now unified into one binary. It means that, for example,
|
||||
doing 'fping google.com' is going to ping the IPv6 IP of google.com on
|
||||
IPv6-enabled hosts.
|
||||
|
||||
If you need exact compatibility with old versions, you can configure and
|
||||
install fping twice: once for ipv4, and once for ipv6:
|
||||
|
||||
./configure --disable-ipv6; make clean install
|
||||
./configure --disable-ipv4 --program-suffix=6; make clean install
|
||||
|
||||
##### Option -n, not the same as -d anymore
|
||||
|
||||
Option -n / --name is now doing a reverse-DNS lookups on host addresses,
|
||||
only if they are given as IP address, but not for hostnames. For example,
|
||||
if you write 'fping -n google.com', fping would previously do a
|
||||
forward-DNS lookup on google.com, and then a reverse-DNS lookup on the
|
||||
resolved IP address. Now, it is just going to keep the name 'google.com'.
|
||||
That same behavior can be achieved with the option -d / --rdns (which was
|
||||
previously an alias for -n).
|
||||
|
||||
fping<4.0 fping>=4.0
|
||||
fping -n NAME NAME->IP->IPNAME NAME
|
||||
fping -d NAME NAME->IP->IPNAME NAME->IP->IPNAME
|
||||
|
||||
##### Discarding of late packets
|
||||
|
||||
fping will now discard replies, if they arrive after the defined timeout
|
||||
for reply packets, specified with -t. This change is relevant only for the
|
||||
count and loop modes, where the measured times should be now more
|
||||
consistent (see github issue [#32][i32] for details).
|
||||
|
||||
To prevent loosing reply packets because of this change, the default
|
||||
timeout in count and loop modes is now automatically adjusted to the
|
||||
period interval (up to 2000 ms), but it can be overriden with the -t
|
||||
option. The default timeout for non-loop/count modes remains 500 ms.
|
||||
|
||||
##### No restrictions by default
|
||||
|
||||
fping will not enforce -i >= 1 and -p >= 10 anymore, except if you
|
||||
'./configure --enable-safe-limits'.
|
||||
|
||||
The reasoning to removing the restrictions by default, is that users can
|
||||
clog the network with other tools anyway, and these restrictions are
|
||||
sometimes getting in the way (for example if you try to ping a lot of
|
||||
hosts).
|
||||
|
||||
##### Default interval (-i) changed from 25ms to 10ms
|
||||
|
||||
The default minimum interval between ping probes has been changed from
|
||||
25ms to 10ms. The reason is that 25ms is very high, considering today's
|
||||
fast networks: it generates at most 31 kbps of traffic (for IPv4 and
|
||||
default payload size).
|
||||
|
||||
## New features
|
||||
|
||||
- Unified 'fping' and 'fping6' into one binary ([#80][i80])
|
||||
- Long option names for all options
|
||||
- IPv6 enabled by default
|
||||
- New option -4 to force IPv4
|
||||
- New option -6 to force IPv6
|
||||
- Keep original name if a hostname is given with -n/--name
|
||||
- Option -d/--rdns now always does a rdns-lookup, even for names, as '-n' was doing until now
|
||||
- Enforce -t timeout on reply packets, by discarding late packets ([#32][i32])
|
||||
- Auto-adjust timeout for -c/-C/-l mode to value of -p
|
||||
|
||||
## Bugfixes and other changes
|
||||
|
||||
- -i/-p restrictions disabled by default (enable with --enable-safe-limits)
|
||||
- Default interval -i changed from 25ms to 10ms
|
||||
- Fix compatibility issue with GNU Hurd
|
||||
- A C99 compiler is now required
|
||||
- Option parsing with optparse (https://github.com/skeeto/optparse). Thanks Christopher Wellons!
|
||||
- New changelog file format
|
||||
|
||||
[i32]: https://github.com/schweikert/fping/issues/32
|
||||
[i80]: https://github.com/schweikert/fping/issues/80
|
||||
|
||||
(see doc/CHANGELOG.pre-v4 for older changes)
|
@ -1,3 +1,7 @@
|
||||
Unreleased (version 3 branch)
|
||||
* Fix portability issue with GNU Hurd
|
||||
* Fix C89 portability issue
|
||||
|
||||
2017-02-09 David Schweikert <david@schweikert.ch>
|
||||
* Version 3.16
|
||||
* (feature) Support kernel-timestamping of received packets (#46)
|
@ -0,0 +1,55 @@
|
||||
fping 3 README
|
||||
--------------
|
||||
fping is a program to send ICMP echo probes to network hosts, similar to ping,
|
||||
but much better performing when pinging multiple hosts. fping has a long long
|
||||
story: Roland Schemers did publish a first version of it in 1992 and it has
|
||||
established itself since then as a standard tool.
|
||||
|
||||
Current maintainer:
|
||||
David Schweikert <david@schweikert.ch>
|
||||
|
||||
Website:
|
||||
http://fping.org/
|
||||
|
||||
Mailing-list:
|
||||
https://groups.google.com/group/fping-users
|
||||
|
||||
|
||||
Installation
|
||||
------------
|
||||
If you want to install fping from source, proceed as follows:
|
||||
|
||||
0. Run ./autogen.sh
|
||||
(only if you got the source from github)
|
||||
|
||||
1. Run ./configure with the correct arguments
|
||||
(see: ./configure --help)
|
||||
|
||||
2. Run make; make install
|
||||
|
||||
3. Make fping either setuid, or, if under Linux:
|
||||
|
||||
sudo setcap cap_net_raw+ep fping
|
||||
|
||||
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
|
||||
is used for that, called fping6. To build it, use ./configure --enable-ipv6
|
||||
(possibly combined with --enable-ipv4 to also build fping for IPv4). E.g.:
|
||||
|
||||
# ./configure --prefix=/usr/local --enable-ipv4 --enable-ipv6
|
||||
# make
|
||||
# make install
|
||||
# sudo setcap cap_net_raw+ep /usr/local/bin/fping*
|
||||
|
||||
|
||||
Credits
|
||||
-------
|
||||
Original author: Roland Schemers (schemers@stanford.edu)
|
||||
Previous maintainer: RL "Bob" Morgan (morgan@stanford.edu)
|
||||
Initial IPv6 Support: Jeroen Massar (jeroen@unfix.org / jeroen@ipng.nl)
|
||||
Other contributors: see ChangeLog
|
@ -1,52 +0,0 @@
|
||||
jobs:
|
||||
- job: linux_build
|
||||
displayName: Linux Build
|
||||
|
||||
pool:
|
||||
name: Azure Pipelines
|
||||
vmImage: 'ubuntu-latest'
|
||||
workspace:
|
||||
clean: all
|
||||
steps:
|
||||
- script: |
|
||||
sudo apt-get update -qq
|
||||
sudo apt-get install libcap2-bin libtest-command-perl
|
||||
displayName: 'before_install'
|
||||
|
||||
- script: |
|
||||
ci/build-4-compile.sh
|
||||
displayName: install
|
||||
|
||||
- script: |
|
||||
set -ex
|
||||
PATH=`pwd`/src:$PATH
|
||||
prove $(ls ci/test-*.pl|grep -v internet-hosts|grep -v -E "test-13-unknown-host.pl|test-14-ping-internet-hosts.pl")
|
||||
ci/test-tarball.sh
|
||||
displayName: 'build_test'
|
||||
|
||||
- job: macos_build
|
||||
displayName: macOS Build
|
||||
|
||||
pool:
|
||||
name: Azure Pipelines
|
||||
vmImage: 'macos-latest'
|
||||
workspace:
|
||||
clean: all
|
||||
steps:
|
||||
- script: |
|
||||
brew install autoconf automake lcov
|
||||
ci/build-2-test-command.sh
|
||||
ci/build-3-prepare-macos.sh
|
||||
displayName: 'before_install'
|
||||
|
||||
- script: |
|
||||
ci/build-4-compile.sh
|
||||
displayName: install
|
||||
|
||||
- script: |
|
||||
set -ex
|
||||
PATH=`pwd`/src:$PATH
|
||||
export SKIP_IPV6=1
|
||||
prove $(ls ci/test-*.pl|grep -v internet-hosts|grep -v test-10-option-u-x.pl)
|
||||
ci/run-lcov.sh
|
||||
displayName: 'build_test'
|
@ -1,6 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -ex
|
||||
|
||||
curl -L http://cpanmin.us | perl - -L $HOME/perl5 App::cpanminus
|
||||
$HOME/perl5/bin/cpanm --sudo Test::Command
|
@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -x
|
||||
|
||||
sudo -H pip install cpp-coveralls
|
||||
|
||||
cd src
|
||||
|
||||
ls -l
|
||||
|
||||
gcov *.o
|
||||
cd ..
|
||||
coveralls --exclude ci --no-gcov
|
@ -1,16 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -xe
|
||||
|
||||
if [ "$TRAVIS_DIST" = "trusty" ]; then
|
||||
echo "skip coveralls on trusty because coveralls errors out due to python issues"
|
||||
exit 0
|
||||
elif [ "$TRAVIS_OS_NAME" = "osx" ]; then
|
||||
pip3 install --user cpp-coveralls
|
||||
PATH="${PATH}:$(python3 -c 'import site; print(site.USER_BASE)')/bin"
|
||||
else
|
||||
pip install --user cpp-coveralls
|
||||
fi
|
||||
|
||||
export COVERALLS_PARALLEL=true
|
||||
coveralls --build-root src --exclude src/optparse.c --exclude ci --exclude config.h --gcov-options '\-lp'
|
@ -1,25 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
COVERITY_SCAN_PROJECT_NAME=schweikert/fping
|
||||
COVERITY_SCAN_EMAIL=david@schweikert.ch
|
||||
|
||||
if [ -z "$COVERITY_SCAN_TOKEN" ]; then
|
||||
echo "ERROR: COVERITY_SCAN_TOKEN not defined." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
curl -o /tmp/cov-analysis-linux64.tgz https://scan.coverity.com/download/linux64 \
|
||||
--form project=$COVERITY_SCAN_PROJECT_NAME --form token=$COVERITY_SCAN_TOKEN
|
||||
tar xfz /tmp/cov-analysis-linux64.tgz
|
||||
./autogen.sh
|
||||
./configure --enable-ipv4 --enable-ipv6 --enable-safe-limits --prefix=/opt/fping
|
||||
cov-analysis-linux64-*/bin/cov-build --dir cov-int make -j4
|
||||
tar cfz cov-int.tar.gz cov-int
|
||||
curl https://scan.coverity.com/builds?project=$COVERITY_SCAN_PROJECT_NAME \
|
||||
--form token=$COVERITY_SCAN_TOKEN \
|
||||
--form email=$COVERITY_SCAN_EMAIL \
|
||||
--form file=@cov-int.tar.gz \
|
||||
--form version="`git rev-parse --short HEAD`" \
|
||||
--form description="`git rev-parse --short HEAD` / $TRAVIS_BUILD_ID "
|
@ -1,7 +1,9 @@
|
||||
#!/bin/bash
|
||||
|
||||
sudo setcap cap_net_raw,cap_net_admin+ep src/fping
|
||||
sudo setcap cap_net_raw+ep src/fping
|
||||
sudo setcap cap_net_raw+ep src/fping6
|
||||
|
||||
if [[ ! $PATH =~ fping/src ]]; then
|
||||
PATH=/home/dws/checkouts/fping/src:$PATH
|
||||
echo "# WARNING: must set PATH:"
|
||||
echo PATH=/home/dws/checkouts/fping/src:\$PATH
|
||||
fi
|
||||
|
@ -1,9 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
lcov -c -no-external \
|
||||
-d . \
|
||||
-b src \
|
||||
-o lcov-all.info
|
||||
|
||||
lcov --remove lcov-all.info -o lcov.info \
|
||||
'*/optparse.c'
|
@ -1,8 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -ex
|
||||
|
||||
PATH=`pwd`/src:$PATH
|
||||
|
||||
prove ci/test-*.pl
|
||||
ci/test-tarball.sh
|
@ -1,40 +1,68 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 12;
|
||||
use Test::Command tests => 9;
|
||||
|
||||
my $I_HELP = " -I, --iface=IFACE bind to a particular interface\n";
|
||||
my $I_HELP = " -I if bind to a particular interface\n";
|
||||
$I_HELP = '' if $^O eq 'darwin';
|
||||
|
||||
# fping -h (special pre-parse code path)
|
||||
# fping -h
|
||||
my $cmd1 = Test::Command->new(cmd => "fping -h");
|
||||
$cmd1->exit_is_num(0);
|
||||
$cmd1->stdout_like(qr{Usage: fping \[options\] \[targets\.\.\.\]
|
||||
$cmd1->stdout_is_eq(<<END);
|
||||
|
||||
Probing options:
|
||||
.*
|
||||
-v, --version show version
|
||||
}s);
|
||||
$cmd1->stderr_is_eq("");
|
||||
|
||||
# fping -4 -h (normal option parsing code path)
|
||||
my $cmd4 = Test::Command->new(cmd => "fping -4 -h");
|
||||
$cmd4->exit_is_num(0);
|
||||
$cmd4->stdout_like(qr{Usage: fping \[options\] \[targets\.\.\.\]
|
||||
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_HELP} -l loop sending pings forever
|
||||
-m use all IPs of provided hostnames (e.g. IPv4 and IPv6), use with -A
|
||||
-M set the Don't Fragment flag
|
||||
-n show targets by name (-d is equivalent)
|
||||
-N output compatible for netdata (-l -Q are required)
|
||||
-o show the accumulated outage time (lost packets * packet interval)
|
||||
-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)
|
||||
-R random packet data (to foil link data compression)
|
||||
-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)
|
||||
|
||||
Probing options:
|
||||
.*
|
||||
-v, --version show version
|
||||
}s);
|
||||
$cmd4->stderr_is_eq("");
|
||||
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+});
|
||||
$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_like(qr{^fping: (illegal|invalid) option -- '?Z'?\nsee 'fping -h' for usage information\n$});
|
||||
if($^O eq 'darwin') {
|
||||
$cmd3->stderr_is_eq("fping: illegal option -- Z\nsee 'fping -h' for usage information\n");
|
||||
}
|
||||
else {
|
||||
$cmd3->stderr_is_eq("fping: invalid option -- 'Z'\nsee 'fping -h' for usage information\n");
|
||||
}
|
||||
|
@ -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+(-rc\d+)?
|
||||
fping: comments to david\@schweikert\.ch
|
||||
});
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 15;
|
||||
|
||||
# -u show targets that are unreachable
|
||||
# -v show version
|
||||
# -x shows if >=N hosts are reachable or not
|
||||
# -X exits true immediately when N hosts are found
|
||||
|
||||
# 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 [45]\.\d+(-rc\d+)?});
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -x
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -x 1 8.8.0.0 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("Enough hosts reachable (required: 1, reachable: 1)\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -x
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -x 2 8.8.0.0 127.0.0.1");
|
||||
$cmd->exit_is_num(1);
|
||||
$cmd->stdout_is_eq("Not enough hosts reachable (required: 2, reachable: 1)\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
|
||||
# fping -X
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping -X 1 --generate 127.0.0.0/29");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("Enough hosts reachable (required: 1, reachable: 1)\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command;
|
||||
use Test::More;
|
||||
|
||||
if( $^O eq 'darwin' ) {
|
||||
plan skip_all => 'Test irrelevant on MacOS';
|
||||
exit 0;
|
||||
}
|
||||
plan 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{: 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{: can't create raw socket \(must run as root\?\) : .*\n});
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use English;
|
||||
use Test::Command;
|
||||
use Test::More;
|
||||
|
||||
if( $^O eq 'darwin' ) {
|
||||
plan skip_all => 'Test irrelevant on MacOS';
|
||||
exit 0;
|
||||
}
|
||||
|
||||
sub get_ping_gid_range {
|
||||
open FD, "/proc/sys/net/ipv4/ping_group_range" or return undef;
|
||||
chomp(my $line = <FD>);
|
||||
my @range = split(/\s+/, $line);
|
||||
close FD;
|
||||
return @range;
|
||||
}
|
||||
|
||||
my @gids = split(' ', $EGID);
|
||||
my @allowed = get_ping_gid_range();
|
||||
|
||||
# Make a copy of the binary so that we get rid of setuid bit
|
||||
my $fping_bin = `which fping`; chomp $fping_bin;
|
||||
system("cp $fping_bin /tmp/fping.copy; chmod +x /tmp/fping.copy");
|
||||
|
||||
# Determine what test to run, based on whether unprivileged
|
||||
# pings are allowed.
|
||||
if(scalar grep { $_ >= $allowed[0] && $_ <= $allowed[1] } @gids) {
|
||||
diag('test unprivileged mode');
|
||||
test_unprivileged_works();
|
||||
}
|
||||
else {
|
||||
test_privileged_fails();
|
||||
}
|
||||
|
||||
sub test_unprivileged_works {
|
||||
plan tests => 3;
|
||||
|
||||
{
|
||||
my $cmd = Test::Command->new(cmd => "fping 127.0.0.1");
|
||||
$cmd->exit_is_num(0);
|
||||
$cmd->stdout_is_eq("127.0.0.1 is alive\n");
|
||||
$cmd->stderr_is_eq("");
|
||||
}
|
||||
}
|
||||
|
||||
sub test_privileged_fails {
|
||||
plan tests => 3;
|
||||
|
||||
{
|
||||
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{: can't create socket \(must run as root\?\)});
|
||||
}
|
||||
}
|
@ -1,27 +1,10 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
use Test::Command tests => 84;
|
||||
use Test::More;
|
||||
use Test::Command tests => 33;
|
||||
|
||||
# some options require a numeric argument
|
||||
for my $arg (qw(b B c C H i O p Q r t x X)) {
|
||||
for my $test_input (qw(xxx '')) {
|
||||
my $cmd = Test::Command->new(cmd => "fping -$arg $test_input");
|
||||
for my $arg (qw(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:});
|
||||
}
|
||||
}
|
||||
|
||||
# fping -k, only supported on Linux, requires a number
|
||||
SKIP: {
|
||||
if($^O ne 'linux') {
|
||||
skip '-k option is only supported on Linux', 6;
|
||||
}
|
||||
for my $test_input (qw(xxx '')) {
|
||||
my $cmd = Test::Command->new(cmd => "fping -k $test_input 127.0.0.1");
|
||||
$cmd->exit_is_num(1);
|
||||
$cmd->stdout_is_eq("");
|
||||
$cmd->stderr_like(qr{Usage:});
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +0,0 @@
|
||||
FROM ubuntu:20.04
|
||||
|
||||
# Base
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential \
|
||||
automake \
|
||||
m4
|
||||
|
||||
# Add source code
|
||||
COPY ./ /app
|
||||
|
||||
# Compile
|
||||
WORKDIR /app
|
||||
RUN autoreconf --install
|
||||
RUN ./configure && make && make install
|
||||
ENTRYPOINT ["fping"]
|
@ -1,6 +1,17 @@
|
||||
man_MANS = fping.8
|
||||
man_MANS =
|
||||
|
||||
EXTRA_DIST = fping.8 fping.pod README.1992 CHANGELOG.pre-v4
|
||||
if IPV4
|
||||
man_MANS += fping.8
|
||||
endif
|
||||
|
||||
if IPV6
|
||||
man_MANS += fping6.8
|
||||
endif
|
||||
|
||||
EXTRA_DIST = fping.8 fping6.8 fping.pod README.1992
|
||||
|
||||
fping.8: fping.pod
|
||||
pod2man -c "" -s 8 -r "fping" $< >$@
|
||||
|
||||
fping6.8: fping.pod
|
||||
pod2man -c "" -s 8 -r "fping" -n fping6 $< >$@
|
||||
|
@ -1,11 +1,18 @@
|
||||
AM_CFLAGS = -Wall -Wextra -Wno-sign-compare
|
||||
|
||||
sbin_PROGRAMS = fping
|
||||
|
||||
fping_SOURCES = fping.c seqmap.c socket4.c fping.h options.h seqmap.h optparse.c optparse.h
|
||||
fping_DEPENDENCIES = ../config.h
|
||||
prog =
|
||||
|
||||
if IPV4
|
||||
prog += fping
|
||||
endif
|
||||
if IPV6
|
||||
fping_SOURCES += socket6.c
|
||||
fping_CFLAGS = $(AM_CFLAGS) -DIPV6
|
||||
prog += fping6
|
||||
endif
|
||||
|
||||
sbin_PROGRAMS = ${prog}
|
||||
|
||||
fping_SOURCES = fping.c seqmap.c socket.c socket4.c fping.h options.h seqmap.h
|
||||
fping_DEPENDENCIES = ../config.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
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
||||
ctags -R --fields=+S /usr/include ..
|
@ -1,266 +0,0 @@
|
||||
#include "optparse.h"
|
||||
|
||||
#define MSG_INVALID "invalid option"
|
||||
#define MSG_MISSING "option requires an argument"
|
||||
#define MSG_TOOMANY "option takes no arguments"
|
||||
|
||||
static int
|
||||
opterror(struct optparse *options, const char *message, const char *data)
|
||||
{
|
||||
unsigned p = 0;
|
||||
while (*message)
|
||||
options->errmsg[p++] = *message++;
|
||||
const char *sep = " -- '";
|
||||
while (*sep)
|
||||
options->errmsg[p++] = *sep++;
|
||||
while (p < sizeof(options->errmsg) - 2 && *data)
|
||||
options->errmsg[p++] = *data++;
|
||||
options->errmsg[p++] = '\'';
|
||||
options->errmsg[p++] = '\0';
|
||||
return '?';
|
||||
}
|
||||
|
||||
void optparse_init(struct optparse *options, char **argv)
|
||||
{
|
||||
options->argv = argv;
|
||||
options->permute = 1;
|
||||
options->optind = 1;
|
||||
options->subopt = 0;
|
||||
options->optarg = 0;
|
||||
options->errmsg[0] = '\0';
|
||||
}
|
||||
|
||||
static inline int
|
||||
is_dashdash(const char *arg)
|
||||
{
|
||||
return arg != 0 && arg[0] == '-' && arg[1] == '-' && arg[2] == '\0';
|
||||
}
|
||||
|
||||
static inline int
|
||||
is_shortopt(const char *arg)
|
||||
{
|
||||
return arg != 0 && arg[0] == '-' && arg[1] != '-' && arg[1] != '\0';
|
||||
}
|
||||
|
||||
static inline int
|
||||
is_longopt(const char *arg)
|
||||
{
|
||||
return arg != 0 && arg[0] == '-' && arg[1] == '-' && arg[2] != '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
permute(struct optparse *options, int index)
|
||||
{
|
||||
char *nonoption = options->argv[index];
|
||||
for (int i = index; i < options->optind - 1; i++)
|
||||
options->argv[i] = options->argv[i + 1];
|
||||
options->argv[options->optind - 1] = nonoption;
|
||||
}
|
||||
|
||||
static int
|
||||
argtype(const char *optstring, char c)
|
||||
{
|
||||
if (c == ':')
|
||||
return -1;
|
||||
for (; *optstring && c != *optstring; optstring++);
|
||||
if (!*optstring)
|
||||
return -1;
|
||||
int count = OPTPARSE_NONE;
|
||||
if (optstring[1] == ':')
|
||||
count += optstring[2] == ':' ? 2 : 1;
|
||||
return count;
|
||||
}
|
||||
|
||||
int optparse(struct optparse *options, const char *optstring)
|
||||
{
|
||||
options->errmsg[0] = '\0';
|
||||
options->optopt = 0;
|
||||
options->optarg = 0;
|
||||
char *option = options->argv[options->optind];
|
||||
if (option == 0) {
|
||||
return -1;
|
||||
} else if (is_dashdash(option)) {
|
||||
options->optind++; /* consume "--" */
|
||||
return -1;
|
||||
} else if (!is_shortopt(option)) {
|
||||
if (options->permute) {
|
||||
int index = options->optind;
|
||||
options->optind++;
|
||||
int r = optparse(options, optstring);
|
||||
permute(options, index);
|
||||
options->optind--;
|
||||
return r;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
option += options->subopt + 1;
|
||||
options->optopt = option[0];
|
||||
int type = argtype(optstring, option[0]);
|
||||
char *next = options->argv[options->optind + 1];
|
||||
switch (type) {
|
||||
case -1: {
|
||||
options->optind++;
|
||||
char str[2] = {option[0]};
|
||||
return opterror(options, MSG_INVALID, str);
|
||||
}
|
||||
case OPTPARSE_NONE:
|
||||
if (option[1]) {
|
||||
options->subopt++;
|
||||
} else {
|
||||
options->subopt = 0;
|
||||
options->optind++;
|
||||
}
|
||||
return option[0];
|
||||
case OPTPARSE_REQUIRED:
|
||||
options->subopt = 0;
|
||||
options->optind++;
|
||||
if (option[1]) {
|
||||
options->optarg = option + 1;
|
||||
} else if (next != 0) {
|
||||
options->optarg = next;
|
||||
options->optind++;
|
||||
} else {
|
||||
options->optarg = 0;
|
||||
char str[2] = {option[0]};
|
||||
return opterror(options, MSG_MISSING, str);
|
||||
}
|
||||
return option[0];
|
||||
case OPTPARSE_OPTIONAL:
|
||||
options->subopt = 0;
|
||||
options->optind++;
|
||||
if (option[1])
|
||||
options->optarg = option + 1;
|
||||
else
|
||||
options->optarg = 0;
|
||||
return option[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *optparse_arg(struct optparse *options)
|
||||
{
|
||||
options->subopt = 0;
|
||||
char *option = options->argv[options->optind];
|
||||
if (option != 0)
|
||||
options->optind++;
|
||||
return option;
|
||||
}
|
||||
|
||||
static inline int
|
||||
longopts_end(const struct optparse_long *longopts, int i)
|
||||
{
|
||||
return !longopts[i].longname && !longopts[i].shortname;
|
||||
}
|
||||
|
||||
static void
|
||||
optstring_from_long(const struct optparse_long *longopts, char *optstring)
|
||||
{
|
||||
char *p = optstring;
|
||||
for (int i = 0; !longopts_end(longopts, i); i++) {
|
||||
if (longopts[i].shortname) {
|
||||
*p++ = longopts[i].shortname;
|
||||
for (int a = 0; a < (int)longopts[i].argtype; a++)
|
||||
*p++ = ':';
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
/* Unlike strcmp(), handles options containing "=". */
|
||||
static int
|
||||
longopts_match(const char *longname, const char *option)
|
||||
{
|
||||
if (longname == 0)
|
||||
return 0;
|
||||
const char *a = option, *n = longname;
|
||||
for (; *a && *n && *a != '='; a++, n++)
|
||||
if (*a != *n)
|
||||
return 0;
|
||||
return *n == '\0' && (*a == '\0' || *a == '=');
|
||||
}
|
||||
|
||||
/* Return the part after "=", or NULL. */
|
||||
static char *
|
||||
longopts_arg(char *option)
|
||||
{
|
||||
for (; *option && *option != '='; option++);
|
||||
if (*option == '=')
|
||||
return option + 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
long_fallback(struct optparse *options,
|
||||
const struct optparse_long *longopts,
|
||||
int *longindex)
|
||||
{
|
||||
char optstring[96 * 3 + 1]; /* 96 ASCII printable characters */
|
||||
optstring_from_long(longopts, optstring);
|
||||
int result = optparse(options, optstring);
|
||||
if (longindex != 0) {
|
||||
*longindex = -1;
|
||||
if (result != -1)
|
||||
for (int i = 0; !longopts_end(longopts, i); i++)
|
||||
if (longopts[i].shortname == options->optopt)
|
||||
*longindex = i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
optparse_long(struct optparse *options,
|
||||
const struct optparse_long *longopts,
|
||||
int *longindex)
|
||||
{
|
||||
char *option = options->argv[options->optind];
|
||||
if (option == 0) {
|
||||
return -1;
|
||||
} else if (is_dashdash(option)) {
|
||||
options->optind++; /* consume "--" */
|
||||
return -1;
|
||||
} else if (is_shortopt(option)) {
|
||||
return long_fallback(options, longopts, longindex);
|
||||
} else if (!is_longopt(option)) {
|
||||
if (options->permute) {
|
||||
int index = options->optind;
|
||||
options->optind++;
|
||||
int r = optparse_long(options, longopts, longindex);
|
||||
permute(options, index);
|
||||
options->optind--;
|
||||
return r;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse as long option. */
|
||||
options->errmsg[0] = '\0';
|
||||
options->optopt = 0;
|
||||
options->optlongname = 0;
|
||||
options->optarg = 0;
|
||||
option += 2; /* skip "--" */
|
||||
options->optind++;
|
||||
for (int i = 0; !longopts_end(longopts, i); i++) {
|
||||
const char *name = longopts[i].longname;
|
||||
if (longopts_match(name, option)) {
|
||||
options->optlongname = option;
|
||||
if (longindex)
|
||||
*longindex = i;
|
||||
options->optopt = longopts[i].shortname;
|
||||
char *arg = longopts_arg(option);
|
||||
if (longopts[i].argtype == OPTPARSE_NONE && arg != 0) {
|
||||
return opterror(options, MSG_TOOMANY, name);
|
||||
} if (arg != 0) {
|
||||
options->optarg = arg;
|
||||
} else if (longopts[i].argtype == OPTPARSE_REQUIRED) {
|
||||
options->optarg = options->argv[options->optind++];
|
||||
if (options->optarg == 0)
|
||||
return opterror(options, MSG_MISSING, name);
|
||||
}
|
||||
return options->optopt;
|
||||
}
|
||||
}
|
||||
return opterror(options, MSG_INVALID, option);
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
#ifndef OPTPARSE_H
|
||||
#define OPTPARSE_H
|
||||
|
||||
/**
|
||||
* Optparse -- portable, reentrant, embeddable, getopt-like option parser
|
||||
*
|
||||
* The POSIX getopt() option parser has three fatal flaws. These flaws
|
||||
* are solved by Optparse.
|
||||
*
|
||||
* 1) Parser state is stored entirely in global variables, some of
|
||||
* which are static and inaccessible. This means only one thread can
|
||||
* use getopt(). It also means it's not possible to recursively parse
|
||||
* nested sub-arguments while in the middle of argument parsing.
|
||||
* Optparse fixes this by storing all state on a local struct.
|
||||
*
|
||||
* 2) The POSIX standard provides no way to properly reset the parser.
|
||||
* This means for portable code that getopt() is only good for one
|
||||
* run, over one argv with one optstring. It also means subcommand
|
||||
* options cannot be processed with getopt(). Most implementations
|
||||
* provide a method to reset the parser, but it's not portable.
|
||||
* Optparse provides an optparse_arg() function for stepping over
|
||||
* subcommands and continuing parsing of options with another
|
||||
* optstring. The Optparse struct itself can be passed around to
|
||||
* subcommand handlers for additional subcommand option parsing. A
|
||||
* full reset can be achieved by with an additional optparse_init().
|
||||
*
|
||||
* 3) Error messages are printed to stderr. This can be disabled with
|
||||
* opterr, but the messages themselves are still inaccessible.
|
||||
* Optparse solves this by writing an error message in its errmsg
|
||||
* field. The downside to Optparse is that this error message will
|
||||
* always be in English rather than the current locale.
|
||||
*
|
||||
* Optparse should be familiar with anyone accustomed to getopt(), and
|
||||
* it could be a nearly drop-in replacement. The optstring is the same
|
||||
* and the fields have the same names as the getopt() global variables
|
||||
* (optarg, optind, optopt).
|
||||
*
|
||||
* Optparse also supports GNU-style long options with optparse_long().
|
||||
* The interface is slightly different and simpler than getopt_long().
|
||||
*
|
||||
* By default, argv is permuted as it is parsed, moving non-option
|
||||
* arguments to the end. This can be disabled by setting the `permute`
|
||||
* field to 0 after initialization.
|
||||
*/
|
||||
|
||||
struct optparse {
|
||||
char **argv;
|
||||
int permute;
|
||||
int optind;
|
||||
int optopt;
|
||||
char *optlongname;
|
||||
char *optarg;
|
||||
char errmsg[64];
|
||||
int subopt;
|
||||
};
|
||||
|
||||
enum optparse_argtype { OPTPARSE_NONE, OPTPARSE_REQUIRED, OPTPARSE_OPTIONAL };
|
||||
|
||||
struct optparse_long {
|
||||
const char *longname;
|
||||
int shortname;
|
||||
enum optparse_argtype argtype;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the parser state.
|
||||
*/
|
||||
void optparse_init(struct optparse *options, char **argv);
|
||||
|
||||
/**
|
||||
* Read the next option in the argv array.
|
||||
* @param optstring a getopt()-formatted option string.
|
||||
* @return the next option character, -1 for done, or '?' for error
|
||||
*
|
||||
* Just like getopt(), a character followed by no colons means no
|
||||
* argument. One colon means the option has a required argument. Two
|
||||
* colons means the option takes an optional argument.
|
||||
*/
|
||||
int optparse(struct optparse *options, const char *optstring);
|
||||
|
||||
/**
|
||||
* Handles GNU-style long options in addition to getopt() options.
|
||||
* This works a lot like GNU's getopt_long(). The last option in
|
||||
* longopts must be all zeros, marking the end of the array. The
|
||||
* longindex argument may be NULL.
|
||||
*/
|
||||
int
|
||||
optparse_long(struct optparse *options,
|
||||
const struct optparse_long *longopts,
|
||||
int *longindex);
|
||||
|
||||
/**
|
||||
* Used for stepping over non-option arguments.
|
||||
* @return the next non-option argument, or NULL for no more arguments
|
||||
*
|
||||
* Argument parsing can continue with optparse() after using this
|
||||
* function. That would be used to parse the options for the
|
||||
* subcommand returned by optparse_arg(). This function allows you to
|
||||
* ignore the value of optind.
|
||||
*/
|
||||
char *optparse_arg(struct optparse *options);
|
||||
|
||||
#endif
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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 "config.h"
|
||||
#include "fping.h"
|
||||
|
||||
int open_ping_socket_ipv4();
|
||||
int open_ping_socket_ipv6();
|
||||
void init_ping_buffer_ipv4(size_t ping_data_size);
|
||||
void init_ping_buffer_ipv6(size_t ping_data_size);
|
||||
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 socket_sendto_ping_ipv4(int s, struct sockaddr* saddr, socklen_t saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr);
|
||||
int socket_sendto_ping_ipv6(int s, struct sockaddr* saddr, socklen_t saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr);
|
||||
|
||||
int open_ping_socket()
|
||||
{
|
||||
#ifndef IPV6
|
||||
return open_ping_socket_ipv4();
|
||||
#else
|
||||
return open_ping_socket_ipv6();
|
||||
#endif
|
||||
}
|
||||
|
||||
void init_ping_buffer(size_t ping_data_size)
|
||||
{
|
||||
#ifndef IPV6
|
||||
return init_ping_buffer_ipv4(ping_data_size);
|
||||
#else
|
||||
return init_ping_buffer_ipv6(ping_data_size);
|
||||
#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
|
||||
}
|
||||
|
||||
int socket_sendto_ping(int s, struct sockaddr* saddr, socklen_t saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr)
|
||||
{
|
||||
#ifndef IPV6
|
||||
return socket_sendto_ping_ipv4(s, saddr, saddr_len, icmp_seq_nr, icmp_id_nr);
|
||||
#else
|
||||
return socket_sendto_ping_ipv6(s, saddr, saddr_len, icmp_seq_nr, icmp_id_nr);
|
||||
#endif
|
||||
}
|
@ -0,0 +1 @@
|
||||
gcc -DHAVE_CONFIG_H -D_BSD_SOURCE -D_POSIX_SOURCE -I.. -Wall -std=c89 -pedantic -c -o fping.o fping.c
|
Loading…
Reference in New Issue