%line | %branch | |||||||||
---|---|---|---|---|---|---|---|---|---|---|
org.apache.commons.net.ntp.NtpV3Impl |
|
|
1 | package org.apache.commons.net.ntp; |
|
2 | /* |
|
3 | * Copyright 2001-2005 The Apache Software Foundation |
|
4 | * |
|
5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
6 | * you may not use this file except in compliance with the License. |
|
7 | * You may obtain a copy of the License at |
|
8 | * |
|
9 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
10 | * |
|
11 | * Unless required by applicable law or agreed to in writing, software |
|
12 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 | * See the License for the specific language governing permissions and |
|
15 | * limitations under the License. |
|
16 | */ |
|
17 | import java.net.DatagramPacket; |
|
18 | ||
19 | /*** |
|
20 | * Implementation of NtpV3Packet with methods converting Java objects to/from |
|
21 | * the Network Time Protocol (NTP) data message header format described in RFC-1305. |
|
22 | * |
|
23 | * @author Naz Irizarry, MITRE Corp |
|
24 | * @author Jason Mathews, MITRE Corp |
|
25 | * |
|
26 | * @version $Revision: 165675 $ $Date: 2005-05-02 15:09:55 -0500 (Mon, 02 May 2005) $ |
|
27 | */ |
|
28 | public class NtpV3Impl implements NtpV3Packet |
|
29 | { |
|
30 | ||
31 | private static final int MODE_INDEX = 0; |
|
32 | private static final int MODE_SHIFT = 0; |
|
33 | ||
34 | private static final int VERSION_INDEX = 0; |
|
35 | private static final int VERSION_SHIFT = 3; |
|
36 | ||
37 | private static final int LI_INDEX = 0; |
|
38 | private static final int LI_SHIFT = 6; |
|
39 | ||
40 | private static final int STRATUM_INDEX = 1; |
|
41 | private static final int POLL_INDEX = 2; |
|
42 | private static final int PRECISION_INDEX = 3; |
|
43 | ||
44 | private static final int ROOT_DELAY_INDEX = 4; |
|
45 | private static final int ROOT_DISPERSION_INDEX = 8; |
|
46 | private static final int REFERENCE_ID_INDEX = 12; |
|
47 | ||
48 | private static final int REFERENCE_TIMESTAMP_INDEX = 16; |
|
49 | private static final int ORIGINATE_TIMESTAMP_INDEX = 24; |
|
50 | private static final int RECEIVE_TIMESTAMP_INDEX = 32; |
|
51 | private static final int TRANSMIT_TIMESTAMP_INDEX = 40; |
|
52 | ||
53 | private static final int KEY_IDENTIFIER_INDEX = 48; |
|
54 | private static final int MESSAGE_DIGEST = 54; /* len 16 bytes */ |
|
55 | ||
56 | 0 | private byte[] buf = new byte[48]; |
57 | ||
58 | private DatagramPacket dp; |
|
59 | ||
60 | /** Creates a new instance of NtpV3Impl */ |
|
61 | public NtpV3Impl() |
|
62 | 0 | { |
63 | 0 | } |
64 | ||
65 | /*** |
|
66 | * Returns mode as defined in RFC-1305 which is a 3-bit integer |
|
67 | * whose value is indicated by the MODE_xxx parameters. |
|
68 | * |
|
69 | * @return mode as defined in RFC-1305. |
|
70 | */ |
|
71 | public int getMode() |
|
72 | { |
|
73 | 0 | return (ui(buf[MODE_INDEX]) >> MODE_SHIFT) & 0x7; |
74 | } |
|
75 | ||
76 | /*** |
|
77 | * Return human-readable name of message mode type as described in |
|
78 | * RFC 1305. |
|
79 | * @return mode name as string. |
|
80 | */ |
|
81 | public String getModeName() |
|
82 | { |
|
83 | 0 | return NtpUtils.getModeName(getMode()); |
84 | } |
|
85 | ||
86 | /*** |
|
87 | * Set mode as defined in RFC-1305. |
|
88 | * @param mode |
|
89 | */ |
|
90 | public void setMode(int mode) |
|
91 | { |
|
92 | 0 | buf[MODE_INDEX] = (byte) (buf[MODE_INDEX] & 0xF8 | mode & 0x7); |
93 | 0 | } |
94 | ||
95 | /*** |
|
96 | * Returns leap indicator as defined in RFC-1305 which is a two-bit code: |
|
97 | * 0=no warning |
|
98 | * 1=last minute has 61 seconds |
|
99 | * 2=last minute has 59 seconds |
|
100 | * 3=alarm condition (clock not synchronized) |
|
101 | * |
|
102 | * @return leap indicator as defined in RFC-1305. |
|
103 | */ |
|
104 | public int getLeapIndicator() |
|
105 | { |
|
106 | 0 | return (ui(buf[LI_INDEX]) >> LI_SHIFT) & 0x3; |
107 | } |
|
108 | ||
109 | /*** |
|
110 | * Set leap indicator as defined in RFC-1305. |
|
111 | * @param li leap indicator. |
|
112 | */ |
|
113 | public void setLeapIndicator(int li) |
|
114 | { |
|
115 | 0 | buf[LI_INDEX] = (byte) (buf[LI_INDEX] & 0x3F | ((li & 0x3) << LI_SHIFT)); |
116 | 0 | } |
117 | ||
118 | /*** |
|
119 | * Returns poll interval as defined in RFC-1305, which is an eight-bit |
|
120 | * signed integer indicating the maximum interval between successive |
|
121 | * messages, in seconds to the nearest power of two (e.g. value of six |
|
122 | * indicates an interval of 64 seconds. The values that can appear in |
|
123 | * this field range from NTP_MINPOLL to NTP_MAXPOLL inclusive. |
|
124 | * |
|
125 | * @return poll interval as defined in RFC-1305. |
|
126 | */ |
|
127 | public int getPoll() |
|
128 | { |
|
129 | 0 | return (int) (buf[POLL_INDEX]); |
130 | } |
|
131 | ||
132 | /*** |
|
133 | * Set poll interval as defined in RFC-1305. |
|
134 | * |
|
135 | * @param poll poll interval. |
|
136 | */ |
|
137 | public void setPoll(int poll) |
|
138 | { |
|
139 | 0 | buf[POLL_INDEX] = (byte) (poll & 0xFF); |
140 | 0 | } |
141 | ||
142 | /*** |
|
143 | * Returns precision as defined in RFC-1305 encoded as an 8-bit signed |
|
144 | * integer (seconds to nearest power of two). |
|
145 | * Values normally range from -6 to -20. |
|
146 | * |
|
147 | * @return precision as defined in RFC-1305. |
|
148 | */ |
|
149 | public int getPrecision() |
|
150 | { |
|
151 | 0 | return (int) buf[PRECISION_INDEX]; |
152 | } |
|
153 | ||
154 | /*** |
|
155 | * Set precision as defined in RFC-1305. |
|
156 | * @param precision |
|
157 | */ |
|
158 | public void setPrecision(int precision) |
|
159 | { |
|
160 | 0 | buf[PRECISION_INDEX] = (byte) (precision & 0xFF); |
161 | 0 | } |
162 | ||
163 | /*** |
|
164 | * Returns NTP version number as defined in RFC-1305. |
|
165 | * |
|
166 | * @return NTP version number. |
|
167 | */ |
|
168 | public int getVersion() |
|
169 | { |
|
170 | 0 | return (ui(buf[VERSION_INDEX]) >> VERSION_SHIFT) & 0x7; |
171 | } |
|
172 | ||
173 | /*** |
|
174 | * Set NTP version as defined in RFC-1305. |
|
175 | * |
|
176 | * @param version NTP version. |
|
177 | */ |
|
178 | public void setVersion(int version) |
|
179 | { |
|
180 | 0 | buf[VERSION_INDEX] = (byte) (buf[VERSION_INDEX] & 0xC7 | ((version & 0x7) << VERSION_SHIFT)); |
181 | 0 | } |
182 | ||
183 | /*** |
|
184 | * Returns Stratum as defined in RFC-1305, which indicates the stratum level |
|
185 | * of the local clock, with values defined as follows: 0=unspecified, |
|
186 | * 1=primary ref clock, and all others a secondary reference (via NTP). |
|
187 | * |
|
188 | * @return Stratum level as defined in RFC-1305. |
|
189 | */ |
|
190 | public int getStratum() |
|
191 | { |
|
192 | 0 | return ui(buf[STRATUM_INDEX]); |
193 | } |
|
194 | ||
195 | /*** |
|
196 | * Set stratum level as defined in RFC-1305. |
|
197 | * |
|
198 | * @param stratum stratum level. |
|
199 | */ |
|
200 | public void setStratum(int stratum) |
|
201 | { |
|
202 | 0 | buf[STRATUM_INDEX] = (byte) (stratum & 0xFF); |
203 | 0 | } |
204 | ||
205 | /*** |
|
206 | * Return root delay as defined in RFC-1305, which is the total roundtrip delay |
|
207 | * to the primary reference source, in seconds. Values can take positive and |
|
208 | * negative values, depending on clock precision and skew. |
|
209 | * |
|
210 | * @return root delay as defined in RFC-1305. |
|
211 | */ |
|
212 | public int getRootDelay() |
|
213 | { |
|
214 | 0 | return getInt(ROOT_DELAY_INDEX); |
215 | } |
|
216 | ||
217 | /*** |
|
218 | * Return root delay as defined in RFC-1305 in milliseconds, which is |
|
219 | * the total roundtrip delay to the primary reference source, in |
|
220 | * seconds. Values can take positive and negative values, depending |
|
221 | * on clock precision and skew. |
|
222 | * |
|
223 | * @return root delay in milliseconds |
|
224 | */ |
|
225 | public double getRootDelayInMillisDouble() |
|
226 | { |
|
227 | 0 | double l = getRootDelay(); |
228 | 0 | return l / 65.536; |
229 | } |
|
230 | ||
231 | /*** |
|
232 | * Returns root dispersion as defined in RFC-1305. |
|
233 | * @return root dispersion. |
|
234 | */ |
|
235 | public int getRootDispersion() |
|
236 | { |
|
237 | 0 | return getInt(ROOT_DISPERSION_INDEX); |
238 | } |
|
239 | ||
240 | /*** |
|
241 | * Returns root dispersion (as defined in RFC-1305) in milliseconds. |
|
242 | * |
|
243 | * @return root dispersion in milliseconds |
|
244 | */ |
|
245 | public long getRootDispersionInMillis() |
|
246 | { |
|
247 | 0 | long l = getRootDispersion(); |
248 | 0 | return (l * 1000) / 65536L; |
249 | } |
|
250 | ||
251 | /*** |
|
252 | * Returns root dispersion (as defined in RFC-1305) in milliseconds |
|
253 | * as double precision value. |
|
254 | * |
|
255 | * @return root dispersion in milliseconds |
|
256 | */ |
|
257 | public double getRootDispersionInMillisDouble() |
|
258 | { |
|
259 | 0 | double l = getRootDispersion(); |
260 | 0 | return l / 65.536; |
261 | } |
|
262 | ||
263 | /*** |
|
264 | * Set reference clock identifier field with 32-bit unsigned integer value. |
|
265 | * See RFC-1305 for description. |
|
266 | * |
|
267 | * @param refId reference clock identifier. |
|
268 | */ |
|
269 | public void setReferenceId(int refId) |
|
270 | { |
|
271 | 0 | for (int i = 3; i >= 0; i--) { |
272 | 0 | buf[REFERENCE_ID_INDEX + i] = (byte) (refId & 0xff); |
273 | 0 | refId >>>= 8; // shift right one-byte |
274 | } |
|
275 | 0 | } |
276 | ||
277 | /*** |
|
278 | * Returns the reference id as defined in RFC-1305, which is |
|
279 | * a 32-bit integer whose value is dependent on several criteria. |
|
280 | * |
|
281 | * @return the reference id as defined in RFC-1305. |
|
282 | */ |
|
283 | public int getReferenceId() |
|
284 | { |
|
285 | 0 | return getInt(REFERENCE_ID_INDEX); |
286 | } |
|
287 | ||
288 | /*** |
|
289 | * Returns the reference id string. String cannot be null but |
|
290 | * value is dependent on the version of the NTP spec supported |
|
291 | * and stratum level. Value can be an empty string, clock type string, |
|
292 | * IP address, or a hex string. |
|
293 | * |
|
294 | * @return the reference id string. |
|
295 | */ |
|
296 | public String getReferenceIdString() |
|
297 | { |
|
298 | 0 | int version = getVersion(); |
299 | 0 | int stratum = getStratum(); |
300 | 0 | if (version == VERSION_3 || version == VERSION_4) { |
301 | 0 | if (stratum == 0 || stratum == 1) { |
302 | 0 | return idAsString(); // 4-character ASCII string (e.g. GPS, USNO) |
303 | } |
|
304 | // in NTPv4 servers this is latest transmit timestamp of ref source |
|
305 | 0 | if (version == VERSION_4) |
306 | 0 | return idAsHex(); |
307 | } |
|
308 | ||
309 | // Stratum 2 and higher this is a four-octet IPv4 address |
|
310 | // of the primary reference host. |
|
311 | 0 | if (stratum >= 2) { |
312 | 0 | return idAsIPAddress(); |
313 | } |
|
314 | 0 | return idAsHex(); |
315 | } |
|
316 | ||
317 | /*** |
|
318 | * Returns Reference id as dotted IP address. |
|
319 | * @return refId as IP address string. |
|
320 | */ |
|
321 | private String idAsIPAddress() |
|
322 | { |
|
323 | 0 | return ui(buf[REFERENCE_ID_INDEX]) + "." + |
324 | ui(buf[REFERENCE_ID_INDEX + 1]) + "." + |
|
325 | ui(buf[REFERENCE_ID_INDEX + 2]) + "." + |
|
326 | ui(buf[REFERENCE_ID_INDEX + 3]); |
|
327 | } |
|
328 | ||
329 | private String idAsString() |
|
330 | { |
|
331 | 0 | String id = ""; |
332 | 0 | for (int i = 0; i <= 3; i++) { |
333 | 0 | char c = (class="keyword">char) buf[REFERENCE_ID_INDEX + i]; |
334 | 0 | if (c == 0) break; // 0-terminated string |
335 | 0 | id = id + c; |
336 | } |
|
337 | 0 | return id; |
338 | } |
|
339 | ||
340 | private String idAsHex() |
|
341 | { |
|
342 | 0 | return Integer.toHexString(getReferenceId()); |
343 | } |
|
344 | ||
345 | /*** |
|
346 | * Returns the transmit timestamp as defined in RFC-1305. |
|
347 | * |
|
348 | * @return the transmit timestamp as defined in RFC-1305. |
|
349 | * Never returns a null object. |
|
350 | */ |
|
351 | public TimeStamp getTransmitTimeStamp() |
|
352 | { |
|
353 | 0 | return getTimestamp(TRANSMIT_TIMESTAMP_INDEX); |
354 | } |
|
355 | ||
356 | /*** |
|
357 | * Set transmit time with NTP timestamp. |
|
358 | * If <code>ts</code> is null then zero time is used. |
|
359 | * |
|
360 | * @param ts NTP timestamp |
|
361 | */ |
|
362 | public void setTransmitTime(TimeStamp ts) |
|
363 | { |
|
364 | 0 | setTimestamp(TRANSMIT_TIMESTAMP_INDEX, ts); |
365 | 0 | } |
366 | ||
367 | /*** |
|
368 | * Set originate timestamp given NTP TimeStamp object. |
|
369 | * If <code>ts</code> is null then zero time is used. |
|
370 | * |
|
371 | * @param ts NTP timestamp |
|
372 | */ |
|
373 | public void setOriginateTimeStamp(TimeStamp ts) |
|
374 | { |
|
375 | 0 | setTimestamp(ORIGINATE_TIMESTAMP_INDEX, ts); |
376 | 0 | } |
377 | ||
378 | /*** |
|
379 | * Returns the originate time as defined in RFC-1305. |
|
380 | * |
|
381 | * @return the originate time. |
|
382 | * Never returns null. |
|
383 | */ |
|
384 | public TimeStamp getOriginateTimeStamp() |
|
385 | { |
|
386 | 0 | return getTimestamp(ORIGINATE_TIMESTAMP_INDEX); |
387 | } |
|
388 | ||
389 | /*** |
|
390 | * Returns the reference time as defined in RFC-1305. |
|
391 | * |
|
392 | * @return the reference time as <code>TimeStamp</code> object. |
|
393 | * Never returns null. |
|
394 | */ |
|
395 | public TimeStamp getReferenceTimeStamp() |
|
396 | { |
|
397 | 0 | return getTimestamp(REFERENCE_TIMESTAMP_INDEX); |
398 | } |
|
399 | ||
400 | /*** |
|
401 | * Set Reference time with NTP timestamp. If <code>ts</code> is null |
|
402 | * then zero time is used. |
|
403 | * |
|
404 | * @param ts NTP timestamp |
|
405 | */ |
|
406 | public void setReferenceTime(TimeStamp ts) |
|
407 | { |
|
408 | 0 | setTimestamp(REFERENCE_TIMESTAMP_INDEX, ts); |
409 | 0 | } |
410 | ||
411 | /*** |
|
412 | * Returns receive timestamp as defined in RFC-1305. |
|
413 | * |
|
414 | * @return the receive time. |
|
415 | * Never returns null. |
|
416 | */ |
|
417 | public TimeStamp getReceiveTimeStamp() |
|
418 | { |
|
419 | 0 | return getTimestamp(RECEIVE_TIMESTAMP_INDEX); |
420 | } |
|
421 | ||
422 | /*** |
|
423 | * Set receive timestamp given NTP TimeStamp object. |
|
424 | * If <code>ts</code> is null then zero time is used. |
|
425 | * |
|
426 | * @param ts timestamp |
|
427 | */ |
|
428 | public void setReceiveTimeStamp(TimeStamp ts) |
|
429 | { |
|
430 | 0 | setTimestamp(RECEIVE_TIMESTAMP_INDEX, ts); |
431 | 0 | } |
432 | ||
433 | /*** |
|
434 | * Return type of time packet. The values (e.g. NTP, TIME, ICMP, ...) |
|
435 | * correspond to the protocol used to obtain the timing information. |
|
436 | * |
|
437 | * @return packet type string identifier which in this case is "NTP". |
|
438 | */ |
|
439 | public String getType() |
|
440 | { |
|
441 | 0 | return "NTP"; |
442 | } |
|
443 | ||
444 | /*** |
|
445 | * @return 4 bytes as 32-bit int |
|
446 | */ |
|
447 | private int getInt(class="keyword">int index) |
|
448 | { |
|
449 | 0 | int i = ui(buf[index]) << 24 | |
450 | ui(buf[index + 1]) << 16 | |
|
451 | ui(buf[index + 2]) << 8 | |
|
452 | ui(buf[index + 3]); |
|
453 | ||
454 | 0 | return i; |
455 | } |
|
456 | ||
457 | /*** |
|
458 | * Get NTP Timestamp at specified starting index. |
|
459 | * |
|
460 | * @param index index into data array |
|
461 | * @return TimeStamp object for 64 bits starting at index |
|
462 | */ |
|
463 | private TimeStamp getTimestamp(int index) |
|
464 | { |
|
465 | 0 | return new TimeStamp(getLong(index)); |
466 | } |
|
467 | ||
468 | /*** |
|
469 | * Get Long value represented by bits starting at specified index. |
|
470 | * |
|
471 | * @return 8 bytes as 64-bit long |
|
472 | */ |
|
473 | private long getLong(int index) |
|
474 | { |
|
475 | 0 | long i = ul(buf[index]) << 56 | |
476 | ul(buf[index + 1]) << 48 | |
|
477 | ul(buf[index + 2]) << 40 | |
|
478 | ul(buf[index + 3]) << 32 | |
|
479 | ul(buf[index + 4]) << 24 | |
|
480 | ul(buf[index + 5]) << 16 | |
|
481 | ul(buf[index + 6]) << 8 | |
|
482 | ul(buf[index + 7]); |
|
483 | 0 | return i; |
484 | } |
|
485 | ||
486 | /*** |
|
487 | * Sets the NTP timestamp at the given array index. |
|
488 | * |
|
489 | * @param index index into the byte array. |
|
490 | * @param t TimeStamp. |
|
491 | */ |
|
492 | private void setTimestamp(int index, TimeStamp t) |
|
493 | { |
|
494 | 0 | long ntpTime = (t == null) ? 0 : t.ntpValue(); |
495 | // copy 64-bits from Long value into 8 x 8-bit bytes of array |
|
496 | // one byte at a time shifting 8-bits for each position. |
|
497 | 0 | for (int i = 7; i >= 0; i--) { |
498 | 0 | buf[index + i] = (byte) (ntpTime & 0xFF); |
499 | 0 | ntpTime >>>= 8; // shift to next byte |
500 | } |
|
501 | // buf[index] |= 0x80; // only set if 1900 baseline.... |
|
502 | 0 | } |
503 | ||
504 | /*** |
|
505 | * Returns the datagram packet with the NTP details already filled in. |
|
506 | * |
|
507 | * @return a datagram packet. |
|
508 | */ |
|
509 | public DatagramPacket getDatagramPacket() |
|
510 | { |
|
511 | 0 | if (dp == null) |
512 | 0 | synchronized(this) { |
513 | 0 | if (dp == null) { |
514 | 0 | dp = new DatagramPacket(buf, buf.length); |
515 | 0 | dp.setPort(NTP_PORT); |
516 | } |
|
517 | 0 | } |
518 | 0 | return dp; |
519 | } |
|
520 | ||
521 | /*** |
|
522 | * Set the contents of this object from source datagram packet. |
|
523 | * |
|
524 | * @param srcDp source DatagramPacket to copy contents from. |
|
525 | */ |
|
526 | public void setDatagramPacket(DatagramPacket srcDp) |
|
527 | { |
|
528 | 0 | byte[] incomingBuf = srcDp.getData(); |
529 | 0 | int len = srcDp.getLength(); |
530 | 0 | if (len > buf.length) |
531 | 0 | len = buf.length; |
532 | ||
533 | 0 | System.arraycopy(incomingBuf, 0, buf, 0, len); |
534 | 0 | } |
535 | ||
536 | /*** |
|
537 | * Convert byte to unsigned integer. |
|
538 | * Java only has signed types so we have to do |
|
539 | * more work to get unsigned ops. |
|
540 | * |
|
541 | * @param b |
|
542 | * @return unsigned int value of byte |
|
543 | */ |
|
544 | protected final static int ui(byte b) |
|
545 | { |
|
546 | 0 | int i = b & 0xFF; |
547 | 0 | return i; |
548 | } |
|
549 | ||
550 | /*** |
|
551 | * Convert byte to unsigned long. |
|
552 | * Java only has signed types so we have to do |
|
553 | * more work to get unsigned ops |
|
554 | * |
|
555 | * @param b |
|
556 | * @return unsigned long value of byte |
|
557 | */ |
|
558 | protected final static long ul(byte b) |
|
559 | { |
|
560 | 0 | long i = b & 0xFF; |
561 | 0 | return i; |
562 | } |
|
563 | ||
564 | /*** |
|
565 | * Returns details of NTP packet as a string. |
|
566 | * |
|
567 | * @return details of NTP packet as a string. |
|
568 | */ |
|
569 | public String toString() |
|
570 | { |
|
571 | 0 | return "[" + |
572 | "version:" + getVersion() + |
|
573 | ", mode:" + getMode() + |
|
574 | ", poll:" + getPoll() + |
|
575 | ", precision:" + getPrecision() + |
|
576 | ", delay:" + getRootDelay() + |
|
577 | ", dispersion(ms):" + getRootDispersionInMillisDouble() + |
|
578 | ", id:" + getReferenceIdString() + |
|
579 | ", xmitTime:" + getTransmitTimeStamp().toDateString() + |
|
580 | " ]"; |
|
581 | } |
|
582 | ||
583 | } |
This report is generated by jcoverage, Maven and Maven JCoverage Plugin. |