ntp 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/History.txt ADDED
@@ -0,0 +1,3 @@
1
+ == 1.0.0 / 2007-05-20
2
+
3
+ * initial release
data/Manifest.txt ADDED
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/ntp
6
+ lib/ntp.rb
7
+ test/test_ntp.rb
data/README.txt ADDED
@@ -0,0 +1,53 @@
1
+ net-ntp
2
+ by Jerome Waibel
3
+ http://rubyforge.org/projects/net-ntp/
4
+
5
+ == DESCRIPTION:
6
+
7
+ Rubyfied version of perl's Net::NTP module, (C) 2004 by James G. Willmore.
8
+
9
+ This module exports a single method (NET::NTP::get_ntp_response) and returns a
10
+ hash based upon RFC1305 and RFC2030.
11
+
12
+ == FEATURES/PROBLEMS:
13
+
14
+ == SYNOPSIS:
15
+
16
+ require 'ntp'
17
+
18
+ ntpresult = NET::NTP::get_ntp_response("de.pool.ntp.org")
19
+ printf "Current epoch time: %f\n", ntpresult["Receive Timestamp"]
20
+ printf "This is %s\n", Time.at(ntpresult["Receive Timestamp"])
21
+ printf "Stratum: %d (%s)\n",
22
+ ntpresult["Stratum"], NET::NTP::STRATUM[ntpresult["Stratum"]]
23
+
24
+ == REQUIREMENTS:
25
+
26
+ == INSTALL:
27
+
28
+ * sudo gem install net-ntp
29
+
30
+ == LICENSE:
31
+
32
+ (The MIT License)
33
+
34
+ Copyright (c) 2007
35
+
36
+ Permission is hereby granted, free of charge, to any person obtaining
37
+ a copy of this software and associated documentation files (the
38
+ 'Software'), to deal in the Software without restriction, including
39
+ without limitation the rights to use, copy, modify, merge, publish,
40
+ distribute, sublicense, and/or sell copies of the Software, and to
41
+ permit persons to whom the Software is furnished to do so, subject to
42
+ the following conditions:
43
+
44
+ The above copyright notice and this permission notice shall be
45
+ included in all copies or substantial portions of the Software.
46
+
47
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
48
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
49
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
50
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
51
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
52
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
53
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/ntp.rb'
6
+
7
+ Hoe.new('ntp', NET::NTP::VERSION) do |p|
8
+ p.rubyforge_name = 'net-ntp'
9
+ p.author = 'Jerome Waibel'
10
+ p.summary = 'Send a packet to an NTP server and decode packet received as outlined in RFC1305 and RFC2030'
11
+ # p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
12
+ # p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
13
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
14
+ end
15
+
16
+ # vim: syntax=Ruby
data/bin/ntp ADDED
File without changes
data/lib/ntp.rb ADDED
@@ -0,0 +1,154 @@
1
+ require 'socket'
2
+ require 'timeout'
3
+
4
+ module NET #:nodoc:
5
+
6
+ class NTP
7
+
8
+ VERSION = '1.0.0' #:nodoc:
9
+
10
+ TIMEOUT = 60 #:nodoc:
11
+
12
+ NTP_ADJ = 2208988800 #:nodoc:
13
+
14
+ MODE = {
15
+ 0 => 'reserved',
16
+ 1 => 'symmetric active',
17
+ 2 => 'symmetric passive',
18
+ 3 => 'client',
19
+ 4 => 'server',
20
+ 5 => 'broadcast',
21
+ 6 => 'reserved for NTP control message',
22
+ 7 => 'reserved for private use' }
23
+
24
+ STRATUM = {
25
+ 0 => 'unspecified or unavailable',
26
+ 1 => 'primary reference (e.g., radio clock)' }
27
+
28
+ 2.upto(15) do |i|
29
+ STRATUM[i] = 'secondary reference (via NTP or SNTP)'
30
+ end
31
+ 16.upto(255) do |i|
32
+ STRATUM[i] = 'reserved'
33
+ end
34
+
35
+ STRATUM_ONE_TEXT = {
36
+ 'LOCL' => 'uncalibrated local clock used as a primary reference for a subnet without external means of synchronization',
37
+ 'PPS' => 'atomic clock or other pulse-per-second source individually calibrated to national standards',
38
+ 'ACTS' => 'NIST dialup modem service',
39
+ 'USNO' => 'USNO modem service',
40
+ 'PTB' => 'PTB (Germany) modem service',
41
+ 'TDF' => 'Allouis (France) Radio 164 kHz',
42
+ 'DCF' => 'Mainflingen (Germany) Radio 77.5 kHz',
43
+ 'MSF' => 'Rugby (UK) Radio 60 kHz',
44
+ 'WWV' => 'Ft. Collins (US) Radio 2.5, 5, 10, 15, 20 MHz',
45
+ 'WWVB' => 'Boulder (US) Radio 60 kHz',
46
+ 'WWVH' => 'Kaui Hawaii (US) Radio 2.5, 5, 10, 15 MHz',
47
+ 'CHU' => 'Ottawa (Canada) Radio 3330, 7335, 14670 kHz',
48
+ 'LORC' => 'LORAN-C radionavigation system',
49
+ 'OMEG' => 'OMEGA radionavigation system',
50
+ 'GPS' => 'Global Positioning Service',
51
+ 'GOES' => 'Geostationary Orbit Environment Satellite' }
52
+
53
+ LEAP_INDICATOR = {
54
+ 0 => 'no warning',
55
+ 1 => 'last minute has 61 seconds',
56
+ 2 => 'last minute has 59 seconds)',
57
+ 3 => 'alarm condition (clock not synchronized)' }
58
+
59
+ def NTP.frac2bin(frac)
60
+ bin = ''
61
+ while ( bin.length < 32 )
62
+ bin += ( frac * 2 ).to_i.to_s
63
+ frac = ( frac * 2 ) - ( frac * 2 ).to_i
64
+ end
65
+ return bin
66
+ end
67
+
68
+ def NTP.bin2frac(bin)
69
+ frac = 0
70
+ bin.reverse.split("").each do |b|
71
+ frac = ( frac + b.to_i ) / 2.0
72
+ end
73
+ return frac
74
+ end
75
+
76
+ def NTP.unpack_ip(stratum, tmp_ip)
77
+ if(stratum < 2)
78
+ ip = [tmp_ip].pack("H8").unpack("A4")
79
+ else
80
+ ipbytes=[tmp_ip].pack("H8").unpack("C4")
81
+ ip = sprintf("%d.%d.%d.%d", ipbytes[0],
82
+ ipbytes[1], ipbytes[2], ipbytes[3]
83
+ )
84
+ end
85
+ return ip
86
+ end
87
+
88
+ private_class_method :frac2bin, :bin2frac, :unpack_ip
89
+
90
+ public
91
+
92
+ ###
93
+ # Sends an NTP datagram to the specified NTP server and returns
94
+ # a hash based upon RFC1305 and RFC2030.
95
+
96
+ def NTP.get_ntp_response(host="pool.ntp.org", port="ntp")
97
+
98
+ sock = UDPSocket.new
99
+ sock.connect(host, port)
100
+
101
+ client_time_send = Time.new.to_i
102
+ client_localtime = client_time_send
103
+ client_adj_localtime = client_localtime + NTP_ADJ
104
+ client_frac_localtime = frac2bin(client_adj_localtime)
105
+
106
+ ntp_msg =
107
+ (['00011011']+Array.new(12, 0)+[client_localtime, client_frac_localtime.to_s]).pack("B8 C3 N10 B32")
108
+
109
+ sock.print ntp_msg
110
+ sock.flush
111
+
112
+ data=NIL
113
+ Timeout::timeout(TIMEOUT) do |t|
114
+ data=sock.recvfrom(960)[0]
115
+ end
116
+ client_time_receive = Time.new.to_i
117
+
118
+ ntp_fields = %w{ byte1 stratum poll precision
119
+ delay delay_fb disp disp_fb ident
120
+ ref_time ref_time_fb
121
+ org_time org_time_fb
122
+ recv_time recv_time_fb
123
+ trans_time trans_time_fb }
124
+
125
+ packetdata =
126
+ data.unpack("a C3 n B16 n B16 H8 N B32 N B32 N B32 N B32");
127
+
128
+ tmp_pkt=Hash.new
129
+ ntp_fields.each do |f|
130
+ tmp_pkt[f]=packetdata.shift
131
+ end
132
+
133
+ packet=Hash.new
134
+ packet['Leap Indicator']=(tmp_pkt['byte1'][0] & 0xC0) >> 6
135
+ packet['Version Number']=(tmp_pkt['byte1'][0] & 0x38) >> 3
136
+ packet['Mode']=(tmp_pkt['byte1'][0] & 0x07)
137
+ packet['Stratum']=tmp_pkt['stratum']
138
+ packet['Poll Interval']=tmp_pkt['poll']
139
+ packet['Precision']=tmp_pkt['precision'] - 255
140
+ packet['Root Delay']=bin2frac(tmp_pkt['delay_fb'])
141
+ packet['Root Dispersion']=tmp_pkt['disp']
142
+ packet['Reference Clock Identifier']=unpack_ip(tmp_pkt['stratum'], tmp_pkt['ident'])
143
+ packet['Reference Timestamp']=((tmp_pkt['ref_time'] + bin2frac(tmp_pkt['ref_time_fb'])) - NTP_ADJ)
144
+ packet['Originate Timestamp']=((tmp_pkt['org_time'] + bin2frac(tmp_pkt['org_time_fb'])) )
145
+ packet['Receive Timestamp']=((tmp_pkt['recv_time'] + bin2frac(tmp_pkt['recv_time_fb'])) - NTP_ADJ)
146
+ packet['Transmit Timestamp']=((tmp_pkt['trans_time'] + bin2frac(tmp_pkt['trans_time_fb'])) - NTP_ADJ)
147
+
148
+ return packet
149
+
150
+ end
151
+
152
+ end
153
+
154
+ end
data/test/test_ntp.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "test/unit"
2
+ require "ntp"
3
+
4
+ class TestNTP < Test::Unit::TestCase
5
+ def test_read_time
6
+ ntpresult = NET::NTP::get_ntp_response("de.pool.ntp.org")
7
+ # We should really be past this timestamp
8
+ assert( ntpresult["Receive Timestamp"] > 1179864677 )
9
+ end
10
+ end
metadata ADDED
@@ -0,0 +1,60 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.2
3
+ specification_version: 1
4
+ name: ntp
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.0.0
7
+ date: 2007-06-03 00:00:00 +02:00
8
+ summary: Send a packet to an NTP server and decode packet received as outlined in RFC1305 and RFC2030
9
+ require_paths:
10
+ - lib
11
+ email: ryand-ruby@zenspider.com
12
+ homepage: http://www.zenspider.com/ZSS/Products/ntp/
13
+ rubyforge_project: net-ntp
14
+ description: The author was too lazy to write a description
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Jerome Waibel
31
+ files:
32
+ - History.txt
33
+ - Manifest.txt
34
+ - README.txt
35
+ - Rakefile
36
+ - bin/ntp
37
+ - lib/ntp.rb
38
+ - test/test_ntp.rb
39
+ test_files:
40
+ - test/test_ntp.rb
41
+ rdoc_options: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ executables:
46
+ - ntp
47
+ extensions: []
48
+
49
+ requirements: []
50
+
51
+ dependencies:
52
+ - !ruby/object:Gem::Dependency
53
+ name: hoe
54
+ version_requirement:
55
+ version_requirements: !ruby/object:Gem::Version::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 1.2.0
60
+ version: