1 // Copyright (C) 2010-2015 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
9 #include <gtest/gtest.h>
10 
11 #include <util/buffer.h>
12 #include <dns/messagerenderer.h>
13 #include <dns/rrtype.h>
14 
15 #include <dns/tests/unittest_util.h>
16 #include <util/unittests/wiredata.h>
17 
18 using namespace std;
19 using namespace isc;
20 using namespace isc::dns;
21 using namespace isc::util;
22 using isc::util::unittests::matchWireData;
23 
24 namespace {
25 class RRTypeTest : public ::testing::Test {
26 protected:
RRTypeTest()27     RRTypeTest() : obuffer(0) {}
28 
29     OutputBuffer obuffer;
30     MessageRenderer renderer;
31 
32     static RRType rrtypeFactoryFromWire(const char* datafile);
33     static const RRType rrtype_1, rrtype_0x80, rrtype_0x800, rrtype_0x8000,
34         rrtype_max;
35     static const uint8_t wiredata[];
36 };
37 
38 const RRType RRTypeTest::rrtype_1(1);
39 const RRType RRTypeTest::rrtype_0x80(0x80);
40 const RRType RRTypeTest::rrtype_0x800(0x800);
41 const RRType RRTypeTest::rrtype_0x8000(0x8000);
42 const RRType RRTypeTest::rrtype_max(0xffff);
43 // This is wire-format data for the above sample RRTypes rendered in the
44 // appearing order.
45 const uint8_t RRTypeTest::wiredata[] = { 0x00, 0x01, 0x00, 0x80, 0x08,
46                                          0x00, 0x80, 0x00, 0xff, 0xff };
47 
48 RRType
rrtypeFactoryFromWire(const char * datafile)49 RRTypeTest::rrtypeFactoryFromWire(const char* datafile) {
50     std::vector<unsigned char> data;
51     UnitTestUtil::readWireData(datafile, data);
52 
53     InputBuffer buffer(&data[0], data.size());
54 
55     return (RRType(buffer));
56 }
57 
TEST_F(RRTypeTest,fromText)58 TEST_F(RRTypeTest, fromText) {
59     EXPECT_EQ("A", RRType("A").toText());
60     EXPECT_EQ("NS", RRType("NS").toText());
61 
62     EXPECT_EQ("TYPE65535", RRType("TYPE65535").toText());
63 
64     // something unusual, but existing implementations accept this form,
65     // so do we.
66     EXPECT_EQ(53, RRType("TYPE00053").getCode());
67     // again, unusual, and the majority of other implementations reject it.
68     // In any case, there should be no reasonable reason to accept such a
69     // ridiculously long input.
70     EXPECT_THROW(RRType("TYPE000053"), InvalidRRType);
71 
72     // bogus TYPEnnn representations: should trigger an exception
73     EXPECT_THROW(RRType("TYPE"), InvalidRRType);
74     EXPECT_THROW(RRType("TYPE-1"), InvalidRRType);
75     EXPECT_THROW(RRType("TYPExxx"), InvalidRRType);
76     EXPECT_THROW(RRType("TYPE65536"), InvalidRRType);
77     EXPECT_THROW(RRType("TYPE6500x"), InvalidRRType);
78     EXPECT_THROW(RRType("TYPE65000 "), InvalidRRType);
79 }
80 
TEST_F(RRTypeTest,fromWire)81 TEST_F(RRTypeTest, fromWire) {
82     EXPECT_EQ(0x1234,
83               rrtypeFactoryFromWire("rrcode16_fromWire1").getCode());
84     EXPECT_THROW(rrtypeFactoryFromWire("rrcode16_fromWire2"), IncompleteRRType);
85 }
86 
87 // from string, lower case
TEST_F(RRTypeTest,caseConstruct)88 TEST_F(RRTypeTest, caseConstruct) {
89     EXPECT_EQ("A", RRType("a").toText());
90     EXPECT_EQ("NS", RRType("ns").toText());
91     EXPECT_EQ("TYPE65535", RRType("type65535").toText());
92 }
93 
TEST_F(RRTypeTest,toText)94 TEST_F(RRTypeTest, toText) {
95     EXPECT_EQ("A", RRType(1).toText());
96     EXPECT_EQ("TYPE65000", RRType(65000).toText());
97 }
98 
TEST_F(RRTypeTest,toWireBuffer)99 TEST_F(RRTypeTest, toWireBuffer) {
100     rrtype_1.toWire(obuffer);
101     rrtype_0x80.toWire(obuffer);
102     rrtype_0x800.toWire(obuffer);
103     rrtype_0x8000.toWire(obuffer);
104     rrtype_max.toWire(obuffer);
105 
106     matchWireData(wiredata, sizeof(wiredata),
107                   obuffer.getData(), obuffer.getLength());
108 }
109 
TEST_F(RRTypeTest,toWireRenderer)110 TEST_F(RRTypeTest, toWireRenderer) {
111     rrtype_1.toWire(renderer);
112     rrtype_0x80.toWire(renderer);
113     rrtype_0x800.toWire(renderer);
114     rrtype_0x8000.toWire(renderer);
115     rrtype_max.toWire(renderer);
116 
117     matchWireData(wiredata, sizeof(wiredata),
118                   renderer.getData(), renderer.getLength());
119 }
120 
TEST_F(RRTypeTest,wellKnownTypes)121 TEST_F(RRTypeTest, wellKnownTypes) {
122     EXPECT_EQ(1, RRType::A().getCode());
123     EXPECT_EQ("A", RRType::A().toText());
124 }
125 
TEST_F(RRTypeTest,compare)126 TEST_F(RRTypeTest, compare) {
127     EXPECT_TRUE(RRType(1) == RRType("A"));
128     EXPECT_TRUE(RRType(1).equals(RRType("A")));
129     EXPECT_TRUE(RRType(0) != RRType("A"));
130     EXPECT_TRUE(RRType(0).nequals(RRType("A")));
131 
132     EXPECT_TRUE(RRType("A") < RRType("NS"));
133     EXPECT_TRUE(RRType(100) < RRType(65535));
134 }
135 
136 // test operator<<.  We simply confirm it appends the result of toText().
TEST_F(RRTypeTest,LeftShiftOperator)137 TEST_F(RRTypeTest, LeftShiftOperator) {
138     ostringstream oss;
139     oss << RRType::A();
140     EXPECT_EQ(RRType::A().toText(), oss.str());
141 }
142 
143 // Below, we'll check definitions for all well-known RR types; whether they
144 // are defined and have the correct parameter values.  Test data are generated
145 // from the list available at:
146 // http://www.iana.org/assignments/dns-parameters/dns-parameters.xml
147 struct TypeParam {
148     const char* const txt;      // "A", "AAAA", "NS", etc
149     const uint16_t code;        // 1, 28, 2, etc
150     const RRType& (*obj)();     // RRType::A(), etc
151 } known_types[] = {
152     {"A", 1, RRType::A}, {"NS", 2, RRType::NS}, {"MD", 3, RRType::MD},
153     {"MF", 4, RRType::MF}, {"CNAME", 5, RRType::CNAME},
154     {"SOA", 6, RRType::SOA}, {"MB", 7, RRType::MB}, {"MG", 8, RRType::MG},
155     {"MR", 9, RRType::MR}, {"NULL", 10, RRType::Null},
156     {"WKS", 11, RRType::WKS}, {"PTR", 12, RRType::PTR},
157     {"HINFO", 13, RRType::HINFO}, {"MINFO", 14, RRType::MINFO},
158     {"MX", 15, RRType::MX}, {"TXT", 16, RRType::TXT}, {"RP", 17, RRType::RP},
159     {"AFSDB", 18, RRType::AFSDB}, {"X25", 19, RRType::X25},
160     {"ISDN", 20, RRType::ISDN}, {"RT", 21, RRType::RT},
161     {"NSAP", 22, RRType::NSAP}, {"NSAP-PTR", 23, RRType::NSAP_PTR},
162     {"SIG", 24, RRType::SIG}, {"KEY", 25, RRType::KEY},
163     {"PX", 26, RRType::PX}, {"GPOS", 27, RRType::GPOS},
164     {"AAAA", 28, RRType::AAAA}, {"LOC", 29, RRType::LOC},
165     {"NXT", 30, RRType::NXT}, {"SRV", 33, RRType::SRV},
166     {"NAPTR", 35, RRType::NAPTR}, {"KX", 36, RRType::KX},
167     {"CERT", 37, RRType::CERT}, {"A6", 38, RRType::A6},
168     {"DNAME", 39, RRType::DNAME}, {"OPT", 41, RRType::OPT},
169     {"APL", 42, RRType::APL}, {"DS", 43, RRType::DS},
170     {"SSHFP", 44, RRType::SSHFP}, {"IPSECKEY", 45, RRType::IPSECKEY},
171     {"RRSIG", 46, RRType::RRSIG}, {"NSEC", 47, RRType::NSEC},
172     {"DNSKEY", 48, RRType::DNSKEY}, {"DHCID", 49, RRType::DHCID},
173     {"NSEC3", 50, RRType::NSEC3}, {"NSEC3PARAM", 51, RRType::NSEC3PARAM},
174     {"TLSA", 52, RRType::TLSA}, {"HIP", 55, RRType::HIP},
175     {"SPF", 99, RRType::SPF}, {"UNSPEC", 103, RRType::UNSPEC},
176     {"NID", 104, RRType::NID}, {"L32", 105, RRType::L32},
177     {"L64", 106, RRType::L64}, {"LP", 107, RRType::LP},
178     {"TKEY", 249, RRType::TKEY}, {"TSIG", 250, RRType::TSIG},
179     {"IXFR", 251, RRType::IXFR}, {"AXFR", 252, RRType::AXFR},
180     {"MAILB", 253, RRType::MAILB}, {"MAILA", 254, RRType::MAILA},
181     {"ANY", 255, RRType::ANY}, {"URI", 256, RRType::URI},
182     {"CAA", 257, RRType::CAA}, {"DLV", 32769, RRType::DLV},
183     {NULL, 0, NULL}
184 };
185 
TEST(RRTypeConstTest,wellKnowns)186 TEST(RRTypeConstTest, wellKnowns) {
187     for (int i = 0; known_types[i].txt; ++i) {
188         SCOPED_TRACE("Checking well known RRType: " +
189                      string(known_types[i].txt));
190         EXPECT_EQ(known_types[i].code, RRType(known_types[i].txt).getCode());
191         EXPECT_EQ(known_types[i].code,
192                   (*known_types[i].obj)().getCode());
193     }
194 }
195 }
196