xref: /netbsd-src/external/bsd/ntp/dist/tests/sandbox/smeartest.c (revision eabc0478de71e4e011a5b4e0392741e01d491794)
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