// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org)
package org.xbill.DNS;
import java.net.*;
/**
* A set functions designed to deal with DNS names used in reverse mappings.
* For the IPv4 address a.b.c.d, the reverse map name is d.c.b.a.in-addr.arpa.
* For an IPv6 address, the reverse map name is ...ip6.arpa.
*
* @author Brian Wellington
*/
public final class ReverseMap {
private static Name inaddr4 = Name.fromConstantString("in-addr.arpa.");
private static Name inaddr6 = Name.fromConstantString("ip6.arpa.");
/* Otherwise the class could be instantiated */
private
ReverseMap() {}
/**
* Creates a reverse map name corresponding to an address contained in
* an array of 4 bytes (for an IPv4 address) or 16 bytes (for an IPv6 address).
* @param addr The address from which to build a name.
* @return The name corresponding to the address in the reverse map.
*/
public static Name
fromAddress(byte [] addr) {
if (addr.length != 4 && addr.length != 16)
throw new IllegalArgumentException("array must contain " +
"4 or 16 elements");
StringBuffer sb = new StringBuffer();
if (addr.length == 4) {
for (int i = addr.length - 1; i >= 0; i--) {
sb.append(addr[i] & 0xFF);
if (i > 0)
sb.append(".");
}
} else {
int [] nibbles = new int[2];
for (int i = addr.length - 1; i >= 0; i--) {
nibbles[0] = (addr[i] & 0xFF) >> 4;
nibbles[1] = (addr[i] & 0xFF) & 0xF;
for (int j = nibbles.length - 1; j >= 0; j--) {
sb.append(Integer.toHexString(nibbles[j]));
if (i > 0 || j > 0)
sb.append(".");
}
}
}
try {
if (addr.length == 4)
return Name.fromString(sb.toString(), inaddr4);
else
return Name.fromString(sb.toString(), inaddr6);
}
catch (TextParseException e) {
throw new IllegalStateException("name cannot be invalid");
}
}
/**
* Creates a reverse map name corresponding to an address contained in
* an array of 4 integers between 0 and 255 (for an IPv4 address) or 16
* integers between 0 and 255 (for an IPv6 address).
* @param addr The address from which to build a name.
* @return The name corresponding to the address in the reverse map.
*/
public static Name
fromAddress(int [] addr) {
byte [] bytes = new byte[addr.length];
for (int i = 0; i < addr.length; i++) {
if (addr[i] < 0 || addr[i] > 0xFF)
throw new IllegalArgumentException("array must " +
"contain values " +
"between 0 and 255");
bytes[i] = (byte) addr[i];
}
return fromAddress(bytes);
}
/**
* Creates a reverse map name corresponding to an address contained in
* an InetAddress.
* @param addr The address from which to build a name.
* @return The name corresponding to the address in the reverse map.
*/
public static Name
fromAddress(InetAddress addr) {
return fromAddress(addr.getAddress());
}
/**
* Creates a reverse map name corresponding to an address contained in
* a String.
* @param addr The address from which to build a name.
* @return The name corresponding to the address in the reverse map.
* @throws UnknownHostException The string does not contain a valid address.
*/
public static Name
fromAddress(String addr, int family) throws UnknownHostException {
byte [] array = Address.toByteArray(addr, family);
if (array == null)
throw new UnknownHostException("Invalid IP address");
return fromAddress(array);
}
/**
* Creates a reverse map name corresponding to an address contained in
* a String.
* @param addr The address from which to build a name.
* @return The name corresponding to the address in the reverse map.
* @throws UnknownHostException The string does not contain a valid address.
*/
public static Name
fromAddress(String addr) throws UnknownHostException {
byte [] array = Address.toByteArray(addr, Address.IPv4);
if (array == null)
array = Address.toByteArray(addr, Address.IPv6);
if (array == null)
throw new UnknownHostException("Invalid IP address");
return fromAddress(array);
}
}