// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)

package org.xbill.DNS;

import java.net.*;
import java.net.Inet6Address;

/**
 * Routines dealing with IP addresses.  Includes functions similar to
 * those in the java.net.InetAddress class.
 *
 * @author Brian Wellington
 */

public final class Address {

public static final int IPv4 = 1;
public static final int IPv6 = 2;

private
Address() {}

private static byte []
parseV4(String s) {
	int numDigits;
	int currentOctet;
	byte [] values = new byte[4];
	int currentValue;
	int length = s.length();

	currentOctet = 0;
	currentValue = 0;
	numDigits = 0;
	for (int i = 0; i < length; i++) {
		char c = s.charAt(i);
		if (c >= '0' && c <= '9') {
			/* Can't have more than 3 digits per octet. */
			if (numDigits == 3)
				return null;
			/* Octets shouldn't start with 0, unless they are 0. */
			if (numDigits > 0 && currentValue == 0)
				return null;
			numDigits++;
			currentValue *= 10;
			currentValue += (c - '0');
			/* 255 is the maximum value for an octet. */
			if (currentValue > 255)
				return null;
		} else if (c == '.') {
			/* Can't have more than 3 dots. */
			if (currentOctet == 3)
				return null;
			/* Two consecutive dots are bad. */
			if (numDigits == 0)
				return null;
			values[currentOctet++] = (byte) currentValue;
			currentValue = 0;
			numDigits = 0;
		} else
			return null;
	}
	/* Must have 4 octets. */
	if (currentOctet != 3)
		return null;
	/* The fourth octet can't be empty. */
	if (numDigits == 0)
		return null;
	values[currentOctet] = (byte) currentValue;
	return values;
}

private static byte []
parseV6(String s) {
	int range = -1;
	byte [] data = new byte[16];

	String [] tokens = s.split(":", -1);

	int first = 0;
	int last = tokens.length - 1;

	if (tokens[0].length() == 0) {
		// If the first two tokens are empty, it means the string
		// started with ::, which is fine.  If only the first is
		// empty, the string started with :, which is bad.
		if (last - first > 0 && tokens[1].length() == 0)
			first++;
		else
			return null;
	}

	if (tokens[last].length() == 0) {
		// If the last two tokens are empty, it means the string
		// ended with ::, which is fine.  If only the last is
		// empty, the string ended with :, which is bad.
		if (last - first > 0 && tokens[last - 1].length() == 0)
			last--;
		else
			return null;
	}

	if (last - first + 1 > 8)
		return null;

	int i, j;
	for (i = first, j = 0; i <= last; i++) {
		if (tokens[i].length() == 0) {
			if (range >= 0)
				return null;
			range = j;
			continue;
		}

		if (tokens[i].indexOf('.') >= 0) {
			// An IPv4 address must be the last component
			if (i < last)
				return null;
			// There can't have been more than 6 components.
			if (i > 6)
				return null;
			byte [] v4addr = Address.toByteArray(tokens[i], IPv4);
			if (v4addr == null)
				return null;
			for (int k = 0; k < 4; k++)
				data[j++] = v4addr[k];
			break;
		}

		try {
			for (int k = 0; k < tokens[i].length(); k++) {
				char c = tokens[i].charAt(k);
				if (Character.digit(c, 16) < 0)
					return null;
			}
			int x = Integer.parseInt(tokens[i], 16);
			if (x > 0xFFFF || x < 0)
				return null;
			data[j++] = (byte)(x >>> 8);
			data[j++] = (byte)(x & 0xFF);
		}
		catch (NumberFormatException e) {
			return null;
		}
	}

	if (j < 16 && range < 0)
		return null;

	if (range >= 0) {
		int empty = 16 - j;
		System.arraycopy(data, range, data, range + empty, j - range);
		for (i = range; i < range + empty; i++)
			data[i] = 0;
	}

	return data;
}

/**
 * Convert a string containing an IP address to an array of 4 or 16 integers.
 * @param s The address, in text format.
 * @param family The address family.
 * @return The address
 */
public static int []
toArray(String s, int family) {
	byte [] byteArray = toByteArray(s, family);
	if (byteArray == null)
		return null;
	int [] intArray = new int[byteArray.length];
	for (int i = 0; i < byteArray.length; i++)
		intArray[i] = byteArray[i] & 0xFF;
	return intArray;
}

/**
 * Convert a string containing an IPv4 address to an array of 4 integers.
 * @param s The address, in text format.
 * @return The address
 */
public static int []
toArray(String s) {
	return toArray(s, IPv4);
}

/**
 * Convert a string containing an IP address to an array of 4 or 16 bytes.
 * @param s The address, in text format.
 * @param family The address family.
 * @return The address
 */
public static byte []
toByteArray(String s, int family) {
	if (family == IPv4)
		return parseV4(s);
	else if (family == IPv6)
		return parseV6(s);
	else
		throw new IllegalArgumentException("unknown address family");
}

/**
 * Determines if a string contains a valid IP address.
 * @param s The string
 * @return Whether the string contains a valid IP address
 */
public static boolean
isDottedQuad(String s) {
	byte [] address = Address.toByteArray(s, IPv4);
	return (address != null);
}

/**
 * Converts a byte array containing an IPv4 address into a dotted quad string.
 * @param addr The array
 * @return The string representation
 */
public static String
toDottedQuad(byte [] addr) {
	return ((addr[0] & 0xFF) + "." + (addr[1] & 0xFF) + "." +
		(addr[2] & 0xFF) + "." + (addr[3] & 0xFF));
}

/**
 * Converts an int array containing an IPv4 address into a dotted quad string.
 * @param addr The array
 * @return The string representation
 */
public static String
toDottedQuad(int [] addr) {
	return (addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3]);
}

private static Record []
lookupHostName(String name) throws UnknownHostException {
	try {
		Record [] records = new Lookup(name).run();
		if (records == null)
			throw new UnknownHostException("unknown host");
		return records;
	}
	catch (TextParseException e) {
		throw new UnknownHostException("invalid name");
	}
}

private static InetAddress
addrFromRecord(String name, Record r) throws UnknownHostException {
	ARecord a = (ARecord) r;
	return InetAddress.getByAddress(name, a.getAddress().getAddress());
}

/**
 * Determines the IP address of a host
 * @param name The hostname to look up
 * @return The first matching IP address
 * @exception UnknownHostException The hostname does not have any addresses
 */
public static InetAddress
getByName(String name) throws UnknownHostException {
	try {
		return getByAddress(name);
	} catch (UnknownHostException e) {
		Record [] records = lookupHostName(name);
		return addrFromRecord(name, records[0]);
	}
}

/**
 * Determines all IP address of a host
 * @param name The hostname to look up
 * @return All matching IP addresses
 * @exception UnknownHostException The hostname does not have any addresses
 */
public static InetAddress []
getAllByName(String name) throws UnknownHostException {
	try {
		InetAddress addr = getByAddress(name);
		return new InetAddress[] {addr};
	} catch (UnknownHostException e) {
		Record [] records = lookupHostName(name);
		InetAddress [] addrs = new InetAddress[records.length];
		for (int i = 0; i < records.length; i++)
			addrs[i] = addrFromRecord(name, records[i]);
		return addrs;
	}
}

/**
 * Converts an address from its string representation to an IP address.
 * The address can be either IPv4 or IPv6.
 * @param addr The address, in string form
 * @return The IP addresses
 * @exception UnknownHostException The address is not a valid IP address.
 */
public static InetAddress
getByAddress(String addr) throws UnknownHostException {
	byte [] bytes;
	bytes = toByteArray(addr, IPv4);
	if (bytes != null)
		return InetAddress.getByAddress(addr, bytes);
	bytes = toByteArray(addr, IPv6);
	if (bytes != null)
		return InetAddress.getByAddress(addr, bytes);
	throw new UnknownHostException("Invalid address: " + addr);
}

/**
 * Converts an address from its string representation to an IP address in
 * a particular family.
 * @param addr The address, in string form
 * @param family The address family, either IPv4 or IPv6.
 * @return The IP addresses
 * @exception UnknownHostException The address is not a valid IP address in
 * the specified address family.
 */
public static InetAddress
getByAddress(String addr, int family) throws UnknownHostException {
	if (family != IPv4 && family != IPv6)
		throw new IllegalArgumentException("unknown address family");
	byte [] bytes;
	bytes = toByteArray(addr, family);
	if (bytes != null)
		return InetAddress.getByAddress(addr, bytes);
	throw new UnknownHostException("Invalid address: " + addr);
}

/**
 * Determines the hostname for an address
 * @param addr The address to look up
 * @return The associated host name
 * @exception UnknownHostException There is no hostname for the address
 */
public static String
getHostName(InetAddress addr) throws UnknownHostException {
	Name name = ReverseMap.fromAddress(addr);
	Record [] records = new Lookup(name, Type.PTR).run();
	if (records == null)
		throw new UnknownHostException("unknown address");
	PTRRecord ptr = (PTRRecord) records[0];
	return ptr.getTarget().toString();
}

/**
 * Returns the family of an InetAddress.
 * @param address The supplied address.
 * @return The family, either IPv4 or IPv6.
 */
public static int
familyOf(InetAddress address) {
	if (address instanceof Inet4Address)
		return IPv4;
	if (address instanceof Inet6Address)
		return IPv6;
	throw new IllegalArgumentException("unknown address family");
}

/**
 * Returns the length of an address in a particular family.
 * @param family The address family, either IPv4 or IPv6.
 * @return The length of addresses in that family.
 */
public static int
addressLength(int family) {
	if (family == IPv4)
		return 4;
	if (family == IPv6)
		return 16;
	throw new IllegalArgumentException("unknown address family");
}

/**
 * Truncates an address to the specified number of bits.  For example,
 * truncating the address 10.1.2.3 to 8 bits would yield 10.0.0.0.
 * @param address The source address
 * @param maskLength The number of bits to truncate the address to.
 */
public static InetAddress
truncate(InetAddress address, int maskLength)
{
	int family = familyOf(address);
	int maxMaskLength = addressLength(family) * 8;
	if (maskLength < 0 || maskLength > maxMaskLength)
		throw new IllegalArgumentException("invalid mask length");
	if (maskLength == maxMaskLength)
		return address;
	byte [] bytes = address.getAddress();
	for (int i = maskLength / 8 + 1; i < bytes.length; i++)
		bytes[i] = 0;
	int maskBits = maskLength % 8;
	int bitmask = 0;
	for (int i = 0; i < maskBits; i++)
		bitmask |= (1 << (7 - i));
	bytes[maskLength / 8] &= bitmask;
	try {
		return InetAddress.getByAddress(bytes);
	} catch (UnknownHostException e) {
		throw new IllegalArgumentException("invalid address");
	}
}

}
