1 /* $NetBSD: smeartest.c,v 1.3 2024/08/18 20:47:27 christos Exp $ */ 2 3 #include <config.h> 4 5 #include <ntp.h> 6 #include <ntp_fp.h> 7 #include <ntp_assert.h> 8 9 /* 10 * we want to test a refid format of: 11 * 254.x.y.x 12 * 13 * where x.y.z are 24 bits containing 2 (signed) integer bits 14 * and 22 fractional bits. 15 * 16 * we want functions to convert to/from this format, with unit tests. 17 * 18 * Interesting test cases include: 19 * 254.0.0.0 20 * 254.0.0.1 21 * 254.127.255.255 22 * 254.128.0.0 23 * 254.255.255.255 24 */ 25 26 char *progname = ""; 27 28 l_fp convertRefIDToLFP(uint32_t r); 29 uint32_t convertLFPToRefID(l_fp num); 30 31 32 /* 33 * The smear data in the refid is the bottom 3 bytes of the refid, 34 * 2 bits of integer 35 * 22 bits of fraction 36 */ 37 l_fp 38 convertRefIDToLFP(uint32_t r) 39 { 40 l_fp temp; 41 42 r = ntohl(r); 43 44 printf("%03d %08x: ", (r >> 24) & 0xFF, (r & 0x00FFFFFF) ); 45 46 temp.l_uf = (r << 10); /* 22 fractional bits */ 47 48 temp.l_ui = (r >> 22) & 0x3; 49 temp.l_ui |= ~(temp.l_ui & 2) + 1; 50 51 return temp; 52 } 53 54 55 uint32_t 56 convertLFPToRefID(l_fp num) 57 { 58 uint32_t temp; 59 60 /* round the input with the highest bit to shift out from the 61 * fraction, then keep just two bits from the integral part. 62 * 63 * TODO: check for overflows; should we clamp/saturate or just 64 * complain? 65 */ 66 L_ADDUF(&num, 0x200); 67 num.l_ui &= 3; 68 69 /* combine integral and fractional part to 24 bits */ 70 temp = (num.l_ui << 22) | (num.l_uf >> 10); 71 72 /* put in the leading 254.0.0.0 */ 73 temp |= UINT32_C(0xFE000000); 74 75 printf("%03d %08x: ", (temp >> 24) & 0xFF, (temp & 0x00FFFFFF) ); 76 77 return htonl(temp); 78 } 79 80 /* Tests start here */ 81 82 void rtol(uint32_t r); 83 84 void 85 rtol(uint32_t r) 86 { 87 l_fp l; 88 89 printf("rtol: "); 90 91 l = convertRefIDToLFP(htonl(r)); 92 printf("refid %#x, smear %s\n", r, lfptoa(&l, 8)); 93 94 return; 95 } 96 97 98 void rtoltor(uint32_t r); 99 100 void 101 rtoltor(uint32_t r) 102 { 103 l_fp l; 104 105 printf("rtoltor: "); 106 l = convertRefIDToLFP(htonl(r)); 107 108 r = convertLFPToRefID(l); 109 printf("smear %s, refid %#.8x\n", lfptoa(&l, 8), ntohl(r)); 110 111 return; 112 } 113 114 115 void ltor(l_fp l); 116 117 void 118 ltor(l_fp l) 119 { 120 uint32_t r; 121 122 printf("ltor: "); 123 124 r = convertLFPToRefID(l); 125 printf("smear %s, refid %#.8x\n", lfptoa(&l, 8), ntohl(r)); 126 127 return; 128 } 129 130 131 int 132 main(void) 133 { 134 l_fp l; 135 int rc; 136 137 init_lib(); 138 139 rtol(0xfe800000); 140 rtol(0xfe800001); 141 rtol(0xfe8ffffe); 142 rtol(0xfe8fffff); 143 rtol(0xfef00000); 144 rtol(0xfef00001); 145 rtol(0xfefffffe); 146 rtol(0xfeffffff); 147 148 rtol(0xfe000000); 149 rtol(0xfe000001); 150 rtol(0xfe6ffffe); 151 rtol(0xfe6fffff); 152 rtol(0xfe700000); 153 rtol(0xfe700001); 154 rtol(0xfe7ffffe); 155 rtol(0xfe7fffff); 156 157 rtoltor(0xfe800000); 158 rtoltor(0xfe800001); 159 rtoltor(0xfe8ffffe); 160 rtoltor(0xfe8fffff); 161 rtoltor(0xfef00000); 162 rtoltor(0xfef00001); 163 rtoltor(0xfefffffe); 164 rtoltor(0xfeffffff); 165 166 rtoltor(0xfe000000); 167 rtoltor(0xfe000001); 168 rtoltor(0xfe6ffffe); 169 rtoltor(0xfe6fffff); 170 rtoltor(0xfe700000); 171 rtoltor(0xfe700001); 172 rtoltor(0xfe7ffffe); 173 rtoltor(0xfe7fffff); 174 175 rc = atolfp("-.932087", &l); 176 INSIST(1 == rc); 177 178 ltor(l); 179 rtol(0xfec458b0); 180 printf("%x -> %d.%d.%d.%d\n", 181 0xfec458b0, 182 0xfe, 183 0xc4, 184 0x58, 185 0xb0); 186 187 return 0; 188 } 189