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