/******************************************************************************* * Copyright 2011 André Rouél * * 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 net.sf.jacclog.util.net; import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * This class provides several methods to translate different representations of Internet Protocol addresses. * * @author André Rouél */ public class IpAddressTranslator { /** * Pattern of an Internet Protocol version 4 (IPv4) address */ private static final Pattern IPV4_PATTERN = Pattern .compile("^0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.0*([1-9]?\\d|1\\d\\d|2[0-4]\\d|25[0-5])$"); /** * Translates an IPv4 address from its Four dimensions byte array representation to an <code>Inet4Address</code>. * * @param ipAddress * Four dimensions byte array representation of an IP address * @return IP address as <code>Inet4Address</code> * @throws IllegalArgumentException * If the given argument is <code>null</code> * @throws IllegalArgumentException * If the given byte array does not have four entries * @throws InvalidIpAddressException * If the IP address is not valid. */ public static Inet4Address toInet4Address(final byte[] ipAddress) { if (ipAddress == null) { throw new IllegalArgumentException("Argument 'ipAddress' can not be null."); } if (ipAddress.length != 4) { throw new IllegalArgumentException("An IP address as byte array needs 4 entries."); } try { return (Inet4Address) InetAddress.getByAddress(ipAddress); } catch (final UnknownHostException e) { throw new InvalidIpAddressException("The given IP address is not valid: " + e.getLocalizedMessage(), e); } } /** * Translates an IPv4 address from its numeric representation to an <code>Inet4Address</code>. * * @param ipAddress * Numerical representation of an IP address as <code>long</code> * @return IP address as <code>Inet4Address</code> * @throws IllegalArgumentException * If the given argument is smaller than 0 * @throws IllegalArgumentException * If the given argument is greater than 4294967295 * @throws InvalidIpAddressException * Thrown to indicate that the IP address of a host could not be determined. */ public static Inet4Address toInet4Address(final long ipAddress) { if (ipAddress < 0L) { throw new IllegalArgumentException("Argument 'ipAddress' can not be smaller than 0."); } if (ipAddress > 4294967295L) { throw new IllegalArgumentException("Argument 'ipAddress' can not be greater than 4294967295."); } final byte[] bytes = new byte[] { (byte) ((ipAddress & 0xFF000000) >> 24), (byte) ((ipAddress & 0x00FF0000) >> 16), (byte) ((ipAddress & 0x0000FF00) >> 8), (byte) ((ipAddress & 0x000000FF) >> 0) }; return toInet4Address(bytes); } /** * Translates an IPv4 address from its textual representation to <code>Inet4Address</code>. * * @param ipAddress * IP address (IPv4) as <code>String</code> * @return IP address as <code>Inet4Address</code> * @throws IllegalArgumentException * If the given argument is <code>null</code> * @throws IllegalArgumentException * If the given argument is not a valid IP address (IPv4) * @throws InvalidIpAddressException * Thrown to indicate that the IP address of a host could not be determined. */ public static Inet4Address toInet4Address(final String ipAddress) { return toInet4Address(toLong(ipAddress)); } /** * Translates an IPv4 address from its textual to numeric representation. * * @param ipAddress * IP address (IPv4) * @return Numerical representation of an IP address as <code>long</code> * @throws IllegalArgumentException * If the given argument is <code>null</code> * @throws IllegalArgumentException * If the given argument is not a valid IP address (IPv4) */ public static long toLong(final Inet4Address ipAddress) { if (ipAddress == null) { throw new IllegalArgumentException("Argument 'ipAddress' can not be null."); } return toLong(ipAddress.getHostAddress()); } /** * Multiplies an IP address, which consists of four numeric parts together into one numeric representation. * * @param partOne * First part of an IP address * @param partTwo * Second part of an IP address * @param partThree * Third part of an IP address * @param partFour * Fourth part of an IP address * @return Numerical representation of an IP address as <code>long</code> * @throws IllegalArgumentException * If any given argument is smaller than 0 * @throws IllegalArgumentException * If any given argument is greater than 255 */ public static long toLong(final long partOne, final long partTwo, final long partThree, final long partFour) { validateIpAddressPart(partOne, "partOne"); validateIpAddressPart(partTwo, "partTwo"); validateIpAddressPart(partThree, "partThree"); validateIpAddressPart(partFour, "partFour"); return 16777216L * partOne + 65536L * partTwo + 256L * partThree + partFour; } /** * Translates an IPv4 address from its textual to numeric representation. * * @param ipAddress * IP address (IPv4) as <code>String</code> * @return Numerical representation of an IP address as <code>long</code> * @throws IllegalArgumentException * If the given argument is <code>null</code> * @throws IllegalArgumentException * If the given argument is not a valid IP address (IPv4) */ public static long toLong(final String ipAddress) { if (ipAddress == null) { throw new IllegalArgumentException("Argument 'ipAddress' can not be null."); } final Matcher matcher = IPV4_PATTERN.matcher(ipAddress); if (!matcher.find()) { throw new IllegalArgumentException("Argument 'ipAddress' is not a valid IP address."); } final int w = Integer.parseInt(matcher.group(1)); final int x = Integer.parseInt(matcher.group(2)); final int y = Integer.parseInt(matcher.group(3)); final int z = Integer.parseInt(matcher.group(4)); return toLong(w, x, y, z); } /** * Validates a part if it is not smaller than <code>0</code> and greater than <code>255</code>. If the first * argument is smaller than zero an <code>IllegalArgumentException</code> will be thrown. Otherwise the value of the * first argument is valid. * * @param part * Value of an IP address part * @param name * Name of the validating argument */ private static void validateIpAddressPart(final long part, final String name) { if (part < 0) { throw new IllegalArgumentException("Argument '" + name + "' can not be smaller than 0."); } if (part > 255) { throw new IllegalArgumentException("Argument '" + name + "' can not be greater than 255."); } } private IpAddressTranslator() { // stateless classes must not be instantiated } }