gt: 		return InetAddress.getByAddress(addr, bytes);
context: // 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, boolean all) throws UnknownHostException {
  	try {
  		Lookup lookup = new Lookup(name, Type.A);
  		Record [] a = lookup.run();
  		if (a == null) {
  			if (lookup.getResult() == Lookup.TYPE_NOT_FOUND) {
  				Record [] aaaa = new Lookup(name, Type.AAAA).run();
  				if (aaaa != null)
  					return aaaa;
  			}
  			throw new UnknownHostException("unknown host");
  		}
  		if (! all)
  			return a;
  		Record [] aaaa = new Lookup(name, Type.AAAA).run();
  		if (aaaa == null)
  			return a;
  		Record [] merged = new Record[a.length + aaaa.length];
  		System.arraycopy(a, 0, merged, 0, a.length);
  		System.arraycopy(aaaa, 0, merged, a.length, aaaa.length);
  		return merged;
  	}
  	catch (TextParseException e) {
  		throw new UnknownHostException("invalid name");
  	}
  }
  
  private static InetAddress
  addrFromRecord(String name, Record r) throws UnknownHostException {
  	InetAddress addr;
  	if (r instanceof ARecord) {
  		addr = ((ARecord)r).getAddress();
  	} else {
  		addr = ((AAAARecord)r).getAddress();
  	}
  	return InetAddress.getByAddress(name, addr.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, false);
  		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, true);
  		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)
  