sync with develop

pull/89/merge
David Schweikert 8 years ago
parent c5612265ae
commit 9787dd0136

@ -1,18 +1,28 @@
Unreleased Unreleased
* INCOMPATIBILITY WARNING: * INCOMPATIBILITY WARNING:
fping and fping6 are now unified into one binary. This means that for fping and fping6 are now unified into one binary. This means that, for
example doing 'fping www.google.com' is going to ping the IPv6 IP of example, doing 'fping www.google.com' is going to ping the IPv6 IP of
www.google.com on IPv6-enabled hosts. If you need exact compatibility with www.google.com on IPv6-enabled hosts.
old versions, you can:
- compile fping with --disable-ipv6 (or use a wrapper, and call 'fping -4')
- compile fping with --enable-ipv6 and rename it to fping6 (same as 'fping -6')
If you need exact compatibility with old versions, you can configure,
compile, 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
Or, alternatively, you could write two wrappers 'fping' and 'fping6',
that set respectively the options '-4' and '-6' when calling the original
fping binary.
* Version 4.0
* (feature) Unified 'fping' and 'fping6' into one binary (#80) * (feature) Unified 'fping' and 'fping6' into one binary (#80)
* (feature) --enable-ipv6 is now default
* (feature) New option '-4' to force IPv4 * (feature) New option '-4' to force IPv4
* (feature) New option '-6' to force IPv6 * (feature) New option '-6' to force IPv6
2017-02-09 David Schweikert <david@schweikert.ch>
* Version 3.16
* (feature) Support kernel-timestamping of received packets (#46) * (feature) Support kernel-timestamping of received packets (#46)
* (feature) Simplify restrictions: only -i >= 1 and -p >= 10 are enforced now * (feature) Simplify restrictions: only -i >= 1 and -p >= 10 are enforced now
* (feature) --enable-ipv6 is now default (you can use --disable-ipv6 to disable IPv6 support)
* (bugfix) Fix option -m to return all IPs of a hostname * (bugfix) Fix option -m to return all IPs of a hostname
* (bugfix) Fix option -H (ttl) for IPv6 * (bugfix) Fix option -H (ttl) for IPv6
* (bugfix) Fix option -M (don't fragment) for IPv6 * (bugfix) Fix option -M (don't fragment) for IPv6

@ -1,5 +0,0 @@
- implement -4
- implement -6
- test -4
- test -6
- fix -m

@ -10,9 +10,9 @@ set -e
# exit 0 # exit 0
#fi #fi
# do this only for the master branch # do this only for the master and version3 branch
if [ "$TRAVIS_BRANCH" != "master" ]; then if [ "$TRAVIS_BRANCH" != "master" -a "$TRAVIS_BRANCH" != "version3" ]; then
echo "skipped upload branch $TRAVIS_BRANCH isn't master" echo "skipped upload branch $TRAVIS_BRANCH isn't master/version3"
exit 0 exit 0
fi fi

@ -31,7 +31,7 @@ $cmd->stderr_is_eq("");
my $cmd = Test::Command->new(cmd => "fping -4 ::1"); my $cmd = Test::Command->new(cmd => "fping -4 ::1");
$cmd->exit_is_num(2); $cmd->exit_is_num(2);
$cmd->stdout_is_eq(""); $cmd->stdout_is_eq("");
$cmd->stderr_is_eq("::1: Address family for hostname not supported\n"); $cmd->stderr_like(qr{^::1:.*(not supported|not known)});
} }
# fping -6 # fping -6
@ -49,7 +49,7 @@ SKIP: {
my $cmd = Test::Command->new(cmd => "fping -6 127.0.0.1"); my $cmd = Test::Command->new(cmd => "fping -6 127.0.0.1");
$cmd->exit_is_num(2); $cmd->exit_is_num(2);
$cmd->stdout_is_eq(""); $cmd->stdout_is_eq("");
$cmd->stderr_is_eq("127.0.0.1: Address family for hostname not supported\n"); $cmd->stderr_like(qr{127\.0\.0\.1:.*(not supported|not known)});
} }
# fping -a # fping -a

@ -1,6 +1,7 @@
#!/usr/bin/perl -w #!/usr/bin/perl -w
use Test::Command tests => 7; use Test::Command tests => 7;
use Test::More;
# -i n interval between sending ping packets (in millisec) (default 25) # -i n interval between sending ping packets (in millisec) (default 25)
# -l loop sending pings forever # -l loop sending pings forever
@ -24,11 +25,14 @@ $cmd->stdout_like(qr{127\.0\.0\.1 : \[0\], 84 bytes, 0\.\d+ ms \(0.\d+ avg, 0% l
} }
# fping -M # fping -M
{ SKIP: {
my $cmd = Test::Command->new(cmd => "fping -M 127.0.0.1"); if($^O eq 'darwin') {
$cmd->exit_is_num(0); skip '-M option not supported on macOS', 3;
$cmd->stdout_is_eq("127.0.0.1 is alive\n"); }
$cmd->stderr_is_eq(""); my $cmd = Test::Command->new(cmd => "fping -M 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 -m -> test-14-internet-hosts # fping -m -> test-14-internet-hosts

@ -72,9 +72,12 @@ $cmd->stderr_is_eq("");
} }
# fping -M # fping -M
{ SKIP: {
my $cmd = Test::Command->new(cmd => "fping -r 0 -b 10000 -M 8.8.8.8"); if($^O eq 'darwin') {
$cmd->exit_is_num(1); skip '-M option not supported on macOS', 3;
$cmd->stdout_is_eq("8.8.8.8 is unreachable\n"); }
$cmd->stderr_is_eq("8.8.8.8: error while sending ping: Message too long\n"); my $cmd = Test::Command->new(cmd => "fping -r 0 -b 10000 -M 8.8.8.8");
$cmd->exit_is_num(1);
$cmd->stdout_is_eq("8.8.8.8 is unreachable\n");
$cmd->stderr_is_eq("8.8.8.8: error while sending ping: Message too long\n");
} }

@ -5,23 +5,36 @@ AC_PREREQ(2.59)
AC_INIT([fping],[3.16-rc2]) AC_INIT([fping],[3.16-rc2])
dnl make ipv4 and ipv6 options dnl --disable-ipv4
AC_ARG_ENABLE([ipv4], AC_ARG_ENABLE([ipv4],
AS_HELP_STRING([--enable-ipv4], [(ignored for compatibility with previous versions)])) AS_HELP_STRING([--disable-ipv4], [Disable support for pinging IPv4 hosts]))
AM_CONDITIONAL([IPV4], [test "x$enable_ipv4" != "xno"])
AM_COND_IF([IPV4], [AC_DEFINE([IPV4], [1], [IPv4 enabled])])
dnl --disable-ipv6
AC_ARG_ENABLE([ipv6], AC_ARG_ENABLE([ipv6],
AS_HELP_STRING([--enable-ipv6], [Build IPv6 capable fping6]), AS_HELP_STRING([--disable-ipv6], [Disable support for pinging IPv6 hosts]))
[case "${enableval}" in AS_IF([test "x$enable_ipv6" != "xno"], [
yes) ipv6=true ;; dnl Test if IPv6 is supported
no) ipv6=false ;; AC_CHECK_HEADERS([netinet/icmp6.h], [have_ipv6="yes"], [], [[
*) AC_MSG_ERROR([bad value ${enableval} for --enable-ipv6]) ;; #include <netinet/in.h>
esac],[ipv6=true]) ]])
AM_CONDITIONAL([IPV6], [test x$ipv6 = xtrue]) ])
dnl Can't disable both IPv4 and IPv6
AS_IF([test "x$enable_ipv4" = "xno" -a "x$enable_ipv6" = "xno"], [
AC_MSG_ERROR([Need to enable IPv4 or IPv6. Can't disable both!)])
])
dnl IPv6 required, but not supported?
AS_IF([test \( "x$enable_ipv6" = "xyes" -o "x$enable_ipv4" = "xno" \) -a "x$have_ipv6" != "xyes" ], [
AC_MSG_ERROR([IPv6 not supported on this platform (netinet/icmp6.h header not found)])
])
AM_CONDITIONAL([IPV6], [test "x$have_ipv6" = "xyes"])
AM_COND_IF([IPV6], [AC_DEFINE([IPV6], [1], [IPv6 enabled])])
AC_ARG_ENABLE([timestamp], AC_ARG_ENABLE([timestamp],
AS_HELP_STRING([--disable-timestamp], [Disable kernel-based packet timestaping (SO_TIMESTAMP)])) AS_HELP_STRING([--disable-timestamp], [Disable kernel-based packet timestaping (SO_TIMESTAMP)]))
AS_IF([test "x$enable_timestamp" != "xno"], [ AS_IF([test "x$enable_timestamp" != "xno"], [
AC_CHECK_DECL([SO_TIMESTAMP], [AC_DEFINE(HAVE_SO_TIMESTAMP, [1], [set define])], [have_so_timestamp="no"], [#include <sys/types.h> AC_CHECK_DECL([SO_TIMESTAMP], [AC_DEFINE(HAVE_SO_TIMESTAMP, [1], [SO_TIMESTAMP is defined])], [have_so_timestamp="no"], [#include <sys/types.h>
#include <sys/socket.h>]) #include <sys/socket.h>])
]) ])
dnl Test if --enable-timestamp is explicitely enabled and make an error if this platform doesn't support it dnl Test if --enable-timestamp is explicitely enabled and make an error if this platform doesn't support it
@ -70,7 +83,7 @@ AH_BOTTOM([
]) ])
dnl Checks for header files. dnl Checks for header files.
AC_CHECK_HEADERS(unistd.h sys/file.h stdlib.h sys/select.h) AC_CHECK_HEADERS([unistd.h sys/file.h stdlib.h sys/select.h])
AC_CONFIG_FILES([Makefile AC_CONFIG_FILES([Makefile
doc/Makefile doc/Makefile

@ -1,15 +1,6 @@
man_MANS = man_MANS = fping.8
man_MANS += fping.8 EXTRA_DIST = fping.8 fping.pod README.1992
if IPV6
man_MANS += fping6.8
endif
EXTRA_DIST = fping.8 fping6.8 fping.pod README.1992
fping.8: fping.pod fping.8: fping.pod
pod2man -c "" -s 8 -r "fping" $< >$@ pod2man -c "" -s 8 -r "fping" $< >$@
fping6.8: fping.pod
pod2man -c "" -s 8 -r "fping" -n fping6 $< >$@

@ -0,0 +1 @@
BasedOnStyle: WebKit

@ -8,6 +8,4 @@ fping_DEPENDENCIES = ../config.h
if IPV6 if IPV6
fping_SOURCES += socket6.c fping_SOURCES += socket6.c
fping_CFLAGS = $(AM_CFLAGS) -DIPV6 fping_CFLAGS = $(AM_CFLAGS) -DIPV6
install-exec-hook:
ln -s fping$(EXEEXT) $(DESTDIR)$(sbindir)/fping6
endif endif

File diff suppressed because it is too large Load Diff

@ -1,4 +1,4 @@
/* /*
* fping: fast-ping, file-ping, favorite-ping, funky-ping * fping: fast-ping, file-ping, favorite-ping, funky-ping
* *
* Ping a list of target hosts in a round robin fashion. * Ping a list of target hosts in a round robin fashion.
@ -22,8 +22,8 @@
* duplicated in all such forms and that any documentation, * duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such * advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed * distribution and use acknowledge that the software was developed
* by Stanford University. The name of the University may not be used * by Stanford University. The name of the University may not be used
* to endorse or promote products derived from this software without * to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
@ -36,11 +36,11 @@
*/ */
#include "seqmap.h" #include "seqmap.h"
#include "options.h"
#include "limits.h" #include "limits.h"
#include "options.h"
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
/* description of the data structure used: /* description of the data structure used:
* *
@ -51,26 +51,26 @@
* - when entering a value, we check that the current entry is expired * - when entering a value, we check that the current entry is expired
*/ */
static SEQMAP_VALUE *seqmap_map = NULL; static SEQMAP_VALUE* seqmap_map = NULL;
static unsigned int seqmap_next_id = 0; static unsigned int seqmap_next_id = 0;
#define SEQMAP_TIMEOUT_IN_S 10 #define SEQMAP_TIMEOUT_IN_S 10
#define SEQMAP_UNASSIGNED_HOST_NR UINT_MAX #define SEQMAP_UNASSIGNED_HOST_NR UINT_MAX
void seqmap_init() void seqmap_init()
{ {
seqmap_map = calloc(SEQMAP_MAXSEQ, sizeof(SEQMAP_VALUE)); seqmap_map = calloc(SEQMAP_MAXSEQ, sizeof(SEQMAP_VALUE));
if(seqmap_map == NULL) { if (seqmap_map == NULL) {
perror("malloc error (can't allocate seqmap_map)"); 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 seqmap_add(unsigned int host_nr, unsigned int ping_count, struct timeval* now)
{ {
unsigned int current_id; unsigned int current_id;
SEQMAP_VALUE *next_value; SEQMAP_VALUE* next_value;
if(!seqmap_map) { if (!seqmap_map) {
fprintf(stderr, "fping internal error: seqmap not initialized.\n"); fprintf(stderr, "fping internal error: seqmap not initialized.\n");
exit(4); exit(4);
} }
@ -78,7 +78,7 @@ unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, struct ti
/* check if expired (note that unused seqmap values will have fields set to /* check if expired (note that unused seqmap values will have fields set to
* 0, so will be seen as expired */ * 0, so will be seen as expired */
next_value = &seqmap_map[seqmap_next_id]; 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) { 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", 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); SEQMAP_TIMEOUT_IN_S, host_nr, ping_count, seqmap_next_id);
exit(4); exit(4);
@ -97,18 +97,18 @@ unsigned int seqmap_add(unsigned int host_nr, unsigned int ping_count, struct ti
return current_id; return current_id;
} }
SEQMAP_VALUE *seqmap_fetch(unsigned int id, struct timeval *now) SEQMAP_VALUE* seqmap_fetch(unsigned int id, struct timeval* now)
{ {
SEQMAP_VALUE *value; SEQMAP_VALUE* value;
if(id > SEQMAP_MAXSEQ) { if (id > SEQMAP_MAXSEQ) {
return NULL; return NULL;
} }
value = &seqmap_map[id]; value = &seqmap_map[id];
/* verify that value is not expired */ /* verify that value is not expired */
if(now->tv_sec - value->ping_ts.tv_sec >= SEQMAP_TIMEOUT_IN_S) { if (now->tv_sec - value->ping_ts.tv_sec >= SEQMAP_TIMEOUT_IN_S) {
return NULL; return NULL;
} }

@ -1,4 +1,4 @@
/* /*
* fping: fast-ping, file-ping, favorite-ping, funky-ping * fping: fast-ping, file-ping, favorite-ping, funky-ping
* *
* Ping a list of target hosts in a round robin fashion. * Ping a list of target hosts in a round robin fashion.
@ -22,47 +22,47 @@
* duplicated in all such forms and that any documentation, * duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such * advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed * distribution and use acknowledge that the software was developed
* by Stanford University. The name of the University may not be used * by Stanford University. The name of the University may not be used
* to endorse or promote products derived from this software without * to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/ */
#include "fping.h"
#include "config.h" #include "config.h"
#include "fping.h"
#include <sys/socket.h> #include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/in_systm.h> #include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h> #include <netinet/ip_icmp.h>
#include <netdb.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <string.h>
#include <sys/socket.h>
char *ping_buffer_ipv4 = 0; char* ping_buffer_ipv4 = 0;
size_t ping_pkt_size_ipv4; size_t ping_pkt_size_ipv4;
int open_ping_socket_ipv4() int open_ping_socket_ipv4()
{ {
struct protoent *proto; struct protoent* proto;
int s; int s;
/* confirm that ICMP is available on this machine */ /* confirm that ICMP is available on this machine */
if( ( proto = getprotobyname( "icmp" ) ) == NULL ) if ((proto = getprotobyname("icmp")) == NULL)
crash_and_burn( "icmp: unknown protocol" ); crash_and_burn("icmp: unknown protocol");
/* create raw socket for ICMP calls (ping) */ /* create raw socket for ICMP calls (ping) */
s = socket( AF_INET, SOCK_RAW, proto->p_proto ); s = socket(AF_INET, SOCK_RAW, proto->p_proto);
if( s < 0 ) { if (s < 0) {
/* try non-privileged icmp (works on Mac OSX without privileges, for example) */ /* try non-privileged icmp (works on Mac OSX without privileges, for example) */
s = socket( AF_INET, SOCK_DGRAM, proto->p_proto ); s = socket(AF_INET, SOCK_DGRAM, proto->p_proto);
if( s < 0 ) { if (s < 0) {
errno_crash_and_burn( "can't create socket (must run as root?)" ); errno_crash_and_burn("can't create socket (must run as root?)");
} }
} }
@ -70,10 +70,10 @@ int open_ping_socket_ipv4()
{ {
int flags; int flags;
if((flags = fcntl(s, F_GETFL, 0)) < 0) if ((flags = fcntl(s, F_GETFL, 0)) < 0)
perror("fcntl"); perror("fcntl");
if(fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0)
perror("fcntl"); perror("fcntl");
} }
@ -84,45 +84,45 @@ void init_ping_buffer_ipv4(size_t ping_data_size)
{ {
/* allocate ping buffer */ /* allocate ping buffer */
ping_pkt_size_ipv4 = ping_data_size + ICMP_MINLEN; ping_pkt_size_ipv4 = ping_data_size + ICMP_MINLEN;
ping_buffer_ipv4 = (char *) calloc(1, ping_pkt_size_ipv4); ping_buffer_ipv4 = (char*)calloc(1, ping_pkt_size_ipv4);
if(!ping_buffer_ipv4) if (!ping_buffer_ipv4)
crash_and_burn( "can't malloc ping packet" ); crash_and_burn("can't malloc ping packet");
} }
void socket_set_src_addr_ipv4(int s, struct in_addr *src_addr) void socket_set_src_addr_ipv4(int s, struct in_addr* src_addr)
{ {
struct sockaddr_in sa; struct sockaddr_in sa;
memset( &sa, 0, sizeof( sa ) ); memset(&sa, 0, sizeof(sa));
sa.sin_family = AF_INET; sa.sin_family = AF_INET;
sa.sin_addr = *src_addr; sa.sin_addr = *src_addr;
if ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 ) if (bind(s, (struct sockaddr*)&sa, sizeof(sa)) < 0)
errno_crash_and_burn( "cannot bind source address" ); errno_crash_and_burn("cannot bind source address");
} }
unsigned short calcsum(unsigned short *buffer, int length) unsigned short calcsum(unsigned short* buffer, int length)
{ {
unsigned long sum; unsigned long sum;
/* initialize sum to zero and loop until length (in words) is 0 */ /* initialize sum to zero and loop until length (in words) is 0 */
for (sum=0; length>1; length-=2) /* sizeof() returns number of bytes, we're interested in number of words */ for (sum = 0; length > 1; length -= 2) /* sizeof() returns number of bytes, we're interested in number of words */
sum += *buffer++; /* add 1 word of buffer to sum and proceed to the next */ sum += *buffer++; /* add 1 word of buffer to sum and proceed to the next */
/* we may have an extra byte */ /* we may have an extra byte */
if (length==1) if (length == 1)
sum += (char)*buffer; sum += (char)*buffer;
sum = (sum >> 16) + (sum & 0xFFFF); /* add high 16 to low 16 */ sum = (sum >> 16) + (sum & 0xFFFF); /* add high 16 to low 16 */
sum += (sum >> 16); /* add carry */ sum += (sum >> 16); /* add carry */
return ~sum; return ~sum;
} }
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_ipv4(int s, struct sockaddr* saddr, socklen_t saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr)
{ {
struct icmp *icp; struct icmp* icp;
int n; int n;
icp = (struct icmp *) ping_buffer_ipv4; icp = (struct icmp*)ping_buffer_ipv4;
icp->icmp_type = ICMP_ECHO; icp->icmp_type = ICMP_ECHO;
icp->icmp_code = 0; icp->icmp_code = 0;
@ -131,12 +131,12 @@ int socket_sendto_ping_ipv4(int s, struct sockaddr *saddr, socklen_t saddr_len,
icp->icmp_id = htons(icmp_id_nr); icp->icmp_id = htons(icmp_id_nr);
if (random_data_flag) { if (random_data_flag) {
for (n = ((char*)&icp->icmp_data - (char *)icp); n < ping_pkt_size_ipv4; ++n) { for (n = ((char*)&icp->icmp_data - (char*)icp); n < ping_pkt_size_ipv4; ++n) {
ping_buffer_ipv4[n] = random() & 0xFF; ping_buffer_ipv4[n] = random() & 0xFF;
} }
} }
icp->icmp_cksum = calcsum((unsigned short *) icp, ping_pkt_size_ipv4); icp->icmp_cksum = calcsum((unsigned short*)icp, ping_pkt_size_ipv4);
n = sendto(s, icp, ping_pkt_size_ipv4, 0, saddr, saddr_len); n = sendto(s, icp, ping_pkt_size_ipv4, 0, saddr, saddr_len);

@ -1,4 +1,4 @@
/* /*
* fping: fast-ping, file-ping, favorite-ping, funky-ping * fping: fast-ping, file-ping, favorite-ping, funky-ping
* *
* Ping a list of target hosts in a round robin fashion. * Ping a list of target hosts in a round robin fashion.
@ -22,46 +22,46 @@
* duplicated in all such forms and that any documentation, * duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such * advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed * distribution and use acknowledge that the software was developed
* by Stanford University. The name of the University may not be used * by Stanford University. The name of the University may not be used
* to endorse or promote products derived from this software without * to endorse or promote products derived from this software without
* specific prior written permission. * specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/ */
#include "fping.h"
#include "config.h" #include "config.h"
#include "fping.h"
#include <sys/socket.h> #include <fcntl.h>
#include <netinet/in.h>
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <fcntl.h> #include <string.h>
#include <sys/socket.h>
#include <netinet/icmp6.h> #include <netinet/icmp6.h>
char *ping_buffer_ipv6 = 0; char* ping_buffer_ipv6 = 0;
size_t ping_pkt_size_ipv6; size_t ping_pkt_size_ipv6;
int open_ping_socket_ipv6() int open_ping_socket_ipv6()
{ {
struct protoent *proto; struct protoent* proto;
int s; int s;
/* confirm that ICMP is available on this machine */ /* confirm that ICMP is available on this machine */
if( ( proto = getprotobyname( "ipv6-icmp" ) ) == NULL ) if ((proto = getprotobyname("ipv6-icmp")) == NULL)
crash_and_burn( "icmp: unknown protocol" ); crash_and_burn("icmp: unknown protocol");
/* create raw socket for ICMP calls (ping) */ /* create raw socket for ICMP calls (ping) */
s = socket( AF_INET6, SOCK_RAW, proto->p_proto ); s = socket(AF_INET6, SOCK_RAW, proto->p_proto);
if( s < 0 ) { if (s < 0) {
/* try non-privileged icmp (works on Mac OSX without privileges, for example) */ /* try non-privileged icmp (works on Mac OSX without privileges, for example) */
s = socket( AF_INET6, SOCK_DGRAM, proto->p_proto ); s = socket(AF_INET6, SOCK_DGRAM, proto->p_proto);
if( s < 0 ) { if (s < 0) {
errno_crash_and_burn( "can't create raw socket (must run as root?)" ); errno_crash_and_burn("can't create raw socket (must run as root?)");
} }
} }
@ -69,10 +69,10 @@ int open_ping_socket_ipv6()
{ {
int flags; int flags;
if((flags = fcntl(s, F_GETFL, 0)) < 0) if ((flags = fcntl(s, F_GETFL, 0)) < 0)
perror("fcntl"); perror("fcntl");
if(fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0)
perror("fcntl"); perror("fcntl");
} }
@ -83,32 +83,32 @@ void init_ping_buffer_ipv6(size_t ping_data_size)
{ {
/* allocate ping buffer */ /* allocate ping buffer */
ping_pkt_size_ipv6 = ping_data_size + sizeof(struct icmp6_hdr); ping_pkt_size_ipv6 = ping_data_size + sizeof(struct icmp6_hdr);
ping_buffer_ipv6 = (char *) calloc(1, ping_pkt_size_ipv6); ping_buffer_ipv6 = (char*)calloc(1, ping_pkt_size_ipv6);
if(!ping_buffer_ipv6) if (!ping_buffer_ipv6)
crash_and_burn( "can't malloc ping packet" ); crash_and_burn("can't malloc ping packet");
} }
void socket_set_src_addr_ipv6(int s, struct in6_addr *src_addr) void socket_set_src_addr_ipv6(int s, struct in6_addr* src_addr)
{ {
struct sockaddr_in6 sa; struct sockaddr_in6 sa;
memset( &sa, 0, sizeof( sa ) ); memset(&sa, 0, sizeof(sa));
sa.sin6_family = AF_INET6; sa.sin6_family = AF_INET6;
sa.sin6_addr = *src_addr; sa.sin6_addr = *src_addr;
if ( bind( s, (struct sockaddr *)&sa, sizeof( sa ) ) < 0 ) if (bind(s, (struct sockaddr*)&sa, sizeof(sa)) < 0)
errno_crash_and_burn( "cannot bind source address" ); errno_crash_and_burn("cannot bind source address");
} }
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 socket_sendto_ping_ipv6(int s, struct sockaddr* saddr, socklen_t saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr)
{ {
struct icmp6_hdr *icp; struct icmp6_hdr* icp;
int n; int n;
icp = (struct icmp6_hdr *) ping_buffer_ipv6; icp = (struct icmp6_hdr*)ping_buffer_ipv6;
icp->icmp6_type = ICMP6_ECHO_REQUEST; icp->icmp6_type = ICMP6_ECHO_REQUEST;
icp->icmp6_code = 0; icp->icmp6_code = 0;
icp->icmp6_seq = htons(icmp_seq_nr); icp->icmp6_seq = htons(icmp_seq_nr);
icp->icmp6_id = htons(icmp_id_nr); icp->icmp6_id = htons(icmp_id_nr);
if (random_data_flag) { if (random_data_flag) {
for (n = sizeof(struct icmp6_hdr); n < ping_pkt_size_ipv6; ++n) { for (n = sizeof(struct icmp6_hdr); n < ping_pkt_size_ipv6; ++n) {
@ -116,7 +116,7 @@ int socket_sendto_ping_ipv6(int s, struct sockaddr *saddr, socklen_t saddr_len,
} }
} }
icp->icmp6_cksum = 0; /* The IPv6 stack calculates the checksum for us... */ icp->icmp6_cksum = 0; /* The IPv6 stack calculates the checksum for us... */
n = sendto(s, icp, ping_pkt_size_ipv6, 0, saddr, saddr_len); n = sendto(s, icp, ping_pkt_size_ipv6, 0, saddr, saddr_len);

Loading…
Cancel
Save