flags.py 2.6 KB

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