Skip to content

Instantly share code, notes, and snippets.

@tormath1
Created November 8, 2020 17:59
Show Gist options
  • Save tormath1/b83854c205d9552f7f72be743963b571 to your computer and use it in GitHub Desktop.
Save tormath1/b83854c205d9552f7f72be743963b571 to your computer and use it in GitHub Desktop.
NTP Go Client
package main
import (
"bufio"
"bytes"
"encoding/binary"
"fmt"
"net"
"os"
"time"
)
var (
// 1970-01-01 00:00:00
ref uint32 = 2208988800
// The NTP message consists of a 384 bit or 48 byte data structure containing 17 fields.
buff []byte = make([]byte, 48)
ntp = &NTPPacket{
// 0x23 for 00100011
// leap indicator: 00
// version: 100 (version 4)
// mode: 011 (mode client)
LIVNMode: 0x21,
}
)
// NTPPacket is the struct defined in
// https://tools.ietf.org/html/rfc5905#section-7.3
type NTPPacket struct {
// LIVNMode is the Leap Indicator + Version + Mode (LLVVVMMM)
LIVNMode byte
Stratum byte
Poll byte
Precision byte
RootDelay uint32
RootDispersion uint32
RefID uint32
RefTms uint32
RefTmf uint32
OrigTms uint32
OrigTmf uint32
RxTms uint32
RxTmf uint32
TxTms uint32
TxTmff uint32
}
func main() {
addr, err := net.ResolveUDPAddr("udp", "pool.ntp.org:123")
if err != nil {
fmt.Print(err)
os.Exit(1)
}
client, err := net.DialUDP(addr.Network(), nil, addr)
if err != nil {
fmt.Print(err)
os.Exit(1)
}
if err := binary.Write(client, binary.BigEndian, *ntp); err != nil {
fmt.Print(err)
os.Exit(1)
}
if _, err := bufio.NewReader(client).Read(buff); err != nil {
fmt.Print(err)
os.Exit(1)
}
buf := bytes.NewBuffer(buff)
// resultat needs to be decoded in network byte order (BigEndian)
if err := binary.Read(buf, binary.BigEndian, ntp); err != nil {
fmt.Print(err)
os.Exit(1)
}
sec := ntp.TxTms
sec -= ref
t := time.Unix(int64(sec), 0)
fmt.Println(t)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment