1# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
2
3# Copyright (C) 2001-2017 Nominum, Inc.
4#
5# Permission to use, copy, modify, and distribute this software and its
6# documentation for any purpose with or without fee is hereby granted,
7# provided that the above copyright notice and this permission notice
8# appear in all copies.
9#
10# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
18"""DNS Result Codes."""
19
20import dns.enum
21import dns.exception
22
23class Rcode(dns.enum.IntEnum):
24    #: No error
25    NOERROR = 0
26    #: Format error
27    FORMERR = 1
28    #: Server failure
29    SERVFAIL = 2
30    #: Name does not exist ("Name Error" in RFC 1025 terminology).
31    NXDOMAIN = 3
32    #: Not implemented
33    NOTIMP = 4
34    #: Refused
35    REFUSED = 5
36    #: Name exists.
37    YXDOMAIN = 6
38    #: RRset exists.
39    YXRRSET = 7
40    #: RRset does not exist.
41    NXRRSET = 8
42    #: Not authoritative.
43    NOTAUTH = 9
44    #: Name not in zone.
45    NOTZONE = 10
46    #: DSO-TYPE Not Implemented
47    DSOTYPENI = 11
48    #: Bad EDNS version.
49    BADVERS = 16
50    #: TSIG Signature Failure
51    BADSIG = 16
52    #: Key not recognized.
53    BADKEY = 17
54    #: Signature out of time window.
55    BADTIME = 18
56    #: Bad TKEY Mode.
57    BADMODE = 19
58    #: Duplicate key name.
59    BADNAME = 20
60    #: Algorithm not supported.
61    BADALG = 21
62    #: Bad Truncation
63    BADTRUNC = 22
64    #: Bad/missing Server Cookie
65    BADCOOKIE = 23
66
67    @classmethod
68    def _maximum(cls):
69        return 4095
70
71    @classmethod
72    def _unknown_exception_class(cls):
73        return UnknownRcode
74
75
76class UnknownRcode(dns.exception.DNSException):
77    """A DNS rcode is unknown."""
78
79
80def from_text(text):
81    """Convert text into an rcode.
82
83    *text*, a ``str``, the textual rcode or an integer in textual form.
84
85    Raises ``dns.rcode.UnknownRcode`` if the rcode mnemonic is unknown.
86
87    Returns an ``int``.
88    """
89
90    return Rcode.from_text(text)
91
92
93def from_flags(flags, ednsflags):
94    """Return the rcode value encoded by flags and ednsflags.
95
96    *flags*, an ``int``, the DNS flags field.
97
98    *ednsflags*, an ``int``, the EDNS flags field.
99
100    Raises ``ValueError`` if rcode is < 0 or > 4095
101
102    Returns an ``int``.
103    """
104
105    value = (flags & 0x000f) | ((ednsflags >> 20) & 0xff0)
106    return value
107
108
109def to_flags(value):
110    """Return a (flags, ednsflags) tuple which encodes the rcode.
111
112    *value*, an ``int``, the rcode.
113
114    Raises ``ValueError`` if rcode is < 0 or > 4095.
115
116    Returns an ``(int, int)`` tuple.
117    """
118
119    if value < 0 or value > 4095:
120        raise ValueError('rcode must be >= 0 and <= 4095')
121    v = value & 0xf
122    ev = (value & 0xff0) << 20
123    return (v, ev)
124
125
126def to_text(value, tsig=False):
127    """Convert rcode into text.
128
129    *value*, an ``int``, the rcode.
130
131    Raises ``ValueError`` if rcode is < 0 or > 4095.
132
133    Returns a ``str``.
134    """
135
136    if tsig and value == Rcode.BADVERS:
137        return 'BADSIG'
138    return Rcode.to_text(value)
139
140### BEGIN generated Rcode constants
141
142NOERROR = Rcode.NOERROR
143FORMERR = Rcode.FORMERR
144SERVFAIL = Rcode.SERVFAIL
145NXDOMAIN = Rcode.NXDOMAIN
146NOTIMP = Rcode.NOTIMP
147REFUSED = Rcode.REFUSED
148YXDOMAIN = Rcode.YXDOMAIN
149YXRRSET = Rcode.YXRRSET
150NXRRSET = Rcode.NXRRSET
151NOTAUTH = Rcode.NOTAUTH
152NOTZONE = Rcode.NOTZONE
153DSOTYPENI = Rcode.DSOTYPENI
154BADVERS = Rcode.BADVERS
155BADSIG = Rcode.BADSIG
156BADKEY = Rcode.BADKEY
157BADTIME = Rcode.BADTIME
158BADMODE = Rcode.BADMODE
159BADNAME = Rcode.BADNAME
160BADALG = Rcode.BADALG
161BADTRUNC = Rcode.BADTRUNC
162BADCOOKIE = Rcode.BADCOOKIE
163
164### END generated Rcode constants
165