KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > 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 JavaDoc;
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     private byte[] buf = new byte[48];
57
58     private DatagramPacket JavaDoc dp;
59
60     /** Creates a new instance of NtpV3Impl */
61     public NtpV3Impl()
62     {
63     }
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         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 JavaDoc getModeName()
82     {
83         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         buf[MODE_INDEX] = (byte) (buf[MODE_INDEX] & 0xF8 | mode & 0x7);
93     }
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         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         buf[LI_INDEX] = (byte) (buf[LI_INDEX] & 0x3F | ((li & 0x3) << LI_SHIFT));
116     }
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         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         buf[POLL_INDEX] = (byte) (poll & 0xFF);
140     }
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         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         buf[PRECISION_INDEX] = (byte) (precision & 0xFF);
161     }
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         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         buf[VERSION_INDEX] = (byte) (buf[VERSION_INDEX] & 0xC7 | ((version & 0x7) << VERSION_SHIFT));
181     }
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         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         buf[STRATUM_INDEX] = (byte) (stratum & 0xFF);
203     }
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         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         double l = getRootDelay();
228         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         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         long l = getRootDispersion();
248         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         double l = getRootDispersion();
260         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         for (int i = 3; i >= 0; i--) {
272             buf[REFERENCE_ID_INDEX + i] = (byte) (refId & 0xff);
273             refId >>>= 8; // shift right one-byte
274
}
275     }
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         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 JavaDoc getReferenceIdString()
297     {
298         int version = getVersion();
299         int stratum = getStratum();
300         if (version == VERSION_3 || version == VERSION_4) {
301             if (stratum == 0 || stratum == 1) {
302                 return idAsString(); // 4-character ASCII string (e.g. GPS, USNO)
303
}
304             // in NTPv4 servers this is latest transmit timestamp of ref source
305
if (version == VERSION_4)
306                 return idAsHex();
307         }
308
309         // Stratum 2 and higher this is a four-octet IPv4 address
310
// of the primary reference host.
311
if (stratum >= 2) {
312             return idAsIPAddress();
313         }
314         return idAsHex();
315     }
316
317     /***
318      * Returns Reference id as dotted IP address.
319      * @return refId as IP address string.
320      */

321     private String JavaDoc idAsIPAddress()
322     {
323         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 JavaDoc idAsString()
330     {
331         String JavaDoc id = "";
332         for (int i = 0; i <= 3; i++) {
333             char c = (char) buf[REFERENCE_ID_INDEX + i];
334             if (c == 0) break; // 0-terminated string
335
id = id + c;
336         }
337         return id;
338     }
339
340     private String JavaDoc idAsHex()
341     {
342         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         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         setTimestamp(TRANSMIT_TIMESTAMP_INDEX, ts);
365     }
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         setTimestamp(ORIGINATE_TIMESTAMP_INDEX, ts);
376     }
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         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         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         setTimestamp(REFERENCE_TIMESTAMP_INDEX, ts);
409     }
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         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         setTimestamp(RECEIVE_TIMESTAMP_INDEX, ts);
431     }
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 JavaDoc getType()
440     {
441         return "NTP";
442     }
443
444     /***
445      * @return 4 bytes as 32-bit int
446      */

447     private int getInt(int index)
448     {
449         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         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         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         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         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         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
for (int i = 7; i >= 0; i--) {
498             buf[index + i] = (byte) (ntpTime & 0xFF);
499             ntpTime >>>= 8; // shift to next byte
500
}
501         // buf[index] |= 0x80; // only set if 1900 baseline....
502
}
503
504     /***
505      * Returns the datagram packet with the NTP details already filled in.
506      *
507      * @return a datagram packet.
508      */

509     public DatagramPacket JavaDoc getDatagramPacket()
510     {
511         if (dp == null)
512             synchronized(this) {
513                 if (dp == null) {
514                     dp = new DatagramPacket JavaDoc(buf, buf.length);
515                     dp.setPort(NTP_PORT);
516                 }
517             }
518         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 JavaDoc srcDp)
527     {
528         byte[] incomingBuf = srcDp.getData();
529         int len = srcDp.getLength();
530         if (len > buf.length)
531             len = buf.length;
532
533         System.arraycopy(incomingBuf, 0, buf, 0, len);
534     }
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         int i = b & 0xFF;
547         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         long i = b & 0xFF;
561         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 JavaDoc toString()
570     {
571         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 }
584
Popular Tags