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