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