001: package examples.ntp;
002:
003: /*
004: * Copyright 2001-2005 The Apache Software Foundation
005: *
006: * Licensed under the Apache License, Version 2.0 (the "License");
007: * you may not use this file except in compliance with the License.
008: * You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing, software
013: * distributed under the License is distributed on an "AS IS" BASIS,
014: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: * See the License for the specific language governing permissions and
016: * limitations under the License.
017: */
018:
019: import java.io.IOException;
020: import java.net.InetAddress;
021: import java.net.SocketException;
022: import java.net.UnknownHostException;
023: import java.text.NumberFormat;
024:
025: import org.apache.commons.net.ntp.*;
026:
027: /***
028: * This is an example program demonstrating how to use the NTPUDPClient
029: * class. This program sends a Datagram client request packet to a
030: * Network time Protocol (NTP) service port on a specified server,
031: * retrieves the time, and prints it to standard output along with
032: * the fields from the NTP message header (e.g. stratum level, reference id,
033: * poll interval, root delay, mode, ...)
034: * See <A HREF="ftp://ftp.rfc-editor.org/in-notes/rfc868.txt"> the spec </A>
035: * for details.
036: * <p>
037: * Usage: NTPClient <hostname-or-address-list>
038: * <br>
039: * Example: NTPClient clock.psu.edu
040: *
041: * @author Jason Mathews, MITRE Corp
042: ***/
043: public final class NTPClient {
044:
045: private static final NumberFormat numberFormat = new java.text.DecimalFormat(
046: "0.00");
047:
048: /**
049: * Process <code>TimeInfo</code> object and print its details.
050: * @param info <code>TimeInfo</code> object.
051: */
052: public static void processResponse(TimeInfo info) {
053: NtpV3Packet message = info.getMessage();
054: int stratum = message.getStratum();
055: String refType;
056: if (stratum <= 0)
057: refType = "(Unspecified or Unavailable)";
058: else if (stratum == 1)
059: refType = "(Primary Reference; e.g., GPS)"; // GPS, radio clock, etc.
060: else
061: refType = "(Secondary Reference; e.g. via NTP or SNTP)";
062: // stratum should be 0..15...
063: System.out.println(" Stratum: " + stratum + " " + refType);
064: int version = message.getVersion();
065: int li = message.getLeapIndicator();
066: System.out.println(" leap=" + li + ", version=" + version
067: + ", precision=" + message.getPrecision());
068:
069: System.out.println(" mode: " + message.getModeName() + " ("
070: + message.getMode() + ")");
071: int poll = message.getPoll();
072: // poll value typically btwn MINPOLL (4) and MAXPOLL (14)
073: System.out.println(" poll: "
074: + (poll <= 0 ? 1 : (int) Math.pow(2, poll))
075: + " seconds" + " (2 ** " + poll + ")");
076: double disp = message.getRootDispersionInMillisDouble();
077: System.out.println(" rootdelay="
078: + numberFormat.format(message
079: .getRootDelayInMillisDouble())
080: + ", rootdispersion(ms): " + numberFormat.format(disp));
081:
082: int refId = message.getReferenceId();
083: String refAddr = NtpUtils.getHostAddress(refId);
084: String refName = null;
085: if (refId != 0) {
086: if (refAddr.equals("127.127.1.0")) {
087: refName = "LOCAL"; // This is the ref address for the Local Clock
088: } else if (stratum >= 2) {
089: // If reference id has 127.127 prefix then it uses its own reference clock
090: // defined in the form 127.127.clock-type.unit-num (e.g. 127.127.8.0 mode 5
091: // for GENERIC DCF77 AM; see refclock.htm from the NTP software distribution.
092: if (!refAddr.startsWith("127.127")) {
093: try {
094: InetAddress addr = InetAddress
095: .getByName(refAddr);
096: String name = addr.getHostName();
097: if (name != null && !name.equals(refAddr))
098: refName = name;
099: } catch (UnknownHostException e) {
100: // some stratum-2 servers sync to ref clock device but fudge stratum level higher... (e.g. 2)
101: // ref not valid host maybe it's a reference clock name?
102: // otherwise just show the ref IP address.
103: refName = NtpUtils.getReferenceClock(message);
104: }
105: }
106: } else if (version >= 3 && (stratum == 0 || stratum == 1)) {
107: refName = NtpUtils.getReferenceClock(message);
108: // refname usually have at least 3 characters (e.g. GPS, WWV, LCL, etc.)
109: }
110: // otherwise give up on naming the beast...
111: }
112: if (refName != null && refName.length() > 1)
113: refAddr += " (" + refName + ")";
114: System.out.println(" Reference Identifier:\t" + refAddr);
115:
116: TimeStamp refNtpTime = message.getReferenceTimeStamp();
117: System.out.println(" Reference Timestamp:\t" + refNtpTime
118: + " " + refNtpTime.toDateString());
119:
120: // Originate Time is time request sent by client (t1)
121: TimeStamp origNtpTime = message.getOriginateTimeStamp();
122: System.out.println(" Originate Timestamp:\t" + origNtpTime
123: + " " + origNtpTime.toDateString());
124:
125: long destTime = info.getReturnTime();
126: // Receive Time is time request received by server (t2)
127: TimeStamp rcvNtpTime = message.getReceiveTimeStamp();
128: System.out.println(" Receive Timestamp:\t" + rcvNtpTime + " "
129: + rcvNtpTime.toDateString());
130:
131: // Transmit time is time reply sent by server (t3)
132: TimeStamp xmitNtpTime = message.getTransmitTimeStamp();
133: System.out.println(" Transmit Timestamp:\t" + xmitNtpTime
134: + " " + xmitNtpTime.toDateString());
135:
136: // Destination time is time reply received by client (t4)
137: TimeStamp destNtpTime = TimeStamp.getNtpTime(destTime);
138: System.out.println(" Destination Timestamp:\t" + destNtpTime
139: + " " + destNtpTime.toDateString());
140:
141: info.computeDetails(); // compute offset/delay if not already done
142: Long offsetValue = info.getOffset();
143: Long delayValue = info.getDelay();
144: String delay = (delayValue == null) ? "N/A" : delayValue
145: .toString();
146: String offset = (offsetValue == null) ? "N/A" : offsetValue
147: .toString();
148:
149: System.out.println(" Roundtrip delay(ms)=" + delay
150: + ", clock offset(ms)=" + offset); // offset in ms
151: }
152:
153: public static final void main(String[] args) {
154: if (args == null || args.length == 0) {
155: System.err
156: .println("Usage: NTPClient <hostname-or-address-list>");
157: System.exit(1);
158: }
159:
160: NTPUDPClient client = new NTPUDPClient();
161: // We want to timeout if a response takes longer than 10 seconds
162: client.setDefaultTimeout(10000);
163: try {
164: client.open(NtpV3Packet.NTP_PORT);
165: for (int i = 0; i < args.length; i++) {
166: System.out.println();
167: try {
168: InetAddress hostAddr = InetAddress
169: .getByName(args[i]);
170: System.out.println("> " + hostAddr.getHostName()
171: + "/" + hostAddr.getHostAddress());
172: TimeInfo info = client.getTime(hostAddr);
173: processResponse(info);
174: } catch (IOException ioe) {
175: ioe.printStackTrace();
176: }
177: }
178: } catch (SocketException e) {
179: e.printStackTrace();
180: }
181:
182: client.close();
183: }
184:
185: }
|