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