mirror of
https://gitlab.com/chrony/chrony.git
synced 2025-12-03 18:05:06 -05:00
Handle the NULL and LOGON requests as unknown (invalid) instead of returning the success and failed status respectively. They have been unused for very long time now.
226 lines
10 KiB
C
226 lines
10 KiB
C
/*
|
|
chronyd/chronyc - Programs for keeping computer clocks accurate.
|
|
|
|
**********************************************************************
|
|
* Copyright (C) Richard P. Curnow 1997-2002
|
|
* Copyright (C) Miroslav Lichvar 2014-2016
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of version 2 of the GNU General Public License as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
**********************************************************************
|
|
|
|
=======================================================================
|
|
|
|
Routines to compute the expected length of a command or reply packet.
|
|
These operate on the RAW NETWORK packets, from the point of view of
|
|
integer endianness within the structures.
|
|
|
|
*/
|
|
#include "config.h"
|
|
|
|
#include "sysincl.h"
|
|
|
|
#include "util.h"
|
|
#include "pktlength.h"
|
|
|
|
#define PADDING_LENGTH_(request_length, reply_length) \
|
|
(uint16_t)((request_length) < (reply_length) ? (reply_length) - (request_length) : 0)
|
|
|
|
#define PADDING_LENGTH(request_data, reply_data) \
|
|
PADDING_LENGTH_(offsetof(CMD_Request, request_data), offsetof(CMD_Reply, reply_data))
|
|
|
|
#define REQ_LENGTH_ENTRY(request_data_field, reply_data_field) \
|
|
{ offsetof(CMD_Request, data.request_data_field.EOR), \
|
|
PADDING_LENGTH(data.request_data_field.EOR, data.reply_data_field.EOR) }
|
|
|
|
#define RPY_LENGTH_ENTRY(reply_data_field) \
|
|
offsetof(CMD_Reply, data.reply_data_field.EOR)
|
|
|
|
/* ================================================== */
|
|
|
|
struct request_length {
|
|
uint16_t command;
|
|
uint16_t padding;
|
|
};
|
|
|
|
static const struct request_length request_lengths[] = {
|
|
{ 0, 0 }, /* NULL - not supported */
|
|
REQ_LENGTH_ENTRY(online, null), /* ONLINE */
|
|
REQ_LENGTH_ENTRY(offline, null), /* OFFLINE */
|
|
REQ_LENGTH_ENTRY(burst, null), /* BURST */
|
|
REQ_LENGTH_ENTRY(modify_minpoll, null), /* MODIFY_MINPOLL */
|
|
REQ_LENGTH_ENTRY(modify_maxpoll, null), /* MODIFY_MAXPOLL */
|
|
REQ_LENGTH_ENTRY(dump, null), /* DUMP */
|
|
REQ_LENGTH_ENTRY(modify_maxdelay, null), /* MODIFY_MAXDELAY */
|
|
REQ_LENGTH_ENTRY(modify_maxdelayratio, null), /* MODIFY_MAXDELAYRATIO */
|
|
REQ_LENGTH_ENTRY(modify_maxupdateskew, null), /* MODIFY_MAXUPDATESKEW */
|
|
{ 0, 0 }, /* LOGON - not supported */
|
|
REQ_LENGTH_ENTRY(settime, manual_timestamp), /* SETTIME */
|
|
{ 0, 0 }, /* LOCAL */
|
|
REQ_LENGTH_ENTRY(manual, null), /* MANUAL */
|
|
REQ_LENGTH_ENTRY(null, n_sources), /* N_SOURCES */
|
|
REQ_LENGTH_ENTRY(source_data, source_data), /* SOURCE_DATA */
|
|
REQ_LENGTH_ENTRY(null, null), /* REKEY */
|
|
REQ_LENGTH_ENTRY(allow_deny, null), /* ALLOW */
|
|
REQ_LENGTH_ENTRY(allow_deny, null), /* ALLOWALL */
|
|
REQ_LENGTH_ENTRY(allow_deny, null), /* DENY */
|
|
REQ_LENGTH_ENTRY(allow_deny, null), /* DENYALL */
|
|
REQ_LENGTH_ENTRY(allow_deny, null), /* CMDALLOW */
|
|
REQ_LENGTH_ENTRY(allow_deny, null), /* CMDALLOWALL */
|
|
REQ_LENGTH_ENTRY(allow_deny, null), /* CMDDENY */
|
|
REQ_LENGTH_ENTRY(allow_deny, null), /* CMDDENYALL */
|
|
REQ_LENGTH_ENTRY(ac_check, null), /* ACCHECK */
|
|
REQ_LENGTH_ENTRY(ac_check, null), /* CMDACCHECK */
|
|
{ 0, 0 }, /* ADD_SERVER */
|
|
{ 0, 0 }, /* ADD_PEER */
|
|
REQ_LENGTH_ENTRY(del_source, null), /* DEL_SOURCE */
|
|
REQ_LENGTH_ENTRY(null, null), /* WRITERTC */
|
|
REQ_LENGTH_ENTRY(dfreq, null), /* DFREQ */
|
|
{ 0, 0 }, /* DOFFSET - not supported */
|
|
REQ_LENGTH_ENTRY(null, tracking), /* TRACKING */
|
|
REQ_LENGTH_ENTRY(sourcestats, sourcestats), /* SOURCESTATS */
|
|
REQ_LENGTH_ENTRY(null, rtc), /* RTCREPORT */
|
|
REQ_LENGTH_ENTRY(null, null), /* TRIMRTC */
|
|
REQ_LENGTH_ENTRY(null, null), /* CYCLELOGS */
|
|
{ 0, 0 }, /* SUBNETS_ACCESSED - not supported */
|
|
{ 0, 0 }, /* CLIENT_ACCESSES - not supported */
|
|
{ 0, 0 }, /* CLIENT_ACCESSES_BY_INDEX - not supported */
|
|
REQ_LENGTH_ENTRY(null, manual_list), /* MANUAL_LIST */
|
|
REQ_LENGTH_ENTRY(manual_delete, null), /* MANUAL_DELETE */
|
|
REQ_LENGTH_ENTRY(null, null), /* MAKESTEP */
|
|
REQ_LENGTH_ENTRY(null, activity), /* ACTIVITY */
|
|
REQ_LENGTH_ENTRY(modify_minstratum, null), /* MODIFY_MINSTRATUM */
|
|
REQ_LENGTH_ENTRY(modify_polltarget, null), /* MODIFY_POLLTARGET */
|
|
REQ_LENGTH_ENTRY(modify_maxdelaydevratio, null), /* MODIFY_MAXDELAYDEVRATIO */
|
|
REQ_LENGTH_ENTRY(null, null), /* RESELECT */
|
|
REQ_LENGTH_ENTRY(reselect_distance, null), /* RESELECTDISTANCE */
|
|
REQ_LENGTH_ENTRY(modify_makestep, null), /* MODIFY_MAKESTEP */
|
|
REQ_LENGTH_ENTRY(null, smoothing), /* SMOOTHING */
|
|
REQ_LENGTH_ENTRY(smoothtime, null), /* SMOOTHTIME */
|
|
REQ_LENGTH_ENTRY(null, null), /* REFRESH */
|
|
REQ_LENGTH_ENTRY(null, server_stats), /* SERVER_STATS */
|
|
{ 0, 0 }, /* CLIENT_ACCESSES_BY_INDEX2 - not supported */
|
|
{ 0, 0 }, /* LOCAL2 - not supported */
|
|
REQ_LENGTH_ENTRY(ntp_data, ntp_data), /* NTP_DATA */
|
|
{ 0, 0 }, /* ADD_SERVER2 */
|
|
{ 0, 0 }, /* ADD_PEER2 */
|
|
{ 0, 0 }, /* ADD_SERVER3 */
|
|
{ 0, 0 }, /* ADD_PEER3 */
|
|
REQ_LENGTH_ENTRY(null, null), /* SHUTDOWN */
|
|
REQ_LENGTH_ENTRY(null, null), /* ONOFFLINE */
|
|
REQ_LENGTH_ENTRY(ntp_source, null), /* ADD_SOURCE */
|
|
REQ_LENGTH_ENTRY(ntp_source_name,
|
|
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 */
|
|
REQ_LENGTH_ENTRY(select_data, select_data), /* SELECT_DATA */
|
|
REQ_LENGTH_ENTRY(null, null), /* RELOAD_SOURCES */
|
|
REQ_LENGTH_ENTRY(doffset, null), /* DOFFSET2 */
|
|
REQ_LENGTH_ENTRY(modify_select_opts, null), /* MODIFY_SELECTOPTS */
|
|
REQ_LENGTH_ENTRY(modify_offset, null), /* MODIFY_OFFSET */
|
|
REQ_LENGTH_ENTRY(local, null), /* LOCAL3 */
|
|
};
|
|
|
|
static const uint16_t reply_lengths[] = {
|
|
0, /* empty slot */
|
|
RPY_LENGTH_ENTRY(null), /* NULL */
|
|
RPY_LENGTH_ENTRY(n_sources), /* N_SOURCES */
|
|
RPY_LENGTH_ENTRY(source_data), /* SOURCE_DATA */
|
|
0, /* MANUAL_TIMESTAMP */
|
|
RPY_LENGTH_ENTRY(tracking), /* TRACKING */
|
|
RPY_LENGTH_ENTRY(sourcestats), /* SOURCESTATS */
|
|
RPY_LENGTH_ENTRY(rtc), /* RTC */
|
|
0, /* SUBNETS_ACCESSED - not supported */
|
|
0, /* CLIENT_ACCESSES - not supported */
|
|
0, /* CLIENT_ACCESSES_BY_INDEX - not supported */
|
|
0, /* MANUAL_LIST - not supported */
|
|
RPY_LENGTH_ENTRY(activity), /* ACTIVITY */
|
|
RPY_LENGTH_ENTRY(smoothing), /* SMOOTHING */
|
|
0, /* SERVER_STATS - not supported */
|
|
0, /* CLIENT_ACCESSES_BY_INDEX2 - not supported */
|
|
0, /* NTP_DATA - not supported */
|
|
RPY_LENGTH_ENTRY(manual_timestamp), /* MANUAL_TIMESTAMP2 */
|
|
RPY_LENGTH_ENTRY(manual_list), /* MANUAL_LIST2 */
|
|
RPY_LENGTH_ENTRY(ntp_source_name), /* NTP_SOURCE_NAME */
|
|
RPY_LENGTH_ENTRY(auth_data), /* AUTH_DATA */
|
|
RPY_LENGTH_ENTRY(client_accesses_by_index), /* CLIENT_ACCESSES_BY_INDEX3 */
|
|
0, /* SERVER_STATS2 - not supported */
|
|
RPY_LENGTH_ENTRY(select_data), /* SELECT_DATA */
|
|
0, /* SERVER_STATS3 - not supported */
|
|
RPY_LENGTH_ENTRY(server_stats), /* SERVER_STATS4 */
|
|
RPY_LENGTH_ENTRY(ntp_data), /* NTP_DATA2 */
|
|
};
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
PKL_CommandLength(CMD_Request *r)
|
|
{
|
|
uint32_t type;
|
|
int command_length;
|
|
|
|
assert(sizeof (request_lengths) / sizeof (request_lengths[0]) == N_REQUEST_TYPES);
|
|
|
|
type = ntohs(r->command);
|
|
if (type >= N_REQUEST_TYPES)
|
|
return 0;
|
|
|
|
command_length = request_lengths[type].command;
|
|
if (!command_length)
|
|
return 0;
|
|
|
|
return command_length + PKL_CommandPaddingLength(r);
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
PKL_CommandPaddingLength(CMD_Request *r)
|
|
{
|
|
uint32_t type;
|
|
|
|
if (r->version < PROTO_VERSION_PADDING)
|
|
return 0;
|
|
|
|
type = ntohs(r->command);
|
|
|
|
if (type >= N_REQUEST_TYPES)
|
|
return 0;
|
|
|
|
return request_lengths[ntohs(r->command)].padding;
|
|
}
|
|
|
|
/* ================================================== */
|
|
|
|
int
|
|
PKL_ReplyLength(CMD_Reply *r)
|
|
{
|
|
uint32_t type;
|
|
|
|
assert(sizeof (reply_lengths) / sizeof (reply_lengths[0]) == N_REPLY_TYPES);
|
|
|
|
type = ntohs(r->reply);
|
|
|
|
/* Note that reply type codes start from 1, not 0 */
|
|
if (type < 1 || type >= N_REPLY_TYPES)
|
|
return 0;
|
|
|
|
return reply_lengths[type];
|
|
}
|
|
|
|
/* ================================================== */
|
|
|