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