control

package
v0.0.0-...-49e71f9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 2, 2021 License: Apache-2.0 Imports: 6 Imported by: 0

README

NTP Control Protocol (RFC1305, Appendix B)

GoDoc

Native Go implementation of NTP Control Protocol.

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/facebookincubator/ntp/ntpcheck

Index

Constants

View Source
const (
	OpReadStatus    = 1
	OpReadVariables = 2
)

Supported operation codes

View Source
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 syncronization 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

View Source
const Mode = 6

Mode is NTP Control operation mode code

Variables

View Source
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

View Source
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

View Source
var LeapDesc = [4]string{"none", "add_sec", "del_sec", "alarm"}

LeapDesc stores human-readable descriptions of LI (leap indicator) field

View Source
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

View Source
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

func MakeREMOp(response, err, more bool, op int) uint8

MakeREMOp composes uint8 with response error and more bits set, combined with operation code

func MakeVnMode

func MakeVnMode(version int, mode int) uint8

MakeVnMode composes uint8 with version and mode bits set

func NormalizeData

func NormalizeData(data []byte) (map[string]string, error)

NormalizeData turns bytes that contain kv ASCII string info a map[string]string

func ReadFlashStatusWord

func ReadFlashStatusWord(flash uint16) []string

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

func (*PeerStatus) Byte

func (ps *PeerStatus) Byte() uint8

Byte encodes PeerStatus as uint8

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL