
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