Files
chrony/pktlength.c
Miroslav Lichvar 9ba6e7655c cmdmon: drop handling of NULL and LOGON requests
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.
2025-02-12 14:52:19 +01:00

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];
}
/* ================================================== */