Documentation
¶
Overview ¶
Package control implements NTP Control Protocol (RFC1305, Appendix B).
To make it more useful, some implementation details diverge from RFC to match what is described in NTPD docs http://doc.ntp.org/current-stable/decode.html.
Library allows communicating with any NTP server that implements Control Protocol (such as ntpd), and get various information, for example: current server status; server variables like offset; peers with their statuses and variables; server counters.
Example usage can be found in ntpcheck project - https://github.com/facebook/time/ntp/ntpcheck
Index ¶
- Constants
- Variables
- func MakeREMOp(response, err, more bool, op int) uint8
- func MakeVnMode(version int, mode int) uint8
- func NormalizeData(data []byte) (map[string]string, error)
- func ReadFlashStatusWord(flash uint16) []string
- type NTPClient
- type NTPControlMsg
- type NTPControlMsgHead
- type PeerStatus
- type PeerStatusWord
- type SystemStatusWord
Constants ¶
const ( OpReadStatus = 1 OpReadVariables = 2 )
Supported operation codes
const ( // SelReject means peer is discarded as not valid (TEST10-TEST13) SelReject uint8 = 0 // SelFalseTick means peer is discarded by intersection algorithm SelFalseTick uint8 = 1 // SelExcess means peer is discarded by table overflow (not used) SelExcess uint8 = 2 // SelOutlier means peer is discarded by the cluster algorithm SelOutlier uint8 = 3 // SelCandidate means peer is included by the combine algorithm SelCandidate uint8 = 4 // SelBackup means peer is a backup (more than tos maxclock sources) SelBackup uint8 = 5 // SelSYSPeer means peer is a system peer (main synchronization source) SelSYSPeer uint8 = 6 // SelPPSPeer means peer is a PPS peer (when the prefer peer is valid) SelPPSPeer uint8 = 7 )
Here go peer selection statuses, as described in http://doc.ntp.org/current-stable/decode.html#peer
const Mode = 6
Mode is NTP Control operation mode code
Variables ¶
var ClockSourceDesc = [10]string{
"unspec",
"pps",
"lf_radio",
"hf_radio",
"uhf_radio",
"local",
"ntp",
"other",
"wristwatch",
"telephone",
}
ClockSourceDesc stores human-readable descriptions of ClockSource field
var FlashDescMap = map[uint16]string{
0x0001: "pkt_dup",
0x0002: "pkt_bogus",
0x0004: "pkt_unsync",
0x0008: "pkt_denied",
0x0010: "pkt_auth",
0x0020: "pkt_stratum",
0x0040: "pkt_header",
0x0080: "pkt_autokey",
0x0100: "pkt_crypto",
0x0200: "peer_stratum",
0x0400: "peer_dist",
0x0800: "peer_loop",
0x1000: "peer_unreach",
}
FlashDescMap maps bit mask with corresponding flash status
var LeapDesc = [4]string{"none", "add_sec", "del_sec", "alarm"}
LeapDesc stores human-readable descriptions of LI (leap indicator) field
var PeerSelect = [8]string{"reject", "falsetick", "excess", "outlyer", "candidate", "backup", "sys.peer", "pps.peer"}
PeerSelect maps PeerSelection uint8 to human-readable string taken from http://doc.ntp.org/4.2.6/decode.html#peer
var SystemEventDesc = [17]string{
"unspecified",
"freq_not_set",
"freq_set",
"spike_detect",
"freq_mode",
"clock_sync",
"restart",
"panic_stop",
"no_system_peer",
"leap_armed",
"leap_disarmed",
"leap_event",
"clock_step",
"kern",
"TAI...",
"stale leapsecond values",
"clockhop",
}
SystemEventDesc stores human-readable descriptions of SystemEvent field
Functions ¶
func MakeREMOp ¶
MakeREMOp composes uint8 with response error and more bits set, combined with operation code
func MakeVnMode ¶
MakeVnMode composes uint8 with version and mode bits set
func NormalizeData ¶
NormalizeData turns bytes that contain kv ASCII string info a map[string]string
func ReadFlashStatusWord ¶
ReadFlashStatusWord returns list of flashers (as strings) decoded from flash status word
Types ¶
type NTPClient ¶
type NTPClient struct { Sequence uint16 Connection io.ReadWriter }
NTPClient is our client to talk to network. The main reason it exists is keeping track of Sequence number.
func (*NTPClient) Communicate ¶
func (n *NTPClient) Communicate(packet *NTPControlMsgHead) (*NTPControlMsg, error)
Communicate sends package over connection, bumps Sequence num and parses (possibly multiple) response packets into NTPControlMsg packet. This function will always return single NTPControlMsg, even if under the hood it was split across multiple packets. Resulting NTPControlMsg will have Data section composed of combined Data sections from all packages.
func (*NTPClient) CommunicateWithData ¶
func (n *NTPClient) CommunicateWithData(packet *NTPControlMsgHead, data []uint8) (*NTPControlMsg, error)
CommunicateWithData sends package + data over connection, bumps Sequence num and parses (possibly multiple) response packets into NTPControlMsg packet. This function will always return single NTPControlMsg, even if under the hood it was split across multiple packets. Resulting NTPControlMsg will have Data section composed of combined Data sections from all packages.
type NTPControlMsg ¶
type NTPControlMsg struct { NTPControlMsgHead Data []uint8 }
NTPControlMsg is just a NTPControlMsgHead with data.
func (NTPControlMsg) GetAssociationInfo ¶
func (n NTPControlMsg) GetAssociationInfo() (map[string]string, error)
GetAssociationInfo returns parsed normalized variables if present
func (NTPControlMsg) GetAssociations ¶
func (n NTPControlMsg) GetAssociations() (map[uint16]*PeerStatusWord, error)
GetAssociations returns map of PeerStatusWord, basically peer information.
func (NTPControlMsg) GetPeerStatus ¶
func (n NTPControlMsg) GetPeerStatus() (*PeerStatusWord, error)
GetPeerStatus returns parsed PeerStatusWord struct if present
func (NTPControlMsg) GetSystemStatus ¶
func (n NTPControlMsg) GetSystemStatus() (*SystemStatusWord, error)
GetSystemStatus returns parsed SystemStatusWord struct if present
type NTPControlMsgHead ¶
type NTPControlMsgHead struct { // 0: 00 Version(3bit) Mode(3bit) VnMode uint8 // 1: Response Error More Operation(5bit) REMOp uint8 // 2-3: Sequence (16bit) Sequence uint16 // 4-5: Status (16bit) Status uint16 // 6-7: Association ID (16bit) AssociationID uint16 // 8-9: Offset (16bit) Offset uint16 // 10-11: Count (16bit) Count uint16 }
NTPControlMsgHead structure is described in NTPv3 RFC1305 Appendix B. NTP Control Messages. We don't have Data defined here as data size is variable and binary package simply doesn't support reading or writing structs with non-fixed fields.
func (NTPControlMsgHead) GetMode ¶
func (n NTPControlMsgHead) GetMode() int
GetMode gets int mode from Version+Mode 8bit word
func (NTPControlMsgHead) GetOperation ¶
func (n NTPControlMsgHead) GetOperation() uint8
GetOperation returns int operation extracted from REMOp 8bit word
func (NTPControlMsgHead) GetVersion ¶
func (n NTPControlMsgHead) GetVersion() int
GetVersion gets int version from Version+Mode 8bit word
func (NTPControlMsgHead) HasError ¶
func (n NTPControlMsgHead) HasError() bool
HasError returns true if packet has error flag set
func (NTPControlMsgHead) HasMore ¶
func (n NTPControlMsgHead) HasMore() bool
HasMore returns true if packet has More flag set
func (NTPControlMsgHead) IsResponse ¶
func (n NTPControlMsgHead) IsResponse() bool
IsResponse returns true if packet is a response
type PeerStatus ¶
type PeerStatus struct { Broadcast bool Reachable bool AuthEnabled bool AuthOK bool Configured bool }
PeerStatus word decoded. Sadly values used by ntpd are different from RFC for v2 and v3 of NTP. Actual values are from http://doc.ntp.org/4.2.6/decode.html#peer
func ReadPeerStatus ¶
func ReadPeerStatus(b uint8) PeerStatus
ReadPeerStatus transforms PeerStatus 8bit flag into usable struct
type PeerStatusWord ¶
type PeerStatusWord struct { PeerStatus PeerStatus PeerSelection uint8 PeerEventCounter uint8 PeerEventCode uint8 }
PeerStatusWord stores parsed PeerStatus 16bit word.
func ReadPeerStatusWord ¶
func ReadPeerStatusWord(b uint16) *PeerStatusWord
ReadPeerStatusWord transforms PeerStatus 16bit word into usable struct
func (*PeerStatusWord) Word ¶
func (psw *PeerStatusWord) Word() uint16
Word encodes PeerStatusWord as uint16 word
type SystemStatusWord ¶
type SystemStatusWord struct { LI uint8 ClockSource uint8 SystemEventCounter uint8 SystemEventCode uint8 }
SystemStatusWord stores parsed SystemStatus 16bit word.
func ReadSystemStatusWord ¶
func ReadSystemStatusWord(b uint16) *SystemStatusWord
ReadSystemStatusWord transforms SystemStatus 16bit word into usable struct.
func (*SystemStatusWord) Word ¶
func (ssw *SystemStatusWord) Word() uint16
Word encodes SystemStatusWord as uint16 word