1*cdfa2a7eSchristos /* $NetBSD: refidsmear.c,v 1.2 2020/05/25 20:47:24 christos Exp $ */ 2067f5680Schristos 3f17b710fSchristos #include <config.h> 4f17b710fSchristos 5f17b710fSchristos #include <ntp.h> 6f17b710fSchristos #include <ntp_fp.h> 7f17b710fSchristos #include <refidsmear.h> 8f17b710fSchristos 9f17b710fSchristos /* 10f17b710fSchristos * we want to test a refid format of: 11f17b710fSchristos * 254.x.y.x 12f17b710fSchristos * 13f17b710fSchristos * where x.y.z are 24 bits containing 2 (signed) integer bits 14f17b710fSchristos * and 22 fractional bits. 15f17b710fSchristos * 16f17b710fSchristos */ 17f17b710fSchristos 18f17b710fSchristos 19f17b710fSchristos l_fp convertRefIDToLFP(uint32_t r)20f17b710fSchristosconvertRefIDToLFP(uint32_t r) 21f17b710fSchristos { 22f17b710fSchristos l_fp temp; 23f17b710fSchristos 24f17b710fSchristos r = ntohl(r); 25f17b710fSchristos 26f17b710fSchristos // printf("%03d %08x: ", (r >> 24) & 0xFF, (r & 0x00FFFFFF) ); 27f17b710fSchristos 28f17b710fSchristos temp.l_uf = (r << 10); /* 22 fractional bits */ 29f17b710fSchristos 30f17b710fSchristos temp.l_ui = (r >> 22) & 0x3; 31f17b710fSchristos temp.l_ui |= ~(temp.l_ui & 2) + 1; 32f17b710fSchristos 33f17b710fSchristos return temp; 34f17b710fSchristos } 35f17b710fSchristos 36f17b710fSchristos 37f17b710fSchristos uint32_t convertLFPToRefID(l_fp num)38f17b710fSchristosconvertLFPToRefID(l_fp num) 39f17b710fSchristos { 40f17b710fSchristos uint32_t temp; 41f17b710fSchristos 42f17b710fSchristos /* round the input with the highest bit to shift out from the 43f17b710fSchristos * fraction, then keep just two bits from the integral part. 44f17b710fSchristos * 45f17b710fSchristos * TODO: check for overflows; should we clamp/saturate or just 46f17b710fSchristos * complain? 47f17b710fSchristos */ 48f17b710fSchristos L_ADDUF(&num, 0x200); 49f17b710fSchristos num.l_ui &= 3; 50f17b710fSchristos 51f17b710fSchristos /* combine integral and fractional part to 24 bits */ 52f17b710fSchristos temp = (num.l_ui << 22) | (num.l_uf >> 10); 53f17b710fSchristos 54f17b710fSchristos /* put in the leading 254.0.0.0 */ 55f17b710fSchristos temp |= UINT32_C(0xFE000000); 56f17b710fSchristos 57f17b710fSchristos // printf("%03d %08x: ", (temp >> 24) & 0xFF, (temp & 0x00FFFFFF) ); 58f17b710fSchristos 59f17b710fSchristos return htonl(temp); 60f17b710fSchristos } 61