예제 #1
0
 /**
  * * Get refId as reference clock string (e.g. GPS, WWV, LCL). If string is invalid (non-ASCII
  * character) then returns empty string "". For details refer to the <A
  * HREF="http://www.eecis.udel.edu/~mills/ntp/html/refclock.html#list">Comprehensive List of Clock
  * Drivers</A>.
  *
  * @param message
  * @return reference clock string if primary NTP server
  */
 public static String getReferenceClock(NtpV3Packet message) {
   if (message == null) return "";
   int refId = message.getReferenceId();
   if (refId == 0) return "";
   StringBuffer buf = new StringBuffer(4);
   // start at highest-order byte (0x4c434c00 -> LCL)
   for (int shiftBits = 24; shiftBits >= 0; shiftBits -= 8) {
     char c = (char) ((refId >>> shiftBits) & 0xff);
     if (c == 0) break; // 0-terminated ASCII string
     if (!Character.isLetterOrDigit(c)) return "";
     buf.append(c);
   }
   return buf.toString();
 }
예제 #2
0
  /**
   * * Retrieves the time information from the specified server and port and returns it. The time is
   * the number of miliiseconds since 00:00 (midnight) 1 January 1900 UTC, as specified by RFC 1305.
   * This method reads the raw NTP packet and constructs a <i>TimeInfo</i> object that allows access
   * to all the fields of the NTP message header.
   *
   * <p>
   *
   * @param host The address of the server.
   * @param port The port of the service.
   * @return The time value retrieved from the server.
   * @exception IOException If an error occurs while retrieving the time. *
   */
  public TimeInfo getTime(InetAddress host, int port) throws IOException {
    // if not connected then open to next available UDP port
    if (!isOpen()) {
      open();
    }

    NtpV3Packet message = new NtpV3Impl();
    message.setMode(NtpV3Packet.MODE_CLIENT);
    message.setVersion(_version);
    DatagramPacket sendPacket = message.getDatagramPacket();
    sendPacket.setAddress(host);
    sendPacket.setPort(port);

    NtpV3Packet recMessage = new NtpV3Impl();
    DatagramPacket receivePacket = recMessage.getDatagramPacket();

    /*
     * Must minimize the time between getting the current time,
     * timestamping the packet, and sending it out which
     * introduces an error in the delay time.
     * No extraneous logging and initializations here !!!
     */
    TimeStamp now = TimeStamp.getCurrentTime();

    // Note that if you do not set the transmit time field then originating time
    // in server response is all 0's which is "Thu Feb 07 01:28:16 EST 2036".
    message.setTransmitTime(now);

    _socket_.send(sendPacket);
    _socket_.receive(receivePacket);

    long returnTime = System.currentTimeMillis();
    // create TimeInfo message container but don't pre-compute the details yet
    TimeInfo info = new TimeInfo(recMessage, returnTime, false);

    return info;
  }
예제 #3
0
  /**
   * Process <code>TimeInfo</code> object and print its details.
   *
   * @param info <code>TimeInfo</code> object.
   */
  public static void processResponse(TimeInfo info) {
    NtpV3Packet message = info.getMessage();
    int stratum = message.getStratum();
    String refType;
    if (stratum <= 0) {
      refType = "(Unspecified or Unavailable)";
    } else if (stratum == 1) {
      refType = "(Primary Reference; e.g., GPS)"; // GPS, radio clock, etc.
    } else {
      refType = "(Secondary Reference; e.g. via NTP or SNTP)";
    }
    // stratum should be 0..15...
    System.out.println(" Stratum: " + stratum + " " + refType);
    int version = message.getVersion();
    int li = message.getLeapIndicator();
    System.out.println(
        " leap=" + li + ", version=" + version + ", precision=" + message.getPrecision());

    System.out.println(" mode: " + message.getModeName() + " (" + message.getMode() + ")");
    int poll = message.getPoll();
    // poll value typically btwn MINPOLL (4) and MAXPOLL (14)
    System.out.println(
        " poll: "
            + (poll <= 0 ? 1 : (int) Math.pow(2, poll))
            + " seconds"
            + " (2 ** "
            + poll
            + ")");
    double disp = message.getRootDispersionInMillisDouble();
    System.out.println(
        " rootdelay="
            + numberFormat.format(message.getRootDelayInMillisDouble())
            + ", rootdispersion(ms): "
            + numberFormat.format(disp));

    int refId = message.getReferenceId();
    String refAddr = NtpUtils.getHostAddress(refId);
    String refName = null;
    if (refId != 0) {
      if (refAddr.equals("127.127.1.0")) {
        refName = "LOCAL"; // This is the ref address for the Local Clock
      } else if (stratum >= 2) {
        // If reference id has 127.127 prefix then it uses its own reference clock
        // defined in the form 127.127.clock-type.unit-num (e.g. 127.127.8.0 mode 5
        // for GENERIC DCF77 AM; see refclock.htm from the NTP software distribution.
        if (!refAddr.startsWith("127.127")) {
          try {
            InetAddress addr = InetAddress.getByName(refAddr);
            String name = addr.getHostName();
            if (name != null && !name.equals(refAddr)) {
              refName = name;
            }
          } catch (UnknownHostException e) {
            // some stratum-2 servers sync to ref clock device but fudge stratum level higher...
            // (e.g. 2)
            // ref not valid host maybe it's a reference clock name?
            // otherwise just show the ref IP address.
            refName = NtpUtils.getReferenceClock(message);
          }
        }
      } else if (version >= 3 && (stratum == 0 || stratum == 1)) {
        refName = NtpUtils.getReferenceClock(message);
        // refname usually have at least 3 characters (e.g. GPS, WWV, LCL, etc.)
      }
      // otherwise give up on naming the beast...
    }
    if (refName != null && refName.length() > 1) {
      refAddr += " (" + refName + ")";
    }
    System.out.println(" Reference Identifier:\t" + refAddr);

    TimeStamp refNtpTime = message.getReferenceTimeStamp();
    System.out.println(" Reference Timestamp:\t" + refNtpTime + "  " + refNtpTime.toDateString());

    // Originate Time is time request sent by client (t1)
    TimeStamp origNtpTime = message.getOriginateTimeStamp();
    System.out.println(" Originate Timestamp:\t" + origNtpTime + "  " + origNtpTime.toDateString());

    long destTime = info.getReturnTime();
    // Receive Time is time request received by server (t2)
    TimeStamp rcvNtpTime = message.getReceiveTimeStamp();
    System.out.println(" Receive Timestamp:\t" + rcvNtpTime + "  " + rcvNtpTime.toDateString());

    // Transmit time is time reply sent by server (t3)
    TimeStamp xmitNtpTime = message.getTransmitTimeStamp();
    System.out.println(" Transmit Timestamp:\t" + xmitNtpTime + "  " + xmitNtpTime.toDateString());

    // Destination time is time reply received by client (t4)
    TimeStamp destNtpTime = TimeStamp.getNtpTime(destTime);
    System.out.println(
        " Destination Timestamp:\t" + destNtpTime + "  " + destNtpTime.toDateString());

    info.computeDetails(); // compute offset/delay if not already done
    Long offsetValue = info.getOffset();
    Long delayValue = info.getDelay();
    String delay = (delayValue == null) ? "N/A" : delayValue.toString();
    String offset = (offsetValue == null) ? "N/A" : offsetValue.toString();

    System.out.println(
        " Roundtrip delay(ms)=" + delay + ", clock offset(ms)=" + offset); // offset in ms
  }
예제 #4
0
 /**
  * * Returns NTP packet reference identifier as IP address.
  *
  * @param packet NTP packet
  * @return the packet reference id (as IP address) in "%d.%d.%d.%d" format.
  */
 public static String getRefAddress(NtpV3Packet packet) {
   int address = (packet == null) ? 0 : packet.getReferenceId();
   return getHostAddress(address);
 }