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