summaryrefslogtreecommitdiff
path: root/org/apache/commons/net/ntp/NtpV3Impl.java
diff options
context:
space:
mode:
authorJoe Robinson <joe@lc8n.com>2010-10-27 14:21:09 +0100
committerJoe Robinson <joe@lc8n.com>2010-10-27 14:21:09 +0100
commit063284837c8c366e5502b1b0264b8eb807b61732 (patch)
treefff3a1e1e5afaa671485b9d990704658276627ac /org/apache/commons/net/ntp/NtpV3Impl.java
Basic upload functionality to predifined location, with basic file browser
Diffstat (limited to 'org/apache/commons/net/ntp/NtpV3Impl.java')
-rw-r--r--org/apache/commons/net/ntp/NtpV3Impl.java583
1 files changed, 583 insertions, 0 deletions
diff --git a/org/apache/commons/net/ntp/NtpV3Impl.java b/org/apache/commons/net/ntp/NtpV3Impl.java
new file mode 100644
index 0000000..4a8569a
--- /dev/null
+++ b/org/apache/commons/net/ntp/NtpV3Impl.java
@@ -0,0 +1,583 @@
+package org.apache.commons.net.ntp;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.net.DatagramPacket;
+
+/***
+ * Implementation of NtpV3Packet with methods converting Java objects to/from
+ * the Network Time Protocol (NTP) data message header format described in RFC-1305.
+ *
+ * @author Naz Irizarry, MITRE Corp
+ * @author Jason Mathews, MITRE Corp
+ *
+ * @version $Revision: 658518 $ $Date: 2008-05-21 02:04:30 +0100 (Wed, 21 May 2008) $
+ */
+public class NtpV3Impl implements NtpV3Packet
+{
+
+ private static final int MODE_INDEX = 0;
+ private static final int MODE_SHIFT = 0;
+
+ private static final int VERSION_INDEX = 0;
+ private static final int VERSION_SHIFT = 3;
+
+ private static final int LI_INDEX = 0;
+ private static final int LI_SHIFT = 6;
+
+ private static final int STRATUM_INDEX = 1;
+ private static final int POLL_INDEX = 2;
+ private static final int PRECISION_INDEX = 3;
+
+ private static final int ROOT_DELAY_INDEX = 4;
+ private static final int ROOT_DISPERSION_INDEX = 8;
+ private static final int REFERENCE_ID_INDEX = 12;
+
+ private static final int REFERENCE_TIMESTAMP_INDEX = 16;
+ private static final int ORIGINATE_TIMESTAMP_INDEX = 24;
+ private static final int RECEIVE_TIMESTAMP_INDEX = 32;
+ private static final int TRANSMIT_TIMESTAMP_INDEX = 40;
+
+ private static final int KEY_IDENTIFIER_INDEX = 48;
+ private static final int MESSAGE_DIGEST = 54; /* len 16 bytes */
+
+ private byte[] buf = new byte[48];
+
+ private volatile DatagramPacket dp;
+
+ /** Creates a new instance of NtpV3Impl */
+ public NtpV3Impl()
+ {
+ }
+
+ /***
+ * Returns mode as defined in RFC-1305 which is a 3-bit integer
+ * whose value is indicated by the MODE_xxx parameters.
+ *
+ * @return mode as defined in RFC-1305.
+ */
+ public int getMode()
+ {
+ return (ui(buf[MODE_INDEX]) >> MODE_SHIFT) & 0x7;
+ }
+
+ /***
+ * Return human-readable name of message mode type as described in
+ * RFC 1305.
+ * @return mode name as string.
+ */
+ public String getModeName()
+ {
+ return NtpUtils.getModeName(getMode());
+ }
+
+ /***
+ * Set mode as defined in RFC-1305.
+ * @param mode
+ */
+ public void setMode(int mode)
+ {
+ buf[MODE_INDEX] = (byte) (buf[MODE_INDEX] & 0xF8 | mode & 0x7);
+ }
+
+ /***
+ * Returns leap indicator as defined in RFC-1305 which is a two-bit code:
+ * 0=no warning
+ * 1=last minute has 61 seconds
+ * 2=last minute has 59 seconds
+ * 3=alarm condition (clock not synchronized)
+ *
+ * @return leap indicator as defined in RFC-1305.
+ */
+ public int getLeapIndicator()
+ {
+ return (ui(buf[LI_INDEX]) >> LI_SHIFT) & 0x3;
+ }
+
+ /***
+ * Set leap indicator as defined in RFC-1305.
+ * @param li leap indicator.
+ */
+ public void setLeapIndicator(int li)
+ {
+ buf[LI_INDEX] = (byte) (buf[LI_INDEX] & 0x3F | ((li & 0x3) << LI_SHIFT));
+ }
+
+ /***
+ * Returns poll interval as defined in RFC-1305, which is an eight-bit
+ * signed integer indicating the maximum interval between successive
+ * messages, in seconds to the nearest power of two (e.g. value of six
+ * indicates an interval of 64 seconds. The values that can appear in
+ * this field range from NTP_MINPOLL to NTP_MAXPOLL inclusive.
+ *
+ * @return poll interval as defined in RFC-1305.
+ */
+ public int getPoll()
+ {
+ return buf[POLL_INDEX];
+ }
+
+ /***
+ * Set poll interval as defined in RFC-1305.
+ *
+ * @param poll poll interval.
+ */
+ public void setPoll(int poll)
+ {
+ buf[POLL_INDEX] = (byte) (poll & 0xFF);
+ }
+
+ /***
+ * Returns precision as defined in RFC-1305 encoded as an 8-bit signed
+ * integer (seconds to nearest power of two).
+ * Values normally range from -6 to -20.
+ *
+ * @return precision as defined in RFC-1305.
+ */
+ public int getPrecision()
+ {
+ return buf[PRECISION_INDEX];
+ }
+
+ /***
+ * Set precision as defined in RFC-1305.
+ * @param precision
+ */
+ public void setPrecision(int precision)
+ {
+ buf[PRECISION_INDEX] = (byte) (precision & 0xFF);
+ }
+
+ /***
+ * Returns NTP version number as defined in RFC-1305.
+ *
+ * @return NTP version number.
+ */
+ public int getVersion()
+ {
+ return (ui(buf[VERSION_INDEX]) >> VERSION_SHIFT) & 0x7;
+ }
+
+ /***
+ * Set NTP version as defined in RFC-1305.
+ *
+ * @param version NTP version.
+ */
+ public void setVersion(int version)
+ {
+ buf[VERSION_INDEX] = (byte) (buf[VERSION_INDEX] & 0xC7 | ((version & 0x7) << VERSION_SHIFT));
+ }
+
+ /***
+ * Returns Stratum as defined in RFC-1305, which indicates the stratum level
+ * of the local clock, with values defined as follows: 0=unspecified,
+ * 1=primary ref clock, and all others a secondary reference (via NTP).
+ *
+ * @return Stratum level as defined in RFC-1305.
+ */
+ public int getStratum()
+ {
+ return ui(buf[STRATUM_INDEX]);
+ }
+
+ /***
+ * Set stratum level as defined in RFC-1305.
+ *
+ * @param stratum stratum level.
+ */
+ public void setStratum(int stratum)
+ {
+ buf[STRATUM_INDEX] = (byte) (stratum & 0xFF);
+ }
+
+ /***
+ * Return root delay as defined in RFC-1305, which is the total roundtrip delay
+ * to the primary reference source, in seconds. Values can take positive and
+ * negative values, depending on clock precision and skew.
+ *
+ * @return root delay as defined in RFC-1305.
+ */
+ public int getRootDelay()
+ {
+ return getInt(ROOT_DELAY_INDEX);
+ }
+
+ /***
+ * Return root delay as defined in RFC-1305 in milliseconds, which is
+ * the total roundtrip delay to the primary reference source, in
+ * seconds. Values can take positive and negative values, depending
+ * on clock precision and skew.
+ *
+ * @return root delay in milliseconds
+ */
+ public double getRootDelayInMillisDouble()
+ {
+ double l = getRootDelay();
+ return l / 65.536;
+ }
+
+ /***
+ * Returns root dispersion as defined in RFC-1305.
+ * @return root dispersion.
+ */
+ public int getRootDispersion()
+ {
+ return getInt(ROOT_DISPERSION_INDEX);
+ }
+
+ /***
+ * Returns root dispersion (as defined in RFC-1305) in milliseconds.
+ *
+ * @return root dispersion in milliseconds
+ */
+ public long getRootDispersionInMillis()
+ {
+ long l = getRootDispersion();
+ return (l * 1000) / 65536L;
+ }
+
+ /***
+ * Returns root dispersion (as defined in RFC-1305) in milliseconds
+ * as double precision value.
+ *
+ * @return root dispersion in milliseconds
+ */
+ public double getRootDispersionInMillisDouble()
+ {
+ double l = getRootDispersion();
+ return l / 65.536;
+ }
+
+ /***
+ * Set reference clock identifier field with 32-bit unsigned integer value.
+ * See RFC-1305 for description.
+ *
+ * @param refId reference clock identifier.
+ */
+ public void setReferenceId(int refId)
+ {
+ for (int i = 3; i >= 0; i--) {
+ buf[REFERENCE_ID_INDEX + i] = (byte) (refId & 0xff);
+ refId >>>= 8; // shift right one-byte
+ }
+ }
+
+ /***
+ * Returns the reference id as defined in RFC-1305, which is
+ * a 32-bit integer whose value is dependent on several criteria.
+ *
+ * @return the reference id as defined in RFC-1305.
+ */
+ public int getReferenceId()
+ {
+ return getInt(REFERENCE_ID_INDEX);
+ }
+
+ /***
+ * Returns the reference id string. String cannot be null but
+ * value is dependent on the version of the NTP spec supported
+ * and stratum level. Value can be an empty string, clock type string,
+ * IP address, or a hex string.
+ *
+ * @return the reference id string.
+ */
+ public String getReferenceIdString()
+ {
+ int version = getVersion();
+ int stratum = getStratum();
+ if (version == VERSION_3 || version == VERSION_4) {
+ if (stratum == 0 || stratum == 1) {
+ return idAsString(); // 4-character ASCII string (e.g. GPS, USNO)
+ }
+ // in NTPv4 servers this is latest transmit timestamp of ref source
+ if (version == VERSION_4)
+ return idAsHex();
+ }
+
+ // Stratum 2 and higher this is a four-octet IPv4 address
+ // of the primary reference host.
+ if (stratum >= 2) {
+ return idAsIPAddress();
+ }
+ return idAsHex();
+ }
+
+ /***
+ * Returns Reference id as dotted IP address.
+ * @return refId as IP address string.
+ */
+ private String idAsIPAddress()
+ {
+ return ui(buf[REFERENCE_ID_INDEX]) + "." +
+ ui(buf[REFERENCE_ID_INDEX + 1]) + "." +
+ ui(buf[REFERENCE_ID_INDEX + 2]) + "." +
+ ui(buf[REFERENCE_ID_INDEX + 3]);
+ }
+
+ private String idAsString()
+ {
+ StringBuilder id = new StringBuilder();
+ for (int i = 0; i <= 3; i++) {
+ char c = (char) buf[REFERENCE_ID_INDEX + i];
+ if (c == 0) break; // 0-terminated string
+ id.append(c);
+ }
+ return id.toString();
+ }
+
+ private String idAsHex()
+ {
+ return Integer.toHexString(getReferenceId());
+ }
+
+ /***
+ * Returns the transmit timestamp as defined in RFC-1305.
+ *
+ * @return the transmit timestamp as defined in RFC-1305.
+ * Never returns a null object.
+ */
+ public TimeStamp getTransmitTimeStamp()
+ {
+ return getTimestamp(TRANSMIT_TIMESTAMP_INDEX);
+ }
+
+ /***
+ * Set transmit time with NTP timestamp.
+ * If <code>ts</code> is null then zero time is used.
+ *
+ * @param ts NTP timestamp
+ */
+ public void setTransmitTime(TimeStamp ts)
+ {
+ setTimestamp(TRANSMIT_TIMESTAMP_INDEX, ts);
+ }
+
+ /***
+ * Set originate timestamp given NTP TimeStamp object.
+ * If <code>ts</code> is null then zero time is used.
+ *
+ * @param ts NTP timestamp
+ */
+ public void setOriginateTimeStamp(TimeStamp ts)
+ {
+ setTimestamp(ORIGINATE_TIMESTAMP_INDEX, ts);
+ }
+
+ /***
+ * Returns the originate time as defined in RFC-1305.
+ *
+ * @return the originate time.
+ * Never returns null.
+ */
+ public TimeStamp getOriginateTimeStamp()
+ {
+ return getTimestamp(ORIGINATE_TIMESTAMP_INDEX);
+ }
+
+ /***
+ * Returns the reference time as defined in RFC-1305.
+ *
+ * @return the reference time as <code>TimeStamp</code> object.
+ * Never returns null.
+ */
+ public TimeStamp getReferenceTimeStamp()
+ {
+ return getTimestamp(REFERENCE_TIMESTAMP_INDEX);
+ }
+
+ /***
+ * Set Reference time with NTP timestamp. If <code>ts</code> is null
+ * then zero time is used.
+ *
+ * @param ts NTP timestamp
+ */
+ public void setReferenceTime(TimeStamp ts)
+ {
+ setTimestamp(REFERENCE_TIMESTAMP_INDEX, ts);
+ }
+
+ /***
+ * Returns receive timestamp as defined in RFC-1305.
+ *
+ * @return the receive time.
+ * Never returns null.
+ */
+ public TimeStamp getReceiveTimeStamp()
+ {
+ return getTimestamp(RECEIVE_TIMESTAMP_INDEX);
+ }
+
+ /***
+ * Set receive timestamp given NTP TimeStamp object.
+ * If <code>ts</code> is null then zero time is used.
+ *
+ * @param ts timestamp
+ */
+ public void setReceiveTimeStamp(TimeStamp ts)
+ {
+ setTimestamp(RECEIVE_TIMESTAMP_INDEX, ts);
+ }
+
+ /***
+ * Return type of time packet. The values (e.g. NTP, TIME, ICMP, ...)
+ * correspond to the protocol used to obtain the timing information.
+ *
+ * @return packet type string identifier which in this case is "NTP".
+ */
+ public String getType()
+ {
+ return "NTP";
+ }
+
+ /***
+ * @return 4 bytes as 32-bit int
+ */
+ private int getInt(int index)
+ {
+ int i = ui(buf[index]) << 24 |
+ ui(buf[index + 1]) << 16 |
+ ui(buf[index + 2]) << 8 |
+ ui(buf[index + 3]);
+
+ return i;
+ }
+
+ /***
+ * Get NTP Timestamp at specified starting index.
+ *
+ * @param index index into data array
+ * @return TimeStamp object for 64 bits starting at index
+ */
+ private TimeStamp getTimestamp(int index)
+ {
+ return new TimeStamp(getLong(index));
+ }
+
+ /***
+ * Get Long value represented by bits starting at specified index.
+ *
+ * @return 8 bytes as 64-bit long
+ */
+ private long getLong(int index)
+ {
+ long i = ul(buf[index]) << 56 |
+ ul(buf[index + 1]) << 48 |
+ ul(buf[index + 2]) << 40 |
+ ul(buf[index + 3]) << 32 |
+ ul(buf[index + 4]) << 24 |
+ ul(buf[index + 5]) << 16 |
+ ul(buf[index + 6]) << 8 |
+ ul(buf[index + 7]);
+ return i;
+ }
+
+ /***
+ * Sets the NTP timestamp at the given array index.
+ *
+ * @param index index into the byte array.
+ * @param t TimeStamp.
+ */
+ private void setTimestamp(int index, TimeStamp t)
+ {
+ long ntpTime = (t == null) ? 0 : t.ntpValue();
+ // copy 64-bits from Long value into 8 x 8-bit bytes of array
+ // one byte at a time shifting 8-bits for each position.
+ for (int i = 7; i >= 0; i--) {
+ buf[index + i] = (byte) (ntpTime & 0xFF);
+ ntpTime >>>= 8; // shift to next byte
+ }
+ // buf[index] |= 0x80; // only set if 1900 baseline....
+ }
+
+ /***
+ * Returns the datagram packet with the NTP details already filled in.
+ *
+ * @return a datagram packet.
+ */
+ public synchronized DatagramPacket getDatagramPacket()
+ {
+ if (dp == null) {
+ dp = new DatagramPacket(buf, buf.length);
+ dp.setPort(NTP_PORT);
+ }
+ return dp;
+ }
+
+ /***
+ * Set the contents of this object from source datagram packet.
+ *
+ * @param srcDp source DatagramPacket to copy contents from.
+ */
+ public void setDatagramPacket(DatagramPacket srcDp)
+ {
+ byte[] incomingBuf = srcDp.getData();
+ int len = srcDp.getLength();
+ if (len > buf.length)
+ len = buf.length;
+
+ System.arraycopy(incomingBuf, 0, buf, 0, len);
+ }
+
+ /***
+ * Convert byte to unsigned integer.
+ * Java only has signed types so we have to do
+ * more work to get unsigned ops.
+ *
+ * @param b
+ * @return unsigned int value of byte
+ */
+ protected final static int ui(byte b)
+ {
+ int i = b & 0xFF;
+ return i;
+ }
+
+ /***
+ * Convert byte to unsigned long.
+ * Java only has signed types so we have to do
+ * more work to get unsigned ops
+ *
+ * @param b
+ * @return unsigned long value of byte
+ */
+ protected final static long ul(byte b)
+ {
+ long i = b & 0xFF;
+ return i;
+ }
+
+ /***
+ * Returns details of NTP packet as a string.
+ *
+ * @return details of NTP packet as a string.
+ */
+ @Override
+ public String toString()
+ {
+ return "[" +
+ "version:" + getVersion() +
+ ", mode:" + getMode() +
+ ", poll:" + getPoll() +
+ ", precision:" + getPrecision() +
+ ", delay:" + getRootDelay() +
+ ", dispersion(ms):" + getRootDispersionInMillisDouble() +
+ ", id:" + getReferenceIdString() +
+ ", xmitTime:" + getTransmitTimeStamp().toDateString() +
+ " ]";
+ }
+
+}