Class: NET::NTP

Inherits:
Object
  • Object
show all
Defined in:
lib/ntp.rb

Constant Summary collapse

VERSION =

:nodoc:

'1.0.0'
TIMEOUT =

:nodoc:

60
NTP_ADJ =

:nodoc:

2208988800
MODE =
{
0    =>    'reserved',
1    =>    'symmetric active',
2    =>    'symmetric passive',
3    =>    'client',
4    =>    'server',
5    =>    'broadcast',
6    =>    'reserved for NTP control message',
7    =>    'reserved for private use' }
STRATUM =
{
0    =>    'unspecified or unavailable',
1    =>    'primary reference (e.g., radio clock)' }
STRATUM_ONE_TEXT =
{
'LOCL'  => 'uncalibrated local clock used as a primary reference for a subnet without external means of synchronization',
'PPS'   => 'atomic clock or other pulse-per-second source individually calibrated to national standards',
'ACTS'  => 'NIST dialup modem service',
'USNO'  => 'USNO modem service',
'PTB'   => 'PTB (Germany) modem service',
'TDF'   => 'Allouis (France) Radio 164 kHz',
'DCF'   => 'Mainflingen (Germany) Radio 77.5 kHz',
'MSF'   => 'Rugby (UK) Radio 60 kHz',
'WWV'   => 'Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz',
'WWVB'  => 'Boulder (US) Radio 60 kHz',
'WWVH'  => 'Kaui Hawaii (US) Radio 2.5, 5, 10, 15 MHz',
'CHU'   => 'Ottawa (Canada) Radio 3330, 7335, 14670 kHz',
'LORC'  => 'LORAN-C radionavigation system',
'OMEG'  => 'OMEGA radionavigation system',
'GPS'   => 'Global Positioning Service',
'GOES'  => 'Geostationary Orbit Environment Satellite' }
LEAP_INDICATOR =
{
0    =>     'no warning',
1    =>     'last minute has 61 seconds',
2    =>     'last minute has 59 seconds)',
3    =>     'alarm condition (clock not synchronized)' }

Class Method Summary collapse

Class Method Details

.get_ntp_response(host = "pool.ntp.org", port = "ntp") ⇒ Object

Sends an NTP datagram to the specified NTP server and returns a hash based upon RFC1305 and RFC2030.



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/ntp.rb', line 96

def NTP.get_ntp_response(host="pool.ntp.org", port="ntp")

  sock = UDPSocket.new
  sock.connect(host, port)

  client_time_send = Time.new.to_i
  client_localtime = client_time_send
  client_adj_localtime = client_localtime + NTP_ADJ
  client_frac_localtime = frac2bin(client_adj_localtime)
  
  ntp_msg =
    (['00011011']+Array.new(12, 0)+[client_localtime, client_frac_localtime.to_s]).pack("B8 C3 N10 B32")
  
  sock.print ntp_msg
  sock.flush
 
  data=NIL 
  Timeout::timeout(TIMEOUT) do |t|
    data=sock.recvfrom(960)[0]
  end
  client_time_receive = Time.new.to_i
  
  ntp_fields = %w{ byte1 stratum poll precision
   delay delay_fb disp disp_fb ident
   ref_time ref_time_fb
   org_time org_time_fb
   recv_time recv_time_fb
   trans_time trans_time_fb }
  
  packetdata =
      data.unpack("a C3   n B16 n B16 H8   N B32 N B32   N B32 N B32"); 
  
  tmp_pkt=Hash.new
  ntp_fields.each do |f|
    tmp_pkt[f]=packetdata.shift
  end

  packet=Hash.new
  packet['Leap Indicator']=(tmp_pkt['byte1'][0] & 0xC0) >> 6 
  packet['Version Number']=(tmp_pkt['byte1'][0] & 0x38) >> 3
  packet['Mode']=(tmp_pkt['byte1'][0] & 0x07)
  packet['Stratum']=tmp_pkt['stratum']
  packet['Poll Interval']=tmp_pkt['poll']
  packet['Precision']=tmp_pkt['precision'] - 255
  packet['Root Delay']=bin2frac(tmp_pkt['delay_fb'])
  packet['Root Dispersion']=tmp_pkt['disp']
  packet['Reference Clock Identifier']=unpack_ip(tmp_pkt['stratum'], tmp_pkt['ident'])
  packet['Reference Timestamp']=((tmp_pkt['ref_time'] + bin2frac(tmp_pkt['ref_time_fb'])) - NTP_ADJ)
  packet['Originate Timestamp']=((tmp_pkt['org_time'] + bin2frac(tmp_pkt['org_time_fb'])) )
  packet['Receive Timestamp']=((tmp_pkt['recv_time'] + bin2frac(tmp_pkt['recv_time_fb'])) - NTP_ADJ)
  packet['Transmit Timestamp']=((tmp_pkt['trans_time'] + bin2frac(tmp_pkt['trans_time_fb'])) - NTP_ADJ)
  
  return packet

end