1 /*
2 * Copyright (c) 2014, Red Hat, Inc.
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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 8035105
27 * @summary DNS resource record parsing
28 */
29
30 import com.sun.jndi.dns.ResourceRecord;
31 import javax.naming.CommunicationException;
32 import javax.naming.InvalidNameException;;
33
34 import java.lang.reflect.Constructor;
35 import java.lang.reflect.InvocationTargetException;
36
37 import java.io.IOException;
38
39 import static java.nio.charset.StandardCharsets.ISO_8859_1;
40
41 public class Parser {
42 static Constructor<ResourceRecord> rrConstructor;
43 static {
44 try {
45 rrConstructor = ResourceRecord.class.getDeclaredConstructor(
46 byte[].class, int.class, int.class, boolean.class,
47 boolean.class);
48 rrConstructor.setAccessible(true);
49 } catch (Exception e) {
50 throw new AssertionError(e);
51 }
52 }
53
54 static ResourceRecord parse(String data, int offset, boolean qSection)
55 throws Throwable {
56 byte[] bytes = data.getBytes(ISO_8859_1);
57 try {
58 return rrConstructor.newInstance(
59 bytes, bytes.length, offset, qSection, !qSection);
60 } catch (InvocationTargetException e) {
61 throw e.getCause();
62 }
63 }
64
65 public static void main(String[] args) throws Throwable {
66 ResourceRecord rr;
67
68 rr = parse("\003www\007example\003com\000\000\002\000\001",
69 0, true);
70 if (!rr.getName().toString().equals("www.example.com."))
71 throw new AssertionError(rr.getName().toString());
72 if (rr.getRrclass() != 1)
73 throw new AssertionError("RCLASS: " + rr.getRrclass());
74 if (rr.getType() != 2)
75 throw new AssertionError("RTYPE: " + rr.getType());
76
77 String longLabel = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" +
78 "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
79
80 rr = parse("\077" + longLabel + "\077" + longLabel +
81 "\077" + longLabel + "\061" + longLabel.substring(0, 49) +
82 "\007example\003com\000\000\002\000\001",
83 0, true);
84 if (!rr.getName().toString().equals(longLabel +
85 '.' + longLabel + '.' + longLabel +
86 '.' + longLabel.substring(0, 49) + ".example.com."))
87 throw new AssertionError(rr.getName().toString());
88 if (rr.getRrclass() != 1)
89 throw new AssertionError("RCLASS: " + rr.getRrclass());
90 if (rr.getType() != 2)
91 throw new AssertionError("RTYPE: " + rr.getType());
92
93 rr = parse("1-2-3-4-5-6-" +
94 "\003www\007example\003com\000\000\002\000\001" +
95 "\300\014\000\002\000\001\000\001\121\200" +
96 "\000\005\002ns\300\020",
97 33, false);
98 if (!rr.getName().toString().equals("www.example.com."))
99 throw new AssertionError(rr.getName().toString());
100 if (rr.getRrclass() != 1)
101 throw new AssertionError("RCLASS: " + rr.getRrclass());
102 if (rr.getType() != 2)
103 throw new AssertionError("RTYPE: " + rr.getType());
104 if (!rr.getRdata().toString().equals("ns.example.com."))
105 throw new AssertionError("RDATA: " + rr.getRdata());
106
107 try {
108 parse("1-2-3-4-5-6-" +
109 "\003www\007example\003com\000\000\002\000\001" +
110 "\300\014\000\002\000\001\300\051\300\047" +
111 "\000\005\002ns\300\051",
112 33, false);
113 throw new AssertionError();
114 } catch (CommunicationException e) {
115 if (!e.getMessage().equals("DNS error: malformed packet")
116 || e.getCause().getClass() != IOException.class
117 || !e.getCause().getMessage().equals(
118 "Too many compression references"))
119 throw e;
120 }
121
122 try {
123 String longLabel62 = "\076" + longLabel.substring(1);
124 parse(longLabel62 + longLabel62 + longLabel62 + longLabel62 +
125 "\002XX\000\000\002\000\001", 0, true);
126 throw new AssertionError();
127 } catch (CommunicationException e) {
128 if (!e.getMessage().equals("DNS error: malformed packet")
129 || e.getCause().getClass() != InvalidNameException.class
130 || !e.getCause().getMessage().equals("Name too long"))
131 throw e;
132 }
133 try {
134 parse("\100Y" + longLabel + "\000\000\002\000\001", 0, true);
135 throw new AssertionError();
136 } catch (CommunicationException e) {
137 if (!e.getMessage().equals("DNS error: malformed packet")
138 || e.getCause().getClass() != IOException.class
139 || !e.getCause().getMessage().equals("Invalid label type: 64"))
140 throw e;
141 }
142 }
143 }