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 */
023public final class NtpUtils {
024
025    /**
026     * Returns 32-bit integer address to IPv4 address string "%d.%d.%d.%d" format.
027     *
028     * @param address the 32-bit address
029     * @return the raw IP address in a string format.
030     */
031    public static String getHostAddress(final int address) {
032        return (address >>> 24 & 0xFF) + "." + (address >>> 16 & 0xFF) + "." + (address >>> 8 & 0xFF) + "." + (address >>> 0 & 0xFF);
033    }
034
035    /**
036     * Return human-readable name of message mode type (RFC 1305).
037     *
038     * @param mode the mode type
039     * @return mode name
040     */
041    public static String getModeName(final int mode) {
042        switch (mode) {
043        case NtpV3Packet.MODE_RESERVED:
044            return "Reserved";
045        case NtpV3Packet.MODE_SYMMETRIC_ACTIVE:
046            return "Symmetric Active";
047        case NtpV3Packet.MODE_SYMMETRIC_PASSIVE:
048            return "Symmetric Passive";
049        case NtpV3Packet.MODE_CLIENT:
050            return "Client";
051        case NtpV3Packet.MODE_SERVER:
052            return "Server";
053        case NtpV3Packet.MODE_BROADCAST:
054            return "Broadcast";
055        case NtpV3Packet.MODE_CONTROL_MESSAGE:
056            return "Control";
057        case NtpV3Packet.MODE_PRIVATE:
058            return "Private";
059        default:
060            return "Unknown";
061        }
062    }
063
064    /**
065     * Returns NTP packet reference identifier as IP address.
066     *
067     * @param packet NTP packet
068     * @return the packet reference id (as IP address) in "%d.%d.%d.%d" format.
069     */
070    public static String getRefAddress(final NtpV3Packet packet) {
071        final int address = packet == null ? 0 : packet.getReferenceId();
072        return getHostAddress(address);
073    }
074
075    /**
076     * 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
077     * the <A HREF="http://www.eecis.udel.edu/~mills/ntp/html/refclock.html#list">Comprehensive List of Clock Drivers</A>.
078     *
079     * @param message the message to check
080     * @return reference clock string if primary NTP server
081     */
082    public static String getReferenceClock(final NtpV3Packet message) {
083        if (message == null) {
084            return "";
085        }
086        final int refId = message.getReferenceId();
087        if (refId == 0) {
088            return "";
089        }
090        final StringBuilder buf = new StringBuilder(4);
091        // start at highest-order byte (0x4c434c00 -> LCL)
092        for (int shiftBits = 24; shiftBits >= 0; shiftBits -= 8) {
093            final char c = (char) (refId >>> shiftBits & 0xff);
094            if (c == 0) { // 0-terminated ASCII string
095                break;
096            }
097            if (!Character.isLetterOrDigit(c)) {
098                return "";
099            }
100            buf.append(c);
101        }
102        return buf.toString();
103    }
104
105}