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