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}