1 /*
2 * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
67 null, null, null, null, null,
68 null, null, null, "AAAA", null,
69 null, null, null, "SRV", null,
70 "NAPTR"
71 };
72
73 /*
74 * Resource record class codes
75 */
76 static final int CLASS_INTERNET = 1;
77 static final int CLASS_HESIOD = 2;
78 static final int QCLASS_STAR = 255; // query class "*"
79
80 /*
81 * Mapping from resource record type codes to class name strings.
82 */
83 static final String rrClassNames[] = {
84 null, "IN", null, null, "HS"
85 };
86
87
88 byte[] msg; // DNS message
89 int msgLen; // msg size (in octets)
90 boolean qSection; // true if this RR is part of question section
91 // and therefore has no ttl or rdata
92 int offset; // offset of RR w/in msg
93 int rrlen; // number of octets in encoded RR
94 DnsName name; // name field of RR, including root label
95 int rrtype; // type field of RR
96 String rrtypeName; // name of of rrtype
97 int rrclass; // class field of RR
98 String rrclassName; // name of rrclass
99 int ttl = 0; // ttl field of RR
100 int rdlen = 0; // number of octets of rdata
101 Object rdata = null; // rdata -- most are String, unknown are byte[]
102
103
104 /*
105 * Constructs a new ResourceRecord. The encoded data of the DNS
106 * message is contained in msg; data for this RR begins at msg[offset].
222 long diff = s2 - s1;
223 if (diff == 0) {
224 return 0;
225 } else if ((diff > 0 && diff <= 0x7FFFFFFF) ||
226 (diff < 0 && -diff > 0x7FFFFFFF)) {
227 return -1;
228 } else {
229 return 1;
230 }
231 }
232
233
234 /*
235 * Decodes the binary format of the RR.
236 * May throw ArrayIndexOutOfBoundsException given corrupt data.
237 */
238 private void decode(boolean decodeRdata) throws InvalidNameException {
239 int pos = offset; // index of next unread octet
240
241 name = new DnsName(); // NAME
242 pos = decodeName(pos, name);
243
244 rrtype = getUShort(pos); // TYPE
245 rrtypeName = (rrtype < rrTypeNames.length)
246 ? rrTypeNames[rrtype]
247 : null;
248 if (rrtypeName == null) {
249 rrtypeName = Integer.toString(rrtype);
250 }
251 pos += 2;
252
253 rrclass = getUShort(pos); // CLASS
254 rrclassName = (rrclass < rrClassNames.length)
255 ? rrClassNames[rrclass]
256 : null;
257 if (rrclassName == null) {
258 rrclassName = Integer.toString(rrclass);
259 }
260 pos += 2;
261
262 if (!qSection) {
301 * Returns the 4-byte signed value at msg[pos]. The high
302 * order byte comes first.
303 */
304 private int getInt(int pos) {
305 return ((getUShort(pos) << 16) | getUShort(pos + 2));
306 }
307
308 /*
309 * Returns the 4-byte unsigned value at msg[pos]. The high
310 * order byte comes first.
311 */
312 private long getUInt(int pos) {
313 return (getInt(pos) & 0xffffffffL);
314 }
315
316 /*
317 * Returns the name encoded at msg[pos], including the root label.
318 */
319 private DnsName decodeName(int pos) throws InvalidNameException {
320 DnsName n = new DnsName();
321 decodeName(pos, n);
322 return n;
323 }
324
325 /*
326 * Prepends to "n" the domain name encoded at msg[pos], including the root
327 * label. Returns the index into "msg" following the name.
328 */
329 private int decodeName(int pos, DnsName n) throws InvalidNameException {
330 if (msg[pos] == 0) { // end of name
331 n.add(0, "");
332 return (pos + 1);
333 } else if ((msg[pos] & 0xC0) != 0) { // name compression
334 decodeName(getUShort(pos) & 0x3FFF, n);
335 return (pos + 2);
336 } else { // append a label
337 int len = msg[pos++];
338 try {
339 n.add(0, new String(msg, pos, len, "ISO-8859-1"));
340 } catch (java.io.UnsupportedEncodingException e) {
341 // assert false : "ISO-Latin-1 charset unavailable";
342 }
343 return decodeName(pos + len, n);
344 }
345 }
346
347 /*
348 * Returns the rdata encoded at msg[pos]. The format is dependent
349 * on the rrtype and rrclass values, which have already been set.
350 * The length of the encoded data is rdlen, which has already been
351 * set.
352 * The rdata of records with unknown type/class combinations is
353 * returned in a newly-allocated byte array.
354 */
355 private Object decodeRdata(int pos) throws InvalidNameException {
356 if (rrclass == CLASS_INTERNET) {
357 switch (rrtype) {
358 case TYPE_A:
359 return decodeA(pos);
360 case TYPE_AAAA:
361 return decodeAAAA(pos);
362 case TYPE_CNAME:
363 case TYPE_NS:
381 byte[] rd = new byte[rdlen];
382 System.arraycopy(msg, pos, rd, 0, rdlen);
383 return rd;
384 }
385
386 /*
387 * Returns the rdata of an MX record that is encoded at msg[pos].
388 */
389 private String decodeMx(int pos) throws InvalidNameException {
390 int preference = getUShort(pos);
391 pos += 2;
392 DnsName name = decodeName(pos);
393 return (preference + " " + name);
394 }
395
396 /*
397 * Returns the rdata of an SOA record that is encoded at msg[pos].
398 */
399 private String decodeSoa(int pos) throws InvalidNameException {
400 DnsName mname = new DnsName();
401 pos = decodeName(pos, mname);
402 DnsName rname = new DnsName();
403 pos = decodeName(pos, rname);
404
405 long serial = getUInt(pos);
406 pos += 4;
407 long refresh = getUInt(pos);
408 pos += 4;
409 long retry = getUInt(pos);
410 pos += 4;
411 long expire = getUInt(pos);
412 pos += 4;
413 long minimum = getUInt(pos); // now used as negative TTL
414 pos += 4;
415
416 return (mname + " " + rname + " " + serial + " " +
417 refresh + " " + retry + " " + expire + " " + minimum);
418 }
419
420 /*
421 * Returns the rdata of an SRV record that is encoded at msg[pos].
422 * See RFC 2782.
423 */
|
1 /*
2 * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
67 null, null, null, null, null,
68 null, null, null, "AAAA", null,
69 null, null, null, "SRV", null,
70 "NAPTR"
71 };
72
73 /*
74 * Resource record class codes
75 */
76 static final int CLASS_INTERNET = 1;
77 static final int CLASS_HESIOD = 2;
78 static final int QCLASS_STAR = 255; // query class "*"
79
80 /*
81 * Mapping from resource record type codes to class name strings.
82 */
83 static final String rrClassNames[] = {
84 null, "IN", null, null, "HS"
85 };
86
87 /*
88 * Maximum number of compression references in labels.
89 * Used to detect compression loops.
90 */
91 private static final int MAXIMUM_COMPRESSION_REFERENCES = 16;
92
93 byte[] msg; // DNS message
94 int msgLen; // msg size (in octets)
95 boolean qSection; // true if this RR is part of question section
96 // and therefore has no ttl or rdata
97 int offset; // offset of RR w/in msg
98 int rrlen; // number of octets in encoded RR
99 DnsName name; // name field of RR, including root label
100 int rrtype; // type field of RR
101 String rrtypeName; // name of of rrtype
102 int rrclass; // class field of RR
103 String rrclassName; // name of rrclass
104 int ttl = 0; // ttl field of RR
105 int rdlen = 0; // number of octets of rdata
106 Object rdata = null; // rdata -- most are String, unknown are byte[]
107
108
109 /*
110 * Constructs a new ResourceRecord. The encoded data of the DNS
111 * message is contained in msg; data for this RR begins at msg[offset].
227 long diff = s2 - s1;
228 if (diff == 0) {
229 return 0;
230 } else if ((diff > 0 && diff <= 0x7FFFFFFF) ||
231 (diff < 0 && -diff > 0x7FFFFFFF)) {
232 return -1;
233 } else {
234 return 1;
235 }
236 }
237
238
239 /*
240 * Decodes the binary format of the RR.
241 * May throw ArrayIndexOutOfBoundsException given corrupt data.
242 */
243 private void decode(boolean decodeRdata) throws InvalidNameException {
244 int pos = offset; // index of next unread octet
245
246 name = new DnsName(); // NAME
247 pos = decodeName(pos, name, 0);
248
249 rrtype = getUShort(pos); // TYPE
250 rrtypeName = (rrtype < rrTypeNames.length)
251 ? rrTypeNames[rrtype]
252 : null;
253 if (rrtypeName == null) {
254 rrtypeName = Integer.toString(rrtype);
255 }
256 pos += 2;
257
258 rrclass = getUShort(pos); // CLASS
259 rrclassName = (rrclass < rrClassNames.length)
260 ? rrClassNames[rrclass]
261 : null;
262 if (rrclassName == null) {
263 rrclassName = Integer.toString(rrclass);
264 }
265 pos += 2;
266
267 if (!qSection) {
306 * Returns the 4-byte signed value at msg[pos]. The high
307 * order byte comes first.
308 */
309 private int getInt(int pos) {
310 return ((getUShort(pos) << 16) | getUShort(pos + 2));
311 }
312
313 /*
314 * Returns the 4-byte unsigned value at msg[pos]. The high
315 * order byte comes first.
316 */
317 private long getUInt(int pos) {
318 return (getInt(pos) & 0xffffffffL);
319 }
320
321 /*
322 * Returns the name encoded at msg[pos], including the root label.
323 */
324 private DnsName decodeName(int pos) throws InvalidNameException {
325 DnsName n = new DnsName();
326 decodeName(pos, n, 0);
327 return n;
328 }
329
330 /*
331 * Prepends to "n" the domain name encoded at msg[pos], including the root
332 * label. Returns the index into "msg" following the name.
333 */
334 private int decodeName(int pos, DnsName n, int level)
335 throws InvalidNameException {
336 if (level > MAXIMUM_COMPRESSION_REFERENCES) {
337 throw new InvalidNameException("Too many compression references");
338 }
339 if (msg[pos] == 0) { // end of name
340 n.add(0, "");
341 return (pos + 1);
342 } else if ((msg[pos] & 0xC0) != 0) { // name compression
343 decodeName(getUShort(pos) & 0x3FFF, n, level + 1);
344 return (pos + 2);
345 } else { // append a label
346 int len = msg[pos++];
347 try {
348 n.add(0, new String(msg, pos, len, "ISO-8859-1"));
349 } catch (java.io.UnsupportedEncodingException e) {
350 // assert false : "ISO-Latin-1 charset unavailable";
351 }
352 return decodeName(pos + len, n, level);
353 }
354 }
355
356 /*
357 * Returns the rdata encoded at msg[pos]. The format is dependent
358 * on the rrtype and rrclass values, which have already been set.
359 * The length of the encoded data is rdlen, which has already been
360 * set.
361 * The rdata of records with unknown type/class combinations is
362 * returned in a newly-allocated byte array.
363 */
364 private Object decodeRdata(int pos) throws InvalidNameException {
365 if (rrclass == CLASS_INTERNET) {
366 switch (rrtype) {
367 case TYPE_A:
368 return decodeA(pos);
369 case TYPE_AAAA:
370 return decodeAAAA(pos);
371 case TYPE_CNAME:
372 case TYPE_NS:
390 byte[] rd = new byte[rdlen];
391 System.arraycopy(msg, pos, rd, 0, rdlen);
392 return rd;
393 }
394
395 /*
396 * Returns the rdata of an MX record that is encoded at msg[pos].
397 */
398 private String decodeMx(int pos) throws InvalidNameException {
399 int preference = getUShort(pos);
400 pos += 2;
401 DnsName name = decodeName(pos);
402 return (preference + " " + name);
403 }
404
405 /*
406 * Returns the rdata of an SOA record that is encoded at msg[pos].
407 */
408 private String decodeSoa(int pos) throws InvalidNameException {
409 DnsName mname = new DnsName();
410 pos = decodeName(pos, mname, 0);
411 DnsName rname = new DnsName();
412 pos = decodeName(pos, rname, 0);
413
414 long serial = getUInt(pos);
415 pos += 4;
416 long refresh = getUInt(pos);
417 pos += 4;
418 long retry = getUInt(pos);
419 pos += 4;
420 long expire = getUInt(pos);
421 pos += 4;
422 long minimum = getUInt(pos); // now used as negative TTL
423 pos += 4;
424
425 return (mname + " " + rname + " " + serial + " " +
426 refresh + " " + retry + " " + expire + " " + minimum);
427 }
428
429 /*
430 * Returns the rdata of an SRV record that is encoded at msg[pos].
431 * See RFC 2782.
432 */
|