All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.addthis.basis.net.NetUtil Maven / Gradle / Ivy

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.addthis.basis.net;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;

import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;

/**
 * A collection of static methods implementing common helper functions
 * used in most classes.
 */
public final class NetUtil {
    private static final String localDomain = System.getProperty("net.domain", ".localhost");
    private static final String localHost = System.getProperty("net.host");

    /**
     * Array of bytes for generating hex strings.
     */
    public static final byte hex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * Helper class that holds a "host:port" pair.  Used to implement trust lists
     * and support easier command-line parsing of host:port pairs.
     */
    public static class Host {
        public Host(InetSocketAddress addr) {
            this.name = addr.getHostName();
            this.port = addr.getPort();
        }

        public Host(String name, int port) {
            this.name = name;
            this.port = port;
        }

        public String name;
        public int port;

        public String toString() {
            return name + ":" + port;
        }

        public InetSocketAddress getAddress() {
            return new InetSocketAddress(name, port);
        }

        /**
         * Return true of
         *
         * @param hostname
         * @return
         */
        public boolean matchName(String hostname) {
            if (hostname.equals(name)) {
                return true;
            }
            try {
                if (hostname.startsWith(".")) {
                    return name.endsWith(hostname) || InetAddress.getByName(name).getHostName().endsWith(hostname);
                }
                if (name.startsWith(".")) {
                    return hostname.endsWith(name) || InetAddress.getByName(hostname).getHostName().endsWith(name);
                }
                return
                        InetAddress.getByName(hostname).getHostAddress().equals(name) ||
                                InetAddress.getByName(name).getHostAddress().equals(hostname);
            } catch (UnknownHostException ex) {
                // ignore and return false
            }
            return false;
        }
    }

    /**
     * Parses a string in the form "host:port" into a NetUtil.Host object.
     */
    public static Host parseHost(String str) {
        return parseHost(str, 0);
    }

    /**
     * Parses a string in the form "host[:port]" into a NetUtil.Host object using defaultPort
     * as the port if none is provided
     */
    public static Host parseHost(String str, int defaultPort) {
        StringTokenizer st = new StringTokenizer(str, ":");
        String host = st.nextToken();
        int port = st.hasMoreTokens() ? Integer.parseInt(st.nextToken()) : defaultPort;
        return new Host(host, port);
    }

    /**
     * Parses a string in the form "host:port,host:port,host:port..." into
     * a List of NetUtil.Host objects.
     */
    public static List parseHostList(String str) {
        LinkedList ll = new LinkedList<>();
        StringTokenizer st = new StringTokenizer(str, ",");
        while (st.hasMoreTokens()) {
            String nt = st.nextToken();
            ll.add(parseHost(nt));
        }
        return ll;
    }

    /**
     * Matches a host name against a List of Hosts
     *
     * @param hostname in the form 'foo.clearspring.com', '.clearspring.com' or '1.2.3.4'
     * @param list     List of Host objects
     * @return true if hostname matches an entry in the list, false otherwise
     */
    public static boolean hostNameMatch(String hostname, List list) {
        if (list == null || hostname == null) {
            return false;
        }
        for (Host aList : list) {
            if (aList.matchName(hostname)) {
                return true;
            }
        }
        return false;
    }

    /**
     * @see hostNameMatch(String, List)
     */
    public static boolean hostNameMatch(InetAddress host, List list) {
        if (list == null || host == null) {
            return false;
        }
        return hostNameMatch(host.getHostName(), list);
    }

    /**
     * @return an InetAddress in the form 'aabbccdd'
     * @throws UnknownHostException
     */
    public static byte[] getInetAddressAsHex(InetAddress addr) {
        byte raddr[] = addr.getAddress();
        byte naddr[] = new byte[raddr.length * 2];
        for (int i = 0; i < raddr.length; i++) {
            naddr[i * 2] = hex[(raddr[i] >> 4) & 0xf];
            naddr[i * 2 + 1] = hex[raddr[i] & 0xf];
        }
        return naddr;
    }

    /**
     * @return an InetAddress given a address in the form 'aabbccdd'
     * @throws UnknownHostException
     */
    public static InetAddress getInetAddressFromHex(String hex) throws UnknownHostException {
        byte addr[] = new byte[hex.length() / 2];
        for (int i = 0; i < addr.length; i++) {
            addr[i] = (byte) (Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16) & 0xff);
        }
        return InetAddress.getByAddress(addr);
    }

    public static String inferDomain() {
        try {
            String myHostName = localHost != null ? localHost : InetAddress.getLocalHost().getHostName();
            int lio = myHostName.indexOf('.');
            if (lio > 0) {
                return myHostName.substring(lio);
            }
        } catch (Exception ex) {
        }
        return localDomain;
    }

    /**
     * Given a host name, returns it's "base" domain via some American
     * centric heuristics
     */
    public static String getBaseDomain(String host) {
        return getBaseDomain(host, true);
    }

    public static String getBaseDomain(String host, boolean tight) {
        int he = host.length();
        if (he < 5) {
            return host;
        }
        host = host.toLowerCase();
        char lastChar = host.charAt(he - 1);
        // strip trailing '.'
        if (lastChar == '.') {
            he--;
        }
        // look for more than one '.'
        int of = host.indexOf('.');
        int d1 = host.lastIndexOf('.', he - 1);
        int d2 = d1 > 0 ? host.lastIndexOf('.', d1 - 1) : -1;
        int d3 = d2 > 0 ? host.lastIndexOf('.', d2 - 1) : -1;
        boolean lastNum = host.charAt(he - 1) - '0' < 10;
        boolean common = (he - d1 == 4); // 3 digit tld (COM, NET, EDU, etc)
        // if host does not end with number (12.34.56.78) and it has more than one '.' but one of those
        // '.' is not trailing and host begins with 'www' or ends with 'com', 'net', 'org', drop first token
        int hs = 0;
        if (!lastNum && ((host.startsWith("www.") || (tight && ((d2 > 0 && d1 > d2 && common) || (d3 > 0 && d2 > d3)))))) {
            hs += of + 1;
        }
        //System.out.println(host+" d1="+d1+" d2="+d2+" d3="+d3+" hs="+hs+" he="+he+" ln="+lastNum+" cm="+common);
        host = host.substring(hs, he);
        return host;
    }

    public static String resolveDottedIP(String ip) {
        if (ip.length() == 0 || !(Character.isDigit(ip.charAt(ip.length() - 1)) && Character.isDigit(ip.charAt(0)))) {
            return ip;
        }
        try {
            String newhost = InetAddress.getByName(ip).getHostName();
            if (newhost != null) {
                return newhost;
            }
        } catch (Exception ex) {
        }
        return ip;
    }

    /**
     * convert an ip address string into it's equivalent 32 bit value stored in a long.
     *
     * @param ip
     * @return long value or -1 if there was an error parsing the ip address
     */
    public static long ipToLong(String ip) {
        if (ip == null) {
            return -1;
        }
        String[] parts = ip.split("\\.");
        try {
            return Long.parseLong(parts[0]) << 24 | Long.parseLong(parts[1]) << 16 |
                    Long.parseLong(parts[2]) << 8 | Long.parseLong(parts[3]);
        } catch (NumberFormatException e) {
            return -1;
        } catch (ArrayIndexOutOfBoundsException e) {
            return -1;
        }
    }

    /**
     * convert a long representation of an ip address into a string
     *
     * @param i
     * @return
     */
    public static String longToIp(long i) {
        return ((i >> 24) & 0xFF) + "." +
                ((i >> 16) & 0xFF) + "." +
                ((i >> 8) & 0xFF) + "." +
                (i & 0xFF);
    }

}





© 2015 - 2025 Weber Informatics LLC | Privacy Policy