Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

350 lines
16 KiB

  1. //--------------------------------------------------------------------
  2. // NtpBase - header
  3. // Copyright (C) Microsoft Corporation, 1999
  4. //
  5. // Created by: Louis Thomas (louisth), 4-16-99
  6. //
  7. // The basic message structure, definitions, and helper functions
  8. //
  9. #ifndef NTPBASE_H
  10. #define NTPBASE_H
  11. #include <dsrole.h>
  12. //--------------------------------------------------------------------
  13. // Time formats
  14. // a clock reading, little-endian, in (10^-7)s
  15. struct NtTimeEpoch {
  16. unsigned __int64 qw;
  17. void dump(void);
  18. };
  19. // a signed time offset, little-endian, in (10^-7)s
  20. struct NtTimeOffset {
  21. signed __int64 qw;
  22. void dump(void);
  23. };
  24. // a length of time, little-endian, in (10^-7)s
  25. struct NtTimePeriod {
  26. unsigned __int64 qw;
  27. void dump(void);
  28. };
  29. // a clock reading, big-endian, in (2^-32)s
  30. struct NtpTimeEpoch {
  31. unsigned __int64 qw;
  32. };
  33. // a signed time offset, big-endian, in (2^-16)s
  34. struct NtpTimeOffset {
  35. signed __int32 dw;
  36. };
  37. // a length of time, big-endian, in (2^-16)s
  38. struct NtpTimePeriod {
  39. unsigned __int32 dw;
  40. };
  41. extern const NtTimeEpoch gc_teNtpZero; // convenient 'zero'
  42. extern const NtpTimeEpoch gc_teZero; // convenient 'zero'
  43. extern const NtTimePeriod gc_tpZero; // convenient 'zero'
  44. extern const NtTimeOffset gc_toZero; // convenient 'zero'
  45. //--------------------------------------------------------------------
  46. // helpful conversion functions
  47. NtTimeEpoch NtTimeEpochFromNtpTimeEpoch(NtpTimeEpoch te);
  48. NtpTimeEpoch NtpTimeEpochFromNtTimeEpoch(NtTimeEpoch te);
  49. NtTimePeriod NtTimePeriodFromNtpTimePeriod(NtpTimePeriod tp);
  50. NtpTimePeriod NtpTimePeriodFromNtTimePeriod(NtTimePeriod tp);
  51. NtTimeOffset NtTimeOffsetFromNtpTimeOffset(NtpTimeOffset to);
  52. NtpTimeOffset NtpTimeOffsetFromNtTimeOffset(NtTimeOffset to);
  53. //--------------------------------------------------------------------
  54. // Math operators
  55. static inline NtTimeOffset operator -(const NtTimeOffset toRight) {
  56. NtTimeOffset toRet;
  57. toRet.qw=-toRight.qw;
  58. return toRet;
  59. }
  60. static inline NtTimeOffset operator -(const NtTimeEpoch teLeft, const NtTimeEpoch teRight) {
  61. NtTimeOffset toRet;
  62. toRet.qw=teLeft.qw-teRight.qw;
  63. return toRet;
  64. }
  65. static inline NtTimeOffset operator -(const NtTimeOffset toLeft, const NtTimeOffset toRight) {
  66. NtTimeOffset toRet;
  67. toRet.qw=toLeft.qw-toRight.qw;
  68. return toRet;
  69. }
  70. static inline NtTimeOffset operator +(const NtTimeOffset toLeft, const NtTimeOffset toRight) {
  71. NtTimeOffset toRet;
  72. toRet.qw=toLeft.qw+toRight.qw;
  73. return toRet;
  74. }
  75. static inline NtTimeOffset & operator /=(NtTimeOffset &toLeft, const int nDiv) {
  76. toLeft.qw/=nDiv;
  77. return toLeft;
  78. }
  79. static inline NtTimeOffset & operator -=(NtTimeOffset &toLeft, const NtTimeOffset toRight) {
  80. toLeft.qw-=toRight.qw;
  81. return toLeft;
  82. }
  83. static inline NtTimeOffset & operator +=(NtTimeOffset &toLeft, const NtTimeOffset toRight) {
  84. toLeft.qw-=toRight.qw;
  85. return toLeft;
  86. }
  87. static inline NtTimeEpoch operator +(const NtTimeEpoch teLeft, const NtTimePeriod tpRight) {
  88. NtTimeEpoch teRet;
  89. teRet.qw=teLeft.qw+tpRight.qw;
  90. return teRet;
  91. }
  92. static inline NtTimePeriod operator *(const NtTimePeriod tpLeft, const unsigned __int64 qwMult) {
  93. NtTimePeriod tpRet;
  94. tpRet.qw=tpLeft.qw*qwMult;
  95. return tpRet;
  96. }
  97. static inline NtTimePeriod & operator *=(NtTimePeriod &tpLeft, const unsigned __int64 qwMult) {
  98. tpLeft.qw*=qwMult;
  99. return tpLeft;
  100. }
  101. static inline NtTimePeriod operator /(const NtTimePeriod tpLeft, const int nDiv) {
  102. NtTimePeriod tpRet;
  103. tpRet.qw=tpLeft.qw/nDiv;
  104. return tpRet;
  105. }
  106. static inline NtTimePeriod & operator +=(NtTimePeriod &tpLeft, const NtTimePeriod tpRight) {
  107. tpLeft.qw+=tpRight.qw;
  108. return tpLeft;
  109. }
  110. static inline NtTimePeriod operator +(const NtTimePeriod tpLeft, const NtTimePeriod tpRight) {
  111. NtTimePeriod tpRet;
  112. tpRet.qw=tpLeft.qw+tpRight.qw;
  113. return tpRet;
  114. }
  115. static inline NtTimePeriod & operator -=(NtTimePeriod &tpLeft, const NtTimePeriod tpRight) {
  116. tpLeft.qw-=tpRight.qw;
  117. return tpLeft;
  118. }
  119. static inline NtTimePeriod operator -(const NtTimePeriod tpLeft, const NtTimePeriod tpRight) {
  120. NtTimePeriod tpRet;
  121. tpRet.qw=tpLeft.qw-tpRight.qw;
  122. return tpRet;
  123. }
  124. static inline bool operator <(const NtTimeEpoch teLeft, const NtTimeEpoch teRight) {
  125. return teLeft.qw<teRight.qw;
  126. }
  127. static inline bool operator <=(const NtTimeEpoch teLeft, const NtTimeEpoch teRight) {
  128. return teLeft.qw<=teRight.qw;
  129. }
  130. static inline bool operator >(const NtTimeEpoch teLeft, const NtTimeEpoch teRight) {
  131. return teLeft.qw>teRight.qw;
  132. }
  133. static inline bool operator >=(const NtTimeEpoch teLeft, const NtTimeEpoch teRight) {
  134. return teLeft.qw>=teRight.qw;
  135. }
  136. static inline bool operator ==(const NtTimeEpoch teLeft, const NtTimeEpoch teRight) {
  137. return teLeft.qw==teRight.qw;
  138. }
  139. static inline bool operator !=(const NtTimeEpoch teLeft, const NtTimeEpoch teRight) {
  140. return teLeft.qw!=teRight.qw;
  141. }
  142. static inline bool operator <(const NtTimePeriod tpLeft, const NtTimePeriod tpRight) {
  143. return tpLeft.qw<tpRight.qw;
  144. }
  145. static inline bool operator <=(const NtTimePeriod tpLeft, const NtTimePeriod tpRight) {
  146. return tpLeft.qw<=tpRight.qw;
  147. }
  148. static inline bool operator >(const NtTimePeriod tpLeft, const NtTimePeriod tpRight) {
  149. return tpLeft.qw>tpRight.qw;
  150. }
  151. static inline bool operator >=(const NtTimePeriod tpLeft, const NtTimePeriod tpRight) {
  152. return tpLeft.qw>=tpRight.qw;
  153. }
  154. static inline bool operator ==(const NtTimePeriod tpLeft, const NtTimePeriod tpRight) {
  155. return tpLeft.qw==tpRight.qw;
  156. }
  157. static inline bool operator !=(const NtTimePeriod tpLeft, const NtTimePeriod tpRight) {
  158. return tpLeft.qw!=tpRight.qw;
  159. }
  160. static inline bool operator <(const NtTimeOffset toLeft, const NtTimeOffset toRight) {
  161. return toLeft.qw<toRight.qw;
  162. }
  163. static inline bool operator <=(const NtTimeOffset toLeft, const NtTimeOffset toRight) {
  164. return toLeft.qw<=toRight.qw;
  165. }
  166. static inline bool operator >(const NtTimeOffset toLeft, const NtTimeOffset toRight) {
  167. return toLeft.qw>toRight.qw;
  168. }
  169. static inline bool operator >=(const NtTimeOffset toLeft, const NtTimeOffset toRight) {
  170. return toLeft.qw>=toRight.qw;
  171. }
  172. static inline bool operator ==(const NtTimeOffset toLeft, const NtTimeOffset toRight) {
  173. return toLeft.qw==toRight.qw;
  174. }
  175. static inline bool operator !=(const NtTimeOffset toLeft, const NtTimeOffset toRight) {
  176. return toLeft.qw!=toRight.qw;
  177. }
  178. static inline bool operator ==(const NtpTimeEpoch teLeft, const NtpTimeEpoch teRight) {
  179. return teLeft.qw==teRight.qw;
  180. }
  181. static inline bool operator !=(const NtpTimeEpoch teLeft, const NtpTimeEpoch teRight) {
  182. return teLeft.qw!=teRight.qw;
  183. }
  184. static inline NtTimePeriod abs(const NtTimeOffset to) {
  185. NtTimePeriod tpRet;
  186. tpRet.qw=((to.qw<0)?((unsigned __int64)(-to.qw)):((unsigned __int64)(to.qw)));
  187. return tpRet;
  188. }
  189. //--------------------------------------------------------------------
  190. static inline NtTimePeriod minimum(NtTimePeriod tpLeft, NtTimePeriod tpRight) {
  191. return ((tpLeft<tpRight)?tpLeft:tpRight);
  192. }
  193. //--------------------------------------------------------------------
  194. // identifies the particular reference source
  195. union NtpRefId {
  196. unsigned __int8 rgnIpAddr[4]; // an IP address
  197. unsigned __int8 rgnName[4]; // 4 ascii characters
  198. unsigned __int32 nTransmitTimestamp; // the low order 32 bits of the latest transmit timestamp of the reference source
  199. unsigned __int32 value; // for copying purposes
  200. };
  201. //--------------------------------------------------------------------
  202. // The format of a standard NTP packet
  203. struct NtpPacket {
  204. struct {
  205. unsigned __int8 nMode:3; // the mode. Valid range: 0-7
  206. unsigned __int8 nVersionNumber:3; // the NTP/SNTP version number. Valid range: 1-4
  207. unsigned __int8 nLeapIndicator:2; // a warning of an impending leap second to be inserted/deleted in the last minute of the current day
  208. };
  209. unsigned __int8 nStratum; // the stratum level of the local clock. Valid Range: 0-15
  210. signed __int8 nPollInterval; // the maximum interval between successive messages, in s, log base 2. Valid range:4(16s)-14(16284s)
  211. signed __int8 nPrecision; // the precision of the local clock, in s, log base 2
  212. NtpTimeOffset toRootDelay; // the total roundtrip delay to the primary reference source, in (2^-16)s
  213. NtpTimePeriod tpRootDispersion; // the nominal error relative to the primary reference, in (2^-16)s
  214. NtpRefId refid; // identifies the particular reference source
  215. NtpTimeEpoch teReferenceTimestamp; // the time at which the local clock was last set or corrected, in (2^-32)s
  216. NtpTimeEpoch teOriginateTimestamp; // the time at which the request departed the client for the server, in (2^-32)s
  217. NtpTimeEpoch teReceiveTimestamp; // the time at which the request arrived at the server, in (2^-32)s
  218. NtpTimeEpoch teTransmitTimestamp; // the time at which the reply departed the server for the client, in (2^-32)s
  219. };
  220. #define SizeOfNtpPacket 48
  221. //--------------------------------------------------------------------
  222. // The format of an authenticated NTP packet
  223. struct AuthenticatedNtpPacket {
  224. struct {
  225. unsigned __int8 nMode:3; // the mode. Valid range: 0-7
  226. unsigned __int8 nVersionNumber:3; // the NTP/SNTP version number. Valid range: 1-4
  227. unsigned __int8 nLeapIndicator:2; // a warning of an impending leap second to be inserted/deleted in the last minute of the current day
  228. };
  229. unsigned __int8 nStratum; // the stratum level of the local clock. Valid Range: 0-15
  230. signed __int8 nPollInterval; // the maximum interval between successive messages, in s, log base 2. Valid range:4(16s)-14(16284s)
  231. signed __int8 nPrecision; // the precision of the local clock, in s, log base 2
  232. NtpTimeOffset toRootDelay; // the total roundtrip delay to the primary reference source, in (2^-16)s
  233. NtpTimePeriod tpRootDispersion; // the nominal error relative to the primary reference, in (2^-16)s
  234. NtpRefId refid; // identifies the particular reference source
  235. NtpTimeEpoch teReferenceTimestamp; // the time at which the local clock was last set or corrected, in (2^-32)s
  236. NtpTimeEpoch teOriginateTimestamp; // the time at which the request departed the client for the server, in (2^-32)s
  237. NtpTimeEpoch teReceiveTimestamp; // the time at which the request arrived at the server, in (2^-32)s
  238. NtpTimeEpoch teTransmitTimestamp; // the time at which the reply departed the server for the client, in (2^-32)s
  239. unsigned __int32 nKeyIdentifier; // implementation specific, for authentication
  240. unsigned __int8 rgnMessageDigest[16]; // implementation specific, for authentication
  241. };
  242. // We define this because of structure packing issues - our structure
  243. // contains qwords, but is not a multiple of 8 in size, so sizeof()
  244. // incorrectly reports the size. If we were to adjust the packing,
  245. // we might misalign the qwords. Interestingly, in the NTP spec,
  246. // the rgnMessageDigest is 12 bytes, so the packet is a multiple of 8.
  247. #define SizeOfNtAuthenticatedNtpPacket 68
  248. //--------------------------------------------------------------------
  249. // The allowed NTP modes
  250. enum NtpMode {
  251. e_Reserved=0,
  252. e_SymmetricActive=1,
  253. e_SymmetricPassive=2,
  254. e_Client=3,
  255. e_Server=4,
  256. e_Broadcast=5,
  257. e_Control=6,
  258. e_PrivateUse=7,
  259. };
  260. //--------------------------------------------------------------------
  261. // The allowed NTP modes
  262. enum NtpLeapIndicator {
  263. e_NoWarning=0,
  264. e_AddSecond=1,
  265. e_SubtractSecond=2,
  266. e_ClockNotSynchronized=3,
  267. };
  268. //--------------------------------------------------------------------
  269. // NTP constants
  270. struct NtpConst {
  271. static const unsigned int nVersionNumber; // 3 // the current NTP version number
  272. static const unsigned int nPort; // 123 // the port number assigned by the Internet Assigned Numbers Authority to NTP
  273. static const unsigned int nMaxStratum; // 15 // the maximum stratum value that can be encoded as a packet value, also interpreted as "infinity" or unreachable
  274. static const signed int nMinPollInverval; // 6 // the minimum poll interval allowed by any peer, in s, log base 2 (6=64s)
  275. static const NtTimePeriod tpMaxClockAge; // 86400.0000000 // the maximum inverval a reference clock will be considered valid after its last update, in (10^-7)s
  276. static const NtTimePeriod tpMaxSkew; // 1.0000000 // the maximum offset error due to skew of the local clock over the interval determined by NTPCONST_MaxAge, in (10^-7)s
  277. static const NtTimePeriod tpMaxDispersion; // 16.0000000 // the maximum peer dispersion and the dispersion assumed for missing data, in (10^-7)s
  278. static const NtTimePeriod tpMinDispersion; // 0.0100000 // the minimum dispersion increment for each stratum level, in (10^-7)s
  279. static const NtTimePeriod tpMaxDistance; // 1.0000000 // the maximum synchronization distance for peers acceptible for synchronization, in (10^-7)s
  280. static const unsigned int nMinSelectClocks; // 1 // the minimum number of peers acceptable for synchronization
  281. static const unsigned int nMaxSelectClocks; // 10 // the maximum number of peers considered for selection
  282. static const DWORD dwLocalRefId; // LOCL // the reference identifier for the local clock
  283. static NtTimePeriod timesMaxSkewRate(NtTimePeriod tp) { // MaxSkewRate == phi == NTPCONST_MaxSkew / NTPCONST_MaxClockAge; in s per s (==11.5740740...PPM)
  284. NtTimePeriod tpRet;
  285. tpRet.qw=tp.qw/86400;
  286. return tpRet;
  287. }
  288. static signed int maxPollInterval(DSROLE_MACHINE_ROLE role) {
  289. if (DsRole_RoleBackupDomainController == role || DsRole_RolePrimaryDomainController == role) { return nMaxPollIntervalDCs; }
  290. else { return nMaxPollInverval; }
  291. }
  292. static void weightFilter(NtTimePeriod &tp) { tp.qw/=2; } // weight the filter dispersion during computation (x * 1/2)
  293. static void weightSelect(unsigned __int64 &tp) { tp*=3;tp/=4; } // weight the select dispersion during computation (x * 3/2)
  294. private:
  295. // These constants should not be accessed directly. Used NtpConst::maxPollInterval() instead.
  296. static const signed int nMaxPollIntervalDCs;// 15 // the maximum poll interval allowed by any DC peer, in s, log base 2 (15=32768s)
  297. static const signed int nMaxPollInverval; // 17 // the maximum poll interval allowed by any non-DC peer, in s, log base 2 (17=~1.5 days)
  298. };
  299. struct NtpReachabilityReg {
  300. static const unsigned int nSize; // 8 // the size of the reachability register, in bits
  301. unsigned __int8 nReg;
  302. };
  303. //--------------------------------------------------------------------
  304. // helpful debug dump functions
  305. void DumpNtpPacket(NtpPacket * pnpIn, NtTimeEpoch teDestinationTimestamp);
  306. void DumpNtpTimeEpoch(NtpTimeEpoch te);
  307. void DumpNtTimeEpoch(NtTimeEpoch te);
  308. void DumpNtTimePeriod(NtTimePeriod tp);
  309. void DumpNtTimeOffset(NtTimeOffset to);
  310. inline void NtTimeEpoch::dump(void) { DumpNtTimeEpoch(*this); }
  311. inline void NtTimePeriod::dump(void) { DumpNtTimePeriod(*this); }
  312. inline void NtTimeOffset::dump(void) { DumpNtTimeOffset(*this); }
  313. NtTimeEpoch GetCurrentSystemNtTimeEpoch(void);
  314. #endif // NTPBASE_H