#define REQ_NTP_SOURCE_NAME 65
#define REQ_RESET_SOURCES 66
#define REQ_AUTH_DATA 67
-#define N_REQUEST_TYPES 68
+#define REQ_CLIENT_ACCESSES_BY_INDEX3 68
+#define N_REQUEST_TYPES 69
/* Structure used to exchange timespecs independent of time_t size */
typedef struct {
typedef struct {
uint32_t first_index;
uint32_t n_clients;
+ uint32_t reset;
int32_t EOR;
} REQ_ClientAccessesByIndex;
"\0(e.g. Sep 25, 2015 16:30:05 or 16:30:05)\0"
"\0\0NTP access:\0\0"
"accheck <address>\0Check whether address is allowed\0"
- "clients\0Report on clients that have accessed the server\0"
+ "clients [-r]\0Report on clients that have accessed the server\0"
"serverstats\0Display statistics of the server\0"
"allow [<subnet>]\0Allow access to subnet as a default\0"
"allow all [<subnet>]\0Allow access to subnet and all children\0"
CMD_Request request;
CMD_Reply reply;
IPAddr ip;
- uint32_t i, n_clients, next_index, n_indices;
+ uint32_t i, n_clients, next_index, n_indices, reset;
RPY_ClientAccesses_Client *client;
- char name[50];
+ char name[50], *opt;
next_index = 0;
+ reset = 0;
+
+ while (*line) {
+ opt = line;
+ line = CPS_SplitWord(line);
+ if (strcmp(opt, "-r") == 0)
+ reset = 1;
+ }
print_header("Hostname NTP Drop Int IntL Last Cmd Drop Int Last");
while (1) {
- request.command = htons(REQ_CLIENT_ACCESSES_BY_INDEX2);
+ request.command = htons(REQ_CLIENT_ACCESSES_BY_INDEX3);
request.data.client_accesses_by_index.first_index = htonl(next_index);
request.data.client_accesses_by_index.n_clients = htonl(MAX_CLIENT_ACCESSES);
+ request.data.client_accesses_by_index.reset = htonl(reset);
if (!request_reply(&request, &reply, RPY_CLIENT_ACCESSES_BY_INDEX2, 0))
return 0;
/* ================================================== */
int
-CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, struct timespec *now)
+CLG_GetClientAccessReportByIndex(int index, int reset,
+ RPT_ClientAccessByIndex_Report *report, struct timespec *now)
{
Record *record;
uint32_t now_ts;
report->last_ntp_hit_ago = get_last_ago(now_ts, record->last_ntp_hit);
report->last_cmd_hit_ago = get_last_ago(now_ts, record->last_cmd_hit);
+ if (reset) {
+ record->ntp_hits = record->cmd_hits = 0;
+ record->ntp_drops = record->cmd_drops = 0;
+ }
+
return 1;
}
/* And some reporting functions, for use by chronyc. */
extern int CLG_GetNumberOfIndices(void);
-extern int CLG_GetClientAccessReportByIndex(int index, RPT_ClientAccessByIndex_Report *report, struct timespec *now);
+extern int CLG_GetClientAccessReportByIndex(int index, int reset,
+ RPT_ClientAccessByIndex_Report *report,
+ struct timespec *now);
extern void CLG_GetServerStatsReport(RPT_ServerStatsReport *report);
#endif /* GOT_CLIENTLOG_H */
PERMIT_OPEN, /* NTP_SOURCE_NAME */
PERMIT_AUTH, /* RESET_SOURCES */
PERMIT_AUTH, /* AUTH_DATA */
+ PERMIT_AUTH, /* CLIENT_ACCESSES_BY_INDEX3 */
};
/* ================================================== */
RPT_ClientAccessByIndex_Report report;
RPY_ClientAccesses_Client *client;
int n_indices;
- uint32_t i, j, req_first_index, req_n_clients;
+ uint32_t i, j, req_first_index, req_n_clients, req_reset;
struct timespec now;
SCH_GetLastEventTime(&now, NULL, NULL);
req_n_clients = ntohl(rx_message->data.client_accesses_by_index.n_clients);
if (req_n_clients > MAX_CLIENT_ACCESSES)
req_n_clients = MAX_CLIENT_ACCESSES;
+ req_reset = ntohl(rx_message->data.client_accesses_by_index.reset);
n_indices = CLG_GetNumberOfIndices();
if (n_indices < 0) {
tx_message->data.client_accesses_by_index.n_indices = htonl(n_indices);
for (i = req_first_index, j = 0; i < (uint32_t)n_indices && j < req_n_clients; i++) {
- if (!CLG_GetClientAccessReportByIndex(i, &report, &now))
+ if (!CLG_GetClientAccessReportByIndex(i, req_reset, &report, &now))
continue;
client = &tx_message->data.client_accesses_by_index.clients[j++];
handle_cyclelogs(&rx_message, &tx_message);
break;
- case REQ_CLIENT_ACCESSES_BY_INDEX2:
+ case REQ_CLIENT_ACCESSES_BY_INDEX3:
handle_client_accesses_by_index(&rx_message, &tx_message);
break;
all*, *deny*, and *deny all* commands specified either via *chronyc*, or in
*chronyd*'s configuration file.
-[[clients]]*clients*::
+[[clients]]*clients* [*-r*]::
This command shows a list of clients that have accessed the server, through
either the NTP or command ports. It does not include accesses over
-the Unix domain command socket. There are no arguments.
+the Unix domain command socket.
++
+If the *-r* option is specified, *chronyd* will reset the counters of received
+and dropped packets after reporting the current values.
+
An example of the output is:
+
REQ_LENGTH_ENTRY(smoothtime, null), /* SMOOTHTIME */
REQ_LENGTH_ENTRY(null, null), /* REFRESH */
REQ_LENGTH_ENTRY(null, server_stats), /* SERVER_STATS */
- REQ_LENGTH_ENTRY(client_accesses_by_index,
- client_accesses_by_index), /* CLIENT_ACCESSES_BY_INDEX2 */
+ { 0, 0 }, /* CLIENT_ACCESSES_BY_INDEX2 - not supported */
REQ_LENGTH_ENTRY(local, null), /* LOCAL2 */
REQ_LENGTH_ENTRY(ntp_data, ntp_data), /* NTP_DATA */
{ 0, 0 }, /* ADD_SERVER2 */
ntp_source_name), /* NTP_SOURCE_NAME */
REQ_LENGTH_ENTRY(null, null), /* RESET_SOURCES */
REQ_LENGTH_ENTRY(auth_data, auth_data), /* AUTH_DATA */
+ REQ_LENGTH_ENTRY(client_accesses_by_index,
+ client_accesses_by_index), /* CLIENT_ACCESSES_BY_INDEX3 */
};
static const uint16_t reply_lengths[] = {