    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}