1 /*
2  * ntp_fp.h - definitions for NTP fixed/floating-point arithmetic
3  */
4 
5 #ifndef GUARD_NTP_FP_H
6 #define GUARD_NTP_FP_H
7 
8 #include <arpa/inet.h>
9 
10 #include "ntp_types.h"
11 
12 /*
13  * NTP uses two fixed point formats.
14  *
15  * The first (l_fp) is the "long" format and is 64 bits wide in units
16  * of 1/2^32 seconds (which is between 232 and 233 decimal
17  * picoseconds).  The zero value signifies the zero date of the
18  * current NTP era; era zero began on the date 1900-00-00T00:00:00 in
19  * proleptic UTC (leap second correction was not introduced until
20  * 1972).
21  *
22  * The long format is used for timestamps in the NTP packet header (in
23  * network byte order).  It is defined in RFC 5905 in Section 6 (Data
24  * Types). In the on-the-wire context, it is always unsigned.
25  *
26  * When it is convenient to compute in seconds, this type can
27  * be interpreted as a fixed-point float with the radix point between
28  * bits 31 and 32. This is why there are macros to extract the low and
29  * high halves.
30  *
31  * Internally, this type is sometimes used for time offsets.  In that
32  * context it is interpreted as signed and can only express offsets
33  * up to a half cycle. Offsets are normally much, much smaller than that;
34  * for an offset to have a value even as large as 1 second would be
35  * highly unusual after ntpd initialization.
36  *
37  * Anyway, an l_fp looks like:
38  *
39  *    0			  1		      2			  3
40  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
41  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
42  *   |			       Integral Part			     |
43  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
44  *   |			       Fractional Part			     |
45  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
46  *
47  * NTP time stamps will overflow in 2036.  Until then we are in
48  * NTP Epoch 0.  After that NTP timestamps will be in Epoch 1.  Negative
49  * epochs can be used to represent time before Jan 1900.
50  *
51  * The epoch number is not explicit on the wire. It will seldom be an
52  * issue: timestamp differences between two adjacent epochs are still
53  * valid as long as the true time difference is less than half an
54  * epoch.  In other words, you don't have to explicitly check for the
55  * epoch of either timestamp if you assume that these are less than 68
56  * years apart.
57  */
58 typedef uint64_t l_fp;
59 #define lfpfrac(n)		((uint32_t)(n))
60 #define lfptouint(n)	        ((uint64_t)((uint64_t)(n) << 32))
61 #define lfpsint(n)		(( int32_t)((n) >> 32))
62 #define lfpuint(n)		((uint32_t)((n) >> 32))
63 #define bumplfpsint(n, i)       ((n) += lfptouint(i))
64 #define bumplfpuint(n, i)       ((n) += lfptouint(i))
65 #define setlfpfrac(n, v)        ((n)  = (lfptouint(lfpuint(n)) | lfpfrac(v)))
66 #define setlfpuint(n, v)        ((n)  = (lfptouint(v) | lfpfrac(n)))
67 
lfpinit(int32_t sec,uint32_t frac)68 static inline l_fp lfpinit(int32_t sec, uint32_t frac) {
69 	l_fp tmp = lfptouint(sec) | lfpfrac(frac);
70 	return tmp;
71 }
72 
lfpinit_u(uint32_t sec,uint32_t frac)73 static inline l_fp lfpinit_u(uint32_t sec, uint32_t frac) {
74 	l_fp tmp = lfptouint(sec) | lfpfrac(frac);
75 	return tmp;
76 }
77 
78 /*
79  * Fractional precision (of an l_fp) is actually the number of
80  * bits in an int32_t/uint32_t.
81  */
82 #define	FRACTION_PREC	(32)
83 
84 /*
85  * The second fixed point format is 32 bits, with the decimal between
86  * bits 15 and 16.  There is a signed version (s_fp) and an unsigned
87  * version (u_fp).  This is used to represent synchronizing distance
88  * and synchronizing dispersion in the NTP packet header (again, in
89  * network byte order) and internally to hold both distance and
90  * dispersion values (in local byte order).  In network byte order
91  * it looks like:
92  *
93  *    0               1               2               3
94  *    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
95  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
96  *   |		  Integer Part	     |	   Fraction Part	     |
97  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
98  *
99  */
100 typedef uint32_t u_fp;
101 
102 
103 typedef struct {
104          uint32_t        l_ui;
105          uint32_t        l_uf;
106 } l_fp_w;
107 
108 #define	M_ISNEG(v_i)			/* v < 0 */ \
109 	(((v_i) & 0x80000000) != 0)
110 
111 /*
112  * Operations on the long fp format.  The only reason these aren't
113  * native operations is to be independent of whether the l_fp
114  * type is signed or unsigned.
115  */
116 #define	L_NEG(v)	(v) = (l_fp)(-(int64_t)(v))
117 #define	L_ISNEG(v)	M_ISNEG(lfpuint(v))
118 #define	L_ISGT(a, b)	((int64_t)(a) > (int64_t)(b))
119 #define	L_ISGTU(a, b)	((a) > (b))
120 
121 /*
122  * scaling to 32bit FP format
123  * double to u_fp conversion
124  */
125 #define FP_SCALE(r)	(ldexp((double)(r),  16))
126 #define FP_UNSCALE(r)	(ldexp((double)(r), -16))
127 #define DTOUFP(r)	((u_fp)FP_SCALE(r))
128 
129 /*
130  * l_fp/double conversions
131  */
132 #define FRAC		4294967296.0 		/* 2^32 as a double */
133 
134 #include <math.h>	/* ldexpl() */
135 
dtolfp(doubletime_t d)136 static inline l_fp dtolfp(doubletime_t d) {
137 /* long double to l_fp
138  * assumes signed l_fp, i.e. a time offset
139  * undefined return if d in NaN
140  */
141 	return (l_fp)(int64_t)(ldexpl(d, 32));
142 }
143 
lfptod(l_fp r)144 static inline doubletime_t lfptod(l_fp r) {
145 /* l_fp to long double
146  * assumes signed l_fp, i.e. a time offset
147  */
148 	return ldexpl((double)((int64_t)r), -32);
149 }
150 
151 /*
152  * Prototypes
153  */
154 extern	char *	dolfptoa	(l_fp, bool, short, bool);
155 extern	char *	mfptoa		(l_fp, short);
156 extern	char *	mfptoms		(l_fp, short);
157 
158 extern	bool	hextolfp	(const char *, l_fp *);
159 extern	void	set_prettydate_pivot(time_t);
160 extern	char *	prettydate	(const l_fp);
161 extern	char *	rfc3339date	(const l_fp);
162 extern	char *	rfc3339time     (time_t);
163 
164 #ifdef ENABLE_FUZZ
165 extern	void	set_sys_fuzz	(double);
166 #endif
167 extern	void	get_systime	(l_fp *);
168 extern	bool	step_systime	(doubletime_t, int (*settime)(struct timespec *));
169 extern	bool	adj_systime	(double, int (*adjtime)(const struct timeval *, struct timeval *));
170 
171 #define	lfptoa(fpv, ndec)	mfptoa((fpv), (ndec))
172 #define	lfptoms(fpv, ndec)	mfptoms((fpv), (ndec))
173 
174 #define	ulfptoa(fpv, ndec)	dolfptoa((fpv), false, (ndec), false)
175 #define	ulfptoms(fpv, ndec)	dolfptoa((fpv), false, (ndec), true)
176 #define	umfptoa(lfp, ndec)	dolfptoa((lfp), false, (ndec), false)
177 
178 /*
179  * Optional callback from libntp step_systime() to ntpd.  Optional
180 *  because other libntp clients like ntpdate don't use it.
181  */
182 typedef void (*time_stepped_callback)(void);
183 extern time_stepped_callback	step_callback;
184 
185 extern uint32_t	convertLFPToRefID(l_fp num) __attribute__((const));
186 
187 #endif /* GUARD_NTP_FP_H */
188