import ( "encoding/binary" "flag" "fmt" "log" "net" "time" )
const ntpEpochOffset = 2208988800
type packet struct { Settings uint8 Stratum uint8 Poll int8 Precision int8 RootDelay uint32 RootDispersion uint32 ReferenceID uint32 RefTimeSec uint32 RefTimeFrac uint32 OrigTimeSec uint32 OrigTimeFrac uint32 RxTimeSec uint32 RxTimeFrac uint32 TxTimeSec uint32 TxTimeFrac uint32 }
func main() { var host string flag.StringVar(&host, "e", "182.92.12.11:123", "NTP host") flag.Parse()
conn, err := net.Dial("udp", host) if err != nil { log.Fatalf("failed to connect: %v", err) } defer conn.Close() if err := conn.SetDeadline(time.Now().Add(15 * time.Second)); err != nil { log.Fatalf("failed to set deadline: %v", err) }
req := &packet{Settings: 0x1B}
if err := binary.Write(conn, binary.BigEndian, req); err != nil { log.Fatalf("failed to send request: %v", err) }
rsp := &packet{} if err := binary.Read(conn, binary.BigEndian, rsp); err != nil { log.Fatalf("failed to read server response: %v", err) }
secs := float64(rsp.TxTimeSec) - ntpEpochOffset nanos := (int64(rsp.TxTimeFrac) * 1e9) >> 32
showtime := time.Unix(int64(secs), nanos) fmt.Printf("%v\n", showtime) }