001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.apache.commons.net.ntp;
019
020/**
021 * Common NtpUtils Helper class.
022 *
023 */
024public final class NtpUtils {
025
026    /**
027     * Returns 32-bit integer address to IPv4 address string "%d.%d.%d.%d" format.
028     *
029     * @param address the 32-bit address
030     * @return the raw IP address in a string format.
031     */
032    public static String getHostAddress(final int address) {
033        return ((address >>> 24) & 0xFF) + "." + ((address >>> 16) & 0xFF) + "." + ((address >>> 8) & 0xFF) + "." + ((address >>> 0) & 0xFF);
034    }
035
036    /**
037     * Return human-readable name of message mode type (RFC 1305).
038     *
039     * @param mode the mode type
040     * @return mode name
041     */
042    public static String getModeName(final int mode) {
043        switch (mode) {
044        case NtpV3Packet.MODE_RESERVED:
045            return "Reserved";
046        case NtpV3Packet.MODE_SYMMETRIC_ACTIVE:
047            return "Symmetric Active";
048        case NtpV3Packet.MODE_SYMMETRIC_PASSIVE:
049            return "Symmetric Passive";
050        case NtpV3Packet.MODE_CLIENT:
051            return "Client";
052        case NtpV3Packet.MODE_SERVER:
053            return "Server";
054        case NtpV3Packet.MODE_BROADCAST:
055            return "Broadcast";
056        case NtpV3Packet.MODE_CONTROL_MESSAGE:
057            return "Control";
058        case NtpV3Packet.MODE_PRIVATE:
059            return "Private";
060        default:
061            return "Unknown";
062        }
063    }
064
065    /**
066     * Returns NTP packet reference identifier as IP address.
067     *
068     * @param packet NTP packet
069     * @return the packet reference id (as IP address) in "%d.%d.%d.%d" format.
070     */
071    public static String getRefAddress(final NtpV3Packet packet) {
072        final int address = (packet == null) ? 0 : packet.getReferenceId();
073        return getHostAddress(address);
074    }
075
076    /**
077     * 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
078     * the <A HREF="http://www.eecis.udel.edu/~mills/ntp/html/refclock.html#list">Comprehensive List of Clock Drivers</A>.
079     *
080     * @param message the message to check
081     * @return reference clock string if primary NTP server
082     */
083    public static String getReferenceClock(final NtpV3Packet message) {
084        if (message == null) {
085            return "";
086        }
087        final int refId = message.getReferenceId();
088        if (refId == 0) {
089            return "";
090        }
091        final StringBuilder buf = new StringBuilder(4);
092        // start at highest-order byte (0x4c434c00 -> LCL)
093        for (int shiftBits = 24; shiftBits >= 0; shiftBits -= 8) {
094            final char c = (char) ((refId >>> shiftBits) & 0xff);
095            if (c == 0) { // 0-terminated ASCII string
096                break;
097            }
098            if (!Character.isLetterOrDigit(c)) {
099                return "";
100            }
101            buf.append(c);
102        }
103        return buf.toString();
104    }
105
106}