1 |
786 |
skrzyp |
|
2 |
|
|
|
3 |
|
|
|
4 |
|
|
|
5 |
|
|
|
6 |
|
|
|
7 |
|
|
|
8 |
|
|
|
9 |
|
|
|
10 |
|
|
|
11 |
|
|
|
12 |
|
|
|
13 |
|
|
|
14 |
|
|
|
15 |
|
|
|
16 |
|
|
|
17 |
|
|
|
18 |
|
|
|
19 |
|
|
|
20 |
|
|
|
21 |
|
|
|
22 |
|
|
|
23 |
|
|
|
24 |
|
|
|
25 |
|
|
|
26 |
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
|
31 |
|
|
Simple Network Time Protocol Client
|
32 |
|
|
|
33 |
|
|
|
34 |
|
|
The SNTP package provides implementation of a client for RFC 2030, the
|
35 |
|
|
Simple Network Time Protocol (SNTP). The client listens for broadcasts
|
36 |
|
|
or IPv6 multicasts from an NTP server and uses the information received to
|
37 |
|
|
set the system clock. It can also be configured to send SNTP time
|
38 |
|
|
requests to specific NTP servers using SNTP's unicast mode.
|
39 |
|
|
|
40 |
|
|
|
41 |
|
|
|
42 |
|
|
The SNTP Client
|
43 |
|
|
|
44 |
|
|
Starting the SNTP client
|
45 |
|
|
|
46 |
|
|
The sntp client is implemented as a thread which listens for NTP
|
47 |
|
|
broadcasts and IPv6 multicasts, and optionally sends SNTP unicast
|
48 |
|
|
requests to specific NTP servers. This thread may be automatically
|
49 |
|
|
started by the system if it receives a list of (S)NTP servers from the
|
50 |
|
|
DHCP server and unicast mode is enabled. Otherwise it must be started
|
51 |
|
|
by the user application. The header file
|
52 |
|
|
cyg/sntp/sntp.h declares the function to be
|
53 |
|
|
called. The thread is then started by calling the function:
|
54 |
|
|
|
55 |
|
|
|
56 |
|
|
void cyg_sntp_start(void);
|
57 |
|
|
|
58 |
|
|
|
59 |
|
|
It is safe to call this function multiple times. Once started, the
|
60 |
|
|
thread will run forever.
|
61 |
|
|
|
62 |
|
|
|
63 |
|
|
|
64 |
|
|
|
65 |
|
|
What it does
|
66 |
|
|
|
67 |
|
|
The SNTP client listens for NTP IPv4 broadcasts from any NTP servers,
|
68 |
|
|
or IPv6 multicasts using the address fe0x:0X::101, where X can be
|
69 |
|
|
2 (Link Local), 5 (Site-Local) or 0xe (Global). Such
|
70 |
|
|
packets contain a timestamp indicating the current time. The packet
|
71 |
|
|
also contains information about where the server is in the hierarchy
|
72 |
|
|
of time servers. A server at the root of the time server tree normally
|
73 |
|
|
has an atomic clock. Such a server is said to be at stratum 0. A time
|
74 |
|
|
server which is synchronised to a stratum 0 server is said to be at
|
75 |
|
|
stratum 1 etc. The client will accept any NTP packets from
|
76 |
|
|
servers using version 3 or 4 of the protocol. When receiving packets
|
77 |
|
|
from multiple servers, it will use the packets from the server with
|
78 |
|
|
the lowest stratum. However, if there are no packets from this server
|
79 |
|
|
for 10 minutes and another server is sending packets, the client will
|
80 |
|
|
change servers.
|
81 |
|
|
|
82 |
|
|
|
83 |
|
|
If SNTP unicast mode is enabled via the CYGPKG_NET_SNTP_UNICAST
|
84 |
|
|
option, the SNTP client can additionally be configured with a list
|
85 |
|
|
of specific NTP servers to query. The general algorithm is as follows: if
|
86 |
|
|
the system clock has not yet been set via an NTP time update, then
|
87 |
|
|
the client will send out NTP requests every 30 seconds to all
|
88 |
|
|
configured NTP servers. Once an NTP time update has been received,
|
89 |
|
|
the client will send out additional NTP requests every 30 minutes
|
90 |
|
|
in order to update the system clock. These requests are resent
|
91 |
|
|
every 30 seconds until a response is received.
|
92 |
|
|
|
93 |
|
|
|
94 |
|
|
The system clock in eCos is accurate to 1 second. The SNTP client will
|
95 |
|
|
change the system clock when the time difference with the received
|
96 |
|
|
timestamp is greater than 2 seconds. The change is made as a step.
|
97 |
|
|
|
98 |
|
|
|
99 |
|
|
|
100 |
|
|
|
101 |
|
|
Configuring the unicast list of NTP servers
|
102 |
|
|
|
103 |
|
|
If SNTP unicast mode is enabled via the CYGPKG_NET_SNTP_UNICAST
|
104 |
|
|
option, the SNTP client can be configured with a list of
|
105 |
|
|
NTP servers to contact for time updates.
|
106 |
|
|
|
107 |
|
|
|
108 |
|
|
By default, this list is configured with NTP server information
|
109 |
|
|
received from DHCP. The number of NTP servers that are extracted
|
110 |
|
|
from DHCP can be configured with the CYGOPT_NET_SNTP_UNICAST_MAXDHCP
|
111 |
|
|
option. This option can also be used to disable DHCP usage entirely.
|
112 |
|
|
|
113 |
|
|
|
114 |
|
|
The list of NTP servers can be manually configured with the following
|
115 |
|
|
API function. Note that manual configuration will override any
|
116 |
|
|
servers that were automatically configured by DHCP. But later
|
117 |
|
|
reconfigurations by DHCP will override manual configurations. Hence it
|
118 |
|
|
is not recommended to manually configure servers when
|
119 |
|
|
CYGOPT_NET_SNTP_UNICAST is enabled.
|
120 |
|
|
|
121 |
|
|
|
122 |
|
|
#include <cyg/sntp/sntp.h>
|
123 |
|
|
|
124 |
|
|
void cyg_sntp_set_servers(struct sockaddr *server_list, cyg_uint32 num_servers);
|
125 |
|
|
|
126 |
|
|
|
127 |
|
|
This function takes an array of sockaddr structures specifying the
|
128 |
|
|
IP address and UDP port of each NTP server to query. Currently,
|
129 |
|
|
both IPv4 and IPv6 sockaddr structures are supported. The
|
130 |
|
|
num_servers argument specifies how many sockaddr's are contained
|
131 |
|
|
in the array. The server_list array must be maintained by the caller.
|
132 |
|
|
Once the array is registered with this function, it must not be
|
133 |
|
|
modified by the caller until it is replaced or unregistered
|
134 |
|
|
by another call to this function.
|
135 |
|
|
|
136 |
|
|
|
137 |
|
|
Calling this function with a server_list of NULL and a num_servers
|
138 |
|
|
value of 0 unregisters any previously configured server_list array.
|
139 |
|
|
|
140 |
|
|
|
141 |
|
|
Finally, note that if this function is called with a non-empty server
|
142 |
|
|
list, it will implicitly start the SNTP client if it has not already
|
143 |
|
|
been started (i.e. it will call cyg_sntp_start()).
|
144 |
|
|
|
145 |
|
|
|
146 |
|
|
|
147 |
|
|
|
148 |
|
|
Warning: timestamp wrap around
|
149 |
|
|
|
150 |
|
|
The timestamp in the NTP packet is a 32bit integer which represents
|
151 |
|
|
the number of seconds after 00:00 01/01/1900. This 32bit number will
|
152 |
|
|
wrap around at 06:28:16 Feb 7 2036. At this point in time, the eCos
|
153 |
|
|
time will jump back to around 00:00:00 Jan 1 1900 when the next
|
154 |
|
|
NTP packet is received.
|
155 |
|
|
|
156 |
|
|
|
157 |
|
|
YOU HAVE BEEN WARNED!
|
158 |
|
|
|
159 |
|
|
|
160 |
|
|
|
161 |
|
|
The SNTP test program
|
162 |
|
|
|
163 |
|
|
The SNTP package contains a simple test program. Testing an SNTP
|
164 |
|
|
client is not easy, so the test program should be considered as more a
|
165 |
|
|
proof of concept. It shows that an NTP packet has been received,
|
166 |
|
|
and is accurate to within a few days.
|
167 |
|
|
|
168 |
|
|
|
169 |
|
|
The test program starts the network interfaces using the standard
|
170 |
|
|
call. It then starts the SNTP thread. A loop is then entered printing
|
171 |
|
|
the current system time every second for two minutes. When the client
|
172 |
|
|
receives an NTP packet the time will jump from 1970 to hopefully the
|
173 |
|
|
present day. Once the two minutes have expired, two simple tests are
|
174 |
|
|
made. If the time is still less than 5 minutes since 00:00:00
|
175 |
|
|
01/01/1970 the test fails. This indicates no NTP messages have
|
176 |
|
|
been received. Check that the server is actually sending packet, using
|
177 |
|
|
the correct port (123), correct IPv6 multicast address, and at a
|
178 |
|
|
sufficiently frequent rate that the
|
179 |
|
|
target has a chance to receive a message within the 2 minute
|
180 |
|
|
interval. If all this is correct, assume the target is broken.
|
181 |
|
|
|
182 |
|
|
|
183 |
|
|
The second test is that the current system time is compared with the
|
184 |
|
|
build time as reported by the CPP macro __DATE__. If the build date is
|
185 |
|
|
in the future relative to the system time, the test fails. If the
|
186 |
|
|
build date is more than 90 days in the past relative to the system
|
187 |
|
|
time the test also fails. If such failures are seen, use walk-clock
|
188 |
|
|
time to verify the time printed during the test. If this seems correct
|
189 |
|
|
check the build date for the test. This is printed at startup. If all
|
190 |
|
|
else fails check that the computer used to build the test has the
|
191 |
|
|
correct time.
|
192 |
|
|
|
193 |
|
|
|
194 |
|
|
If SNTP unicast mode is enabled, the above tests are run twice. The
|
195 |
|
|
first time, the SNTP client is configured with NTP server addresses
|
196 |
|
|
from DHCP. The second time, unicast mode is disabled and only
|
197 |
|
|
multicasts are listened for. Note that the unicast test is partially
|
198 |
|
|
bogus in the sense that any multicast packet received will also make
|
199 |
|
|
the unicast test pass. To reduce the chance of this happening the
|
200 |
|
|
test will wait for a sorter time for replies. This is not ideal, but
|
201 |
|
|
it is the best that can be done with an automated test.
|
202 |
|
|
|
203 |
|
|
|
204 |
|
|
|
205 |
|
|
|