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 Message Flags.""" 17 18# Standard DNS flags 19 20QR = 0x8000 21AA = 0x0400 22TC = 0x0200 23RD = 0x0100 24RA = 0x0080 25AD = 0x0020 26CD = 0x0010 27 28# EDNS flags 29 30DO = 0x8000 31 32_by_text = { 33 'QR' : QR, 34 'AA' : AA, 35 'TC' : TC, 36 'RD' : RD, 37 'RA' : RA, 38 'AD' : AD, 39 'CD' : CD 40} 41 42_edns_by_text = { 43 'DO' : DO 44} 45 46 47# We construct the inverse mappings programmatically to ensure that we 48# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that 49# would cause the mappings not to be true inverses. 50 51_by_value = dict([(y, x) for x, y in _by_text.iteritems()]) 52 53_edns_by_value = dict([(y, x) for x, y in _edns_by_text.iteritems()]) 54 55def _order_flags(table): 56 order = list(table.iteritems()) 57 order.sort() 58 order.reverse() 59 return order 60 61_flags_order = _order_flags(_by_value) 62 63_edns_flags_order = _order_flags(_edns_by_value) 64 65def _from_text(text, table): 66 flags = 0 67 tokens = text.split() 68 for t in tokens: 69 flags = flags | table[t.upper()] 70 return flags 71 72def _to_text(flags, table, order): 73 text_flags = [] 74 for k, v in order: 75 if flags & k != 0: 76 text_flags.append(v) 77 return ' '.join(text_flags) 78 79def from_text(text): 80 """Convert a space-separated list of flag text values into a flags 81 value. 82 @rtype: int""" 83 84 return _from_text(text, _by_text) 85 86def to_text(flags): 87 """Convert a flags value into a space-separated list of flag text 88 values. 89 @rtype: string""" 90 91 return _to_text(flags, _by_value, _flags_order) 92 93 94def edns_from_text(text): 95 """Convert a space-separated list of EDNS flag text values into a EDNS 96 flags value. 97 @rtype: int""" 98 99 return _from_text(text, _edns_by_text) 100 101def edns_to_text(flags): 102 """Convert an EDNS flags value into a space-separated list of EDNS flag 103 text values. 104 @rtype: string""" 105 106 return _to_text(flags, _edns_by_value, _edns_flags_order) 107