1d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) 2d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 3d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpackage org.xbill.DNS; 4d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 5d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.io.*; 6d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.net.*; 7d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport java.util.*; 8d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenimport org.xbill.DNS.utils.*; 9d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 10d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 11d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * APL - Address Prefix List. See RFC 3123. 12d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * 13d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @author Brian Wellington 14d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 15d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 16d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/* 17d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Note: this currently uses the same constants as the Address class; 18d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * this could change if more constants are defined for APL records. 19d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 20d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 21d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic class APLRecord extends Record { 22d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 23d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic static class Element { 24d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public final int family; 25d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public final boolean negative; 26d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public final int prefixLength; 27d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public final Object address; 28d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 29d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen private 30d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Element(int family, boolean negative, Object address, int prefixLength) 31d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 32d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.family = family; 33d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.negative = negative; 34d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.address = address; 35d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.prefixLength = prefixLength; 36d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!validatePrefixLength(family, prefixLength)) { 37d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("invalid prefix " + 38d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen "length"); 39d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 40d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 41d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 42d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen /** 43d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Creates an APL element corresponding to an IPv4 or IPv6 prefix. 44d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param negative Indicates if this prefix is a negation. 45d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param address The IPv4 or IPv6 address. 46d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param prefixLength The length of this prefix, in bits. 47d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @throws IllegalArgumentException The prefix length is invalid. 48d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 49d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public 50d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Element(boolean negative, InetAddress address, int prefixLength) { 51d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this(Address.familyOf(address), negative, address, 52d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen prefixLength); 53d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 54d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 55d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public String 56d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen toString() { 57d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen StringBuffer sb = new StringBuffer(); 58d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (negative) 59d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append("!"); 60d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(family); 61d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(":"); 62d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (family == Address.IPv4 || family == Address.IPv6) 63d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(((InetAddress) address).getHostAddress()); 64d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen else 65d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(base16.toString((byte []) address)); 66d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append("/"); 67d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(prefixLength); 68d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return sb.toString(); 69d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 70d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 71d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public boolean 72d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen equals(Object arg) { 73d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (arg == null || !(arg instanceof Element)) 74d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 75d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Element elt = (Element) arg; 76d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return (family == elt.family && 77d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen negative == elt.negative && 78d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen prefixLength == elt.prefixLength && 79d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen address.equals(elt.address)); 80d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 81d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 82d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen public int 83d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen hashCode() { 84d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return address.hashCode() + prefixLength + (negative ? 1 : 0); 85d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 86d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 87d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 88d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static final long serialVersionUID = -1348173791712935864L; 89d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 90d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate List elements; 91d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 92d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenAPLRecord() {} 93d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 94d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenRecord 95d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetObject() { 96d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return new APLRecord(); 97d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 98d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 99d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static boolean 100d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenvalidatePrefixLength(int family, int prefixLength) { 101d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (prefixLength < 0 || prefixLength >= 256) 102d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 103d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if ((family == Address.IPv4 && prefixLength > 32) || 104d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen (family == Address.IPv6 && prefixLength > 128)) 105d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return false; 106d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return true; 107d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 108d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 109d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** 110d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * Creates an APL Record from the given data. 111d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen * @param elements The list of APL elements. 112d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen */ 113d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic 114d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenAPLRecord(Name name, int dclass, long ttl, List elements) { 115d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen super(name, Type.APL, dclass, ttl); 116d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.elements = new ArrayList(elements.size()); 117d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Iterator it = elements.iterator(); it.hasNext(); ) { 118d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Object o = it.next(); 119d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!(o instanceof Element)) { 120d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("illegal element"); 121d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 122d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Element element = (Element) o; 123d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (element.family != Address.IPv4 && 124d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen element.family != Address.IPv6) 125d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 126d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new IllegalArgumentException("unknown family"); 127d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 128d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen this.elements.add(element); 129d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 130d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 131d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 132d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 133d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static byte [] 134d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenparseAddress(byte [] in, int length) throws WireParseException { 135d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (in.length > length) 136d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new WireParseException("invalid address length"); 137d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (in.length == length) 138d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return in; 139d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] out = new byte[length]; 140d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen System.arraycopy(in, 0, out, 0, in.length); 141d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return out; 142d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 143d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 144d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenvoid 145d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrrFromWire(DNSInput in) throws IOException { 146d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen elements = new ArrayList(1); 147d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen while (in.remaining() != 0) { 148d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int family = in.readU16(); 149d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int prefix = in.readU8(); 150d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int length = in.readU8(); 151d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen boolean negative = (length & 0x80) != 0; 152d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen length &= ~0x80; 153d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 154d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] data = in.readByteArray(length); 155d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Element element; 156d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!validatePrefixLength(family, prefix)) { 157d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw new WireParseException("invalid prefix length"); 158d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 159d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 160d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (family == Address.IPv4 || family == Address.IPv6) { 161d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen data = parseAddress(data, 162d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Address.addressLength(family)); 163d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen InetAddress addr = InetAddress.getByAddress(data); 164d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen element = new Element(negative, addr, prefix); 165d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else { 166d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen element = new Element(family, negative, data, prefix); 167d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 168d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen elements.add(element); 169d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 170d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 171d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 172d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 173d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenvoid 174d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrdataFromString(Tokenizer st, Name origin) throws IOException { 175d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen elements = new ArrayList(1); 176d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen while (true) { 177d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Tokenizer.Token t = st.get(); 178d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!t.isString()) 179d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen break; 180d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 181d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen boolean negative = false; 182d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int family = 0; 183d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int prefix = 0; 184d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 185d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String s = t.value; 186d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int start = 0; 187d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (s.startsWith("!")) { 188d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen negative = true; 189d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen start = 1; 190d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 191d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int colon = s.indexOf(':', start); 192d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (colon < 0) 193d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw st.exception("invalid address prefix element"); 194d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int slash = s.indexOf('/', colon); 195d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (slash < 0) 196d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw st.exception("invalid address prefix element"); 197d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 198d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String familyString = s.substring(start, colon); 199d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String addressString = s.substring(colon + 1, slash); 200d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen String prefixString = s.substring(slash + 1); 201d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 202d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 203d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen family = Integer.parseInt(familyString); 204d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 205d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (NumberFormatException e) { 206d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw st.exception("invalid family"); 207d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 208d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (family != Address.IPv4 && family != Address.IPv6) 209d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw st.exception("unknown family"); 210d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 211d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen try { 212d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen prefix = Integer.parseInt(prefixString); 213d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 214d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen catch (NumberFormatException e) { 215d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw st.exception("invalid prefix length"); 216d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 217d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 218d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (!validatePrefixLength(family, prefix)) { 219d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw st.exception("invalid prefix length"); 220d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 221d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 222d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] bytes = Address.toByteArray(addressString, family); 223d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (bytes == null) 224d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen throw st.exception("invalid IP address " + 225d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen addressString); 226d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 227d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen InetAddress address = InetAddress.getByAddress(bytes); 228d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen elements.add(new Element(negative, address, prefix)); 229d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 230d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen st.unget(); 231d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 232d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 233d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenString 234d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrrToString() { 235d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen StringBuffer sb = new StringBuffer(); 236d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Iterator it = elements.iterator(); it.hasNext(); ) { 237d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Element element = (Element) it.next(); 238d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(element); 239d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (it.hasNext()) 240d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen sb.append(" "); 241d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 242d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return sb.toString(); 243d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 244d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 245d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen/** Returns the list of APL elements. */ 246d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenpublic List 247d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChengetElements() { 248d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return elements; 249d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 250d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 251d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenprivate static int 252d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenaddressLength(byte [] addr) { 253d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (int i = addr.length - 1; i >= 0; i--) { 254d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (addr[i] != 0) 255d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return i + 1; 256d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 257d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen return 0; 258d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 259d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 260d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chenvoid 261d7955ce24d294fb2014c59d11fca184471056f44Shuyi ChenrrToWire(DNSOutput out, Compression c, boolean canonical) { 262d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen for (Iterator it = elements.iterator(); it.hasNext(); ) { 263d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen Element element = (Element) it.next(); 264d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int length = 0; 265d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen byte [] data; 266d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (element.family == Address.IPv4 || 267d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen element.family == Address.IPv6) 268d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen { 269d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen InetAddress addr = (InetAddress) element.address; 270d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen data = addr.getAddress(); 271d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen length = addressLength(data); 272d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } else { 273d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen data = (byte []) element.address; 274d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen length = data.length; 275d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 276d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen int wlength = length; 277d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen if (element.negative) { 278d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen wlength |= 0x80; 279d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 280d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen out.writeU16(element.family); 281d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen out.writeU8(element.prefixLength); 282d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen out.writeU8(wlength); 283d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen out.writeByteArray(data, 0, length); 284d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen } 285d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 286d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen 287d7955ce24d294fb2014c59d11fca184471056f44Shuyi Chen} 288