packetHandling.c revision 330141
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	static const int EXPECTED_PKTLEN = LEN_PKT_NOMAC + MAX_MD5_LEN;
76
77	struct key	testkey;
78	struct pkt	testpkt;
79	struct timeval	xmt;
80	l_fp		expected_xmt, actual_xmt;
81	char 		expected_mac[MAX_MD5_LEN];
82
83	testkey.next = NULL;
84	testkey.key_id = 30;
85	testkey.key_len = 9;
86	memcpy(testkey.key_seq, "123456789", testkey.key_len);
87	strlcpy(testkey.typen, "MD5", sizeof(testkey.typen));
88	testkey.typei = keytype_from_text(testkey.typen, NULL);
89
90	GETTIMEOFDAY(&xmt, NULL);
91	xmt.tv_sec += JAN_1970;
92
93	TEST_ASSERT_EQUAL(EXPECTED_PKTLEN,
94			  generate_pkt(&testpkt, &xmt, testkey.key_id, &testkey));
95
96	TEST_ASSERT_EQUAL(LEAP_NOTINSYNC, PKT_LEAP(testpkt.li_vn_mode));
97	TEST_ASSERT_EQUAL(NTP_VERSION, PKT_VERSION(testpkt.li_vn_mode));
98	TEST_ASSERT_EQUAL(MODE_CLIENT, PKT_MODE(testpkt.li_vn_mode));
99
100	TEST_ASSERT_EQUAL(STRATUM_UNSPEC, PKT_TO_STRATUM(testpkt.stratum));
101	TEST_ASSERT_EQUAL(8, testpkt.ppoll);
102
103	TVTOTS(&xmt, &expected_xmt);
104	NTOHL_FP(&testpkt.xmt, &actual_xmt);
105	TEST_ASSERT_TRUE(LfpEquality(expected_xmt, actual_xmt));
106
107	TEST_ASSERT_EQUAL(testkey.key_id, ntohl(testpkt.exten[0]));
108
109	TEST_ASSERT_EQUAL(MAX_MD5_LEN - 4, /* Remove the key_id, only keep the mac. */
110			  make_mac(&testpkt, LEN_PKT_NOMAC, MAX_MD5_LEN-4, &testkey, expected_mac));
111	TEST_ASSERT_EQUAL_MEMORY(expected_mac, (char*)&testpkt.exten[1], MAX_MD5_LEN -4);
112}
113
114
115void
116test_OffsetCalculationPositiveOffset(void)
117{
118	struct pkt	rpkt;
119	l_fp		reftime, tmp;
120	struct timeval	dst;
121	double		offset, precision, synch_distance;
122
123	rpkt.precision = -16; /* 0,000015259 */
124	rpkt.rootdelay = HTONS_FP(DTOUFP(0.125));
125	rpkt.rootdisp = HTONS_FP(DTOUFP(0.25));
126
127	/* Synch Distance: (0.125+0.25)/2.0 == 0.1875 */
128	get_systime(&reftime);
129	HTONL_FP(&reftime, &rpkt.reftime);
130
131	/* T1 - Originate timestamp */
132	tmp.l_ui = 1000000000UL;
133	tmp.l_uf = 0UL;
134	HTONL_FP(&tmp, &rpkt.org);
135
136	/* T2 - Receive timestamp */
137	tmp.l_ui = 1000000001UL;
138	tmp.l_uf = 2147483648UL;
139	HTONL_FP(&tmp, &rpkt.rec);
140
141	/* T3 - Transmit timestamp */
142	tmp.l_ui = 1000000002UL;
143	tmp.l_uf = 0UL;
144	HTONL_FP(&tmp, &rpkt.xmt);
145
146	/* T4 - Destination timestamp as standard timeval */
147	tmp.l_ui = 1000000001UL;
148	tmp.l_uf = 0UL;
149	TSTOTV(&tmp, &dst);
150	dst.tv_sec -= JAN_1970;
151
152	offset_calculation(&rpkt, LEN_PKT_NOMAC, &dst, &offset, &precision, &synch_distance);
153
154	TEST_ASSERT_EQUAL_DOUBLE(1.25, offset);
155	TEST_ASSERT_EQUAL_DOUBLE(1. / ULOGTOD(16), precision);
156	/* 1.1250150000000001 ? */
157	TEST_ASSERT_EQUAL_DOUBLE(1.125015, synch_distance);
158}
159
160
161void
162test_OffsetCalculationNegativeOffset(void)
163{
164	struct pkt	rpkt;
165	l_fp		reftime, tmp;
166	struct timeval	dst;
167	double		offset, precision, synch_distance;
168
169	rpkt.precision = -1;
170	rpkt.rootdelay = HTONS_FP(DTOUFP(0.5));
171	rpkt.rootdisp = HTONS_FP(DTOUFP(0.5));
172
173	/* Synch Distance is (0.5+0.5)/2.0, or 0.5 */
174	get_systime(&reftime);
175	HTONL_FP(&reftime, &rpkt.reftime);
176
177	/* T1 - Originate timestamp */
178	tmp.l_ui = 1000000001UL;
179	tmp.l_uf = 0UL;
180	HTONL_FP(&tmp, &rpkt.org);
181
182	/* T2 - Receive timestamp */
183	tmp.l_ui = 1000000000UL;
184	tmp.l_uf = 2147483648UL;
185	HTONL_FP(&tmp, &rpkt.rec);
186
187	/*/ T3 - Transmit timestamp */
188	tmp.l_ui = 1000000001UL;
189	tmp.l_uf = 2147483648UL;
190	HTONL_FP(&tmp, &rpkt.xmt);
191
192	/* T4 - Destination timestamp as standard timeval */
193	tmp.l_ui = 1000000003UL;
194	tmp.l_uf = 0UL;
195
196	TSTOTV(&tmp, &dst);
197	dst.tv_sec -= JAN_1970;
198
199	offset_calculation(&rpkt, LEN_PKT_NOMAC, &dst, &offset, &precision, &synch_distance);
200
201	TEST_ASSERT_EQUAL_DOUBLE(-1, offset);
202	TEST_ASSERT_EQUAL_DOUBLE(1. / ULOGTOD(1), precision);
203	TEST_ASSERT_EQUAL_DOUBLE(1.3333483333333334, synch_distance);
204}
205
206
207void
208test_HandleUnusableServer(void)
209{
210	struct pkt	rpkt;
211	sockaddr_u	host;
212	int		rpktl;
213
214	ZERO(rpkt);
215	ZERO(host);
216	rpktl = SERVER_UNUSEABLE;
217	TEST_ASSERT_EQUAL(-1, handle_pkt(rpktl, &rpkt, &host, ""));
218}
219
220
221void
222test_HandleUnusablePacket(void)
223{
224	struct pkt	rpkt;
225	sockaddr_u	host;
226	int		rpktl;
227
228	ZERO(rpkt);
229	ZERO(host);
230	rpktl = PACKET_UNUSEABLE;
231	TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, ""));
232}
233
234
235void
236test_HandleServerAuthenticationFailure(void)
237{
238	struct pkt	rpkt;
239	sockaddr_u	host;
240	int		rpktl;
241
242	ZERO(rpkt);
243	ZERO(host);
244	rpktl = SERVER_AUTH_FAIL;
245	TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, ""));
246}
247
248
249void
250test_HandleKodDemobilize(void)
251{
252	static const char *	HOSTNAME = "192.0.2.1";
253	static const char *	REASON = "DENY";
254	struct pkt		rpkt;
255	sockaddr_u		host;
256	int			rpktl;
257	struct kod_entry *	entry;
258
259	rpktl = KOD_DEMOBILIZE;
260	ZERO(rpkt);
261	memcpy(&rpkt.refid, REASON, 4);
262	ZERO(host);
263	host.sa4.sin_family = AF_INET;
264	host.sa4.sin_addr.s_addr = inet_addr(HOSTNAME);
265
266	/* Test that the KOD-entry is added to the database. */
267	kod_init_kod_db("/dev/null", TRUE);
268
269	TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, HOSTNAME));
270
271	TEST_ASSERT_EQUAL(1, search_entry(HOSTNAME, &entry));
272	TEST_ASSERT_EQUAL_MEMORY(REASON, entry->type, 4);
273}
274
275
276void
277test_HandleKodRate(void)
278{
279	struct 	pkt	rpkt;
280	sockaddr_u	host;
281	int		rpktl;
282
283	ZERO(rpkt);
284	ZERO(host);
285	rpktl = KOD_RATE;
286	TEST_ASSERT_EQUAL(1, handle_pkt(rpktl, &rpkt, &host, ""));
287}
288
289
290void
291test_HandleCorrectPacket(void)
292{
293	struct pkt	rpkt;
294	sockaddr_u	host;
295	int		rpktl;
296	l_fp		now;
297
298	/* We don't want our testing code to actually change the system clock. */
299	TEST_ASSERT_FALSE(ENABLED_OPT(STEP));
300	TEST_ASSERT_FALSE(ENABLED_OPT(SLEW));
301
302	get_systime(&now);
303	HTONL_FP(&now, &rpkt.reftime);
304	HTONL_FP(&now, &rpkt.org);
305	HTONL_FP(&now, &rpkt.rec);
306	HTONL_FP(&now, &rpkt.xmt);
307	rpktl = LEN_PKT_NOMAC;
308	ZERO(host);
309	AF(&host) = AF_INET;
310
311	TEST_ASSERT_EQUAL(0, handle_pkt(rpktl, &rpkt, &host, ""));
312}
313
314/* packetHandling.c */
315