fping.c (fping-5.0) | : | fping.c (fping-5.1) | ||
---|---|---|---|---|
skipping to change at line 63 | skipping to change at line 63 | |||
#include <unistd.h> | #include <unistd.h> | |||
#endif /* HAVE_UNISTD_H */ | #endif /* HAVE_UNISTD_H */ | |||
#ifdef HAVE_STDLIB_H | #ifdef HAVE_STDLIB_H | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#endif /* HAVE_STDLIB_H */ | #endif /* HAVE_STDLIB_H */ | |||
#include <stddef.h> | #include <stddef.h> | |||
#include <string.h> | #include <string.h> | |||
#include <time.h> | ||||
#include <sys/socket.h> | #include <sys/socket.h> | |||
#include <sys/time.h> | #include <sys/time.h> | |||
#include <sys/types.h> | #include <sys/types.h> | |||
#if HAVE_SYS_FILE_H | #if HAVE_SYS_FILE_H | |||
#include <sys/file.h> | #include <sys/file.h> | |||
#endif /* HAVE_SYS_FILE_H */ | #endif /* HAVE_SYS_FILE_H */ | |||
#ifdef IPV6 | #ifdef IPV6 | |||
#include <netinet/icmp6.h> | #include <netinet/icmp6.h> | |||
skipping to change at line 125 | skipping to change at line 123 | |||
#ifdef __cplusplus | #ifdef __cplusplus | |||
} | } | |||
#endif /* __cplusplus */ | #endif /* __cplusplus */ | |||
/*** Constants ***/ | /*** Constants ***/ | |||
#if HAVE_SO_TIMESTAMPNS | #if HAVE_SO_TIMESTAMPNS | |||
#define CLOCKID CLOCK_REALTIME | #define CLOCKID CLOCK_REALTIME | |||
#endif | #endif | |||
/* CLOCK_MONTONIC starts under macOS, OpenBSD and FreeBSD with undefined positiv | ||||
e point and can not be use | ||||
* see github PR #217 | ||||
*/ | ||||
#if !defined(CLOCKID) | #if !defined(CLOCKID) | |||
#if defined(CLOCK_MONOTONIC) | #if defined(CLOCK_MONOTONIC) && !defined(__APPLE__) && !defined(__OpenBSD__) && !defined(__FreeBSD__) | |||
#define CLOCKID CLOCK_MONOTONIC | #define CLOCKID CLOCK_MONOTONIC | |||
#else | #else | |||
#define CLOCKID CLOCK_REALTIME | #define CLOCKID CLOCK_REALTIME | |||
#endif | #endif | |||
#endif | #endif | |||
/*** Ping packet defines ***/ | /*** Ping packet defines ***/ | |||
#define MAX_IP_PACKET 65536 /* (theoretical) max IP packet size */ | #define MAX_IP_PACKET 65536 /* (theoretical) max IP packet size */ | |||
#define SIZE_IP_HDR 40 | #define SIZE_IP_HDR 40 | |||
skipping to change at line 400 | skipping to change at line 401 | |||
void print_warning(char* fmt, ...); | void print_warning(char* fmt, ...); | |||
int addr_cmp(struct sockaddr* a, struct sockaddr* b); | int addr_cmp(struct sockaddr* a, struct sockaddr* b); | |||
void host_add_ping_event(HOST_ENTRY *h, int index, int64_t ev_time); | void host_add_ping_event(HOST_ENTRY *h, int index, int64_t ev_time); | |||
void host_add_timeout_event(HOST_ENTRY *h, int index, int64_t ev_time); | void host_add_timeout_event(HOST_ENTRY *h, int index, int64_t ev_time); | |||
struct event *host_get_timeout_event(HOST_ENTRY *h, int index); | struct event *host_get_timeout_event(HOST_ENTRY *h, int index); | |||
void stats_add(HOST_ENTRY *h, int index, int success, int64_t latency); | void stats_add(HOST_ENTRY *h, int index, int success, int64_t latency); | |||
void update_current_time(); | void update_current_time(); | |||
/************************************************************ | /************************************************************ | |||
Function: p_setsockopt | ||||
************************************************************* | ||||
Inputs: p_uid: privileged uid. Others as per setsockopt(2) | ||||
Description: | ||||
Elevates privileges to p_uid when required, calls | ||||
setsockopt, and drops privileges back. | ||||
************************************************************/ | ||||
int p_setsockopt(uid_t p_uid, int sockfd, int level, int optname, | ||||
const void *optval, socklen_t optlen) | ||||
{ | ||||
const uid_t saved_uid = geteuid(); | ||||
int res; | ||||
if (p_uid != saved_uid && seteuid(p_uid)) { | ||||
perror("cannot elevate privileges for setsockopt"); | ||||
} | ||||
res = setsockopt(sockfd, level, optname, optval, optlen); | ||||
if (p_uid != saved_uid && seteuid(saved_uid)) { | ||||
perror("fatal error: could not drop privileges after setsockopt"); | ||||
/* continuing would be a security hole */ | ||||
exit(4); | ||||
} | ||||
return res; | ||||
} | ||||
/************************************************************ | ||||
Function: main | Function: main | |||
************************************************************* | ************************************************************* | |||
Inputs: int argc, char** argv | Inputs: int argc, char** argv | |||
Description: | Description: | |||
Main program entry point | Main program entry point | |||
************************************************************/ | ************************************************************/ | |||
int main(int argc, char** argv) | int main(int argc, char** argv) | |||
{ | { | |||
int c; | int c; | |||
uid_t uid; | const uid_t suid = geteuid(); | |||
int tos = 0; | int tos = 0; | |||
struct optparse optparse_state; | struct optparse optparse_state; | |||
#ifdef USE_SIGACTION | #ifdef USE_SIGACTION | |||
struct sigaction act; | struct sigaction act; | |||
#endif | #endif | |||
/* pre-parse -h/--help, so that we also can output help information | /* pre-parse -h/--help, so that we also can output help information | |||
* without trying to open the socket, which might fail */ | * without trying to open the socket, which might fail */ | |||
prog = argv[0]; | prog = argv[0]; | |||
if(argc == 2 && ( strcmp(argv[1],"-h")==0 || strcmp(argv[1],"--help")==0 )) { | if(argc == 2 && ( strcmp(argv[1],"-h")==0 || strcmp(argv[1],"--help")==0 )) { | |||
skipping to change at line 451 | skipping to change at line 488 | |||
if (strstr(prog, "fping6")) { | if (strstr(prog, "fping6")) { | |||
hints_ai_family = AF_INET6; | hints_ai_family = AF_INET6; | |||
} | } | |||
#endif | #endif | |||
memset(&src_addr, 0, sizeof(src_addr)); | memset(&src_addr, 0, sizeof(src_addr)); | |||
#ifdef IPV6 | #ifdef IPV6 | |||
memset(&src_addr6, 0, sizeof(src_addr6)); | memset(&src_addr6, 0, sizeof(src_addr6)); | |||
#endif | #endif | |||
if ((uid = getuid())) { | if (!suid && suid != getuid()) { | |||
/* drop privileges */ | /* *temporarily* drop privileges */ | |||
if (setuid(getuid()) == -1) | if (seteuid(getuid()) == -1) | |||
perror("cannot setuid"); | perror("cannot setuid"); | |||
} | } | |||
optparse_init(&optparse_state, argv); | optparse_init(&optparse_state, argv); | |||
ident4 = ident6 = htons(getpid() & 0xFFFF); | ident4 = ident6 = htons(getpid() & 0xFFFF); | |||
verbose_flag = 1; | verbose_flag = 1; | |||
backoff_flag = 1; | backoff_flag = 1; | |||
opterr = 1; | opterr = 1; | |||
/* get command line options */ | /* get command line options */ | |||
skipping to change at line 513 | skipping to change at line 550 | |||
{ NULL, 'z', OPTPARSE_REQUIRED }, | { NULL, 'z', OPTPARSE_REQUIRED }, | |||
#endif | #endif | |||
{ 0, 0, 0 } | { 0, 0, 0 } | |||
}; | }; | |||
float opt_value_float; | float opt_value_float; | |||
while ((c = optparse_long(&optparse_state, longopts, NULL)) != EOF) { | while ((c = optparse_long(&optparse_state, longopts, NULL)) != EOF) { | |||
switch (c) { | switch (c) { | |||
case '4': | case '4': | |||
#ifdef IPV6 | #ifdef IPV6 | |||
if (hints_ai_family != AF_UNSPEC) { | if (hints_ai_family != AF_UNSPEC && hints_ai_family != AF_INET) { | |||
fprintf(stderr, "%s: can't specify both -4 and -6\n", prog); | fprintf(stderr, "%s: can't specify both -4 and -6\n", prog); | |||
exit(1); | exit(1); | |||
} | } | |||
hints_ai_family = AF_INET; | hints_ai_family = AF_INET; | |||
#endif | #endif | |||
break; | break; | |||
case '6': | case '6': | |||
#ifdef IPV6 | #ifdef IPV6 | |||
if (hints_ai_family != AF_UNSPEC && hints_ai_family != AF_INET6) { | if (hints_ai_family != AF_UNSPEC && hints_ai_family != AF_INET6) { | |||
fprintf(stderr, "%s: can't specify both -4 and -6\n", prog); | fprintf(stderr, "%s: can't specify both -4 and -6\n", prog); | |||
skipping to change at line 743 | skipping to change at line 780 | |||
src_addr6_set = 1; | src_addr6_set = 1; | |||
break; | break; | |||
} | } | |||
#endif | #endif | |||
fprintf(stderr, "%s: can't parse source address: %s\n", prog, optpar se_state.optarg); | fprintf(stderr, "%s: can't parse source address: %s\n", prog, optpar se_state.optarg); | |||
exit(1); | exit(1); | |||
case 'I': | case 'I': | |||
#ifdef SO_BINDTODEVICE | #ifdef SO_BINDTODEVICE | |||
if (socket4 >= 0) { | if (socket4 >= 0) { | |||
if (setsockopt(socket4, SOL_SOCKET, SO_BINDTODEVICE, optparse_st ate.optarg, strlen(optparse_state.optarg))) { | if (p_setsockopt(suid, socket4, SOL_SOCKET, SO_BINDTODEVICE, opt parse_state.optarg, strlen(optparse_state.optarg))) { | |||
perror("binding to specific interface (SO_BINTODEVICE)"); | perror("binding to specific interface (SO_BINTODEVICE)"); | |||
exit(1); | exit(1); | |||
} | } | |||
} | } | |||
#ifdef IPV6 | #ifdef IPV6 | |||
if (socket6 >= 0) { | if (socket6 >= 0) { | |||
if (setsockopt(socket6, SOL_SOCKET, SO_BINDTODEVICE, optparse_st ate.optarg, strlen(optparse_state.optarg))) { | if (p_setsockopt(suid, socket6, SOL_SOCKET, SO_BINDTODEVICE, opt parse_state.optarg, strlen(optparse_state.optarg))) { | |||
perror("binding to specific interface (SO_BINTODEVICE), IPV6 "); | perror("binding to specific interface (SO_BINTODEVICE), IPV6 "); | |||
exit(1); | exit(1); | |||
} | } | |||
} | } | |||
#endif | #endif | |||
#else | #else | |||
printf("%s: cant bind to a particular net interface since SO_BINDTOD EVICE is not supported on your os.\n", prog); | printf("%s: cant bind to a particular net interface since SO_BINDTOD EVICE is not supported on your os.\n", prog); | |||
exit(3); | exit(3); | |||
; | ; | |||
#endif | #endif | |||
skipping to change at line 799 | skipping to change at line 836 | |||
break; | break; | |||
case '?': | case '?': | |||
fprintf(stderr, "%s: %s\n", argv[0], optparse_state.errmsg); | fprintf(stderr, "%s: %s\n", argv[0], optparse_state.errmsg); | |||
fprintf(stderr, "see 'fping -h' for usage information\n"); | fprintf(stderr, "see 'fping -h' for usage information\n"); | |||
exit(1); | exit(1); | |||
break; | break; | |||
} | } | |||
} | } | |||
/* permanently drop privileges */ | ||||
if (suid != getuid() && setuid(getuid())) { | ||||
perror("fatal: failed to permanently drop privileges"); | ||||
/* continuing would be a security hole */ | ||||
exit(4); | ||||
} | ||||
/* validate various option settings */ | /* validate various option settings */ | |||
#ifndef IPV6 | #ifndef IPV6 | |||
if (socket4 < 0) { | if (socket4 < 0) { | |||
#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 | #endif | |||
crash_and_burn("can't create socket (must run as root?)"); | crash_and_burn("can't create socket (must run as root?)"); | |||
} | } | |||
skipping to change at line 1063 | skipping to change at line 1107 | |||
} | } | |||
} | } | |||
else { | else { | |||
usage(1); | usage(1); | |||
} | } | |||
if (!num_hosts) { | if (!num_hosts) { | |||
exit(num_noaddress ? 2 : 1); | exit(num_noaddress ? 2 : 1); | |||
} | } | |||
if (socket4 >= 0) { | if (src_addr_set && socket4 >= 0) { | |||
socket_set_src_addr_ipv4(socket4, &src_addr, (socktype4 == SOCK_DGRAM) ? &ident4 : NULL); | socket_set_src_addr_ipv4(socket4, &src_addr, (socktype4 == SOCK_DGRAM) ? &ident4 : NULL); | |||
} | } | |||
#ifdef IPV6 | #ifdef IPV6 | |||
if (socket6 >= 0) { | if (src_addr6_set && socket6 >= 0) { | |||
socket_set_src_addr_ipv6(socket6, &src_addr6, (socktype6 == SOCK_DGRAM) ? &ident6 : NULL); | socket_set_src_addr_ipv6(socket6, &src_addr6, (socktype6 == SOCK_DGRAM) ? &ident6 : NULL); | |||
} | } | |||
#endif | #endif | |||
/* allocate and initialize array to map host nr to host_entry */ | /* allocate and initialize array to map host nr to host_entry */ | |||
{ | { | |||
struct event *cursor = event_queue_ping.first; | struct event *cursor = event_queue_ping.first; | |||
int i= 0; | int i= 0; | |||
table = (HOST_ENTRY**)calloc(num_hosts, sizeof(HOST_ENTRY *)); | table = (HOST_ENTRY**)calloc(num_hosts, sizeof(HOST_ENTRY *)); | |||
if (!table) | if (!table) | |||
skipping to change at line 1619 | skipping to change at line 1663 | |||
static int sent_charts = 0; | static int sent_charts = 0; | |||
int i; | int i; | |||
int64_t avg; | int64_t avg; | |||
HOST_ENTRY* h; | HOST_ENTRY* h; | |||
for (i = 0; i < num_hosts; i++) { | for (i = 0; i < num_hosts; i++) { | |||
h = table[i]; | h = table[i]; | |||
if (!sent_charts) { | if (!sent_charts) { | |||
printf("CHART fping.%s_packets '' 'FPing Packets for host %s' packet s '%s' fping.packets line 110020 %.0f\n", h->name, h->host, h->name, report_inte rval / 1e9); | printf("CHART fping.%s_packets '' 'FPing Packets for host %s' packet s '%s' fping.packets line 110020 %.0f\n", h->name, h->host, h->host, report_inte rval / 1e9); | |||
printf("DIMENSION xmt sent absolute 1 1\n"); | printf("DIMENSION xmt sent absolute 1 1\n"); | |||
printf("DIMENSION rcv received absolute 1 1\n"); | printf("DIMENSION rcv received absolute 1 1\n"); | |||
} | } | |||
printf("BEGIN fping.%s_packets\n", h->name); | printf("BEGIN fping.%s_packets\n", h->name); | |||
printf("SET xmt = %d\n", h->num_sent_i); | printf("SET xmt = %d\n", h->num_sent_i); | |||
printf("SET rcv = %d\n", h->num_recv_i); | printf("SET rcv = %d\n", h->num_recv_i); | |||
printf("END\n"); | printf("END\n"); | |||
if (!sent_charts) { | if (!sent_charts) { | |||
printf("CHART fping.%s_quality '' 'FPing Quality for host %s' percen tage '%s' fping.quality area 110010 %.0f\n", h->name, h->host, h->name, report_i nterval / 1e9); | printf("CHART fping.%s_quality '' 'FPing Quality for host %s' percen tage '%s' fping.quality area 110010 %.0f\n", h->name, h->host, h->host, report_i nterval / 1e9); | |||
printf("DIMENSION returned '' absolute 1 1\n"); | printf("DIMENSION returned '' absolute 1 1\n"); | |||
/* printf("DIMENSION lost '' absolute 1 1\n"); */ | /* printf("DIMENSION lost '' absolute 1 1\n"); */ | |||
} | } | |||
printf("BEGIN fping.%s_quality\n", h->name); | printf("BEGIN fping.%s_quality\n", h->name); | |||
/* | /* | |||
if( h->num_recv_i <= h->num_sent_i ) | if( h->num_recv_i <= h->num_sent_i ) | |||
printf("SET lost = %d\n", h->num_sent_i > 0 ? ( ( h->num_sent_i - h- >num_recv_i ) * 100 ) / h->num_sent_i : 0 ); | printf("SET lost = %d\n", h->num_sent_i > 0 ? ( ( h->num_sent_i - h- >num_recv_i ) * 100 ) / h->num_sent_i : 0 ); | |||
else | else | |||
printf("SET lost = 0\n"); | printf("SET lost = 0\n"); | |||
*/ | */ | |||
printf("SET returned = %d\n", h->num_sent_i > 0 ? ((h->num_recv_i * 100) / h->num_sent_i) : 0); | printf("SET returned = %d\n", h->num_sent_i > 0 ? ((h->num_recv_i * 100) / h->num_sent_i) : 0); | |||
printf("END\n"); | printf("END\n"); | |||
if (!sent_charts) { | if (!sent_charts) { | |||
printf("CHART fping.%s_latency '' 'FPing Latency for host %s' ms '%s ' fping.latency area 110000 %.0f\n", h->name, h->host, h->name, report_interval / 1e9); | printf("CHART fping.%s_latency '' 'FPing Latency for host %s' ms '%s ' fping.latency area 110000 %.0f\n", h->name, h->host, h->host, report_interval / 1e9); | |||
printf("DIMENSION min minimum absolute 1 1000000\n"); | printf("DIMENSION min minimum absolute 1 1000000\n"); | |||
printf("DIMENSION max maximum absolute 1 1000000\n"); | printf("DIMENSION max maximum absolute 1 1000000\n"); | |||
printf("DIMENSION avg average absolute 1 1000000\n"); | printf("DIMENSION avg average absolute 1 1000000\n"); | |||
} | } | |||
printf("BEGIN fping.%s_latency\n", h->name); | printf("BEGIN fping.%s_latency\n", h->name); | |||
if (h->num_recv_i) { | if (h->num_recv_i) { | |||
avg = h->total_time_i / h->num_recv_i; | avg = h->total_time_i / h->num_recv_i; | |||
printf("SET min = %ld\n", h->min_reply_i); | printf("SET min = %" PRId64 "\n", h->min_reply_i); | |||
printf("SET avg = %ld\n", avg); | printf("SET avg = %" PRId64 "\n", avg); | |||
printf("SET max = %ld\n", h->max_reply_i); | printf("SET max = %" PRId64 "\n", h->max_reply_i); | |||
} | } | |||
printf("END\n"); | printf("END\n"); | |||
h->num_sent_i = h->num_recv_i = h->max_reply_i = h->min_reply_i = h->tot al_time_i = 0; | h->num_sent_i = h->num_recv_i = h->max_reply_i = h->min_reply_i = h->tot al_time_i = 0; | |||
} | } | |||
sent_charts = 1; | sent_charts = 1; | |||
} | } | |||
/************************************************************ | /************************************************************ | |||
skipping to change at line 2056 | skipping to change at line 2100 | |||
hlen = (ip->ip_vhl & 0x0F) << 2; | hlen = (ip->ip_vhl & 0x0F) << 2; | |||
#else | #else | |||
hlen = ip->ip_hl << 2; | hlen = ip->ip_hl << 2; | |||
#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((struct sockaddr*)&response_addr, sizeof(response_addr), buf, INET6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST); | getnameinfo( response_addr, sizeof( struct sockaddr_in ), buf, INET6 _ADDRSTRLEN, NULL, 0, NI_NUMERICHOST); | |||
printf("received packet too short for ICMP (%d bytes from %s)\n", (i nt)reply_buf_len, buf); | printf("received packet too short for ICMP (%d bytes from %s)\n", (i nt)reply_buf_len, buf); | |||
} | } | |||
return -1; | return -1; | |||
} | } | |||
icp = (struct icmp*)(reply_buf + hlen); | icp = (struct icmp*)(reply_buf + hlen); | |||
if (icp->icmp_type != ICMP_ECHOREPLY) { | if (icp->icmp_type != ICMP_ECHOREPLY) { | |||
/* Handle other ICMP packets */ | /* Handle other ICMP packets */ | |||
struct icmp* sent_icmp; | struct icmp* sent_icmp; | |||
skipping to change at line 2089 | skipping to change at line 2133 | |||
if (sent_icmp->icmp_type != ICMP_ECHO || sent_icmp->icmp_id != ident4) { | if (sent_icmp->icmp_type != ICMP_ECHO || sent_icmp->icmp_id != ident4) { | |||
/* not caused by us */ | /* not caused by us */ | |||
return -1; | return -1; | |||
} | } | |||
seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), current_time_ns) ; | seqmap_value = seqmap_fetch(ntohs(sent_icmp->icmp_seq), current_time_ns) ; | |||
if (seqmap_value == NULL) { | if (seqmap_value == NULL) { | |||
return -1; | return -1; | |||
} | } | |||
getnameinfo(response_addr, response_addr_len, addr_ascii, INET6_ADDRSTRL EN, NULL, 0, NI_NUMERICHOST); | getnameinfo(response_addr, sizeof( struct sockaddr_in ), addr_ascii, INE T6_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST); | |||
switch (icp->icmp_type) { | switch (icp->icmp_type) { | |||
case ICMP_UNREACH: | case ICMP_UNREACH: | |||
h = table[seqmap_value->host_nr]; | h = table[seqmap_value->host_nr]; | |||
if (icp->icmp_code > ICMP_UNREACH_MAXTYPE) { | if (icp->icmp_code > ICMP_UNREACH_MAXTYPE) { | |||
print_warning("ICMP Unreachable (Invalid Code) from %s for ICMP Echo sent to %s", | print_warning("ICMP Unreachable (Invalid Code) from %s for ICMP Echo sent to %s", | |||
addr_ascii, h->host); | addr_ascii, h->host); | |||
} | } | |||
else { | else { | |||
print_warning("%s from %s for ICMP Echo sent to %s", | print_warning("%s from %s for ICMP Echo sent to %s", | |||
skipping to change at line 2881 | skipping to change at line 2925 | |||
fprintf(out, " -r, --retry=N number of retries (default: %d)\n", DEFA ULT_RETRY); | fprintf(out, " -r, --retry=N number of retries (default: %d)\n", DEFA ULT_RETRY); | |||
fprintf(out, " -R, --random random packet data (to foil link data co mpression)\n"); | fprintf(out, " -R, --random random packet data (to foil link data co mpression)\n"); | |||
fprintf(out, " -S, --src=IP set source address\n"); | fprintf(out, " -S, --src=IP set source address\n"); | |||
fprintf(out, " -t, --timeout=MSEC individual target initial timeout (defau lt: %.0f ms,\n", timeout / 1e6); | fprintf(out, " -t, --timeout=MSEC individual target initial timeout (defau lt: %.0f ms,\n", timeout / 1e6); | |||
fprintf(out, " except with -l/-c/-C, where it's the -p period up to 2000 ms)\n"); | fprintf(out, " except with -l/-c/-C, where it's the -p period up to 2000 ms)\n"); | |||
fprintf(out, "\n"); | fprintf(out, "\n"); | |||
fprintf(out, "Output options:\n"); | fprintf(out, "Output options:\n"); | |||
fprintf(out, " -a, --alive show targets that are alive\n"); | fprintf(out, " -a, --alive show targets that are alive\n"); | |||
fprintf(out, " -A, --addr show targets by address\n"); | fprintf(out, " -A, --addr show targets by address\n"); | |||
fprintf(out, " -C, --vcount=N same as -c, report results in verbose fo rmat\n"); | fprintf(out, " -C, --vcount=N same as -c, report results in verbose fo rmat\n"); | |||
fprintf(out, " -d, --rdns show targets by name (force reverse-DNS lookup)\n"); | ||||
fprintf(out, " -D, --timestamp print timestamp before each output line\ n"); | fprintf(out, " -D, --timestamp print timestamp before each output line\ n"); | |||
fprintf(out, " -e, --elapsed show elapsed time on return packets\n"); | fprintf(out, " -e, --elapsed show elapsed time on return packets\n"); | |||
fprintf(out, " -i, --interval=MSEC interval between sending ping packets (default: %.0f ms)\n", interval / 1e6); | fprintf(out, " -i, --interval=MSEC interval between sending ping packets (default: %.0f ms)\n", interval / 1e6); | |||
fprintf(out, " -n, --name show targets by name (-d is equivalent)\ n"); | fprintf(out, " -n, --name show targets by name (reverse-DNS lookup for target IPs)\n"); | |||
fprintf(out, " -N, --netdata output compatible for netdata (-l -Q are required)\n"); | fprintf(out, " -N, --netdata output compatible for netdata (-l -Q are required)\n"); | |||
fprintf(out, " -o, --outage show the accumulated outage time (lost p ackets * packet interval)\n"); | fprintf(out, " -o, --outage show the accumulated outage time (lost p ackets * packet interval)\n"); | |||
fprintf(out, " -q, --quiet quiet (don't show per-target/per-ping re sults)\n"); | fprintf(out, " -q, --quiet quiet (don't show per-target/per-ping re sults)\n"); | |||
fprintf(out, " -Q, --squiet=SECS same as -q, but show summary every n sec onds\n"); | fprintf(out, " -Q, --squiet=SECS same as -q, but add interval summary eve ry SECS seconds\n"); | |||
fprintf(out, " -s, --stats print final stats\n"); | fprintf(out, " -s, --stats print final stats\n"); | |||
fprintf(out, " -u, --unreach show targets that are unreachable\n"); | fprintf(out, " -u, --unreach show targets that are unreachable\n"); | |||
fprintf(out, " -v, --version show version\n"); | fprintf(out, " -v, --version show version\n"); | |||
fprintf(out, " -x, --reachable=N shows if >=N hosts are reachable or not\ n"); | fprintf(out, " -x, --reachable=N shows if >=N hosts are reachable or not\ n"); | |||
exit(is_error); | exit(is_error); | |||
} | } | |||
End of changes. 21 change blocks. | ||||
22 lines changed or deleted | 68 lines changed or added |