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