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