client: don't require address in ntpdata command

If no address is specified, use the SOURCE_DATA command to get addresses
of NTP sources, and request NTP_DATA for all of them.
This commit is contained in:
Miroslav Lichvar 2016-12-14 09:56:52 +01:00
parent 2e311d1766
commit 967f3e4f77
2 changed files with 96 additions and 64 deletions

154
client.c
View file

@ -1191,7 +1191,7 @@ give_help(void)
"\0\0" "\0\0"
"NTP sources:\0\0" "NTP sources:\0\0"
"activity\0Check how many NTP sources are online/offline\0" "activity\0Check how many NTP sources are online/offline\0"
"ntpdata <address>\0Display information about last valid measurement\0" "ntpdata [<address>]\0Display information about last valid measurement\0"
"add server <address> [options]\0Add new NTP server\0" "add server <address> [options]\0Add new NTP server\0"
"add peer <address> [options]\0Add new NTP peer\0" "add peer <address> [options]\0Add new NTP peer\0"
"delete <address>\0Remove server or peer\0" "delete <address>\0Remove server or peer\0"
@ -2244,71 +2244,103 @@ process_cmd_ntpdata(char *line)
CMD_Reply reply; CMD_Reply reply;
IPAddr remote_addr, local_addr; IPAddr remote_addr, local_addr;
struct timespec ref_time; struct timespec ref_time;
uint32_t i, n_sources;
uint16_t mode;
int specified_addr;
if (DNS_Name2IPAddress(line, &remote_addr, 1) != DNS_Success) { if (*line) {
LOG(LOGS_ERR, LOGF_Client, "Could not get address for hostname"); specified_addr = 1;
return 0; n_sources = 1;
} else {
specified_addr = 0;
request.command = htons(REQ_N_SOURCES);
if (!request_reply(&request, &reply, RPY_N_SOURCES, 0))
return 0;
n_sources = ntohl(reply.data.n_sources.n_sources);
} }
request.command = htons(REQ_NTP_DATA); for (i = 0; i < n_sources; i++) {
UTI_IPHostToNetwork(&remote_addr, &request.data.ntp_data.ip_addr); if (specified_addr) {
if (!request_reply(&request, &reply, RPY_NTP_DATA, 0)) if (DNS_Name2IPAddress(line, &remote_addr, 1) != DNS_Success) {
return 0; LOG(LOGS_ERR, LOGF_Client, "Could not get address for hostname");
return 0;
}
} else {
request.command = htons(REQ_SOURCE_DATA);
request.data.source_data.index = htonl(i);
if (!request_reply(&request, &reply, RPY_SOURCE_DATA, 0))
return 0;
UTI_IPNetworkToHost(&reply.data.ntp_data.remote_addr, &remote_addr); mode = ntohs(reply.data.source_data.mode);
UTI_IPNetworkToHost(&reply.data.ntp_data.local_addr, &local_addr); if (mode != RPY_SD_MD_CLIENT && mode != RPY_SD_MD_PEER)
UTI_TimespecNetworkToHost(&reply.data.ntp_data.ref_time, &ref_time); continue;
print_report("Remote address : %s (%R)\n" UTI_IPNetworkToHost(&reply.data.source_data.ip_addr, &remote_addr);
"Remote port : %u\n" }
"Local address : %s (%R)\n"
"Leap status : %L\n" request.command = htons(REQ_NTP_DATA);
"Version : %u\n" UTI_IPHostToNetwork(&remote_addr, &request.data.ntp_data.ip_addr);
"Mode : %M\n" if (!request_reply(&request, &reply, RPY_NTP_DATA, 0))
"Stratum : %u\n" return 0;
"Poll : %d\n"
"Precision : %.9f seconds\n" UTI_IPNetworkToHost(&reply.data.ntp_data.remote_addr, &remote_addr);
"Root delay : %.6f seconds\n" UTI_IPNetworkToHost(&reply.data.ntp_data.local_addr, &local_addr);
"Root dispersion : %.6f seconds\n" UTI_TimespecNetworkToHost(&reply.data.ntp_data.ref_time, &ref_time);
"Reference ID : %R\n"
"Reference time : %T\n" if (!specified_addr && !csv_mode)
"Offset : %+.9f seconds\n" printf("\n");
"Peer delay : %.9f seconds\n"
"Peer dispersion : %.9f seconds\n" print_report("Remote address : %s (%R)\n"
"Response time : %.9f seconds\n" "Remote port : %u\n"
"Jitter asymmetry: %+.2f\n" "Local address : %s (%R)\n"
"NTP tests : %.3b %.3b %.4b\n" "Leap status : %L\n"
"Interleaved : %B\n" "Version : %u\n"
"Authenticated : %B\n" "Mode : %M\n"
"TX timestamping : %N\n" "Stratum : %u\n"
"RX timestamping : %N\n" "Poll : %d\n"
"Total TX : %U\n" "Precision : %.9f seconds\n"
"Total RX : %U\n" "Root delay : %.6f seconds\n"
"Total valid RX : %U\n", "Root dispersion : %.6f seconds\n"
UTI_IPToString(&remote_addr), (unsigned long)UTI_IPToRefid(&remote_addr), "Reference ID : %R\n"
ntohs(reply.data.ntp_data.remote_port), "Reference time : %T\n"
UTI_IPToString(&local_addr), (unsigned long)UTI_IPToRefid(&local_addr), "Offset : %+.9f seconds\n"
reply.data.ntp_data.leap, reply.data.ntp_data.version, "Peer delay : %.9f seconds\n"
reply.data.ntp_data.mode, reply.data.ntp_data.stratum, "Peer dispersion : %.9f seconds\n"
reply.data.ntp_data.poll, UTI_Log2ToDouble(reply.data.ntp_data.precision), "Response time : %.9f seconds\n"
UTI_FloatNetworkToHost(reply.data.ntp_data.root_delay), "Jitter asymmetry: %+.2f\n"
UTI_FloatNetworkToHost(reply.data.ntp_data.root_dispersion), "NTP tests : %.3b %.3b %.4b\n"
(unsigned long)ntohl(reply.data.ntp_data.ref_id), &ref_time, "Interleaved : %B\n"
UTI_FloatNetworkToHost(reply.data.ntp_data.offset), "Authenticated : %B\n"
UTI_FloatNetworkToHost(reply.data.ntp_data.peer_delay), "TX timestamping : %N\n"
UTI_FloatNetworkToHost(reply.data.ntp_data.peer_dispersion), "RX timestamping : %N\n"
UTI_FloatNetworkToHost(reply.data.ntp_data.response_time), "Total TX : %U\n"
UTI_FloatNetworkToHost(reply.data.ntp_data.jitter_asymmetry), "Total RX : %U\n"
ntohs(reply.data.ntp_data.flags) >> 7, "Total valid RX : %U\n",
ntohs(reply.data.ntp_data.flags) >> 4, UTI_IPToString(&remote_addr), (unsigned long)UTI_IPToRefid(&remote_addr),
ntohs(reply.data.ntp_data.flags), ntohs(reply.data.ntp_data.remote_port),
ntohs(reply.data.ntp_data.flags) & RPY_NTP_FLAG_INTERLEAVED, UTI_IPToString(&local_addr), (unsigned long)UTI_IPToRefid(&local_addr),
ntohs(reply.data.ntp_data.flags) & RPY_NTP_FLAG_AUTHENTICATED, reply.data.ntp_data.leap, reply.data.ntp_data.version,
reply.data.ntp_data.tx_tss_char, reply.data.ntp_data.rx_tss_char, reply.data.ntp_data.mode, reply.data.ntp_data.stratum,
(unsigned long)ntohl(reply.data.ntp_data.total_tx_count), reply.data.ntp_data.poll, UTI_Log2ToDouble(reply.data.ntp_data.precision),
(unsigned long)ntohl(reply.data.ntp_data.total_rx_count), UTI_FloatNetworkToHost(reply.data.ntp_data.root_delay),
(unsigned long)ntohl(reply.data.ntp_data.total_valid_count), UTI_FloatNetworkToHost(reply.data.ntp_data.root_dispersion),
REPORT_END); (unsigned long)ntohl(reply.data.ntp_data.ref_id), &ref_time,
UTI_FloatNetworkToHost(reply.data.ntp_data.offset),
UTI_FloatNetworkToHost(reply.data.ntp_data.peer_delay),
UTI_FloatNetworkToHost(reply.data.ntp_data.peer_dispersion),
UTI_FloatNetworkToHost(reply.data.ntp_data.response_time),
UTI_FloatNetworkToHost(reply.data.ntp_data.jitter_asymmetry),
ntohs(reply.data.ntp_data.flags) >> 7,
ntohs(reply.data.ntp_data.flags) >> 4,
ntohs(reply.data.ntp_data.flags),
ntohs(reply.data.ntp_data.flags) & RPY_NTP_FLAG_INTERLEAVED,
ntohs(reply.data.ntp_data.flags) & RPY_NTP_FLAG_AUTHENTICATED,
reply.data.ntp_data.tx_tss_char, reply.data.ntp_data.rx_tss_char,
(unsigned long)ntohl(reply.data.ntp_data.total_tx_count),
(unsigned long)ntohl(reply.data.ntp_data.total_rx_count),
(unsigned long)ntohl(reply.data.ntp_data.total_valid_count),
REPORT_END);
}
return 1; return 1;
} }

View file

@ -441,10 +441,10 @@ the offline state.
the name of the server or peer was not resolved to an address yet; this source is the name of the server or peer was not resolved to an address yet; this source is
not visible in the *sources* and *sourcestats* reports. not visible in the *sources* and *sourcestats* reports.
[[ntpdata]]*ntpdata* _address_:: [[ntpdata]]*ntpdata* [_address_]::
The *ntpdata* command displays the last valid measurement and other The *ntpdata* command displays the last valid measurement and other
NTP-specific information about the NTP source. An example of the output is NTP-specific information about the specified NTP source, or all NTP sources if
shown below. no address was specified. An example of the output is shown below.
+ +
---- ----
Remote address : 203.0.113.15 (CB00710F) Remote address : 203.0.113.15 (CB00710F)