1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org) 2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.xbill.DNS; 4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.net.*; 6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.net.Inet6Address; 7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Routines dealing with IP addresses. Includes functions similar to 10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * those in the java.net.InetAddress class. 11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Brian Wellington 13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic final class Address { 16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static final int IPv4 = 1; 18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static final int IPv6 = 2; 19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate 21d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenAddress() {} 22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static byte [] 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenparseV4(String s) { 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int numDigits; 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int currentOctet; 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] values = new byte[4]; 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int currentValue; 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int length = s.length(); 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen currentOctet = 0; 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen currentValue = 0; 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen numDigits = 0; 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int i = 0; i < length; i++) { 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen char c = s.charAt(i); 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (c >= '0' && c <= '9') { 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /* Can't have more than 3 digits per octet. */ 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (numDigits == 3) 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /* Octets shouldn't start with 0, unless they are 0. */ 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (numDigits > 0 && currentValue == 0) 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen numDigits++; 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen currentValue *= 10; 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen currentValue += (c - '0'); 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /* 255 is the maximum value for an octet. */ 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (currentValue > 255) 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else if (c == '.') { 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /* Can't have more than 3 dots. */ 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (currentOctet == 3) 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /* Two consecutive dots are bad. */ 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (numDigits == 0) 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen values[currentOctet++] = (byte) currentValue; 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen currentValue = 0; 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen numDigits = 0; 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /* Must have 4 octets. */ 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (currentOctet != 3) 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /* The fourth octet can't be empty. */ 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (numDigits == 0) 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen values[currentOctet] = (byte) currentValue; 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return values; 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static byte [] 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenparseV6(String s) { 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int range = -1; 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] data = new byte[16]; 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String [] tokens = s.split(":", -1); 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int first = 0; 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int last = tokens.length - 1; 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (tokens[0].length() == 0) { 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // If the first two tokens are empty, it means the string 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // started with ::, which is fine. If only the first is 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // empty, the string started with :, which is bad. 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (last - first > 0 && tokens[1].length() == 0) 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen first++; 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (tokens[last].length() == 0) { 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // If the last two tokens are empty, it means the string 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // ended with ::, which is fine. If only the last is 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // empty, the string ended with :, which is bad. 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (last - first > 0 && tokens[last - 1].length() == 0) 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen last--; 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (last - first + 1 > 8) 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int i, j; 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (i = first, j = 0; i <= last; i++) { 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (tokens[i].length() == 0) { 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (range >= 0) 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen range = j; 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen continue; 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (tokens[i].indexOf('.') >= 0) { 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // An IPv4 address must be the last component 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (i < last) 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen // There can't have been more than 6 components. 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (i > 6) 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] v4addr = Address.toByteArray(tokens[i], IPv4); 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (v4addr == null) 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int k = 0; k < 4; k++) 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen data[j++] = v4addr[k]; 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen break; 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int k = 0; k < tokens[i].length(); k++) { 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen char c = tokens[i].charAt(k); 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (Character.digit(c, 16) < 0) 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int x = Integer.parseInt(tokens[i], 16); 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (x > 0xFFFF || x < 0) 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen data[j++] = (byte)(x >>> 8); 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen data[j++] = (byte)(x & 0xFF); 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (NumberFormatException e) { 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (j < 16 && range < 0) 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (range >= 0) { 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int empty = 16 - j; 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen System.arraycopy(data, range, data, range + empty, j - range); 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (i = range; i < range + empty; i++) 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen data[i] = 0; 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return data; 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Convert a string containing an IP address to an array of 4 or 16 integers. 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param s The address, in text format. 162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param family The address family. 163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The address 164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static int [] 166d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChentoArray(String s, int family) { 167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] byteArray = toByteArray(s, family); 168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (byteArray == null) 169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return null; 170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int [] intArray = new int[byteArray.length]; 171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int i = 0; i < byteArray.length; i++) 172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen intArray[i] = byteArray[i] & 0xFF; 173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return intArray; 174d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Convert a string containing an IPv4 address to an array of 4 integers. 178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param s The address, in text format. 179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The address 180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static int [] 182d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChentoArray(String s) { 183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return toArray(s, IPv4); 184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Convert a string containing an IP address to an array of 4 or 16 bytes. 188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param s The address, in text format. 189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param family The address family. 190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The address 191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static byte [] 193d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChentoByteArray(String s, int family) { 194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (family == IPv4) 195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return parseV4(s); 196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else if (family == IPv6) 197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return parseV6(s); 198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else 199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("unknown address family"); 200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Determines if a string contains a valid IP address. 204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param s The string 205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return Whether the string contains a valid IP address 206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static boolean 208d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenisDottedQuad(String s) { 209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] address = Address.toByteArray(s, IPv4); 210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return (address != null); 211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Converts a byte array containing an IPv4 address into a dotted quad string. 215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param addr The array 216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The string representation 217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static String 219d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChentoDottedQuad(byte [] addr) { 220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return ((addr[0] & 0xFF) + "." + (addr[1] & 0xFF) + "." + 221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen (addr[2] & 0xFF) + "." + (addr[3] & 0xFF)); 222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Converts an int array containing an IPv4 address into a dotted quad string. 226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param addr The array 227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The string representation 228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static String 230d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChentoDottedQuad(int [] addr) { 231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return (addr[0] + "." + addr[1] + "." + addr[2] + "." + addr[3]); 232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 233d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 234d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static Record [] 235d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenlookupHostName(String name) throws UnknownHostException { 236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Record [] records = new Lookup(name).run(); 238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (records == null) 239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new UnknownHostException("unknown host"); 240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return records; 241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (TextParseException e) { 243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new UnknownHostException("invalid name"); 244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 247d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static InetAddress 248d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenaddrFromRecord(String name, Record r) throws UnknownHostException { 249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen ARecord a = (ARecord) r; 250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return InetAddress.getByAddress(name, a.getAddress().getAddress()); 251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 252d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Determines the IP address of a host 255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name The hostname to look up 256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The first matching IP address 257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @exception UnknownHostException The hostname does not have any addresses 258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static InetAddress 260d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetByName(String name) throws UnknownHostException { 261d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return getByAddress(name); 263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } catch (UnknownHostException e) { 264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Record [] records = lookupHostName(name); 265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return addrFromRecord(name, records[0]); 266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Determines all IP address of a host 271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param name The hostname to look up 272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return All matching IP addresses 273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @exception UnknownHostException The hostname does not have any addresses 274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static InetAddress [] 276d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetAllByName(String name) throws UnknownHostException { 277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen InetAddress addr = getByAddress(name); 279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return new InetAddress[] {addr}; 280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } catch (UnknownHostException e) { 281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Record [] records = lookupHostName(name); 282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen InetAddress [] addrs = new InetAddress[records.length]; 283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int i = 0; i < records.length; i++) 284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen addrs[i] = addrFromRecord(name, records[i]); 285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return addrs; 286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 287d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 288d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 289d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 290d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Converts an address from its string representation to an IP address. 291d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * The address can be either IPv4 or IPv6. 292d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param addr The address, in string form 293d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The IP addresses 294d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @exception UnknownHostException The address is not a valid IP address. 295d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 296d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static InetAddress 297d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetByAddress(String addr) throws UnknownHostException { 298d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] bytes; 299d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen bytes = toByteArray(addr, IPv4); 300d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (bytes != null) 301d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return InetAddress.getByAddress(addr, bytes); 302d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen bytes = toByteArray(addr, IPv6); 303d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (bytes != null) 304d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return InetAddress.getByAddress(addr, bytes); 305d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new UnknownHostException("Invalid address: " + addr); 306d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 307d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 308d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 309d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Converts an address from its string representation to an IP address in 310d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * a particular family. 311d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param addr The address, in string form 312d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param family The address family, either IPv4 or IPv6. 313d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The IP addresses 314d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @exception UnknownHostException The address is not a valid IP address in 315d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * the specified address family. 316d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 317d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static InetAddress 318d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetByAddress(String addr, int family) throws UnknownHostException { 319d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (family != IPv4 && family != IPv6) 320d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("unknown address family"); 321d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] bytes; 322d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen bytes = toByteArray(addr, family); 323d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (bytes != null) 324d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return InetAddress.getByAddress(addr, bytes); 325d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new UnknownHostException("Invalid address: " + addr); 326d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 327d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 328d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 329d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Determines the hostname for an address 330d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param addr The address to look up 331d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The associated host name 332d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @exception UnknownHostException There is no hostname for the address 333d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 334d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static String 335d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetHostName(InetAddress addr) throws UnknownHostException { 336d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Name name = ReverseMap.fromAddress(addr); 337d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Record [] records = new Lookup(name, Type.PTR).run(); 338d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (records == null) 339d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new UnknownHostException("unknown address"); 340d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen PTRRecord ptr = (PTRRecord) records[0]; 341d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return ptr.getTarget().toString(); 342d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 343d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 344d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 345d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the family of an InetAddress. 346d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param address The supplied address. 347d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The family, either IPv4 or IPv6. 348d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 349d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static int 350d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenfamilyOf(InetAddress address) { 351d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (address instanceof Inet4Address) 352d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return IPv4; 353d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (address instanceof Inet6Address) 354d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return IPv6; 355d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("unknown address family"); 356d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 357d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 358d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 359d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Returns the length of an address in a particular family. 360d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param family The address family, either IPv4 or IPv6. 361d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @return The length of addresses in that family. 362d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 363d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static int 364d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenaddressLength(int family) { 365d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (family == IPv4) 366d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return 4; 367d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (family == IPv6) 368d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return 16; 369d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("unknown address family"); 370d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 371d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 372d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 373d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Truncates an address to the specified number of bits. For example, 374d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * truncating the address 10.1.2.3 to 8 bits would yield 10.0.0.0. 375d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param address The source address 376d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param maskLength The number of bits to truncate the address to. 377d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 378d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static InetAddress 379d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chentruncate(InetAddress address, int maskLength) 380d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen{ 381d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int family = familyOf(address); 382d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int maxMaskLength = addressLength(family) * 8; 383d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (maskLength < 0 || maskLength > maxMaskLength) 384d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("invalid mask length"); 385d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (maskLength == maxMaskLength) 386d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return address; 387d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] bytes = address.getAddress(); 388d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int i = maskLength / 8 + 1; i < bytes.length; i++) 389d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen bytes[i] = 0; 390d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int maskBits = maskLength % 8; 391d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int bitmask = 0; 392d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int i = 0; i < maskBits; i++) 393d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen bitmask |= (1 << (7 - i)); 394d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen bytes[maskLength / 8] &= bitmask; 395d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 396d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return InetAddress.getByAddress(bytes); 397d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } catch (UnknownHostException e) { 398d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("invalid address"); 399d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 400d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 401d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 402d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 403