packetHandling.c revision 1.4 1 1.2 christos /* $NetBSD: packetHandling.c,v 1.4 2024/08/18 20:47:26 christos Exp $ */
2 1.2 christos
3 1.1 christos #include "config.h"
4 1.1 christos #include "ntp_debug.h"
5 1.1 christos #include "ntp_stdlib.h"
6 1.1 christos #include "ntp_types.h"
7 1.1 christos
8 1.1 christos #include "sntptest.h"
9 1.1 christos
10 1.1 christos #include "kod_management.h"
11 1.1 christos #include "main.h"
12 1.1 christos #include "networking.h"
13 1.1 christos #include "ntp.h"
14 1.1 christos
15 1.1 christos #include "unity.h"
16 1.1 christos
17 1.2 christos void setUp(void);
18 1.2 christos int LfpEquality(const l_fp expected, const l_fp actual);
19 1.2 christos void test_GenerateUnauthenticatedPacket(void);
20 1.2 christos void test_GenerateAuthenticatedPacket(void);
21 1.2 christos void test_OffsetCalculationPositiveOffset(void);
22 1.2 christos void test_OffsetCalculationNegativeOffset(void);
23 1.2 christos void test_HandleUnusableServer(void);
24 1.2 christos void test_HandleUnusablePacket(void);
25 1.2 christos void test_HandleServerAuthenticationFailure(void);
26 1.2 christos void test_HandleKodDemobilize(void);
27 1.2 christos void test_HandleKodRate(void);
28 1.2 christos void test_HandleCorrectPacket(void);
29 1.1 christos
30 1.1 christos
31 1.2 christos void
32 1.2 christos setUp(void)
33 1.1 christos {
34 1.1 christos init_lib();
35 1.1 christos }
36 1.1 christos
37 1.1 christos
38 1.2 christos int
39 1.2 christos LfpEquality(
40 1.2 christos const l_fp expected,
41 1.2 christos const l_fp actual
42 1.2 christos )
43 1.2 christos {
44 1.2 christos return !!(L_ISEQU(&expected, &actual));
45 1.2 christos }
46 1.1 christos
47 1.1 christos
48 1.2 christos void
49 1.2 christos test_GenerateUnauthenticatedPacket(void)
50 1.2 christos {
51 1.2 christos struct pkt testpkt;
52 1.2 christos struct timeval xmt;
53 1.2 christos l_fp expected_xmt, actual_xmt;
54 1.1 christos
55 1.1 christos GETTIMEOFDAY(&xmt, NULL);
56 1.1 christos xmt.tv_sec += JAN_1970;
57 1.1 christos
58 1.1 christos TEST_ASSERT_EQUAL(LEN_PKT_NOMAC,
59 1.1 christos generate_pkt(&testpkt, &xmt, 0, NULL));
60 1.1 christos
61 1.1 christos TEST_ASSERT_EQUAL(LEAP_NOTINSYNC, PKT_LEAP(testpkt.li_vn_mode));
62 1.1 christos TEST_ASSERT_EQUAL(NTP_VERSION, PKT_VERSION(testpkt.li_vn_mode));
63 1.1 christos TEST_ASSERT_EQUAL(MODE_CLIENT, PKT_MODE(testpkt.li_vn_mode));
64 1.1 christos
65 1.1 christos TEST_ASSERT_EQUAL(STRATUM_UNSPEC, PKT_TO_STRATUM(testpkt.stratum));
66 1.1 christos TEST_ASSERT_EQUAL(8, testpkt.ppoll);
67 1.1 christos
68 1.1 christos TVTOTS(&xmt, &expected_xmt);
69 1.1 christos NTOHL_FP(&testpkt.xmt, &actual_xmt);
70 1.1 christos TEST_ASSERT_TRUE(LfpEquality(expected_xmt, actual_xmt));
71 1.1 christos }
72 1.1 christos
73 1.2 christos
74 1.2 christos void
75 1.2 christos test_GenerateAuthenticatedPacket(void)
76 1.2 christos {
77 1.4 christos #ifdef OPENSSL
78 1.4 christos
79 1.4 christos const int EXPECTED_PKTLEN = LEN_PKT_NOMAC + MAX_SHAKE128_LEN;
80 1.4 christos
81 1.2 christos struct key testkey;
82 1.2 christos struct pkt testpkt;
83 1.2 christos struct timeval xmt;
84 1.2 christos l_fp expected_xmt, actual_xmt;
85 1.4 christos const char key[] = "123456789";
86 1.4 christos size_t mac_sz;
87 1.4 christos const u_char expected_mac[] = {
88 1.4 christos 0x46, 0x79, 0x81, 0x6b,
89 1.4 christos 0x22, 0xe3, 0xa7, 0xaf,
90 1.4 christos 0x1d, 0x63, 0x20, 0xfb,
91 1.4 christos 0xc7, 0xd6, 0x87, 0x2c
92 1.4 christos };
93 1.4 christos
94 1.1 christos testkey.next = NULL;
95 1.1 christos testkey.key_id = 30;
96 1.4 christos strlcpy(testkey.key_seq, key, sizeof(testkey.key_seq));
97 1.4 christos testkey.key_len = strlen(testkey.key_seq);
98 1.4 christos strlcpy(testkey.typen, "SHAKE128", sizeof(testkey.typen));
99 1.2 christos testkey.typei = keytype_from_text(testkey.typen, NULL);
100 1.1 christos
101 1.4 christos xmt.tv_sec = JAN_1970;
102 1.4 christos xmt.tv_usec = 0;
103 1.1 christos
104 1.1 christos TEST_ASSERT_EQUAL(EXPECTED_PKTLEN,
105 1.4 christos generate_pkt(&testpkt, &xmt, testkey.key_id,
106 1.4 christos &testkey));
107 1.1 christos
108 1.1 christos TEST_ASSERT_EQUAL(LEAP_NOTINSYNC, PKT_LEAP(testpkt.li_vn_mode));
109 1.1 christos TEST_ASSERT_EQUAL(NTP_VERSION, PKT_VERSION(testpkt.li_vn_mode));
110 1.1 christos TEST_ASSERT_EQUAL(MODE_CLIENT, PKT_MODE(testpkt.li_vn_mode));
111 1.1 christos
112 1.1 christos TEST_ASSERT_EQUAL(STRATUM_UNSPEC, PKT_TO_STRATUM(testpkt.stratum));
113 1.1 christos TEST_ASSERT_EQUAL(8, testpkt.ppoll);
114 1.1 christos
115 1.1 christos TVTOTS(&xmt, &expected_xmt);
116 1.1 christos NTOHL_FP(&testpkt.xmt, &actual_xmt);
117 1.1 christos TEST_ASSERT_TRUE(LfpEquality(expected_xmt, actual_xmt));
118 1.1 christos
119 1.1 christos TEST_ASSERT_EQUAL(testkey.key_id, ntohl(testpkt.exten[0]));
120 1.4 christos
121 1.4 christos TEST_ASSERT_EQUAL(sizeof(expected_mac), SHAKE128_LENGTH);
122 1.4 christos mac_sz = make_mac(&testpkt, LEN_PKT_NOMAC, &testkey,
123 1.4 christos &testpkt.exten[1], MAX_MDG_LEN);
124 1.4 christos TEST_ASSERT_EQUAL(mac_sz, SHAKE128_LENGTH);
125 1.4 christos
126 1.4 christos TEST_ASSERT_EQUAL_MEMORY(expected_mac, (void *)&testpkt.exten[1],
127 1.4 christos SHAKE128_LENGTH);
128 1.4 christos
129 1.4 christos #else /* !OPENSSL follows */
130 1.4 christos
131 1.4 christos TEST_IGNORE_MESSAGE("OpenSSL not found, skipping...");
132 1.4 christos
133 1.4 christos #endif
134 1.1 christos }
135 1.1 christos
136 1.1 christos
137 1.2 christos void
138 1.2 christos test_OffsetCalculationPositiveOffset(void)
139 1.2 christos {
140 1.2 christos struct pkt rpkt;
141 1.2 christos l_fp reftime, tmp;
142 1.2 christos struct timeval dst;
143 1.2 christos double offset, precision, synch_distance;
144 1.2 christos
145 1.2 christos rpkt.precision = -16; /* 0,000015259 */
146 1.1 christos rpkt.rootdelay = HTONS_FP(DTOUFP(0.125));
147 1.1 christos rpkt.rootdisp = HTONS_FP(DTOUFP(0.25));
148 1.2 christos
149 1.2 christos /* Synch Distance: (0.125+0.25)/2.0 == 0.1875 */
150 1.1 christos get_systime(&reftime);
151 1.1 christos HTONL_FP(&reftime, &rpkt.reftime);
152 1.1 christos
153 1.2 christos /* T1 - Originate timestamp */
154 1.1 christos tmp.l_ui = 1000000000UL;
155 1.1 christos tmp.l_uf = 0UL;
156 1.1 christos HTONL_FP(&tmp, &rpkt.org);
157 1.1 christos
158 1.2 christos /* T2 - Receive timestamp */
159 1.1 christos tmp.l_ui = 1000000001UL;
160 1.1 christos tmp.l_uf = 2147483648UL;
161 1.1 christos HTONL_FP(&tmp, &rpkt.rec);
162 1.1 christos
163 1.2 christos /* T3 - Transmit timestamp */
164 1.1 christos tmp.l_ui = 1000000002UL;
165 1.1 christos tmp.l_uf = 0UL;
166 1.1 christos HTONL_FP(&tmp, &rpkt.xmt);
167 1.1 christos
168 1.2 christos /* T4 - Destination timestamp as standard timeval */
169 1.1 christos tmp.l_ui = 1000000001UL;
170 1.1 christos tmp.l_uf = 0UL;
171 1.1 christos TSTOTV(&tmp, &dst);
172 1.1 christos dst.tv_sec -= JAN_1970;
173 1.1 christos
174 1.1 christos offset_calculation(&rpkt, LEN_PKT_NOMAC, &dst, &offset, &precision, &synch_distance);
175 1.1 christos
176 1.2 christos TEST_ASSERT_EQUAL_DOUBLE(1.25, offset);
177 1.2 christos TEST_ASSERT_EQUAL_DOUBLE(1. / ULOGTOD(16), precision);
178 1.2 christos /* 1.1250150000000001 ? */
179 1.2 christos TEST_ASSERT_EQUAL_DOUBLE(1.125015, synch_distance);
180 1.1 christos }
181 1.1 christos
182 1.2 christos
183 1.2 christos void
184 1.2 christos test_OffsetCalculationNegativeOffset(void)
185 1.2 christos {
186 1.2 christos struct pkt rpkt;
187 1.2 christos l_fp reftime, tmp;
188 1.2 christos struct timeval dst;
189 1.2 christos double offset, precision, synch_distance;
190 1.1 christos
191 1.1 christos rpkt.precision = -1;
192 1.1 christos rpkt.rootdelay = HTONS_FP(DTOUFP(0.5));
193 1.1 christos rpkt.rootdisp = HTONS_FP(DTOUFP(0.5));
194 1.4 christos
195 1.2 christos /* Synch Distance is (0.5+0.5)/2.0, or 0.5 */
196 1.1 christos get_systime(&reftime);
197 1.1 christos HTONL_FP(&reftime, &rpkt.reftime);
198 1.1 christos
199 1.2 christos /* T1 - Originate timestamp */
200 1.1 christos tmp.l_ui = 1000000001UL;
201 1.1 christos tmp.l_uf = 0UL;
202 1.1 christos HTONL_FP(&tmp, &rpkt.org);
203 1.1 christos
204 1.2 christos /* T2 - Receive timestamp */
205 1.1 christos tmp.l_ui = 1000000000UL;
206 1.1 christos tmp.l_uf = 2147483648UL;
207 1.1 christos HTONL_FP(&tmp, &rpkt.rec);
208 1.1 christos
209 1.2 christos /*/ T3 - Transmit timestamp */
210 1.1 christos tmp.l_ui = 1000000001UL;
211 1.1 christos tmp.l_uf = 2147483648UL;
212 1.1 christos HTONL_FP(&tmp, &rpkt.xmt);
213 1.1 christos
214 1.2 christos /* T4 - Destination timestamp as standard timeval */
215 1.1 christos tmp.l_ui = 1000000003UL;
216 1.1 christos tmp.l_uf = 0UL;
217 1.2 christos
218 1.1 christos TSTOTV(&tmp, &dst);
219 1.1 christos dst.tv_sec -= JAN_1970;
220 1.1 christos
221 1.1 christos offset_calculation(&rpkt, LEN_PKT_NOMAC, &dst, &offset, &precision, &synch_distance);
222 1.1 christos
223 1.2 christos TEST_ASSERT_EQUAL_DOUBLE(-1, offset);
224 1.2 christos TEST_ASSERT_EQUAL_DOUBLE(1. / ULOGTOD(1), precision);
225 1.2 christos TEST_ASSERT_EQUAL_DOUBLE(1.3333483333333334, synch_distance);
226 1.1 christos }
227 1.1 christos
228 1.2 christos
229 1.2 christos void
230 1.2 christos test_HandleUnusableServer(void)
231 1.2 christos {
232 1.2 christos struct pkt rpkt;
233 1.1 christos sockaddr_u host;
234 1.1 christos int rpktl;
235 1.1 christos
236 1.1 christos ZERO(rpkt);
237 1.1 christos ZERO(host);
238 1.1 christos rpktl = SERVER_UNUSEABLE;
239 1.1 christos TEST_ASSERT_EQUAL(-1, handle_pkt(rpktl, &rpkt, &host, ""));
240 1.1 christos }
241 1.1 christos
242 1.2 christos
243 1.2 christos void
244 1.2 christos test_HandleUnusablePacket(void)
245 1.2 christos {
246 1.2 christos struct pkt rpkt;
247 1.1 christos sockaddr_u host;
248 1.1 christos int rpktl;
249 1.1 christos
250 1.1 christos ZERO(rpkt);
251 1.1 christos ZERO(host);
252 1.1 christos rpktl = PACKET_UNUSEABLE;
253 1.1 christos TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, ""));
254 1.1 christos }
255 1.1 christos
256 1.2 christos
257 1.2 christos void
258 1.2 christos test_HandleServerAuthenticationFailure(void)
259 1.2 christos {
260 1.2 christos struct pkt rpkt;
261 1.1 christos sockaddr_u host;
262 1.1 christos int rpktl;
263 1.1 christos
264 1.1 christos ZERO(rpkt);
265 1.1 christos ZERO(host);
266 1.1 christos rpktl = SERVER_AUTH_FAIL;
267 1.1 christos TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, ""));
268 1.1 christos }
269 1.1 christos
270 1.2 christos
271 1.2 christos void
272 1.2 christos test_HandleKodDemobilize(void)
273 1.2 christos {
274 1.2 christos static const char * HOSTNAME = "192.0.2.1";
275 1.2 christos static const char * REASON = "DENY";
276 1.1 christos struct pkt rpkt;
277 1.2 christos sockaddr_u host;
278 1.2 christos int rpktl;
279 1.1 christos struct kod_entry * entry;
280 1.1 christos
281 1.1 christos rpktl = KOD_DEMOBILIZE;
282 1.1 christos ZERO(rpkt);
283 1.1 christos memcpy(&rpkt.refid, REASON, 4);
284 1.1 christos ZERO(host);
285 1.1 christos host.sa4.sin_family = AF_INET;
286 1.1 christos host.sa4.sin_addr.s_addr = inet_addr(HOSTNAME);
287 1.1 christos
288 1.2 christos /* Test that the KOD-entry is added to the database. */
289 1.1 christos kod_init_kod_db("/dev/null", TRUE);
290 1.1 christos
291 1.1 christos TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, HOSTNAME));
292 1.1 christos
293 1.1 christos TEST_ASSERT_EQUAL(1, search_entry(HOSTNAME, &entry));
294 1.2 christos TEST_ASSERT_EQUAL_MEMORY(REASON, entry->type, 4);
295 1.1 christos }
296 1.1 christos
297 1.2 christos
298 1.2 christos void
299 1.2 christos test_HandleKodRate(void)
300 1.2 christos {
301 1.2 christos struct pkt rpkt;
302 1.1 christos sockaddr_u host;
303 1.1 christos int rpktl;
304 1.1 christos
305 1.1 christos ZERO(rpkt);
306 1.1 christos ZERO(host);
307 1.1 christos rpktl = KOD_RATE;
308 1.1 christos TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, ""));
309 1.1 christos }
310 1.1 christos
311 1.2 christos
312 1.2 christos void
313 1.2 christos test_HandleCorrectPacket(void)
314 1.2 christos {
315 1.2 christos struct pkt rpkt;
316 1.1 christos sockaddr_u host;
317 1.1 christos int rpktl;
318 1.1 christos l_fp now;
319 1.1 christos
320 1.2 christos /* We don't want our testing code to actually change the system clock. */
321 1.1 christos TEST_ASSERT_FALSE(ENABLED_OPT(STEP));
322 1.1 christos TEST_ASSERT_FALSE(ENABLED_OPT(SLEW));
323 1.1 christos
324 1.1 christos get_systime(&now);
325 1.1 christos HTONL_FP(&now, &rpkt.reftime);
326 1.1 christos HTONL_FP(&now, &rpkt.org);
327 1.1 christos HTONL_FP(&now, &rpkt.rec);
328 1.1 christos HTONL_FP(&now, &rpkt.xmt);
329 1.1 christos rpktl = LEN_PKT_NOMAC;
330 1.1 christos ZERO(host);
331 1.1 christos AF(&host) = AF_INET;
332 1.1 christos
333 1.1 christos TEST_ASSERT_EQUAL(0, handle_pkt(rpktl, &rpkt, &host, ""));
334 1.1 christos }
335 1.1 christos
336 1.1 christos /* packetHandling.c */
337