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