NTPSvr.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package NTP
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "log"
  6. "net"
  7. "sync"
  8. "time"
  9. )
  10. const (
  11. STANDARD_PACKET_SIZE = 48 // 标准NTP的报文大小
  12. )
  13. type NTPServer struct {
  14. srvAddress string
  15. conn *net.UDPConn
  16. wait sync.WaitGroup
  17. ntpPack NtpPacket // NTP协议报文
  18. requestCount uint64 // 请求计数
  19. }
  20. type NtpPacket struct {
  21. /*
  22. LI: 2bit 00 Leap Indicator(0)
  23. VN: 3bit 100 NTP Version(4)
  24. Mode: 3bit 100 Mode: server(4), client(3)
  25. */
  26. Header uint8 // 报文头: 包含LI、VN、Mode
  27. Stratum uint8 // Peer Clock Stratum: primary reference (1)
  28. Poll uint8 // Peer Polling Interval: invalid (0)
  29. Precision uint8 // Peer Clock Precision: 0.000000 seconds
  30. RootDelay uint32 // Root Delay
  31. RootDisp uint32 // Root Dispersion
  32. RefID uint32 // Reference Identifier
  33. RefTS uint64 // Reference Timestamp 参考时间戳
  34. OrigTS uint64 // Originate Timestamp 起始时间戳
  35. RecvTS uint64 // Receive Timestamp 接收时间戳
  36. TransTS uint64 // Transmit Timestamp 传输时间戳
  37. }
  38. func (srv *NTPServer) NewNtpPacket() *NtpPacket {
  39. // 初始化Header字段
  40. header := uint8(0)
  41. header |= (0 << 6) // LI: 2bit 00
  42. header |= (4 << 3) // VN: 3bit 100
  43. header |= (4 << 0) // Mode: 3bit 100
  44. // 创建新的NtpPacket实例
  45. packet := &NtpPacket{
  46. Header: header,
  47. Stratum: 0x01,
  48. Poll: 0x00,
  49. Precision: 0x00,
  50. RootDelay: 0,
  51. RootDisp: 0,
  52. RefID: 0,
  53. RefTS: 0,
  54. OrigTS: 0,
  55. RecvTS: 0,
  56. TransTS: 0,
  57. }
  58. return packet
  59. }
  60. func (pack *NtpPacket) SetTimestamp(timestamp time.Time, field string) {
  61. ntpTime := ToNTPTime(timestamp)
  62. switch field {
  63. case "RefTS":
  64. pack.RefTS = ntpTime
  65. case "OrigTS":
  66. pack.OrigTS = ntpTime
  67. case "RecvTS":
  68. pack.RecvTS = ntpTime
  69. case "TransTS":
  70. pack.TransTS = ntpTime
  71. }
  72. }
  73. // toNTPTime 将Unix时间转换为NTP时间
  74. func ToNTPTime(t time.Time) uint64 {
  75. seconds := uint32(t.Unix()) + 2208988800 // NTP时间从1900年开始计算
  76. fraction := uint32(float64(t.Nanosecond()) * (1 << 32) / 1e9)
  77. return uint64(seconds)<<32 | uint64(fraction)
  78. }
  79. func NewNTPServer(srvAddr string) *NTPServer {
  80. return &NTPServer{srvAddress: srvAddr}
  81. }
  82. // 启动NTP服务器
  83. func (srv *NTPServer) Start() error {
  84. addr, err := net.ResolveUDPAddr("udp", srv.srvAddress)
  85. if err != nil {
  86. return err
  87. }
  88. log.Println(fmt.Sprintf("<%s:%d>", addr.IP.String(), addr.Port))
  89. conn, err := net.ListenUDP("udp", addr)
  90. if err != nil {
  91. return err
  92. }
  93. srv.wait.Add(1)
  94. srv.conn = conn
  95. go RecvMsg(srv)
  96. return nil
  97. }
  98. // 关闭NTP服务器
  99. func (srv *NTPServer) Stop() {
  100. srv.conn.Close()
  101. srv.wait.Wait()
  102. }
  103. // 接收数据
  104. func RecvMsg(srv *NTPServer) {
  105. defer srv.wait.Done()
  106. buffer := make([]byte, 2*1024)
  107. for {
  108. n, remoteAddr, err := srv.conn.ReadFromUDP(buffer[0:])
  109. if err != nil {
  110. fmt.Println("ReadFromUDP error:", err)
  111. return
  112. }
  113. log.Println(fmt.Sprintf("[Recv] %d bytes from <%s>", n, remoteAddr.String()))
  114. if n != STANDARD_PACKET_SIZE {
  115. continue
  116. }
  117. // 接收到NTP客户端消息的时间
  118. recvMsgTime := time.Now().UTC()
  119. recvHexString := BytesToHex(buffer[:n])
  120. log.Println(fmt.Sprintf("[Recv] %s", recvHexString))
  121. udpPacket, err := ParseUDPPacket(buffer[:n])
  122. if err != nil {
  123. log.Printf("Error parsing UDP packet: %v", err)
  124. continue
  125. }
  126. ntpPack := srv.NewNtpPacket()
  127. ntpPack.SetTimestamp(time.Now().UTC(), "RefTS")
  128. ntpPack.OrigTS = udpPacket.TransTS
  129. ntpPack.SetTimestamp(recvMsgTime, "RecvTS")
  130. ntpPack.SetTimestamp(time.Now().UTC(), "TransTS")
  131. sendPacket := ntpPack.Serialize()
  132. sendLen, err := srv.conn.WriteToUDP(sendPacket, remoteAddr)
  133. if err != nil {
  134. log.Println(err.Error())
  135. continue
  136. }
  137. if sendLen > 0 {
  138. log.Println(fmt.Sprintf("[Send] %s", BytesToHex(sendPacket)))
  139. }
  140. srv.requestCount++
  141. }
  142. }
  143. func (pack *NtpPacket) Serialize() []byte {
  144. packet := make([]byte, 48)
  145. // binary.BigEndian.PutUint32(packet[0:4], pack.Header)
  146. packet[0] = pack.Header
  147. packet[1] = pack.Stratum
  148. packet[2] = pack.Poll
  149. packet[3] = pack.Precision
  150. binary.BigEndian.PutUint32(packet[4:8], pack.RootDelay)
  151. binary.BigEndian.PutUint32(packet[8:12], pack.RootDisp)
  152. binary.BigEndian.PutUint32(packet[12:16], pack.RefID)
  153. binary.BigEndian.PutUint64(packet[16:24], pack.RefTS)
  154. binary.BigEndian.PutUint64(packet[24:32], pack.OrigTS)
  155. binary.BigEndian.PutUint64(packet[32:40], pack.RecvTS)
  156. binary.BigEndian.PutUint64(packet[40:48], pack.TransTS)
  157. return packet
  158. }
  159. // BytesToHex 将字节数组转换为16进制字符串
  160. func BytesToHex(data []byte) string {
  161. hexString := make([]byte, 3*len(data)-1)
  162. for i, b := range data {
  163. high := "0123456789ABCDEF"[(b >> 4)]
  164. low := "0123456789ABCDEF"[(b & 0x0F)]
  165. hexString[i*3] = high
  166. hexString[i*3+1] = low
  167. if i < len(data)-1 {
  168. hexString[i*3+2] = ' ' // 每个16进制数据之间加空格
  169. }
  170. }
  171. return string(hexString)
  172. }
  173. func ParseUDPPacket(buf []byte) (*NtpPacket, error) {
  174. if len(buf) < STANDARD_PACKET_SIZE { // 最小有效长度为48字节
  175. return nil, fmt.Errorf("Invalid UDP packet length: %d", len(buf))
  176. }
  177. packet := &NtpPacket{
  178. // Header: binary.BigEndian.Uint32(buf[0:4]),
  179. Header: buf[0],
  180. Stratum: buf[1],
  181. Poll: buf[2],
  182. Precision: buf[3],
  183. RootDelay: binary.BigEndian.Uint32(buf[4:8]),
  184. RootDisp: binary.BigEndian.Uint32(buf[8:12]),
  185. RefID: binary.BigEndian.Uint32(buf[12:16]),
  186. RefTS: binary.BigEndian.Uint64(buf[16:24]),
  187. OrigTS: binary.BigEndian.Uint64(buf[24:32]),
  188. RecvTS: binary.BigEndian.Uint64(buf[32:40]),
  189. TransTS: binary.BigEndian.Uint64(buf[40:48]),
  190. }
  191. return packet, nil
  192. }