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 Rdata Types."""
19
20import dns.enum
21import dns.exception
22
23class RdataType(dns.enum.IntEnum):
24    """DNS Rdata Type"""
25    TYPE0 = 0
26    NONE = 0
27    A = 1
28    NS = 2
29    MD = 3
30    MF = 4
31    CNAME = 5
32    SOA = 6
33    MB = 7
34    MG = 8
35    MR = 9
36    NULL = 10
37    WKS = 11
38    PTR = 12
39    HINFO = 13
40    MINFO = 14
41    MX = 15
42    TXT = 16
43    RP = 17
44    AFSDB = 18
45    X25 = 19
46    ISDN = 20
47    RT = 21
48    NSAP = 22
49    NSAP_PTR = 23
50    SIG = 24
51    KEY = 25
52    PX = 26
53    GPOS = 27
54    AAAA = 28
55    LOC = 29
56    NXT = 30
57    SRV = 33
58    NAPTR = 35
59    KX = 36
60    CERT = 37
61    A6 = 38
62    DNAME = 39
63    OPT = 41
64    APL = 42
65    DS = 43
66    SSHFP = 44
67    IPSECKEY = 45
68    RRSIG = 46
69    NSEC = 47
70    DNSKEY = 48
71    DHCID = 49
72    NSEC3 = 50
73    NSEC3PARAM = 51
74    TLSA = 52
75    SMIMEA = 53
76    HIP = 55
77    NINFO = 56
78    CDS = 59
79    CDNSKEY = 60
80    OPENPGPKEY = 61
81    CSYNC = 62
82    SVCB = 64
83    HTTPS = 65
84    SPF = 99
85    UNSPEC = 103
86    EUI48 = 108
87    EUI64 = 109
88    TKEY = 249
89    TSIG = 250
90    IXFR = 251
91    AXFR = 252
92    MAILB = 253
93    MAILA = 254
94    ANY = 255
95    URI = 256
96    CAA = 257
97    AVC = 258
98    AMTRELAY = 259
99    TA = 32768
100    DLV = 32769
101
102    @classmethod
103    def _maximum(cls):
104        return 65535
105
106    @classmethod
107    def _short_name(cls):
108        return "type"
109
110    @classmethod
111    def _prefix(cls):
112        return "TYPE"
113
114    @classmethod
115    def _unknown_exception_class(cls):
116        return UnknownRdatatype
117
118_registered_by_text = {}
119_registered_by_value = {}
120
121_metatypes = {RdataType.OPT}
122
123_singletons = {RdataType.SOA, RdataType.NXT, RdataType.DNAME,
124               RdataType.NSEC, RdataType.CNAME}
125
126
127class UnknownRdatatype(dns.exception.DNSException):
128    """DNS resource record type is unknown."""
129
130
131def from_text(text):
132    """Convert text into a DNS rdata type value.
133
134    The input text can be a defined DNS RR type mnemonic or
135    instance of the DNS generic type syntax.
136
137    For example, "NS" and "TYPE2" will both result in a value of 2.
138
139    Raises ``dns.rdatatype.UnknownRdatatype`` if the type is unknown.
140
141    Raises ``ValueError`` if the rdata type value is not >= 0 and <= 65535.
142
143    Returns an ``int``.
144    """
145
146    text = text.upper().replace('-', '_')
147    try:
148        return RdataType.from_text(text)
149    except UnknownRdatatype:
150        registered_type = _registered_by_text.get(text)
151        if registered_type:
152            return registered_type
153        raise
154
155
156def to_text(value):
157    """Convert a DNS rdata type value to text.
158
159    If the value has a known mnemonic, it will be used, otherwise the
160    DNS generic type syntax will be used.
161
162    Raises ``ValueError`` if the rdata type value is not >= 0 and <= 65535.
163
164    Returns a ``str``.
165    """
166
167    text = RdataType.to_text(value)
168    if text.startswith("TYPE"):
169        registered_text = _registered_by_value.get(value)
170        if registered_text:
171            text = registered_text
172    return text.replace('_', '-')
173
174
175def is_metatype(rdtype):
176    """True if the specified type is a metatype.
177
178    *rdtype* is an ``int``.
179
180    The currently defined metatypes are TKEY, TSIG, IXFR, AXFR, MAILA,
181    MAILB, ANY, and OPT.
182
183    Returns a ``bool``.
184    """
185
186    return (256 > rdtype >= 128) or rdtype in _metatypes
187
188
189def is_singleton(rdtype):
190    """Is the specified type a singleton type?
191
192    Singleton types can only have a single rdata in an rdataset, or a single
193    RR in an RRset.
194
195    The currently defined singleton types are CNAME, DNAME, NSEC, NXT, and
196    SOA.
197
198    *rdtype* is an ``int``.
199
200    Returns a ``bool``.
201    """
202
203    if rdtype in _singletons:
204        return True
205    return False
206
207# pylint: disable=redefined-outer-name
208def register_type(rdtype, rdtype_text, is_singleton=False):
209    """Dynamically register an rdatatype.
210
211    *rdtype*, an ``int``, the rdatatype to register.
212
213    *rdtype_text*, a ``str``, the textual form of the rdatatype.
214
215    *is_singleton*, a ``bool``, indicating if the type is a singleton (i.e.
216    RRsets of the type can have only one member.)
217    """
218
219    _registered_by_text[rdtype_text] = rdtype
220    _registered_by_value[rdtype] = rdtype_text
221    if is_singleton:
222        _singletons.add(rdtype)
223
224### BEGIN generated RdataType constants
225
226TYPE0 = RdataType.TYPE0
227NONE = RdataType.NONE
228A = RdataType.A
229NS = RdataType.NS
230MD = RdataType.MD
231MF = RdataType.MF
232CNAME = RdataType.CNAME
233SOA = RdataType.SOA
234MB = RdataType.MB
235MG = RdataType.MG
236MR = RdataType.MR
237NULL = RdataType.NULL
238WKS = RdataType.WKS
239PTR = RdataType.PTR
240HINFO = RdataType.HINFO
241MINFO = RdataType.MINFO
242MX = RdataType.MX
243TXT = RdataType.TXT
244RP = RdataType.RP
245AFSDB = RdataType.AFSDB
246X25 = RdataType.X25
247ISDN = RdataType.ISDN
248RT = RdataType.RT
249NSAP = RdataType.NSAP
250NSAP_PTR = RdataType.NSAP_PTR
251SIG = RdataType.SIG
252KEY = RdataType.KEY
253PX = RdataType.PX
254GPOS = RdataType.GPOS
255AAAA = RdataType.AAAA
256LOC = RdataType.LOC
257NXT = RdataType.NXT
258SRV = RdataType.SRV
259NAPTR = RdataType.NAPTR
260KX = RdataType.KX
261CERT = RdataType.CERT
262A6 = RdataType.A6
263DNAME = RdataType.DNAME
264OPT = RdataType.OPT
265APL = RdataType.APL
266DS = RdataType.DS
267SSHFP = RdataType.SSHFP
268IPSECKEY = RdataType.IPSECKEY
269RRSIG = RdataType.RRSIG
270NSEC = RdataType.NSEC
271DNSKEY = RdataType.DNSKEY
272DHCID = RdataType.DHCID
273NSEC3 = RdataType.NSEC3
274NSEC3PARAM = RdataType.NSEC3PARAM
275TLSA = RdataType.TLSA
276SMIMEA = RdataType.SMIMEA
277HIP = RdataType.HIP
278NINFO = RdataType.NINFO
279CDS = RdataType.CDS
280CDNSKEY = RdataType.CDNSKEY
281OPENPGPKEY = RdataType.OPENPGPKEY
282CSYNC = RdataType.CSYNC
283SVCB = RdataType.SVCB
284HTTPS = RdataType.HTTPS
285SPF = RdataType.SPF
286UNSPEC = RdataType.UNSPEC
287EUI48 = RdataType.EUI48
288EUI64 = RdataType.EUI64
289TKEY = RdataType.TKEY
290TSIG = RdataType.TSIG
291IXFR = RdataType.IXFR
292AXFR = RdataType.AXFR
293MAILB = RdataType.MAILB
294MAILA = RdataType.MAILA
295ANY = RdataType.ANY
296URI = RdataType.URI
297CAA = RdataType.CAA
298AVC = RdataType.AVC
299AMTRELAY = RdataType.AMTRELAY
300TA = RdataType.TA
301DLV = RdataType.DLV
302
303### END generated RdataType constants
304