1// Copyright (c) 2003-2004 Brian Wellington (bwelling@xbill.org)
2
3package org.xbill.DNS;
4
5import java.net.*;
6
7/**
8 * A set functions designed to deal with DNS names used in reverse mappings.
9 * For the IPv4 address a.b.c.d, the reverse map name is d.c.b.a.in-addr.arpa.
10 * For an IPv6 address, the reverse map name is ...ip6.arpa.
11 *
12 * @author Brian Wellington
13 */
14
15public final class ReverseMap {
16
17private static Name inaddr4 = Name.fromConstantString("in-addr.arpa.");
18private static Name inaddr6 = Name.fromConstantString("ip6.arpa.");
19
20/* Otherwise the class could be instantiated */
21private
22ReverseMap() {}
23
24/**
25 * Creates a reverse map name corresponding to an address contained in
26 * an array of 4 bytes (for an IPv4 address) or 16 bytes (for an IPv6 address).
27 * @param addr The address from which to build a name.
28 * @return The name corresponding to the address in the reverse map.
29 */
30public static Name
31fromAddress(byte [] addr) {
32	if (addr.length != 4 && addr.length != 16)
33		throw new IllegalArgumentException("array must contain " +
34						   "4 or 16 elements");
35
36	StringBuffer sb = new StringBuffer();
37	if (addr.length == 4) {
38		for (int i = addr.length - 1; i >= 0; i--) {
39			sb.append(addr[i] & 0xFF);
40			if (i > 0)
41				sb.append(".");
42		}
43	} else {
44		int [] nibbles = new int[2];
45		for (int i = addr.length - 1; i >= 0; i--) {
46			nibbles[0] = (addr[i] & 0xFF) >> 4;
47			nibbles[1] = (addr[i] & 0xFF) & 0xF;
48			for (int j = nibbles.length - 1; j >= 0; j--) {
49				sb.append(Integer.toHexString(nibbles[j]));
50				if (i > 0 || j > 0)
51					sb.append(".");
52			}
53		}
54	}
55
56	try {
57		if (addr.length == 4)
58			return Name.fromString(sb.toString(), inaddr4);
59		else
60			return Name.fromString(sb.toString(), inaddr6);
61	}
62	catch (TextParseException e) {
63		throw new IllegalStateException("name cannot be invalid");
64	}
65}
66
67/**
68 * Creates a reverse map name corresponding to an address contained in
69 * an array of 4 integers between 0 and 255 (for an IPv4 address) or 16
70 * integers between 0 and 255 (for an IPv6 address).
71 * @param addr The address from which to build a name.
72 * @return The name corresponding to the address in the reverse map.
73 */
74public static Name
75fromAddress(int [] addr) {
76	byte [] bytes = new byte[addr.length];
77	for (int i = 0; i < addr.length; i++) {
78		if (addr[i] < 0 || addr[i] > 0xFF)
79			throw new IllegalArgumentException("array must " +
80							   "contain values " +
81							   "between 0 and 255");
82		bytes[i] = (byte) addr[i];
83	}
84	return fromAddress(bytes);
85}
86
87/**
88 * Creates a reverse map name corresponding to an address contained in
89 * an InetAddress.
90 * @param addr The address from which to build a name.
91 * @return The name corresponding to the address in the reverse map.
92 */
93public static Name
94fromAddress(InetAddress addr) {
95	return fromAddress(addr.getAddress());
96}
97
98/**
99 * Creates a reverse map name corresponding to an address contained in
100 * a String.
101 * @param addr The address from which to build a name.
102 * @return The name corresponding to the address in the reverse map.
103 * @throws UnknownHostException The string does not contain a valid address.
104 */
105public static Name
106fromAddress(String addr, int family) throws UnknownHostException {
107	byte [] array = Address.toByteArray(addr, family);
108	if (array == null)
109		throw new UnknownHostException("Invalid IP address");
110	return fromAddress(array);
111}
112
113/**
114 * Creates a reverse map name corresponding to an address contained in
115 * a String.
116 * @param addr The address from which to build a name.
117 * @return The name corresponding to the address in the reverse map.
118 * @throws UnknownHostException The string does not contain a valid address.
119 */
120public static Name
121fromAddress(String addr) throws UnknownHostException {
122	byte [] array = Address.toByteArray(addr, Address.IPv4);
123	if (array == null)
124		array = Address.toByteArray(addr, Address.IPv6);
125	if (array == null)
126		throw new UnknownHostException("Invalid IP address");
127	return fromAddress(array);
128}
129
130}
131