]>
Commit | Line | Data |
---|---|---|
88840341 | 1 | /* |
88840341 RC |
2 | chronyd/chronyc - Programs for keeping computer clocks accurate. |
3 | ||
4 | ********************************************************************** | |
5 | * Copyright (C) Richard P. Curnow 1997-2002 | |
00861537 | 6 | * Copyright (C) Miroslav Lichvar 2014-2016 |
88840341 RC |
7 | * |
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. | |
11 | * | |
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. | |
16 | * | |
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., | |
8e23110a | 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
88840341 RC |
20 | * |
21 | ********************************************************************** | |
22 | ||
23 | ======================================================================= | |
24 | ||
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. | |
28 | ||
29 | */ | |
da2c8d90 ML |
30 | #include "config.h" |
31 | ||
88840341 RC |
32 | #include "sysincl.h" |
33 | ||
34 | #include "util.h" | |
35 | #include "pktlength.h" | |
36 | ||
0a9d75bf | 37 | #define PADDING_LENGTH_(request_length, reply_length) \ |
f225469e | 38 | (uint16_t)((request_length) < (reply_length) ? (reply_length) - (request_length) : 0) |
88840341 | 39 | |
0a9d75bf ML |
40 | #define PADDING_LENGTH(request_data, reply_data) \ |
41 | PADDING_LENGTH_(offsetof(CMD_Request, request_data), offsetof(CMD_Reply, reply_data)) | |
88840341 | 42 | |
0a9d75bf ML |
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) } | |
88840341 | 46 | |
0a9d75bf ML |
47 | #define RPY_LENGTH_ENTRY(reply_data_field) \ |
48 | offsetof(CMD_Reply, data.reply_data_field.EOR) | |
49 | ||
50 | /* ================================================== */ | |
88840341 | 51 | |
0a9d75bf ML |
52 | struct request_length { |
53 | uint16_t command; | |
54 | uint16_t padding; | |
55 | }; | |
56 | ||
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 */ | |
53b15bd5 | 70 | { 0, 0 }, /* LOCAL */ |
0a9d75bf ML |
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 */ | |
65fd30a5 ML |
85 | { 0, 0 }, /* ADD_SERVER */ |
86 | { 0, 0 }, /* ADD_PEER */ | |
0a9d75bf ML |
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 */ | |
705e32ac | 98 | { 0, 0 }, /* CLIENT_ACCESSES_BY_INDEX - not supported */ |
0a9d75bf ML |
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 */ | |
705e32ac ML |
113 | REQ_LENGTH_ENTRY(client_accesses_by_index, |
114 | client_accesses_by_index), /* CLIENT_ACCESSES_BY_INDEX2 */ | |
53b15bd5 | 115 | REQ_LENGTH_ENTRY(local, null), /* LOCAL2 */ |
535ca64b | 116 | REQ_LENGTH_ENTRY(ntp_data, ntp_data), /* NTP_DATA */ |
5ab645e3 ML |
117 | { 0, 0 }, /* ADD_SERVER2 */ |
118 | { 0, 0 }, /* ADD_PEER2 */ | |
00fff161 ML |
119 | { 0, 0 }, /* ADD_SERVER3 */ |
120 | { 0, 0 }, /* ADD_PEER3 */ | |
499f513d | 121 | REQ_LENGTH_ENTRY(null, null), /* SHUTDOWN */ |
34db671b | 122 | REQ_LENGTH_ENTRY(null, null), /* ONOFFLINE */ |
00fff161 | 123 | REQ_LENGTH_ENTRY(ntp_source, null), /* ADD_SOURCE */ |
93f63589 ML |
124 | REQ_LENGTH_ENTRY(ntp_source_name, |
125 | ntp_source_name), /* NTP_SOURCE_NAME */ | |
e7a25426 | 126 | REQ_LENGTH_ENTRY(null, null), /* RESET */ |
0a9d75bf ML |
127 | }; |
128 | ||
129 | static const uint16_t reply_lengths[] = { | |
130 | 0, /* empty slot */ | |
131 | RPY_LENGTH_ENTRY(null), /* NULL */ | |
132 | RPY_LENGTH_ENTRY(n_sources), /* N_SOURCES */ | |
133 | RPY_LENGTH_ENTRY(source_data), /* SOURCE_DATA */ | |
01a29c7a | 134 | 0, /* MANUAL_TIMESTAMP */ |
0a9d75bf ML |
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 */ | |
705e32ac | 140 | 0, /* CLIENT_ACCESSES_BY_INDEX - not supported */ |
eda4b111 | 141 | 0, /* MANUAL_LIST - not supported */ |
0a9d75bf ML |
142 | RPY_LENGTH_ENTRY(activity), /* ACTIVITY */ |
143 | RPY_LENGTH_ENTRY(smoothing), /* SMOOTHING */ | |
144 | RPY_LENGTH_ENTRY(server_stats), /* SERVER_STATS */ | |
705e32ac | 145 | RPY_LENGTH_ENTRY(client_accesses_by_index), /* CLIENT_ACCESSES_BY_INDEX2 */ |
535ca64b | 146 | RPY_LENGTH_ENTRY(ntp_data), /* NTP_DATA */ |
01a29c7a | 147 | RPY_LENGTH_ENTRY(manual_timestamp), /* MANUAL_TIMESTAMP2 */ |
eda4b111 | 148 | RPY_LENGTH_ENTRY(manual_list), /* MANUAL_LIST2 */ |
93f63589 | 149 | RPY_LENGTH_ENTRY(ntp_source_name), /* NTP_SOURCE_NAME */ |
0a9d75bf | 150 | }; |
88840341 | 151 | |
dba458d5 ML |
152 | /* ================================================== */ |
153 | ||
154 | int | |
155 | PKL_CommandLength(CMD_Request *r) | |
156 | { | |
0a9d75bf | 157 | uint32_t type; |
dba458d5 ML |
158 | int command_length; |
159 | ||
0a9d75bf ML |
160 | assert(sizeof (request_lengths) / sizeof (request_lengths[0]) == N_REQUEST_TYPES); |
161 | ||
162 | type = ntohs(r->command); | |
163 | if (type >= N_REQUEST_TYPES) | |
164 | return 0; | |
165 | ||
166 | command_length = request_lengths[type].command; | |
dba458d5 ML |
167 | if (!command_length) |
168 | return 0; | |
169 | ||
170 | return command_length + PKL_CommandPaddingLength(r); | |
171 | } | |
172 | ||
173 | /* ================================================== */ | |
174 | ||
dba458d5 ML |
175 | int |
176 | PKL_CommandPaddingLength(CMD_Request *r) | |
177 | { | |
0a9d75bf | 178 | uint32_t type; |
dba458d5 ML |
179 | |
180 | if (r->version < PROTO_VERSION_PADDING) | |
181 | return 0; | |
182 | ||
183 | type = ntohs(r->command); | |
184 | ||
0a9d75bf | 185 | if (type >= N_REQUEST_TYPES) |
dba458d5 ML |
186 | return 0; |
187 | ||
0a9d75bf | 188 | return request_lengths[ntohs(r->command)].padding; |
dba458d5 ML |
189 | } |
190 | ||
88840341 RC |
191 | /* ================================================== */ |
192 | ||
193 | int | |
eda4b111 | 194 | PKL_ReplyLength(CMD_Reply *r) |
88840341 | 195 | { |
0a9d75bf ML |
196 | uint32_t type; |
197 | ||
198 | assert(sizeof (reply_lengths) / sizeof (reply_lengths[0]) == N_REPLY_TYPES); | |
199 | ||
88840341 | 200 | type = ntohs(r->reply); |
0a9d75bf | 201 | |
88840341 | 202 | /* Note that reply type codes start from 1, not 0 */ |
0a9d75bf | 203 | if (type < 1 || type >= N_REPLY_TYPES) |
88840341 | 204 | return 0; |
0a9d75bf | 205 | |
0a9d75bf | 206 | return reply_lengths[type]; |
88840341 RC |
207 | } |
208 | ||
209 | /* ================================================== */ | |
210 |