Move dnspython to third_party.
[bbaumbach/samba-autobuild/.git] / third_party / dnspython / dns / rdatatype.py
1 # Copyright (C) 2001-2007, 2009-2011 Nominum, Inc.
2 #
3 # Permission to use, copy, modify, and distribute this software and its
4 # documentation for any purpose with or without fee is hereby granted,
5 # provided that the above copyright notice and this permission notice
6 # appear in all copies.
7 #
8 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
9 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
11 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
14 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
16 """DNS Rdata Types.
17
18 @var _by_text: The rdata type textual name to value mapping
19 @type _by_text: dict
20 @var _by_value: The rdata type value to textual name mapping
21 @type _by_value: dict
22 @var _metatypes: If an rdatatype is a metatype, there will be a mapping
23 whose key is the rdatatype value and whose value is True in this dictionary.
24 @type _metatypes: dict
25 @var _singletons: If an rdatatype is a singleton, there will be a mapping
26 whose key is the rdatatype value and whose value is True in this dictionary.
27 @type _singletons: dict"""
28
29 import re
30
31 import dns.exception
32
33 NONE = 0
34 A = 1
35 NS = 2
36 MD = 3
37 MF = 4
38 CNAME = 5
39 SOA = 6
40 MB = 7
41 MG = 8
42 MR = 9
43 NULL = 10
44 WKS = 11
45 PTR = 12
46 HINFO = 13
47 MINFO = 14
48 MX = 15
49 TXT = 16
50 RP = 17
51 AFSDB = 18
52 X25 = 19
53 ISDN = 20
54 RT = 21
55 NSAP = 22
56 NSAP_PTR = 23
57 SIG = 24
58 KEY = 25
59 PX = 26
60 GPOS = 27
61 AAAA = 28
62 LOC = 29
63 NXT = 30
64 SRV = 33
65 NAPTR = 35
66 KX = 36
67 CERT = 37
68 A6 = 38
69 DNAME = 39
70 OPT = 41
71 APL = 42
72 DS = 43
73 SSHFP = 44
74 IPSECKEY = 45
75 RRSIG = 46
76 NSEC = 47
77 DNSKEY = 48
78 DHCID = 49
79 NSEC3 = 50
80 NSEC3PARAM = 51
81 HIP = 55
82 SPF = 99
83 UNSPEC = 103
84 TKEY = 249
85 TSIG = 250
86 IXFR = 251
87 AXFR = 252
88 MAILB = 253
89 MAILA = 254
90 ANY = 255
91 TA = 32768
92 DLV = 32769
93
94 _by_text = {
95     'NONE' : NONE,
96     'A' : A,
97     'NS' : NS,
98     'MD' : MD,
99     'MF' : MF,
100     'CNAME' : CNAME,
101     'SOA' : SOA,
102     'MB' : MB,
103     'MG' : MG,
104     'MR' : MR,
105     'NULL' : NULL,
106     'WKS' : WKS,
107     'PTR' : PTR,
108     'HINFO' : HINFO,
109     'MINFO' : MINFO,
110     'MX' : MX,
111     'TXT' : TXT,
112     'RP' : RP,
113     'AFSDB' : AFSDB,
114     'X25' : X25,
115     'ISDN' : ISDN,
116     'RT' : RT,
117     'NSAP' : NSAP,
118     'NSAP-PTR' : NSAP_PTR,
119     'SIG' : SIG,
120     'KEY' : KEY,
121     'PX' : PX,
122     'GPOS' : GPOS,
123     'AAAA' : AAAA,
124     'LOC' : LOC,
125     'NXT' : NXT,
126     'SRV' : SRV,
127     'NAPTR' : NAPTR,
128     'KX' : KX,
129     'CERT' : CERT,
130     'A6' : A6,
131     'DNAME' : DNAME,
132     'OPT' : OPT,
133     'APL' : APL,
134     'DS' : DS,
135     'SSHFP' : SSHFP,
136     'IPSECKEY' : IPSECKEY,
137     'RRSIG' : RRSIG,
138     'NSEC' : NSEC,
139     'DNSKEY' : DNSKEY,
140     'DHCID' : DHCID,
141     'NSEC3' : NSEC3,
142     'NSEC3PARAM' : NSEC3PARAM,
143     'HIP' : HIP,
144     'SPF' : SPF,
145     'UNSPEC' : UNSPEC,
146     'TKEY' : TKEY,
147     'TSIG' : TSIG,
148     'IXFR' : IXFR,
149     'AXFR' : AXFR,
150     'MAILB' : MAILB,
151     'MAILA' : MAILA,
152     'ANY' : ANY,
153     'TA' : TA,
154     'DLV' : DLV,
155     }
156
157 # We construct the inverse mapping programmatically to ensure that we
158 # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
159 # would cause the mapping not to be true inverse.
160
161 _by_value = dict([(y, x) for x, y in _by_text.iteritems()])
162
163
164 _metatypes = {
165     OPT : True
166     }
167
168 _singletons = {
169     SOA : True,
170     NXT : True,
171     DNAME : True,
172     NSEC : True,
173     # CNAME is technically a singleton, but we allow multiple CNAMEs.
174     }
175
176 _unknown_type_pattern = re.compile('TYPE([0-9]+)$', re.I);
177
178 class UnknownRdatatype(dns.exception.DNSException):
179     """Raised if a type is unknown."""
180     pass
181
182 def from_text(text):
183     """Convert text into a DNS rdata type value.
184     @param text: the text
185     @type text: string
186     @raises dns.rdatatype.UnknownRdatatype: the type is unknown
187     @raises ValueError: the rdata type value is not >= 0 and <= 65535
188     @rtype: int"""
189
190     value = _by_text.get(text.upper())
191     if value is None:
192         match = _unknown_type_pattern.match(text)
193         if match == None:
194             raise UnknownRdatatype
195         value = int(match.group(1))
196         if value < 0 or value > 65535:
197             raise ValueError("type must be between >= 0 and <= 65535")
198     return value
199
200 def to_text(value):
201     """Convert a DNS rdata type to text.
202     @param value: the rdata type value
203     @type value: int
204     @raises ValueError: the rdata type value is not >= 0 and <= 65535
205     @rtype: string"""
206
207     if value < 0 or value > 65535:
208         raise ValueError("type must be between >= 0 and <= 65535")
209     text = _by_value.get(value)
210     if text is None:
211         text = 'TYPE' + `value`
212     return text
213
214 def is_metatype(rdtype):
215     """True if the type is a metatype.
216     @param rdtype: the type
217     @type rdtype: int
218     @rtype: bool"""
219
220     if rdtype >= TKEY and rdtype <= ANY or _metatypes.has_key(rdtype):
221         return True
222     return False
223
224 def is_singleton(rdtype):
225     """True if the type is a singleton.
226     @param rdtype: the type
227     @type rdtype: int
228     @rtype: bool"""
229
230     if _singletons.has_key(rdtype):
231         return True
232     return False