Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * This file is part of PowerDNS or dnsdist. |
3 | | * Copyright -- PowerDNS.COM B.V. and its contributors |
4 | | * |
5 | | * This program is free software; you can redistribute it and/or modify |
6 | | * it under the terms of version 2 of the GNU General Public License as |
7 | | * published by the Free Software Foundation. |
8 | | * |
9 | | * In addition, for the avoidance of any doubt, permission is granted to |
10 | | * link this program with OpenSSL and to (re)distribute the binaries |
11 | | * produced as the result of such linking. |
12 | | * |
13 | | * This program is distributed in the hope that it will be useful, |
14 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | | * GNU General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU General Public License |
19 | | * along with this program; if not, write to the Free Software |
20 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
21 | | */ |
22 | | #include "dns.hh" |
23 | | #include <iostream> |
24 | | #include <string> |
25 | | #include <vector> |
26 | | #include <utility> |
27 | | #include <sstream> |
28 | | #include "qtype.hh" |
29 | | #include "misc.hh" |
30 | | |
31 | | static_assert(sizeof(QType) == 2, "QType is not 2 bytes in size, something is wrong!"); |
32 | | |
33 | | const map<const string, uint16_t> QType::names = { |
34 | | {"A", 1}, |
35 | | {"NS", 2}, |
36 | | {"CNAME", 5}, |
37 | | {"SOA", 6}, |
38 | | {"MB", 7}, |
39 | | {"MG", 8}, |
40 | | {"MR", 9}, |
41 | | {"PTR", 12}, |
42 | | {"HINFO", 13}, |
43 | | {"MINFO", 14}, |
44 | | {"MX", 15}, |
45 | | {"TXT", 16}, |
46 | | {"RP", 17}, |
47 | | {"AFSDB", 18}, |
48 | | {"SIG", 24}, |
49 | | {"KEY", 25}, |
50 | | {"AAAA", 28}, |
51 | | {"LOC", 29}, |
52 | | {"SRV", 33}, |
53 | | {"NAPTR", 35}, |
54 | | {"KX", 36}, |
55 | | {"CERT", 37}, |
56 | | {"A6", 38}, |
57 | | {"DNAME", 39}, |
58 | | {"OPT", 41}, |
59 | | {"APL", 42}, |
60 | | {"DS", 43}, |
61 | | {"SSHFP", 44}, |
62 | | {"IPSECKEY", 45}, |
63 | | {"RRSIG", 46}, |
64 | | {"NSEC", 47}, |
65 | | {"DNSKEY", 48}, |
66 | | {"DHCID", 49}, |
67 | | {"NSEC3", 50}, |
68 | | {"NSEC3PARAM", 51}, |
69 | | {"TLSA", 52}, |
70 | | {"SMIMEA", 53}, |
71 | | {"RKEY", 57}, |
72 | | {"CDS", 59}, |
73 | | {"CDNSKEY", 60}, |
74 | | {"OPENPGPKEY", 61}, |
75 | | {"CSYNC", 62}, |
76 | | {"ZONEMD", 63}, |
77 | | {"SVCB", 64}, |
78 | | {"HTTPS", 65}, |
79 | | {"SPF", 99}, |
80 | | {"NID", 104}, |
81 | | {"L32", 105}, |
82 | | {"L64", 106}, |
83 | | {"LP", 107}, |
84 | | {"EUI48", 108}, |
85 | | {"EUI64", 109}, |
86 | | {"TKEY", 249}, |
87 | | {"TSIG", 250}, |
88 | | {"IXFR", 251}, |
89 | | {"AXFR", 252}, |
90 | | {"MAILB", 253}, |
91 | | {"MAILA", 254}, |
92 | | {"ANY", 255}, |
93 | | {"URI", 256}, |
94 | | {"CAA", 257}, |
95 | | {"DLV", 32769}, |
96 | | {"ADDR", 65400}, |
97 | | #if !defined(RECURSOR) |
98 | | {"ALIAS", 65401}, |
99 | | {"LUA", 65402}, |
100 | | #endif |
101 | | }; |
102 | | |
103 | 2 | static map<uint16_t, const string> swapElements(const map<const string, uint16_t>& names) { |
104 | 2 | map<uint16_t, const string> ret; |
105 | | |
106 | 130 | for (const auto& n : names) { |
107 | 130 | ret.emplace(n.second, n.first); |
108 | 130 | } |
109 | 2 | return ret; |
110 | 2 | } |
111 | | |
112 | | const map<uint16_t, const string> QType::numbers = swapElements(names); |
113 | | |
114 | | |
115 | | bool QType::isSupportedType() const |
116 | 0 | { |
117 | 0 | return numbers.count(code) == 1; |
118 | 0 | } |
119 | | |
120 | | bool QType::isMetadataType() const |
121 | 0 | { |
122 | | // rfc6895 section 3.1, note ANY is 255 and falls outside the range |
123 | 0 | if (code == QType::OPT || (code >= rfc6895MetaLowerBound && code <= rfc6895MetaUpperBound)) { |
124 | 0 | return true; |
125 | 0 | } |
126 | 0 | return false; |
127 | 0 | } |
128 | | |
129 | | const string QType::toString() const |
130 | 166 | { |
131 | 166 | const auto& name = numbers.find(code); |
132 | 166 | if (name != numbers.cend()) { |
133 | 166 | return name->second; |
134 | 166 | } |
135 | 0 | return "TYPE" + std::to_string(code); |
136 | 166 | } |
137 | | |
138 | | uint16_t QType::chartocode(const char *p) |
139 | 0 | { |
140 | 0 | string P = toUpper(p); |
141 | |
|
142 | 0 | const auto& num = names.find(P); |
143 | 0 | if (num != names.cend()) { |
144 | 0 | return num->second; |
145 | 0 | } |
146 | 0 | if (*p == '#') { |
147 | 0 | return static_cast<uint16_t>(atoi(p + 1)); |
148 | 0 | } |
149 | | |
150 | 0 | if (boost::starts_with(P, "TYPE")) { |
151 | 0 | return static_cast<uint16_t>(atoi(p + 4)); |
152 | 0 | } |
153 | | |
154 | 0 | return 0; |
155 | 0 | } |
156 | | |
157 | | QType &QType::operator=(const char *p) |
158 | 0 | { |
159 | 0 | code = chartocode(p); |
160 | 0 | return *this; |
161 | 0 | } |
162 | | |
163 | | QType &QType::operator=(const string &s) |
164 | 0 | { |
165 | 0 | code = chartocode(s.c_str()); |
166 | 0 | return *this; |
167 | 0 | } |
168 | | |
169 | | const std::string QClass::toString() const |
170 | 0 | { |
171 | 0 | switch (qclass) { |
172 | 0 | case IN: |
173 | 0 | return "IN"; |
174 | 0 | case CHAOS: |
175 | 0 | return "CHAOS"; |
176 | 0 | case NONE: |
177 | 0 | return "NONE"; |
178 | 0 | case ANY: |
179 | 0 | return "ANY"; |
180 | 0 | default : |
181 | 0 | return "CLASS" + std::to_string(qclass); |
182 | 0 | } |
183 | 0 | } |