AM_CFLAGS = -Wall -Wextra -Wno-sign-compare
-prog =
+sbin_PROGRAMS = fping
+
+fping_SOURCES = fping.c seqmap.c socket4.c fping.h options.h seqmap.h
+fping_DEPENDENCIES = ../config.h
-if IPV4
-prog += fping
-endif
if IPV6
-prog += fping6
+fping_SOURCES += socket6.c
+fping_CFLAGS = $(AM_CFLAGS) -DIPV6
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
char *prog;
int ident; /* our pid */
-#ifndef IPV6
int socket4 = 0;
+#ifndef IPV6
+int hints_ai_family = AF_INET;
+#else
+int hints_ai_family = AF_UNSPEC;
+#endif
+
+#ifndef IPV6
int *allsocket[2] = { &socket4, NULL };
#else
int socket6 = 0;
-/* FIXME UNIFY */
-int *allsocket[2] = { &socket6, NULL };
+int *allsocket[3] = { &socket4, &socket6, NULL };
#endif
unsigned int debugging = 0;
void errno_crash_and_burn( char *message );
char *get_host_by_address( struct in_addr in );
void remove_job( HOST_ENTRY *h );
-int send_ping( int s, HOST_ENTRY *h );
+int send_ping( HOST_ENTRY *h );
long timeval_diff( struct timeval *a, struct timeval *b );
void timeval_add(struct timeval *a, long t_10u);
void usage( int );
prog = argv[0];
-#ifndef IPV6
socket4 = open_ping_socket_ipv4(ping_data_size);
-#else
+#ifdef IPV6
socket6 = open_ping_socket_ipv6(ping_data_size);
#endif
}/* FOR */
- init_ping_buffer(ping_data_size);
+ init_ping_buffer_ipv4(ping_data_size);
+#ifdef IPV6
+ init_ping_buffer_ipv6(ping_data_size);
+#endif
signal( SIGINT, finish );
h = ev_dequeue();
/* Send the ping */
- /*printf("Sending ping after %d ms\n", lt/100); */
-#ifndef IPV6
- send_ping(socket4, h);
-#else
- send_ping(socket6, h);
-#endif
+ send_ping(h);
/* Check what needs to be done next */
if(!loop_flag && !count_flag) {
************************************************************/
-int send_ping( int s, HOST_ENTRY *h )
+int send_ping( HOST_ENTRY *h )
{
int n;
int myseq;
printf( "sending [%d] to %s\n", h->num_sent, h->host );
#endif /* DEBUG || _DEBUG */
- n = socket_sendto_ping(s, (struct sockaddr *) &h->saddr, h->saddr_len, myseq, ident);
+ if(h->saddr.ss_family == AF_INET) {
+ n = socket_sendto_ping_ipv4(socket4, (struct sockaddr *) &h->saddr, h->saddr_len, myseq, ident);
+ }
+#ifdef IPV6
+ else if(h->saddr.ss_family == AF_INET6) {
+ n = socket_sendto_ping_ipv6(socket6, (struct sockaddr *) &h->saddr, h->saddr_len, myseq, ident);
+ }
+#endif
+ else {
+ return 0;
+ }
if(
(n < 0)
{
int nfound;
fd_set readset, writeset;
- int s;
+ int socketmax;
-/* FIXME UNIFY */
#ifndef IPV6
- s = socket4;
+ socketmax = socket4;
#else
- s = socket6;
+ socketmax = socket4 > socket6 ? socket4 : socket6;
#endif
select_again:
FD_ZERO( &readset );
FD_ZERO( &writeset );
- FD_SET( s, &readset );
+ FD_SET( socket4, &readset );
+#ifdef IPV6
+ FD_SET( socket6, &readset );
+#endif
- nfound = select(s + 1, &readset, &writeset, NULL, timeout);
+ nfound = select(socketmax + 1, &readset, &writeset, NULL, timeout);
if(nfound < 0) {
if(errno == EINTR) {
/* interrupted system call: redo the select */
}
}
- if(nfound == 0)
- return 0;
- else
- return s;
+ if(nfound > 0) {
+ if(FD_ISSET(socket4, &readset)) {
+ return socket4;
+ }
+#ifdef IPV6
+ if(FD_ISSET(socket6, &readset)) {
+ return socket6;
+ }
+#endif
+ }
+
+ return 0;
}
int receive_packet(int socket,
return recv_len;
}
-#ifndef IPV6
int decode_icmp_ipv4(
struct sockaddr *response_addr,
size_t response_addr_len,
return 1;
}
-#else
+#ifdef IPV6
int decode_icmp_ipv6(
struct sockaddr *response_addr,
size_t response_addr_len,
gettimeofday( ¤t_time, &tz );
/* Process ICMP packet and retrieve id/seq */
-#ifndef IPV6
- if(!decode_icmp_ipv4(
-#else
- if(!decode_icmp_ipv6(
+ if(response_addr.ss_family == AF_INET) {
+ if(!decode_icmp_ipv4(
+ (struct sockaddr *) &response_addr,
+ sizeof(response_addr),
+ buffer,
+ sizeof(buffer),
+ &id,
+ &seq)
+ ) {
+ return 1;
+ }
+ }
+#ifdef IPV6
+ else if(response_addr.ss_family == AF_INET6) {
+ if(!decode_icmp_ipv6(
+ (struct sockaddr *) &response_addr,
+ sizeof(response_addr),
+ buffer,
+ sizeof(buffer),
+ &id,
+ &seq)
+ ) {
+ return 1;
+ }
+ }
#endif
- (struct sockaddr *) &response_addr,
- sizeof(response_addr),
- buffer,
- sizeof(buffer),
- &id,
- &seq)
- ) {
- return(1);
+ else {
+ return 1;
}
if( id != ident ) {
bzero(&hints, sizeof(struct addrinfo));
hints.ai_flags = 0;
hints.ai_socktype = SOCK_RAW;
-#ifndef IPV6
- hints.ai_family = AF_INET;
- hints.ai_protocol = IPPROTO_ICMP;
-#else
- hints.ai_family = AF_INET6;
- hints.ai_protocol = IPPROTO_ICMPV6;
+ hints.ai_family = hints_ai_family;
+ if(hints_ai_family == AF_INET) {
+ hints.ai_protocol = IPPROTO_ICMP;
+ }
+#ifdef IPV6
+ else if(hints_ai_family == AF_INET6) {
+ hints.ai_protocol = IPPROTO_ICMPV6;
+ }
#endif
+ else {
+ hints.ai_protocol = 0;
+ }
ret_ga = getaddrinfo(name, NULL, &hints, &res0);
if (ret_ga) {
if(!quiet_flag)
/* socket.c */
int open_ping_socket_ipv4();
-int open_ping_socket();
-void init_ping_buffer(size_t ping_data_size);
+void init_ping_buffer_ipv4(size_t ping_data_size);
void socket_set_src_addr_ipv4(int s, struct in_addr *src_addr);
+int socket_sendto_ping_ipv4(int s, struct sockaddr *saddr, socklen_t saddr_len, uint16_t icmp_seq, uint16_t icmp_id);
#ifdef IPV6
int open_ping_socket_ipv6();
+void init_ping_buffer_ipv6(size_t ping_data_size);
void socket_set_src_addr_ipv6(int s, struct in6_addr *src_addr);
+int socket_sendto_ping_ipv6(int s, struct sockaddr *saddr, socklen_t saddr_len, uint16_t icmp_seq, uint16_t icmp_id);
#endif
-int socket_sendto_ping(int s, struct sockaddr *saddr, socklen_t saddr_len, uint16_t icmp_seq, uint16_t icmp_id);
#endif
+++ /dev/null
-/*
- * 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 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, struct in_addr *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);
-#ifdef IPV6
-void socket_set_src_addr_ipv6(int s, struct in6_addr *src_addr);
-int socket_sendto_ping_ipv6(int s, struct sockaddr *saddr, socklen_t saddr_len, uint16_t icmp_seq_nr, uint16_t icmp_id_nr);
-#endif
-
-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
-}
-
-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
-}
#include <stdlib.h>
#include <fcntl.h>
-char *ping_buffer = 0;
-size_t ping_pkt_size;
+char *ping_buffer_ipv4 = 0;
+size_t ping_pkt_size_ipv4;
int open_ping_socket_ipv4()
{
void init_ping_buffer_ipv4(size_t ping_data_size)
{
/* allocate ping buffer */
- ping_pkt_size = ping_data_size + ICMP_MINLEN;
- ping_buffer = (char *) calloc(1, ping_pkt_size);
- if(!ping_buffer)
+ ping_pkt_size_ipv4 = ping_data_size + ICMP_MINLEN;
+ ping_buffer_ipv4 = (char *) calloc(1, ping_pkt_size_ipv4);
+ if(!ping_buffer_ipv4)
crash_and_burn( "can't malloc ping packet" );
}
struct icmp *icp;
int n;
- icp = (struct icmp *) ping_buffer;
+ icp = (struct icmp *) ping_buffer_ipv4;
icp->icmp_type = ICMP_ECHO;
icp->icmp_code = 0;
icp->icmp_id = htons(icmp_id_nr);
if (random_data_flag) {
- for (n = ((void*)&icp->icmp_data - (void *)icp); n < ping_pkt_size; ++n) {
- ping_buffer[n] = random() & 0xFF;
+ for (n = ((void*)&icp->icmp_data - (void *)icp); n < ping_pkt_size_ipv4; ++n) {
+ ping_buffer_ipv4[n] = random() & 0xFF;
}
}
- icp->icmp_cksum = calcsum((unsigned short *) icp, ping_pkt_size);
+ icp->icmp_cksum = calcsum((unsigned short *) icp, ping_pkt_size_ipv4);
- n = sendto(s, icp, ping_pkt_size, 0, saddr, saddr_len);
+ n = sendto(s, icp, ping_pkt_size_ipv4, 0, saddr, saddr_len);
return n;
}
#include <netinet/icmp6.h>
-char *ping_buffer = 0;
-size_t ping_pkt_size;
+char *ping_buffer_ipv6 = 0;
+size_t ping_pkt_size_ipv6;
int open_ping_socket_ipv6()
{
void init_ping_buffer_ipv6(size_t ping_data_size)
{
/* allocate ping buffer */
- ping_pkt_size = ping_data_size + sizeof(struct icmp6_hdr);
- ping_buffer = (char *) calloc(1, ping_pkt_size);
- if(!ping_buffer)
+ ping_pkt_size_ipv6 = ping_data_size + sizeof(struct icmp6_hdr);
+ ping_buffer_ipv6 = (char *) calloc(1, ping_pkt_size_ipv6);
+ if(!ping_buffer_ipv6)
crash_and_burn( "can't malloc ping packet" );
}
struct icmp6_hdr *icp;
int n;
- icp = (struct icmp6_hdr *) ping_buffer;
+ icp = (struct icmp6_hdr *) ping_buffer_ipv6;
icp->icmp6_type = ICMP6_ECHO_REQUEST;
icp->icmp6_code = 0;
icp->icmp6_seq = htons(icmp_seq_nr);
icp->icmp6_id = htons(icmp_id_nr);
if (random_data_flag) {
- for (n = sizeof(struct icmp6_hdr); n < ping_pkt_size; ++n) {
- ping_buffer[n] = random() & 0xFF;
+ for (n = sizeof(struct icmp6_hdr); n < ping_pkt_size_ipv6; ++n) {
+ ping_buffer_ipv6[n] = random() & 0xFF;
}
}
icp->icmp6_cksum = 0; // The IPv6 stack calculates the checksum for us...
- n = sendto(s, icp, ping_pkt_size, 0, saddr, saddr_len);
+ n = sendto(s, icp, ping_pkt_size_ipv6, 0, saddr, saddr_len);
return n;
}