dns_message_parser/question.rs
1//! This module contains struct for [questions] handling.
2//!
3//! The [`Question`] struct represents an arbitrary question. Each [type] has a dedicated enum
4//! variant in the [`QType`] enum.
5//!
6//! The [`QClass`] enum represents the [class] field of the resource record.
7//!
8//! The [`QType`] enum represents the [type] field of the resource record.
9//!
10//! # Example
11//! ```rust
12//! use dns_message_parser::question::{Question, QType, QClass};
13//!
14//! // Init A record
15//! let question = Question {
16//! // The domain name of the question
17//! domain_name: "example.org".parse().unwrap(),
18//! // The class of the question
19//! q_class: QClass::IN,
20//! // The type of the question
21//! q_type: QType::A,
22//! };
23//!
24//! // Encode the A question into bytes::BytesMut
25//! let bytes = question.encode().unwrap();
26//!
27//! // Decode the A question into a Question struct
28//! let rr = Question::decode(bytes.freeze()).unwrap();
29//! ```
30//!
31//! [`Question`]: crate::question::Question
32//! [`QClass`]: crate::question::QClass
33//! [`QType`]: crate::question::QType
34//! [questions]: https://tools.ietf.org/html/rfc1035#section-4.1.2
35//! [class]: https://tools.ietf.org/html/rfc1035#section-3.2.5
36//! [type]: https://tools.ietf.org/html/rfc1035#section-3.2.3
37
38use crate::DomainName;
39use std::fmt::{Display, Formatter, Result as FmtResult};
40
41try_from_enum_to_integer! {
42 #[repr(u16)]
43 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
44 pub enum QType {
45 A = 1,
46 NS = 2,
47 MD = 3,
48 MF = 4,
49 CNAME = 5,
50 SOA = 6,
51 MB = 7,
52 MG = 8,
53 MR = 9,
54 NULL = 10,
55 WKS = 11,
56 PTR = 12,
57 HINFO = 13,
58 MINFO = 14,
59 MX = 15,
60 TXT = 16,
61 RP = 17,
62 AFSDB = 18,
63 X25 = 19,
64 ISDN = 20,
65 RT = 21,
66 NSAP = 22,
67 NSAP_PTR = 23,
68 SIG = 24,
69 KEY = 25,
70 PX = 26,
71 GPOS = 27,
72 AAAA = 28,
73 LOC = 29,
74 NXT = 30,
75 EID = 31,
76 NIMLOC = 32,
77 SRV = 33,
78 ATMA = 34,
79 NAPTR = 35,
80 KX = 36,
81 CERT = 37,
82 A6 = 38,
83 DNAME = 39,
84 SINK = 40,
85 // OPT = 41,
86 APL = 42,
87 DS = 43,
88 SSHFP = 44,
89 IPSECKEY = 45,
90 RRSIG = 46,
91 NSEC = 47,
92 DNSKEY = 48,
93 DHCID = 49,
94 NSEC3 = 50,
95 NSEC3PARAM = 51,
96 TLSA = 52,
97 SMIMEA = 53,
98
99 HIP = 55,
100 NINFO = 56,
101 RKEY = 57,
102 TALINK = 58,
103 CDS = 59,
104 CDNSKEY = 60,
105 OPENPGPKEY = 61,
106 CSYNC = 62,
107 ZONEMD = 63,
108 /// Service Binding
109 SVCB = 64,
110 /// Service Binding specific to the https and http schemes
111 HTTPS = 65,
112
113 SPF = 99,
114 UINFO = 100,
115 UID = 101,
116 GID = 102,
117 UNSPEC = 103,
118 NID = 104,
119 L32 = 105,
120 L64 = 106,
121 LP = 107,
122 EUI48 = 108,
123 EUI64 = 109,
124
125 TKEY = 249,
126 TSIG = 250,
127 IXFR = 251,
128 // TODO QType?
129 URI = 256,
130 CAA = 257,
131 AVC = 258,
132 DOA = 259,
133 AMTRELAY = 260,
134
135 TA = 32768,
136 DLV = 32769,
137 AXFR = 252,
138 MAILB = 253,
139 MAILA = 254,
140 ALL = 255,
141 }
142}
143
144try_from_enum_to_integer! {
145 #[repr(u16)]
146 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
147 pub enum QClass {
148 IN = 1,
149 CS = 2,
150 CH = 3,
151 HS = 4,
152 NONE = 254,
153 ANY = 255,
154 }
155}
156
157#[derive(Debug, Clone, PartialEq, Eq, Hash)]
158pub struct Question {
159 pub domain_name: DomainName,
160 pub q_class: QClass,
161 pub q_type: QType,
162}
163
164impl Display for Question {
165 fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
166 write!(f, "{} {} {}", self.domain_name, self.q_class, self.q_type)
167 }
168}