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