• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright (C) 2001-2007, 2009, 2010 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
23whose 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
26whose key is the rdatatype value and whose value is True in this dictionary.
27@type _singletons: dict"""
28
29import re
30
31import dns.exception
32
33NONE = 0
34A = 1
35NS = 2
36MD = 3
37MF = 4
38CNAME = 5
39SOA = 6
40MB = 7
41MG = 8
42MR = 9
43NULL = 10
44WKS = 11
45PTR = 12
46HINFO = 13
47MINFO = 14
48MX = 15
49TXT = 16
50RP = 17
51AFSDB = 18
52X25 = 19
53ISDN = 20
54RT = 21
55NSAP = 22
56NSAP_PTR = 23
57SIG = 24
58KEY = 25
59PX = 26
60GPOS = 27
61AAAA = 28
62LOC = 29
63NXT = 30
64SRV = 33
65NAPTR = 35
66KX = 36
67CERT = 37
68A6 = 38
69DNAME = 39
70OPT = 41
71APL = 42
72DS = 43
73SSHFP = 44
74IPSECKEY = 45
75RRSIG = 46
76NSEC = 47
77DNSKEY = 48
78DHCID = 49
79NSEC3 = 50
80NSEC3PARAM = 51
81HIP = 55
82SPF = 99
83UNSPEC = 103
84TKEY = 249
85TSIG = 250
86IXFR = 251
87AXFR = 252
88MAILB = 253
89MAILA = 254
90ANY = 255
91TA = 32768
92DLV = 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
178class UnknownRdatatype(dns.exception.DNSException):
179    """Raised if a type is unknown."""
180    pass
181
182def 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
200def 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
214def 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
224def 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
233