1284990Scy#include "config.h"
2284990Scy#include "ntp_debug.h"
3284990Scy#include "ntp_stdlib.h"
4284990Scy#include "ntp_types.h"
5284990Scy
6284990Scy#include "sntptest.h"
7284990Scy
8284990Scy#include "kod_management.h"
9284990Scy#include "main.h"
10284990Scy#include "networking.h"
11284990Scy#include "ntp.h"
12284990Scy
13284990Scy#include "unity.h"
14284990Scy
15289764Sglebiusvoid setUp(void);
16289764Sglebiusint LfpEquality(const l_fp expected, const l_fp actual);
17289764Sglebiusvoid test_GenerateUnauthenticatedPacket(void);
18289764Sglebiusvoid test_GenerateAuthenticatedPacket(void);
19289764Sglebiusvoid test_OffsetCalculationPositiveOffset(void);
20289764Sglebiusvoid test_OffsetCalculationNegativeOffset(void);
21289764Sglebiusvoid test_HandleUnusableServer(void);
22289764Sglebiusvoid test_HandleUnusablePacket(void);
23289764Sglebiusvoid test_HandleServerAuthenticationFailure(void);
24289764Sglebiusvoid test_HandleKodDemobilize(void);
25289764Sglebiusvoid test_HandleKodRate(void);
26289764Sglebiusvoid test_HandleCorrectPacket(void);
27284990Scy
28284990Scy
29289764Sglebiusvoid
30294554SdelphijsetUp(void)
31294554Sdelphij{
32284990Scy	init_lib();
33284990Scy}
34284990Scy
35284990Scy
36289764Sglebiusint
37294554SdelphijLfpEquality(
38294554Sdelphij	const l_fp	expected,
39294554Sdelphij	const l_fp 	actual
40294554Sdelphij	)
41294554Sdelphij{
42294554Sdelphij	return !!(L_ISEQU(&expected, &actual));
43284990Scy}
44284990Scy
45289764Sglebius
46289764Sglebiusvoid
47294554Sdelphijtest_GenerateUnauthenticatedPacket(void)
48294554Sdelphij{
49294554Sdelphij	struct pkt	testpkt;
50294554Sdelphij	struct timeval	xmt;
51294554Sdelphij	l_fp		expected_xmt, actual_xmt;
52284990Scy
53284990Scy	GETTIMEOFDAY(&xmt, NULL);
54284990Scy	xmt.tv_sec += JAN_1970;
55284990Scy
56284990Scy	TEST_ASSERT_EQUAL(LEN_PKT_NOMAC,
57284990Scy			  generate_pkt(&testpkt, &xmt, 0, NULL));
58284990Scy
59284990Scy	TEST_ASSERT_EQUAL(LEAP_NOTINSYNC, PKT_LEAP(testpkt.li_vn_mode));
60284990Scy	TEST_ASSERT_EQUAL(NTP_VERSION, PKT_VERSION(testpkt.li_vn_mode));
61284990Scy	TEST_ASSERT_EQUAL(MODE_CLIENT, PKT_MODE(testpkt.li_vn_mode));
62284990Scy
63284990Scy	TEST_ASSERT_EQUAL(STRATUM_UNSPEC, PKT_TO_STRATUM(testpkt.stratum));
64284990Scy	TEST_ASSERT_EQUAL(8, testpkt.ppoll);
65284990Scy
66284990Scy	TVTOTS(&xmt, &expected_xmt);
67284990Scy	NTOHL_FP(&testpkt.xmt, &actual_xmt);
68284990Scy	TEST_ASSERT_TRUE(LfpEquality(expected_xmt, actual_xmt));
69284990Scy}
70284990Scy
71289764Sglebius
72289764Sglebiusvoid
73294554Sdelphijtest_GenerateAuthenticatedPacket(void)
74294554Sdelphij{
75294554Sdelphij	static const int EXPECTED_PKTLEN = LEN_PKT_NOMAC + MAX_MD5_LEN;
76294554Sdelphij
77294554Sdelphij	struct key	testkey;
78294554Sdelphij	struct pkt	testpkt;
79294554Sdelphij	struct timeval	xmt;
80294554Sdelphij	l_fp		expected_xmt, actual_xmt;
81294554Sdelphij	char 		expected_mac[MAX_MD5_LEN];
82294554Sdelphij
83284990Scy	testkey.next = NULL;
84284990Scy	testkey.key_id = 30;
85284990Scy	testkey.key_len = 9;
86284990Scy	memcpy(testkey.key_seq, "123456789", testkey.key_len);
87330106Sdelphij	strlcpy(testkey.typen, "MD5", sizeof(testkey.typen));
88330106Sdelphij	testkey.typei = keytype_from_text(testkey.typen, NULL);
89284990Scy
90284990Scy	GETTIMEOFDAY(&xmt, NULL);
91284990Scy	xmt.tv_sec += JAN_1970;
92284990Scy
93284990Scy	TEST_ASSERT_EQUAL(EXPECTED_PKTLEN,
94284990Scy			  generate_pkt(&testpkt, &xmt, testkey.key_id, &testkey));
95284990Scy
96284990Scy	TEST_ASSERT_EQUAL(LEAP_NOTINSYNC, PKT_LEAP(testpkt.li_vn_mode));
97284990Scy	TEST_ASSERT_EQUAL(NTP_VERSION, PKT_VERSION(testpkt.li_vn_mode));
98284990Scy	TEST_ASSERT_EQUAL(MODE_CLIENT, PKT_MODE(testpkt.li_vn_mode));
99284990Scy
100284990Scy	TEST_ASSERT_EQUAL(STRATUM_UNSPEC, PKT_TO_STRATUM(testpkt.stratum));
101284990Scy	TEST_ASSERT_EQUAL(8, testpkt.ppoll);
102284990Scy
103284990Scy	TVTOTS(&xmt, &expected_xmt);
104284990Scy	NTOHL_FP(&testpkt.xmt, &actual_xmt);
105284990Scy	TEST_ASSERT_TRUE(LfpEquality(expected_xmt, actual_xmt));
106284990Scy
107284990Scy	TEST_ASSERT_EQUAL(testkey.key_id, ntohl(testpkt.exten[0]));
108284990Scy
109294554Sdelphij	TEST_ASSERT_EQUAL(MAX_MD5_LEN - 4, /* Remove the key_id, only keep the mac. */
110330106Sdelphij			  make_mac(&testpkt, LEN_PKT_NOMAC, MAX_MD5_LEN-4, &testkey, expected_mac));
111289764Sglebius	TEST_ASSERT_EQUAL_MEMORY(expected_mac, (char*)&testpkt.exten[1], MAX_MD5_LEN -4);
112284990Scy}
113284990Scy
114289764Sglebius
115289764Sglebiusvoid
116294554Sdelphijtest_OffsetCalculationPositiveOffset(void)
117294554Sdelphij{
118294554Sdelphij	struct pkt	rpkt;
119294554Sdelphij	l_fp		reftime, tmp;
120294554Sdelphij	struct timeval	dst;
121294554Sdelphij	double		offset, precision, synch_distance;
122284990Scy
123294554Sdelphij	rpkt.precision = -16; /* 0,000015259 */
124284990Scy	rpkt.rootdelay = HTONS_FP(DTOUFP(0.125));
125284990Scy	rpkt.rootdisp = HTONS_FP(DTOUFP(0.25));
126294554Sdelphij
127294554Sdelphij	/* Synch Distance: (0.125+0.25)/2.0 == 0.1875 */
128284990Scy	get_systime(&reftime);
129284990Scy	HTONL_FP(&reftime, &rpkt.reftime);
130284990Scy
131294554Sdelphij	/* T1 - Originate timestamp */
132284990Scy	tmp.l_ui = 1000000000UL;
133284990Scy	tmp.l_uf = 0UL;
134284990Scy	HTONL_FP(&tmp, &rpkt.org);
135284990Scy
136294554Sdelphij	/* T2 - Receive timestamp */
137284990Scy	tmp.l_ui = 1000000001UL;
138284990Scy	tmp.l_uf = 2147483648UL;
139284990Scy	HTONL_FP(&tmp, &rpkt.rec);
140284990Scy
141294554Sdelphij	/* T3 - Transmit timestamp */
142284990Scy	tmp.l_ui = 1000000002UL;
143284990Scy	tmp.l_uf = 0UL;
144284990Scy	HTONL_FP(&tmp, &rpkt.xmt);
145284990Scy
146294554Sdelphij	/* T4 - Destination timestamp as standard timeval */
147284990Scy	tmp.l_ui = 1000000001UL;
148284990Scy	tmp.l_uf = 0UL;
149284990Scy	TSTOTV(&tmp, &dst);
150284990Scy	dst.tv_sec -= JAN_1970;
151284990Scy
152284990Scy	offset_calculation(&rpkt, LEN_PKT_NOMAC, &dst, &offset, &precision, &synch_distance);
153284990Scy
154289764Sglebius	TEST_ASSERT_EQUAL_DOUBLE(1.25, offset);
155289764Sglebius	TEST_ASSERT_EQUAL_DOUBLE(1. / ULOGTOD(16), precision);
156294554Sdelphij	/* 1.1250150000000001 ? */
157289764Sglebius	TEST_ASSERT_EQUAL_DOUBLE(1.125015, synch_distance);
158284990Scy}
159284990Scy
160289764Sglebius
161289764Sglebiusvoid
162294554Sdelphijtest_OffsetCalculationNegativeOffset(void)
163294554Sdelphij{
164294554Sdelphij	struct pkt	rpkt;
165294554Sdelphij	l_fp		reftime, tmp;
166294554Sdelphij	struct timeval	dst;
167294554Sdelphij	double		offset, precision, synch_distance;
168284990Scy
169284990Scy	rpkt.precision = -1;
170284990Scy	rpkt.rootdelay = HTONS_FP(DTOUFP(0.5));
171284990Scy	rpkt.rootdisp = HTONS_FP(DTOUFP(0.5));
172294554Sdelphij
173294554Sdelphij	/* Synch Distance is (0.5+0.5)/2.0, or 0.5 */
174284990Scy	get_systime(&reftime);
175284990Scy	HTONL_FP(&reftime, &rpkt.reftime);
176284990Scy
177294554Sdelphij	/* T1 - Originate timestamp */
178284990Scy	tmp.l_ui = 1000000001UL;
179284990Scy	tmp.l_uf = 0UL;
180284990Scy	HTONL_FP(&tmp, &rpkt.org);
181284990Scy
182294554Sdelphij	/* T2 - Receive timestamp */
183284990Scy	tmp.l_ui = 1000000000UL;
184284990Scy	tmp.l_uf = 2147483648UL;
185284990Scy	HTONL_FP(&tmp, &rpkt.rec);
186284990Scy
187294554Sdelphij	/*/ T3 - Transmit timestamp */
188284990Scy	tmp.l_ui = 1000000001UL;
189284990Scy	tmp.l_uf = 2147483648UL;
190284990Scy	HTONL_FP(&tmp, &rpkt.xmt);
191284990Scy
192294554Sdelphij	/* T4 - Destination timestamp as standard timeval */
193284990Scy	tmp.l_ui = 1000000003UL;
194284990Scy	tmp.l_uf = 0UL;
195294554Sdelphij
196284990Scy	TSTOTV(&tmp, &dst);
197284990Scy	dst.tv_sec -= JAN_1970;
198284990Scy
199284990Scy	offset_calculation(&rpkt, LEN_PKT_NOMAC, &dst, &offset, &precision, &synch_distance);
200284990Scy
201289764Sglebius	TEST_ASSERT_EQUAL_DOUBLE(-1, offset);
202289764Sglebius	TEST_ASSERT_EQUAL_DOUBLE(1. / ULOGTOD(1), precision);
203289764Sglebius	TEST_ASSERT_EQUAL_DOUBLE(1.3333483333333334, synch_distance);
204284990Scy}
205284990Scy
206289764Sglebius
207289764Sglebiusvoid
208294554Sdelphijtest_HandleUnusableServer(void)
209294554Sdelphij{
210294554Sdelphij	struct pkt	rpkt;
211284990Scy	sockaddr_u	host;
212284990Scy	int		rpktl;
213284990Scy
214284990Scy	ZERO(rpkt);
215284990Scy	ZERO(host);
216284990Scy	rpktl = SERVER_UNUSEABLE;
217284990Scy	TEST_ASSERT_EQUAL(-1, handle_pkt(rpktl, &rpkt, &host, ""));
218284990Scy}
219284990Scy
220289764Sglebius
221289764Sglebiusvoid
222294554Sdelphijtest_HandleUnusablePacket(void)
223294554Sdelphij{
224294554Sdelphij	struct pkt	rpkt;
225284990Scy	sockaddr_u	host;
226284990Scy	int		rpktl;
227284990Scy
228284990Scy	ZERO(rpkt);
229284990Scy	ZERO(host);
230284990Scy	rpktl = PACKET_UNUSEABLE;
231284990Scy	TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, ""));
232284990Scy}
233284990Scy
234289764Sglebius
235289764Sglebiusvoid
236294554Sdelphijtest_HandleServerAuthenticationFailure(void)
237294554Sdelphij{
238294554Sdelphij	struct pkt	rpkt;
239284990Scy	sockaddr_u	host;
240284990Scy	int		rpktl;
241284990Scy
242284990Scy	ZERO(rpkt);
243284990Scy	ZERO(host);
244284990Scy	rpktl = SERVER_AUTH_FAIL;
245284990Scy	TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, ""));
246284990Scy}
247284990Scy
248289764Sglebius
249289764Sglebiusvoid
250294554Sdelphijtest_HandleKodDemobilize(void)
251294554Sdelphij{
252294554Sdelphij	static const char *	HOSTNAME = "192.0.2.1";
253294554Sdelphij	static const char *	REASON = "DENY";
254284990Scy	struct pkt		rpkt;
255294554Sdelphij	sockaddr_u		host;
256294554Sdelphij	int			rpktl;
257284990Scy	struct kod_entry *	entry;
258284990Scy
259284990Scy	rpktl = KOD_DEMOBILIZE;
260284990Scy	ZERO(rpkt);
261284990Scy	memcpy(&rpkt.refid, REASON, 4);
262284990Scy	ZERO(host);
263284990Scy	host.sa4.sin_family = AF_INET;
264284990Scy	host.sa4.sin_addr.s_addr = inet_addr(HOSTNAME);
265284990Scy
266294554Sdelphij	/* Test that the KOD-entry is added to the database. */
267284990Scy	kod_init_kod_db("/dev/null", TRUE);
268284990Scy
269284990Scy	TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, HOSTNAME));
270284990Scy
271284990Scy	TEST_ASSERT_EQUAL(1, search_entry(HOSTNAME, &entry));
272289764Sglebius	TEST_ASSERT_EQUAL_MEMORY(REASON, entry->type, 4);
273284990Scy}
274284990Scy
275289764Sglebius
276289764Sglebiusvoid
277294554Sdelphijtest_HandleKodRate(void)
278294554Sdelphij{
279294554Sdelphij	struct 	pkt	rpkt;
280284990Scy	sockaddr_u	host;
281284990Scy	int		rpktl;
282284990Scy
283284990Scy	ZERO(rpkt);
284284990Scy	ZERO(host);
285284990Scy	rpktl = KOD_RATE;
286284990Scy	TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, ""));
287284990Scy}
288284990Scy
289289764Sglebius
290289764Sglebiusvoid
291294554Sdelphijtest_HandleCorrectPacket(void)
292294554Sdelphij{
293294554Sdelphij	struct pkt	rpkt;
294284990Scy	sockaddr_u	host;
295284990Scy	int		rpktl;
296284990Scy	l_fp		now;
297284990Scy
298294554Sdelphij	/* We don't want our testing code to actually change the system clock. */
299284990Scy	TEST_ASSERT_FALSE(ENABLED_OPT(STEP));
300284990Scy	TEST_ASSERT_FALSE(ENABLED_OPT(SLEW));
301284990Scy
302284990Scy	get_systime(&now);
303284990Scy	HTONL_FP(&now, &rpkt.reftime);
304284990Scy	HTONL_FP(&now, &rpkt.org);
305284990Scy	HTONL_FP(&now, &rpkt.rec);
306284990Scy	HTONL_FP(&now, &rpkt.xmt);
307284990Scy	rpktl = LEN_PKT_NOMAC;
308284990Scy	ZERO(host);
309284990Scy	AF(&host) = AF_INET;
310284990Scy
311284990Scy	TEST_ASSERT_EQUAL(0, handle_pkt(rpktl, &rpkt, &host, ""));
312284990Scy}
313284990Scy
314284990Scy/* packetHandling.c */
315