2 chronyd/chronyc - Programs for keeping computer clocks accurate.
4 **********************************************************************
5 * Copyright (C) Richard P. Curnow 1997-2002
6 * Copyright (C) Miroslav Lichvar 2014-2016
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of version 2 of the GNU General Public License as
10 * published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 **********************************************************************
23 =======================================================================
25 Routines to compute the expected length of a command or reply packet.
26 These operate on the RAW NETWORK packets, from the point of view of
27 integer endianness within the structures.
35 #include "pktlength.h"
37 #define PADDING_LENGTH_(request_length, reply_length) \
38 (uint16_t)((request_length) < (reply_length) ? (reply_length) - (request_length) : 0)
40 #define PADDING_LENGTH(request_data, reply_data) \
41 PADDING_LENGTH_(offsetof(CMD_Request, request_data), offsetof(CMD_Reply, reply_data))
43 #define REQ_LENGTH_ENTRY(request_data_field, reply_data_field) \
44 { offsetof(CMD_Request, data.request_data_field.EOR), \
45 PADDING_LENGTH(data.request_data_field.EOR, data.reply_data_field.EOR) }
47 #define RPY_LENGTH_ENTRY(reply_data_field) \
48 offsetof(CMD_Reply, data.reply_data_field.EOR)
50 /* ================================================== */
52 struct request_length
{
57 static const struct request_length request_lengths
[] = {
58 REQ_LENGTH_ENTRY(null
, null
), /* NULL */
59 REQ_LENGTH_ENTRY(online
, null
), /* ONLINE */
60 REQ_LENGTH_ENTRY(offline
, null
), /* OFFLINE */
61 REQ_LENGTH_ENTRY(burst
, null
), /* BURST */
62 REQ_LENGTH_ENTRY(modify_minpoll
, null
), /* MODIFY_MINPOLL */
63 REQ_LENGTH_ENTRY(modify_maxpoll
, null
), /* MODIFY_MAXPOLL */
64 REQ_LENGTH_ENTRY(dump
, null
), /* DUMP */
65 REQ_LENGTH_ENTRY(modify_maxdelay
, null
), /* MODIFY_MAXDELAY */
66 REQ_LENGTH_ENTRY(modify_maxdelayratio
, null
), /* MODIFY_MAXDELAYRATIO */
67 REQ_LENGTH_ENTRY(modify_maxupdateskew
, null
), /* MODIFY_MAXUPDATESKEW */
68 REQ_LENGTH_ENTRY(logon
, null
), /* LOGON */
69 REQ_LENGTH_ENTRY(settime
, manual_timestamp
), /* SETTIME */
71 REQ_LENGTH_ENTRY(manual
, null
), /* MANUAL */
72 REQ_LENGTH_ENTRY(null
, n_sources
), /* N_SOURCES */
73 REQ_LENGTH_ENTRY(source_data
, source_data
), /* SOURCE_DATA */
74 REQ_LENGTH_ENTRY(null
, null
), /* REKEY */
75 REQ_LENGTH_ENTRY(allow_deny
, null
), /* ALLOW */
76 REQ_LENGTH_ENTRY(allow_deny
, null
), /* ALLOWALL */
77 REQ_LENGTH_ENTRY(allow_deny
, null
), /* DENY */
78 REQ_LENGTH_ENTRY(allow_deny
, null
), /* DENYALL */
79 REQ_LENGTH_ENTRY(allow_deny
, null
), /* CMDALLOW */
80 REQ_LENGTH_ENTRY(allow_deny
, null
), /* CMDALLOWALL */
81 REQ_LENGTH_ENTRY(allow_deny
, null
), /* CMDDENY */
82 REQ_LENGTH_ENTRY(allow_deny
, null
), /* CMDDENYALL */
83 REQ_LENGTH_ENTRY(ac_check
, null
), /* ACCHECK */
84 REQ_LENGTH_ENTRY(ac_check
, null
), /* CMDACCHECK */
85 { 0, 0 }, /* ADD_SERVER */
86 { 0, 0 }, /* ADD_PEER */
87 REQ_LENGTH_ENTRY(del_source
, null
), /* DEL_SOURCE */
88 REQ_LENGTH_ENTRY(null
, null
), /* WRITERTC */
89 REQ_LENGTH_ENTRY(dfreq
, null
), /* DFREQ */
90 REQ_LENGTH_ENTRY(doffset
, null
), /* DOFFSET */
91 REQ_LENGTH_ENTRY(null
, tracking
), /* TRACKING */
92 REQ_LENGTH_ENTRY(sourcestats
, sourcestats
), /* SOURCESTATS */
93 REQ_LENGTH_ENTRY(null
, rtc
), /* RTCREPORT */
94 REQ_LENGTH_ENTRY(null
, null
), /* TRIMRTC */
95 REQ_LENGTH_ENTRY(null
, null
), /* CYCLELOGS */
96 { 0, 0 }, /* SUBNETS_ACCESSED - not supported */
97 { 0, 0 }, /* CLIENT_ACCESSES - not supported */
98 { 0, 0 }, /* CLIENT_ACCESSES_BY_INDEX - not supported */
99 REQ_LENGTH_ENTRY(null
, manual_list
), /* MANUAL_LIST */
100 REQ_LENGTH_ENTRY(manual_delete
, null
), /* MANUAL_DELETE */
101 REQ_LENGTH_ENTRY(null
, null
), /* MAKESTEP */
102 REQ_LENGTH_ENTRY(null
, activity
), /* ACTIVITY */
103 REQ_LENGTH_ENTRY(modify_minstratum
, null
), /* MODIFY_MINSTRATUM */
104 REQ_LENGTH_ENTRY(modify_polltarget
, null
), /* MODIFY_POLLTARGET */
105 REQ_LENGTH_ENTRY(modify_maxdelaydevratio
, null
), /* MODIFY_MAXDELAYDEVRATIO */
106 REQ_LENGTH_ENTRY(null
, null
), /* RESELECT */
107 REQ_LENGTH_ENTRY(reselect_distance
, null
), /* RESELECTDISTANCE */
108 REQ_LENGTH_ENTRY(modify_makestep
, null
), /* MODIFY_MAKESTEP */
109 REQ_LENGTH_ENTRY(null
, smoothing
), /* SMOOTHING */
110 REQ_LENGTH_ENTRY(smoothtime
, null
), /* SMOOTHTIME */
111 REQ_LENGTH_ENTRY(null
, null
), /* REFRESH */
112 REQ_LENGTH_ENTRY(null
, server_stats
), /* SERVER_STATS */
113 REQ_LENGTH_ENTRY(client_accesses_by_index
,
114 client_accesses_by_index
), /* CLIENT_ACCESSES_BY_INDEX2 */
115 REQ_LENGTH_ENTRY(local
, null
), /* LOCAL2 */
116 REQ_LENGTH_ENTRY(ntp_data
, ntp_data
), /* NTP_DATA */
117 { 0, 0 }, /* ADD_SERVER2 */
118 { 0, 0 }, /* ADD_PEER2 */
119 { 0, 0 }, /* ADD_SERVER3 */
120 { 0, 0 }, /* ADD_PEER3 */
121 REQ_LENGTH_ENTRY(null
, null
), /* SHUTDOWN */
122 REQ_LENGTH_ENTRY(null
, null
), /* ONOFFLINE */
123 REQ_LENGTH_ENTRY(ntp_source
, null
), /* ADD_SOURCE */
124 REQ_LENGTH_ENTRY(ntp_source_name
,
125 ntp_source_name
), /* NTP_SOURCE_NAME */
126 REQ_LENGTH_ENTRY(null
, null
), /* RESET */
129 static const uint16_t reply_lengths
[] = {
131 RPY_LENGTH_ENTRY(null
), /* NULL */
132 RPY_LENGTH_ENTRY(n_sources
), /* N_SOURCES */
133 RPY_LENGTH_ENTRY(source_data
), /* SOURCE_DATA */
134 0, /* MANUAL_TIMESTAMP */
135 RPY_LENGTH_ENTRY(tracking
), /* TRACKING */
136 RPY_LENGTH_ENTRY(sourcestats
), /* SOURCESTATS */
137 RPY_LENGTH_ENTRY(rtc
), /* RTC */
138 0, /* SUBNETS_ACCESSED - not supported */
139 0, /* CLIENT_ACCESSES - not supported */
140 0, /* CLIENT_ACCESSES_BY_INDEX - not supported */
141 0, /* MANUAL_LIST - not supported */
142 RPY_LENGTH_ENTRY(activity
), /* ACTIVITY */
143 RPY_LENGTH_ENTRY(smoothing
), /* SMOOTHING */
144 RPY_LENGTH_ENTRY(server_stats
), /* SERVER_STATS */
145 RPY_LENGTH_ENTRY(client_accesses_by_index
), /* CLIENT_ACCESSES_BY_INDEX2 */
146 RPY_LENGTH_ENTRY(ntp_data
), /* NTP_DATA */
147 RPY_LENGTH_ENTRY(manual_timestamp
), /* MANUAL_TIMESTAMP2 */
148 RPY_LENGTH_ENTRY(manual_list
), /* MANUAL_LIST2 */
149 RPY_LENGTH_ENTRY(ntp_source_name
), /* NTP_SOURCE_NAME */
152 /* ================================================== */
155 PKL_CommandLength(CMD_Request
*r
)
160 assert(sizeof (request_lengths
) / sizeof (request_lengths
[0]) == N_REQUEST_TYPES
);
162 type
= ntohs(r
->command
);
163 if (type
>= N_REQUEST_TYPES
)
166 command_length
= request_lengths
[type
].command
;
170 return command_length
+ PKL_CommandPaddingLength(r
);
173 /* ================================================== */
176 PKL_CommandPaddingLength(CMD_Request
*r
)
180 if (r
->version
< PROTO_VERSION_PADDING
)
183 type
= ntohs(r
->command
);
185 if (type
>= N_REQUEST_TYPES
)
188 return request_lengths
[ntohs(r
->command
)].padding
;
191 /* ================================================== */
194 PKL_ReplyLength(CMD_Reply
*r
)
198 assert(sizeof (reply_lengths
) / sizeof (reply_lengths
[0]) == N_REPLY_TYPES
);
200 type
= ntohs(r
->reply
);
202 /* Note that reply type codes start from 1, not 0 */
203 if (type
< 1 || type
>= N_REPLY_TYPES
)
206 return reply_lengths
[type
];
209 /* ================================================== */