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