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