first version of fping that can do ipv4 and ipv6 at the same time

pull/89/merge
David Schweikert 8 years ago
parent 8d4c69998d
commit 3c53d9be3f

@ -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

@ -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( &current_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)

@ -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

@ -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 <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
}

@ -44,8 +44,8 @@
#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()
{
@ -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;
}

@ -43,8 +43,8 @@
#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()
{
@ -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;
}

Loading…
Cancel
Save