From: David Schweikert Date: Mon, 30 Jan 2017 10:26:47 +0000 (+0100) Subject: first version of fping that can do ipv4 and ipv6 at the same time X-Git-Url: https://git.gsnw.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3c53d9be3f4cb97ba6c018b997408019698f6bb9;p=fping.git first version of fping that can do ipv4 and ipv6 at the same time --- diff --git a/src/Makefile.am b/src/Makefile.am index 4dcfae8..c518d34 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,18 +1,11 @@ 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 diff --git a/src/fping.c b/src/fping.c index 131280f..df91155 100644 --- a/src/fping.c +++ b/src/fping.c @@ -234,13 +234,18 @@ HOST_ENTRY *ev_last; 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; @@ -310,7 +315,7 @@ void crash_and_burn( char *message ); 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 ); @@ -356,9 +361,8 @@ int main( int argc, char **argv ) 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 @@ -869,7 +873,10 @@ int main( int argc, char **argv ) }/* 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 ); @@ -1046,12 +1053,7 @@ void main_loop() 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) { @@ -1552,7 +1554,7 @@ void print_global_stats( void ) ************************************************************/ -int send_ping( int s, HOST_ENTRY *h ) +int send_ping( HOST_ENTRY *h ) { int n; int myseq; @@ -1566,7 +1568,17 @@ int send_ping( int s, HOST_ENTRY *h ) 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) @@ -1608,21 +1620,23 @@ int socket_can_read(struct timeval *timeout) { 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 */ @@ -1633,10 +1647,18 @@ select_again: } } - 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, @@ -1699,7 +1721,6 @@ int receive_packet(int socket, return recv_len; } -#ifndef IPV6 int decode_icmp_ipv4( struct sockaddr *response_addr, size_t response_addr_len, @@ -1807,7 +1828,7 @@ int decode_icmp_ipv4( return 1; } -#else +#ifdef IPV6 int decode_icmp_ipv6( struct sockaddr *response_addr, size_t response_addr_len, @@ -1958,19 +1979,34 @@ int wait_for_reply(long wait_time) 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 ) { @@ -2155,13 +2191,18 @@ void add_name( char *name ) 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) diff --git a/src/fping.h b/src/fping.h index 0dedc61..44be999 100644 --- a/src/fping.h +++ b/src/fping.h @@ -15,13 +15,14 @@ int random_data_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 diff --git a/src/socket.c b/src/socket.c deleted file mode 100644 index dd692dc..0000000 --- a/src/socket.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 - * IPv6 Support: Jeroen Massar - * Improved main loop: David Schweikert - * Debian Merge, TOS settings: Tobi Oetiker - * 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 -} diff --git a/src/socket4.c b/src/socket4.c index e97193f..8b80d6d 100644 --- a/src/socket4.c +++ b/src/socket4.c @@ -44,8 +44,8 @@ #include #include -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() { @@ -83,9 +83,9 @@ 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" ); } @@ -122,7 +122,7 @@ int socket_sendto_ping_ipv4(int s, struct sockaddr *saddr, socklen_t saddr_len, 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; @@ -131,14 +131,14 @@ int socket_sendto_ping_ipv4(int s, struct sockaddr *saddr, socklen_t saddr_len, 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; } diff --git a/src/socket6.c b/src/socket6.c index 83738f8..fac7a09 100644 --- a/src/socket6.c +++ b/src/socket6.c @@ -43,8 +43,8 @@ #include -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() { @@ -82,9 +82,9 @@ 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" ); } @@ -104,21 +104,21 @@ int socket_sendto_ping_ipv6(int s, struct sockaddr *saddr, socklen_t saddr_len, 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; }