    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}