blob: 346711dfe9419ad6f2f14c0b94710c6b37a878a7 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001// -*- mode: c++ -*-
2#ifndef DNS_PROTO_H
3#define DNS_PROTO_H
4// Utilities for processing DNS packet contents
5
6// Include ares internal file for DNS protocol constants
7#include "nameser.h"
8
9#include <memory>
10#include <string>
11#include <vector>
12
13namespace ares {
14
15typedef unsigned char byte;
16
17std::string HexDump(std::vector<byte> data);
18std::string HexDump(const byte *data, int len);
19std::string HexDump(const char *data, int len);
20
21std::string StatusToString(int status);
22std::string RcodeToString(int rcode);
23std::string RRTypeToString(int rrtype);
24std::string ClassToString(int qclass);
25std::string AddressToString(const void* addr, int len);
26
27// Convert DNS protocol data to strings.
28// Note that these functions are not defensive; they assume
29// a validly formatted input, and so should not be used on
30// externally-determined inputs.
31std::string PacketToString(const std::vector<byte>& packet);
32std::string QuestionToString(const std::vector<byte>& packet,
33 const byte** data, int* len);
34std::string RRToString(const std::vector<byte>& packet,
35 const byte** data, int* len);
36
37
38// Manipulate DNS protocol data.
39void PushInt32(std::vector<byte>* data, int value);
40void PushInt16(std::vector<byte>* data, int value);
41std::vector<byte> EncodeString(const std::string& name);
42
43struct DNSQuestion {
44 DNSQuestion(const std::string& name, ns_type rrtype, ns_class qclass)
45 : name_(name), rrtype_(rrtype), qclass_(qclass) {}
46 DNSQuestion(const std::string& name, ns_type rrtype)
47 : name_(name), rrtype_(rrtype), qclass_(ns_c_in) {}
48 virtual ~DNSQuestion() {}
49 virtual std::vector<byte> data() const;
50 std::string name_;
51 ns_type rrtype_;
52 ns_class qclass_;
53};
54
55struct DNSRR : public DNSQuestion {
56 DNSRR(const std::string& name, ns_type rrtype, ns_class qclass, int ttl)
57 : DNSQuestion(name, rrtype, qclass), ttl_(ttl) {}
58 DNSRR(const std::string& name, ns_type rrtype, int ttl)
59 : DNSQuestion(name, rrtype), ttl_(ttl) {}
60 virtual ~DNSRR() {}
61 virtual std::vector<byte> data() const = 0;
62 int ttl_;
63};
64
65struct DNSAddressRR : public DNSRR {
66 DNSAddressRR(const std::string& name, ns_type rrtype, int ttl,
67 const byte* addr, int addrlen)
68 : DNSRR(name, rrtype, ttl), addr_(addr, addr + addrlen) {}
69 DNSAddressRR(const std::string& name, ns_type rrtype, int ttl,
70 const std::vector<byte>& addr)
71 : DNSRR(name, rrtype, ttl), addr_(addr) {}
72 virtual std::vector<byte> data() const;
73 std::vector<byte> addr_;
74};
75
76struct DNSARR : public DNSAddressRR {
77 DNSARR(const std::string& name, int ttl, const byte* addr, int addrlen)
78 : DNSAddressRR(name, ns_t_a, ttl, addr, addrlen) {}
79 DNSARR(const std::string& name, int ttl, const std::vector<byte>& addr)
80 : DNSAddressRR(name, ns_t_a, ttl, addr) {}
81};
82
83struct DNSAaaaRR : public DNSAddressRR {
84 DNSAaaaRR(const std::string& name, int ttl, const byte* addr, int addrlen)
85 : DNSAddressRR(name, ns_t_aaaa, ttl, addr, addrlen) {}
86 DNSAaaaRR(const std::string& name, int ttl, const std::vector<byte>& addr)
87 : DNSAddressRR(name, ns_t_aaaa, ttl, addr) {}
88};
89
90struct DNSSingleNameRR : public DNSRR {
91 DNSSingleNameRR(const std::string& name, ns_type rrtype, int ttl,
92 const std::string& other)
93 : DNSRR(name, rrtype, ttl), other_(other) {}
94 virtual std::vector<byte> data() const;
95 std::string other_;
96};
97
98struct DNSCnameRR : public DNSSingleNameRR {
99 DNSCnameRR(const std::string& name, int ttl, const std::string& other)
100 : DNSSingleNameRR(name, ns_t_cname, ttl, other) {}
101};
102
103struct DNSNsRR : public DNSSingleNameRR {
104 DNSNsRR(const std::string& name, int ttl, const std::string& other)
105 : DNSSingleNameRR(name, ns_t_ns, ttl, other) {}
106};
107
108struct DNSPtrRR : public DNSSingleNameRR {
109 DNSPtrRR(const std::string& name, int ttl, const std::string& other)
110 : DNSSingleNameRR(name, ns_t_ptr, ttl, other) {}
111};
112
113struct DNSTxtRR : public DNSRR {
114 DNSTxtRR(const std::string& name, int ttl, const std::vector<std::string>& txt)
115 : DNSRR(name, ns_t_txt, ttl), txt_(txt) {}
116 virtual std::vector<byte> data() const;
117 std::vector<std::string> txt_;
118};
119
120struct DNSMxRR : public DNSRR {
121 DNSMxRR(const std::string& name, int ttl, int pref, const std::string& other)
122 : DNSRR(name, ns_t_mx, ttl), pref_(pref), other_(other) {}
123 virtual std::vector<byte> data() const;
124 int pref_;
125 std::string other_;
126};
127
128struct DNSSrvRR : public DNSRR {
129 DNSSrvRR(const std::string& name, int ttl,
130 int prio, int weight, int port, const std::string& target)
131 : DNSRR(name, ns_t_srv, ttl), prio_(prio), weight_(weight), port_(port), target_(target) {}
132 virtual std::vector<byte> data() const;
133 int prio_;
134 int weight_;
135 int port_;
136 std::string target_;
137};
138
139struct DNSSoaRR : public DNSRR {
140 DNSSoaRR(const std::string& name, int ttl,
141 const std::string& nsname, const std::string& rname,
142 int serial, int refresh, int retry, int expire, int minimum)
143 : DNSRR(name, ns_t_soa, ttl), nsname_(nsname), rname_(rname),
144 serial_(serial), refresh_(refresh), retry_(retry),
145 expire_(expire), minimum_(minimum) {}
146 virtual std::vector<byte> data() const;
147 std::string nsname_;
148 std::string rname_;
149 int serial_;
150 int refresh_;
151 int retry_;
152 int expire_;
153 int minimum_;
154};
155
156struct DNSNaptrRR : public DNSRR {
157 DNSNaptrRR(const std::string& name, int ttl,
158 int order, int pref,
159 const std::string& flags,
160 const std::string& service,
161 const std::string& regexp,
162 const std::string& replacement)
163 : DNSRR(name, ns_t_naptr, ttl), order_(order), pref_(pref),
164 flags_(flags), service_(service), regexp_(regexp), replacement_(replacement) {}
165 virtual std::vector<byte> data() const;
166 int order_;
167 int pref_;
168 std::string flags_;
169 std::string service_;
170 std::string regexp_;
171 std::string replacement_;
172};
173
174struct DNSOption {
175 int code_;
176 std::vector<byte> data_;
177};
178
179struct DNSOptRR : public DNSRR {
180 DNSOptRR(int extrcode, int udpsize)
181 : DNSRR("", ns_t_opt, static_cast<ns_class>(udpsize), extrcode) {}
182 virtual std::vector<byte> data() const;
183 std::vector<DNSOption> opts_;
184};
185
186struct DNSPacket {
187 DNSPacket()
188 : qid_(0), response_(false), opcode_(ns_o_query),
189 aa_(false), tc_(false), rd_(false), ra_(false),
190 z_(false), ad_(false), cd_(false), rcode_(ns_r_noerror) {}
191 // Convenience functions that take ownership of given pointers.
192 DNSPacket& add_question(DNSQuestion *q) {
193 questions_.push_back(std::unique_ptr<DNSQuestion>(q));
194 return *this;
195 }
196 DNSPacket& add_answer(DNSRR *q) {
197 answers_.push_back(std::unique_ptr<DNSRR>(q));
198 return *this;
199 }
200 DNSPacket& add_auth(DNSRR *q) {
201 auths_.push_back(std::unique_ptr<DNSRR>(q));
202 return *this;
203 }
204 DNSPacket& add_additional(DNSRR *q) {
205 adds_.push_back(std::unique_ptr<DNSRR>(q));
206 return *this;
207 }
208 // Chainable setters.
209 DNSPacket& set_qid(int qid) { qid_ = qid; return *this; }
210 DNSPacket& set_response(bool v = true) { response_ = v; return *this; }
211 DNSPacket& set_aa(bool v = true) { aa_ = v; return *this; }
212 DNSPacket& set_tc(bool v = true) { tc_ = v; return *this; }
213 DNSPacket& set_rd(bool v = true) { rd_ = v; return *this; }
214 DNSPacket& set_ra(bool v = true) { ra_ = v; return *this; }
215 DNSPacket& set_z(bool v = true) { z_ = v; return *this; }
216 DNSPacket& set_ad(bool v = true) { ad_ = v; return *this; }
217 DNSPacket& set_cd(bool v = true) { cd_ = v; return *this; }
218 DNSPacket& set_rcode(ns_rcode rcode) { rcode_ = rcode; return *this; }
219
220 // Return the encoded packet.
221 std::vector<byte> data() const;
222
223 int qid_;
224 bool response_;
225 ns_opcode opcode_;
226 bool aa_;
227 bool tc_;
228 bool rd_;
229 bool ra_;
230 bool z_;
231 bool ad_;
232 bool cd_;
233 ns_rcode rcode_;
234 std::vector<std::unique_ptr<DNSQuestion>> questions_;
235 std::vector<std::unique_ptr<DNSRR>> answers_;
236 std::vector<std::unique_ptr<DNSRR>> auths_;
237 std::vector<std::unique_ptr<DNSRR>> adds_;
238};
239
240} // namespace ares
241
242#endif