domain/base/iana/
rcode.rs

1//! DNS response codes and extended response codes.
2//!
3//! The original DNS specification in [RFC 1035] specified four bits of the
4//! message header as response code. The type [`Rcode`] defined herein
5//! represents these codes. Later, [RFC 2671][] (now [RFC 6891]) added eight
6//! bits to the response code to be transmitted as part of the OPT
7//! pseudo-resource record. To make matters even worse, the TSIG and TKEY
8//! records defined by [RFC 2845] and [RFC 2930] use a 16 bit error code.
9//! All of these codes share the same definition space. Even so, we have
10//! separate types for each of these.
11//!
12//! [`Rcode`]: enum.Rcode.html
13//! [RFC 1035]: https://tools.ietf.org/html/rfc1035
14//! [RFC 2671]: https://tools.ietf.org/html/rfc2671
15//! [RFC 2845]: https://tools.ietf.org/html/rfc2845
16//! [RFC 2930]: https://tools.ietf.org/html/rfc2930
17//! [RFC 6891]: https://tools.ietf.org/html/rfc6891
18//!
19#![allow(clippy::upper_case_acronyms)]
20
21use core::{cmp, fmt, hash};
22
23//------------ Rcode --------------------------------------------------------
24
25/// DNS Response Codes.
26///
27/// The response code of a response indicates what happend on the server
28/// when trying to answer the query. The code is a 4 bit value and part of
29/// the header of a DNS message.
30///
31/// This response was defined as part of [RFC 1035]. Later, [RFC 2671]
32/// defined an extended response code of 12 bits using the lower four bits
33/// from the header and eight additional bits stored in the OPT
34/// pseudo-record. The type [OptRcode] represents this extended response
35/// code. A third response code, now 16 bit wide, was defined for the
36/// transaction authentication mechansim (TSIG) in [RFC 2845] and is
37/// represented by [TsigRcode].
38///
39/// All three codes share the same name space. Their values are defined in
40/// one registry, [IANA DNS RCODEs]. This type is complete as of 2019-01-28.
41///
42/// [OptRcode]: enum.OptRcode.html
43/// [TsigRcode]: enum.TsigRcode.html
44/// [IANA DNS RCODEs]: http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6
45/// [RFC 1035]: https://tools.ietf.org/html/rfc1035
46/// [RFC 2671]: https://tools.ietf.org/html/rfc2671
47#[derive(Clone, Copy, Debug)]
48pub enum Rcode {
49    /// No error condition.
50    ///
51    /// (Otherwise known as success.)
52    ///
53    /// Defined in [RFC 1035].
54    ///
55    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
56    NoError,
57
58    /// Format error.
59    ///
60    /// The name server was unable to interpret the query.
61    ///
62    /// Defined in [RFC 1035].
63    ///
64    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
65    FormErr,
66
67    /// Server failure.
68    ///
69    /// The name server was unable to process this query due to a problem
70    /// with the name server.
71    ///
72    /// Defined in [RFC 1035].
73    ///
74    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
75    ServFail,
76
77    /// Name error.
78    ///
79    /// The domain name given in the query does not exist at the name server.
80    ///
81    /// Defined in [RFC 1035].
82    ///
83    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
84    NXDomain,
85
86    /// Not implemented.
87    ///
88    /// The name server does not support the requested kind of query.
89    ///
90    /// Defined in [RFC 1035].
91    ///
92    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
93    NotImp,
94
95    /// Query refused.
96    ///
97    /// The name server refused to perform the operation requested by the
98    /// query for policy reasons.
99    ///
100    /// Defined in [RFC 1035].
101    ///
102    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
103    Refused,
104
105    /// Name exists when it should not.
106    ///
107    /// Returned for an UPDATE query when a domain requested to not exist
108    /// does in fact exist.
109    ///
110    /// Returned when resolving a DNAME redirection when the resulting name
111    /// exceeds the length of 255 octets.
112    ///
113    /// Defined in [RFC 2136] for the UPDATE query and [RFC 6672] for DNAME
114    /// redirection.
115    ///
116    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
117    /// [RFC 6672]: https://tools.ietf.org/html/rfc6672
118    YXDomain,
119
120    /// RR set exists when it should not.
121    ///
122    /// Returned for an UPDATE query when an RRset requested to not exist
123    /// does in fact exist.
124    ///
125    /// Defined in [RFC 2136].
126    ///
127    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
128    YXRRSet,
129
130    /// RR set that should exist does not.
131    ///
132    /// Returned for an UPDATE query when an RRset requested to exist
133    /// does not.
134    ///
135    /// Defined in [RFC 2136].
136    ///
137    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
138    NXRRSet,
139
140    /// Server not authoritative for zone or client not authorized.
141    ///
142    /// Returned for an UPDATE query when the server is not an authoritative
143    /// name server for the requested domain.
144    ///
145    /// Returned for queries using TSIG when authorisation failed.
146    ///
147    /// Defined in [RFC 2136] for UPDATE and [RFC 2845] for TSIG.
148    ///
149    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
150    /// [RFC 2845]: https://tools.ietf.org/html/rfc2845
151    NotAuth,
152
153    /// Name not contained in zone.
154    ///
155    /// A name used in the prerequisite or update section is not within the
156    /// zone given in the zone section.
157    ///
158    /// Defined in [RFC 2136].
159    ///
160    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
161    NotZone,
162
163    /// A raw, integer rcode value.
164    ///
165    /// When converting to an `u8`, only the lower four bits are used.
166    Int(u8),
167}
168
169impl Rcode {
170    /// Creates an rcode from an integer.
171    ///
172    /// Only the lower four bits of `value` are considered.
173    #[must_use]
174    pub fn from_int(value: u8) -> Rcode {
175        use self::Rcode::*;
176
177        match value & 0x0F {
178            0 => NoError,
179            1 => FormErr,
180            2 => ServFail,
181            3 => NXDomain,
182            4 => NotImp,
183            5 => Refused,
184            6 => YXDomain,
185            7 => YXRRSet,
186            8 => NXRRSet,
187            9 => NotAuth,
188            10 => NotZone,
189            value => Int(value),
190        }
191    }
192
193    /// Returns the integer value for this rcode.
194    #[must_use]
195    pub fn to_int(self) -> u8 {
196        use self::Rcode::*;
197
198        match self {
199            NoError => 0,
200            FormErr => 1,
201            ServFail => 2,
202            NXDomain => 3,
203            NotImp => 4,
204            Refused => 5,
205            YXDomain => 6,
206            YXRRSet => 7,
207            NXRRSet => 8,
208            NotAuth => 9,
209            NotZone => 10,
210            Int(value) => value & 0x0F,
211        }
212    }
213}
214
215//--- From
216
217impl From<u8> for Rcode {
218    fn from(value: u8) -> Rcode {
219        Rcode::from_int(value)
220    }
221}
222
223impl From<Rcode> for u8 {
224    fn from(value: Rcode) -> u8 {
225        value.to_int()
226    }
227}
228
229//--- Display
230
231impl fmt::Display for Rcode {
232    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
233        use self::Rcode::*;
234
235        match *self {
236            NoError => "NOERROR".fmt(f),
237            FormErr => "FORMERR".fmt(f),
238            ServFail => "SERVFAIL".fmt(f),
239            NXDomain => "NXDOMAIN".fmt(f),
240            NotImp => "NOTIMP".fmt(f),
241            Refused => "REFUSED".fmt(f),
242            YXDomain => "YXDOMAIN".fmt(f),
243            YXRRSet => "YXRRSET".fmt(f),
244            NXRRSet => "NXRRSET".fmt(f),
245            NotAuth => "NOAUTH".fmt(f),
246            NotZone => "NOTZONE".fmt(f),
247            Int(i) => match Rcode::from_int(i) {
248                Rcode::Int(i) => i.fmt(f),
249                value => value.fmt(f),
250            },
251        }
252    }
253}
254
255//--- PartialEq and Eq
256
257impl cmp::PartialEq for Rcode {
258    fn eq(&self, other: &Rcode) -> bool {
259        self.to_int() == other.to_int()
260    }
261}
262
263impl cmp::PartialEq<u8> for Rcode {
264    fn eq(&self, other: &u8) -> bool {
265        self.to_int() == *other
266    }
267}
268
269impl cmp::PartialEq<Rcode> for u8 {
270    fn eq(&self, other: &Rcode) -> bool {
271        *self == other.to_int()
272    }
273}
274
275impl cmp::Eq for Rcode {}
276
277//--- PartialOrd and Ord
278
279impl cmp::PartialOrd for Rcode {
280    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
281        Some(self.cmp(other))
282    }
283}
284
285impl cmp::PartialOrd<u8> for Rcode {
286    fn partial_cmp(&self, other: &u8) -> Option<cmp::Ordering> {
287        self.to_int().partial_cmp(other)
288    }
289}
290
291impl cmp::PartialOrd<Rcode> for u8 {
292    fn partial_cmp(&self, other: &Rcode) -> Option<cmp::Ordering> {
293        self.partial_cmp(&other.to_int())
294    }
295}
296
297impl cmp::Ord for Rcode {
298    fn cmp(&self, other: &Rcode) -> cmp::Ordering {
299        self.to_int().cmp(&other.to_int())
300    }
301}
302
303//--- Hash
304
305impl hash::Hash for Rcode {
306    fn hash<H: hash::Hasher>(&self, state: &mut H) {
307        self.to_int().hash(state)
308    }
309}
310
311//--- Serialize and Deserialize
312
313#[cfg(feature = "serde")]
314impl serde::Serialize for Rcode {
315    fn serialize<S: serde::Serializer>(
316        &self,
317        serializer: S,
318    ) -> Result<S::Ok, S::Error> {
319        self.to_int().serialize(serializer)
320    }
321}
322
323#[cfg(feature = "serde")]
324impl<'de> serde::Deserialize<'de> for Rcode {
325    fn deserialize<D: serde::Deserializer<'de>>(
326        deserializer: D,
327    ) -> Result<Self, D::Error> {
328        u8::deserialize(deserializer).map(Rcode::from_int)
329    }
330}
331
332//------------ OptRcode -----------------------------------------------------
333
334/// Extended DNS Response Codes for OPT records.
335///
336/// Originally, the response code of embedded in the header of each DNS
337/// message was four bits long. This code, defined in [RFC 1035], is
338/// represented by the [Rcode] type. The extension mechanism for DNS
339/// initially defined in [RFC 2671] and updated by [RFC 6891] added eight
340/// more bits to be stored in the OPT pseudo-resource record. This type
341/// represents the complete 12 bit extended response code.
342///
343/// There is a third, 16 bit wide response code for transaction
344/// authentication (TSIG) defined in [RFC 2845] and represented by the
345/// [`TsigRcode`] type. The code mostly shares the same name space except
346/// for an unfortunate collision in between the BADVERS and BADSIG values.
347/// Because of this, we decided to have separate types.
348///
349/// The values for all three response code types are defined in
350/// the [IANA DNS RCODEs] registry. This type is complete as of 2019-01-28.
351///
352/// [Rcode]: enum.Rcode.html
353/// [`TsigRcode`]: enum.TsigRcode.html
354/// [IANA DNS RCODEs]: http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6
355/// [RFC 2671]: https://tools.ietf.org/html/rfc2671
356/// [RFC 2845]: https://tools.ietf.org/html/rfc2845
357/// [RFC 2930]: https://tools.ietf.org/html/rfc2930
358/// [RFC 6891]: https://tools.ietf.org/html/rfc6891
359#[derive(Clone, Copy, Debug)]
360pub enum OptRcode {
361    /// No error condition.
362    ///
363    /// (Otherwise known as success.)
364    ///
365    /// Defined in [RFC 1035].
366    ///
367    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
368    NoError,
369
370    /// Format error.
371    ///
372    /// The name server was unable to interpret the query.
373    ///
374    /// Defined in [RFC 1035].
375    ///
376    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
377    FormErr,
378
379    /// Server failure.
380    ///
381    /// The name server was unable to process this query due to a problem
382    /// with the name server.
383    ///
384    /// Defined in [RFC 1035].
385    ///
386    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
387    ServFail,
388
389    /// Name error.
390    ///
391    /// The domain name given in the query does not exist at the name server.
392    ///
393    /// Defined in [RFC 1035].
394    ///
395    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
396    NXDomain,
397
398    /// Not implemented.
399    ///
400    /// The name server does not support the requested kind of query.
401    ///
402    /// Defined in [RFC 1035].
403    ///
404    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
405    NotImp,
406
407    /// Query refused.
408    ///
409    /// The name server refused to perform the operation requested by the
410    /// query for policy reasons.
411    ///
412    /// Defined in [RFC 1035].
413    ///
414    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
415    Refused,
416
417    /// Name exists when it should not.
418    ///
419    /// Returned for an UPDATE query when a domain requested to not exist
420    /// does in fact exist.
421    ///
422    /// Returned when resolving a DNAME redirection when the resulting name
423    /// exceeds the length of 255 octets.
424    ///
425    /// Defined in [RFC 2136] for the UPDATE query and [RFC 6672] for DNAME
426    /// redirection.
427    ///
428    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
429    /// [RFC 6672]: https://tools.ietf.org/html/rfc6672
430    YXDomain,
431
432    /// RR set exists when it should not.
433    ///
434    /// Returned for an UPDATE query when an RRset requested to not exist
435    /// does in fact exist.
436    ///
437    /// Defined in [RFC 2136].
438    ///
439    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
440    YXRRSet,
441
442    /// RR set that should exist does not.
443    ///
444    /// Returned for an UPDATE query when an RRset requested to exist
445    /// does not.
446    ///
447    /// Defined in [RFC 2136].
448    ///
449    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
450    NXRRSet,
451
452    /// Server not authoritative for zone or client not authorized.
453    ///
454    /// Returned for an UPDATE query when the server is not an authoritative
455    /// name server for the requested domain.
456    ///
457    /// Returned for queries using TSIG when authorisation failed.
458    ///
459    /// Defined in [RFC 2136] for UPDATE and [RFC 2845] for TSIG.
460    ///
461    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
462    /// [RFC 2845]: https://tools.ietf.org/html/rfc2845
463    NotAuth,
464
465    /// Name not contained in zone.
466    ///
467    /// A name used in the prerequisite or update section is not within the
468    /// zone given in the zone section.
469    ///
470    /// Defined in [RFC 2136].
471    ///
472    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
473    NotZone,
474
475    /// Bad OPT version.
476    ///
477    /// A name server does not implement the EDNS version requested in the
478    /// OPT record.
479    ///
480    /// Defined in [RFC 6891].
481    ///
482    /// [RFC 6891]: https://tools.ietf.org/html/rfc6891
483    BadVers,
484
485    // XXX We will not define the values from the TSIG and TKEY RFCs,
486    //     unless are used in OPT records, too?
487    /// Bad or missing server cookie.
488    ///
489    /// The request contained a COOKIE option either without a server cookie
490    /// or with a server cookie that did not validate.
491    ///
492    /// Defined in [RFC 7873].
493    ///
494    /// [RFC 7873]: https://tools.ietf.org/html/rfc7873
495    BadCookie,
496
497    /// A raw, integer rcode value.
498    ///
499    /// When converting to a 12 bit code, the upper four bits are simply
500    /// ignored.
501    Int(u16),
502}
503
504impl OptRcode {
505    /// Creates an rcode from an integer.
506    ///
507    /// Only the lower twelve bits of `value` are considered.
508    #[must_use]
509    pub fn from_int(value: u16) -> OptRcode {
510        use self::OptRcode::*;
511
512        match value & 0x0FFF {
513            0 => NoError,
514            1 => FormErr,
515            2 => ServFail,
516            3 => NXDomain,
517            4 => NotImp,
518            5 => Refused,
519            6 => YXDomain,
520            7 => YXRRSet,
521            8 => NXRRSet,
522            9 => NotAuth,
523            10 => NotZone,
524            16 => BadVers,
525            23 => BadCookie,
526            value => Int(value),
527        }
528    }
529
530    /// Returns the integer value for this rcode.
531    #[must_use]
532    pub fn to_int(self) -> u16 {
533        use self::OptRcode::*;
534
535        match self {
536            NoError => 0,
537            FormErr => 1,
538            ServFail => 2,
539            NXDomain => 3,
540            NotImp => 4,
541            Refused => 5,
542            YXDomain => 6,
543            YXRRSet => 7,
544            NXRRSet => 8,
545            NotAuth => 9,
546            NotZone => 10,
547            BadVers => 16,
548            BadCookie => 23,
549            Int(value) => value & 0x0F,
550        }
551    }
552
553    /// Creates an extended rcode value from its parts.
554    #[must_use]
555    pub fn from_parts(rcode: Rcode, ext: u8) -> OptRcode {
556        OptRcode::from_int(u16::from(ext) << 4 | u16::from(rcode.to_int()))
557    }
558
559    /// Returns the two parts of an extended rcode value.
560    #[must_use]
561    pub fn to_parts(self) -> (Rcode, u8) {
562        let res = self.to_int();
563        (Rcode::from_int(res as u8), (res >> 8) as u8)
564    }
565
566    /// Returns the rcode part of the extended rcode.
567    #[must_use]
568    pub fn rcode(self) -> Rcode {
569        self.to_parts().0
570    }
571
572    /// Returns the extended octet of the extended rcode.
573    #[must_use]
574    pub fn ext(self) -> u8 {
575        self.to_parts().1
576    }
577}
578
579//--- From
580
581impl From<u16> for OptRcode {
582    fn from(value: u16) -> OptRcode {
583        OptRcode::from_int(value)
584    }
585}
586
587impl From<OptRcode> for u16 {
588    fn from(value: OptRcode) -> u16 {
589        value.to_int()
590    }
591}
592
593impl From<Rcode> for OptRcode {
594    fn from(value: Rcode) -> OptRcode {
595        OptRcode::from_parts(value, 0)
596    }
597}
598
599//--- Display
600
601impl fmt::Display for OptRcode {
602    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
603        use self::OptRcode::*;
604
605        match *self {
606            NoError => "NOERROR".fmt(f),
607            FormErr => "FORMERR".fmt(f),
608            ServFail => "SERVFAIL".fmt(f),
609            NXDomain => "NXDOMAIN".fmt(f),
610            NotImp => "NOTIMP".fmt(f),
611            Refused => "REFUSED".fmt(f),
612            YXDomain => "YXDOMAIN".fmt(f),
613            YXRRSet => "YXRRSET".fmt(f),
614            NXRRSet => "NXRRSET".fmt(f),
615            NotAuth => "NOAUTH".fmt(f),
616            NotZone => "NOTZONE".fmt(f),
617            BadVers => "BADVER".fmt(f),
618            BadCookie => "BADCOOKIE".fmt(f),
619            Int(i) => match OptRcode::from_int(i) {
620                Int(i) => i.fmt(f),
621                value => value.fmt(f),
622            },
623        }
624    }
625}
626
627//------------ TsigRcode ----------------------------------------------------
628
629int_enum! {
630    /// Response codes for transaction authentication (TSIG).
631    ///
632    /// TSIG and TKEY resource records contain a 16 bit wide error field whose
633    /// values are an extension of the standard DNS [`Rcode`]. While it was
634    /// intended to also share the same space with the extended response codes
635    /// used by EDNS (see [`OptRcode`]), both used the value 16. To allow
636    /// distinguish between the two uses of this value, we have two separate
637    /// types.
638    ///
639    /// The values for all three response code types are defined in
640    /// the [IANA DNS RCODEs] registry. This type is complete as of 2019-01-28.
641    ///
642    /// [`Rcode`]: enum.Rcode.html
643    /// [`OptRcode`]: enum.OptRcode.html
644    /// [IANA DNS RCODEs]: http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6
645    =>
646    TsigRcode, u16;
647
648    /// No error condition.
649    ///
650    /// (Otherwise known as success.)
651    ///
652    /// Defined in [RFC 1035].
653    ///
654    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
655    (NoError => 0, b"NOERROR")
656
657    /// Format error.
658    ///
659    /// The name server was unable to interpret the query.
660    ///
661    /// Defined in [RFC 1035].
662    ///
663    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
664    (FormErr => 1, b"FORMERR")
665
666    /// Server failure.
667    ///
668    /// The name server was unable to process this query due to a problem
669    /// with the name server.
670    ///
671    /// Defined in [RFC 1035].
672    ///
673    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
674    (ServFail => 2, b"SERVFAIL")
675
676    /// Name error.
677    ///
678    /// The domain name given in the query does not exist at the name server.
679    ///
680    /// Defined in [RFC 1035].
681    ///
682    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
683    (NXDomain => 3, b"NXDOMAIN")
684
685    /// Not implemented.
686    ///
687    /// The name server does not support the requested kind of query.
688    ///
689    /// Defined in [RFC 1035].
690    ///
691    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
692    (NotImp => 4, b"NOTIMPL")
693
694    /// Query refused.
695    ///
696    /// The name server refused to perform the operation requested by the
697    /// query for policy reasons.
698    ///
699    /// Defined in [RFC 1035].
700    ///
701    /// [RFC 1035]: https://tools.ietf.org/html/rfc1035
702    (Refused => 5, b"REFUSED")
703
704    /// Name exists when it should not.
705    ///
706    /// Returned for an UPDATE query when a domain requested to not exist
707    /// does in fact exist.
708    ///
709    /// Returned when resolving a DNAME redirection when the resulting name
710    /// exceeds the length of 255 octets.
711    ///
712    /// Defined in [RFC 2136] for the UPDATE query and [RFC 6672] for DNAME
713    /// redirection.
714    ///
715    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
716    /// [RFC 6672]: https://tools.ietf.org/html/rfc6672
717    (YXDomain => 6, b"YXDOMAIN")
718
719    /// RR set exists when it should not.
720    ///
721    /// Returned for an UPDATE query when an RRset requested to not exist
722    /// does in fact exist.
723    ///
724    /// Defined in [RFC 2136].
725    ///
726    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
727    (YXRRSet => 7, b"YXRRSET")
728
729    /// RR set that should exist does not.
730    ///
731    /// Returned for an UPDATE query when an RRset requested to exist
732    /// does not.
733    ///
734    /// Defined in [RFC 2136].
735    ///
736    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
737    (NXRRSet => 8, b"NXRRSET")
738
739    /// Server not authoritative for zone or client not authorized.
740    ///
741    /// Returned for an UPDATE query when the server is not an authoritative
742    /// name server for the requested domain.
743    ///
744    /// Returned for queries using TSIG when authorisation failed.
745    ///
746    /// Defined in [RFC 2136] for UPDATE and [RFC 2845] for TSIG.
747    ///
748    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
749    /// [RFC 2845]: https://tools.ietf.org/html/rfc2845
750    (NotAuth => 9, b"NOTAUTH")
751
752    /// Name not contained in zone.
753    ///
754    /// A name used in the prerequisite or update section is not within the
755    /// zone given in the zone section.
756    ///
757    /// Defined in [RFC 2136].
758    ///
759    /// [RFC 2136]: https://tools.ietf.org/html/rfc2136
760    (NotZone => 10, b"NOTZONE")
761
762    /// TSIG signature failure.
763    ///
764    /// The TSIG signature fails to verify.
765    ///
766    /// Defined in [RFC 2845].
767    ///
768    /// [RFC 2845]: https://tools.ietf.org/html/rfc2845
769    (BadSig => 16, b"BADSIG")
770
771    /// Key not recognized.
772    ///
773    /// The server did not recognize the key used for generating the
774    /// signature.
775    ///
776    /// Defined in [RFC 2845].
777    ///
778    /// [RFC 2845]: https://tools.ietf.org/html/rfc2845
779    (BadKey => 17, b"BADKEY")
780
781    /// Signature out of time window.
782    ///
783    /// The server time was outside the time interval specified by the
784    /// request.
785    ///
786    /// Defined in [RFC 2845].
787    ///
788    /// [RFC 2845]: https://tools.ietf.org/html/rfc2845
789    (BadTime => 18, b"BADTIME")
790
791    /// Bad TKEY mode.
792    ///
793    /// The mode field in a TKEY resource record contained a mode not
794    /// supported by the server.
795    ///
796    /// Defined in [RFC 2930].
797    ///
798    /// [RFC 2930]: https://tools.ietf.org/html/rfc2930
799    (BadMode => 19, b"BADMODE")
800
801    /// Duplicate key name.
802    ///
803    /// In TKEY records, when establishing a new key, the name used already
804    /// exists at the server or when deleting a key, a key of this name does
805    /// not exist.
806    ///
807    /// Defined in [RFC 2930].
808    ///
809    /// [RFC 2930]: https://tools.ietf.org/html/rfc2930
810    (BadName => 20, b"BADNAME")
811
812    /// Algorithm not supported.
813    ///
814    /// The value is defined in [RFC 2930] but never actually explained.
815    /// Presumably, it will be returned when the algorithm field of a TKEY
816    /// record contains a value not supported by the server.
817    ///
818    /// [RFC 2930]: https://tools.ietf.org/html/rfc2930
819    (BadAlg => 21, b"BADALG")
820
821    /// Bad truncation.
822    ///
823    /// A TSIG record was received with a MAC too short for the local
824    /// policy in force.
825    ///
826    /// Defined in [RFC 4635].
827    ///
828    /// [RFC 4635]: https://tools.ietf.org/html/rfc4635
829    (BadTrunc => 22, b"BADTRUNC")
830
831    /// Bad or missing server cookie.
832    ///
833    /// The request contained a COOKIE option either without a server cookie
834    /// or with a server cookie that did not validate.
835    ///
836    /// Defined in [RFC 7873].
837    ///
838    /// [RFC 7873]: https://tools.ietf.org/html/rfc7873
839    (BadCookie => 23, b"BADCOOKIE")
840}
841
842//--- From
843
844impl From<Rcode> for TsigRcode {
845    fn from(value: Rcode) -> TsigRcode {
846        TsigRcode::from_int(u16::from(value.to_int()))
847    }
848}
849
850impl From<OptRcode> for TsigRcode {
851    fn from(value: OptRcode) -> TsigRcode {
852        TsigRcode::from_int(value.to_int())
853    }
854}
855
856int_enum_str_with_decimal!(TsigRcode, u16, "unknown TSIG error");