|
|
@ -34,17 +34,17 @@
|
|
|
|
extern "C" {
|
|
|
|
extern "C" {
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
#endif /* __cplusplus */
|
|
|
|
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
#include "fping.h"
|
|
|
|
#include "fping.h"
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
#include "options.h"
|
|
|
|
#include "options.h"
|
|
|
|
#include "optparse.h"
|
|
|
|
#include "optparse.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <inttypes.h>
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <signal.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <time.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include "seqmap.h"
|
|
|
|
#include "seqmap.h"
|
|
|
@ -844,11 +844,13 @@ int main(int argc, char** argv)
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef IPV6
|
|
|
|
#ifndef IPV6
|
|
|
|
if (socket4 < 0) {
|
|
|
|
if (socket4 < 0) {
|
|
|
|
|
|
|
|
crash_and_burn("can't create socket (must run as root?)");
|
|
|
|
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
if ((socket4 < 0 && socket6 < 0) || (hints_ai_family == AF_INET6 && socket6 < 0)) {
|
|
|
|
if ((socket4 < 0 && socket6 < 0) || (hints_ai_family == AF_INET6 && socket6 < 0)) {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
crash_and_burn("can't create socket (must run as root?)");
|
|
|
|
crash_and_burn("can't create socket (must run as root?)");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
if (ttl > 255) {
|
|
|
|
if (ttl > 255) {
|
|
|
|
fprintf(stderr, "%s: ttl %u out of range\n", prog, ttl);
|
|
|
|
fprintf(stderr, "%s: ttl %u out of range\n", prog, ttl);
|
|
|
@ -1305,9 +1307,7 @@ void main_loop()
|
|
|
|
dbg_printf("%s", "# main_loop\n");
|
|
|
|
dbg_printf("%s", "# main_loop\n");
|
|
|
|
|
|
|
|
|
|
|
|
/* timeout event ? */
|
|
|
|
/* timeout event ? */
|
|
|
|
if (event_queue_timeout.first &&
|
|
|
|
if (event_queue_timeout.first && event_queue_timeout.first->ev_time - current_time_ns <= 0) {
|
|
|
|
event_queue_timeout.first->ev_time - current_time_ns <= 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
event = ev_dequeue(&event_queue_timeout);
|
|
|
|
event = ev_dequeue(&event_queue_timeout);
|
|
|
|
h = event->host;
|
|
|
|
h = event->host;
|
|
|
|
|
|
|
|
|
|
|
@ -1356,9 +1356,7 @@ void main_loop()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ping event ? */
|
|
|
|
/* ping event ? */
|
|
|
|
if (event_queue_ping.first &&
|
|
|
|
if (event_queue_ping.first && event_queue_ping.first->ev_time - current_time_ns <= 0) {
|
|
|
|
event_queue_ping.first->ev_time - current_time_ns <= 0)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Make sure that we don't ping more than once every "interval" */
|
|
|
|
/* Make sure that we don't ping more than once every "interval" */
|
|
|
|
lt = current_time_ns - last_send_time;
|
|
|
|
lt = current_time_ns - last_send_time;
|
|
|
|
if (lt < interval)
|
|
|
|
if (lt < interval)
|
|
|
@ -1504,7 +1502,6 @@ void update_current_time()
|
|
|
|
current_time_ns = timespec_ns(¤t_time);
|
|
|
|
current_time_ns = timespec_ns(¤t_time);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************
|
|
|
|
/************************************************************
|
|
|
|
|
|
|
|
|
|
|
|
Function: finish
|
|
|
|
Function: finish
|
|
|
@ -1559,7 +1556,8 @@ void finish()
|
|
|
|
if ((num_hosts - num_unreachable) >= min_reachable) {
|
|
|
|
if ((num_hosts - num_unreachable) >= min_reachable) {
|
|
|
|
printf("Enough hosts reachable (required: %d, reachable: %d)\n", min_reachable, num_hosts - num_unreachable);
|
|
|
|
printf("Enough hosts reachable (required: %d, reachable: %d)\n", min_reachable, num_hosts - num_unreachable);
|
|
|
|
exit(0);
|
|
|
|
exit(0);
|
|
|
|
} else {
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
printf("Not enough hosts reachable (required: %d, reachable: %d)\n", min_reachable, num_hosts - num_unreachable);
|
|
|
|
printf("Not enough hosts reachable (required: %d, reachable: %d)\n", min_reachable, num_hosts - num_unreachable);
|
|
|
|
exit(1);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -1906,9 +1904,11 @@ int socket_can_read(struct timeval* timeout)
|
|
|
|
|
|
|
|
|
|
|
|
select_again:
|
|
|
|
select_again:
|
|
|
|
FD_ZERO(&readset);
|
|
|
|
FD_ZERO(&readset);
|
|
|
|
if(socket4 >= 0) FD_SET(socket4, &readset);
|
|
|
|
if (socket4 >= 0)
|
|
|
|
|
|
|
|
FD_SET(socket4, &readset);
|
|
|
|
#ifdef IPV6
|
|
|
|
#ifdef IPV6
|
|
|
|
if(socket6 >= 0) FD_SET(socket6, &readset);
|
|
|
|
if (socket6 >= 0)
|
|
|
|
|
|
|
|
FD_SET(socket6, &readset);
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
nfound = select(socketmax + 1, &readset, NULL, NULL, timeout);
|
|
|
|
nfound = select(socketmax + 1, &readset, NULL, NULL, timeout);
|
|
|
@ -1989,8 +1989,7 @@ int receive_packet(int64_t wait_time,
|
|
|
|
struct timespec reply_timestamp_ts;
|
|
|
|
struct timespec reply_timestamp_ts;
|
|
|
|
for (cmsg = CMSG_FIRSTHDR(&recv_msghdr);
|
|
|
|
for (cmsg = CMSG_FIRSTHDR(&recv_msghdr);
|
|
|
|
cmsg != NULL;
|
|
|
|
cmsg != NULL;
|
|
|
|
cmsg = CMSG_NXTHDR(&recv_msghdr, cmsg))
|
|
|
|
cmsg = CMSG_NXTHDR(&recv_msghdr, cmsg)) {
|
|
|
|
{
|
|
|
|
|
|
|
|
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMPNS) {
|
|
|
|
if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_TIMESTAMPNS) {
|
|
|
|
memcpy(&reply_timestamp_ts, CMSG_DATA(cmsg), sizeof(reply_timestamp_ts));
|
|
|
|
memcpy(&reply_timestamp_ts, CMSG_DATA(cmsg), sizeof(reply_timestamp_ts));
|
|
|
|
*reply_timestamp = timespec_ns(&reply_timestamp_ts);
|
|
|
|
*reply_timestamp = timespec_ns(&reply_timestamp_ts);
|
|
|
@ -2098,12 +2097,11 @@ int decode_icmp_ipv4(
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (reply_buf_len < hlen + ICMP_MINLEN) {
|
|
|
|
if (reply_buf_len < hlen + ICMP_MINLEN) {
|
|
|
|
/* too short */
|
|
|
|
/* too short */
|
|
|
|
if (verbose_flag) {
|
|
|
|
if (verbose_flag) {
|
|
|
|
char buf[INET6_ADDRSTRLEN];
|
|
|
|
char buf[INET6_ADDRSTRLEN];
|
|
|
|
getnameinfo( response_addr, sizeof( struct sockaddr_in ), buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
|
|
|
|
getnameinfo(response_addr, response_addr_len, buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
|
|
|
|
printf("received packet too short for ICMP (%d bytes from %s)\n", (int)reply_buf_len, buf);
|
|
|
|
printf("received packet too short for ICMP (%d bytes from %s)\n", (int)reply_buf_len, buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
return -1;
|
|
|
@ -2302,7 +2300,8 @@ int wait_for_reply(int64_t wait_time)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
update_current_time();
|
|
|
|
update_current_time();
|
|
|
|
if(recv_time==0) recv_time = current_time_ns;
|
|
|
|
if (recv_time == 0)
|
|
|
|
|
|
|
|
recv_time = current_time_ns;
|
|
|
|
|
|
|
|
|
|
|
|
/* Process ICMP packet and retrieve id/seq */
|
|
|
|
/* Process ICMP packet and retrieve id/seq */
|
|
|
|
if (response_addr.ss_family == AF_INET) {
|
|
|
|
if (response_addr.ss_family == AF_INET) {
|
|
|
@ -2783,7 +2782,6 @@ struct event *host_get_timeout_event(HOST_ENTRY *h, int index)
|
|
|
|
return &h->event_storage_timeout[index % event_storage_count];
|
|
|
|
return &h->event_storage_timeout[index % event_storage_count];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************
|
|
|
|
/************************************************************
|
|
|
|
|
|
|
|
|
|
|
|
Function: ev_enqueue
|
|
|
|
Function: ev_enqueue
|
|
|
|