You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
2.9 KiB

4 years ago
  1. # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
  2. # Copyright (C) 2001-2017 Nominum, Inc.
  3. #
  4. # Permission to use, copy, modify, and distribute this software and its
  5. # documentation for any purpose with or without fee is hereby granted,
  6. # provided that the above copyright notice and this permission notice
  7. # appear in all copies.
  8. #
  9. # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
  10. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
  12. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  15. # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. """DNS Message Flags."""
  17. # Standard DNS flags
  18. #: Query Response
  19. QR = 0x8000
  20. #: Authoritative Answer
  21. AA = 0x0400
  22. #: Truncated Response
  23. TC = 0x0200
  24. #: Recursion Desired
  25. RD = 0x0100
  26. #: Recursion Available
  27. RA = 0x0080
  28. #: Authentic Data
  29. AD = 0x0020
  30. #: Checking Disabled
  31. CD = 0x0010
  32. # EDNS flags
  33. #: DNSSEC answer OK
  34. DO = 0x8000
  35. _by_text = {
  36. 'QR': QR,
  37. 'AA': AA,
  38. 'TC': TC,
  39. 'RD': RD,
  40. 'RA': RA,
  41. 'AD': AD,
  42. 'CD': CD
  43. }
  44. _edns_by_text = {
  45. 'DO': DO
  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. _by_value = {y: x for x, y in _by_text.items()}
  51. _edns_by_value = {y: x for x, y in _edns_by_text.items()}
  52. def _order_flags(table):
  53. order = list(table.items())
  54. order.sort()
  55. order.reverse()
  56. return order
  57. _flags_order = _order_flags(_by_value)
  58. _edns_flags_order = _order_flags(_edns_by_value)
  59. def _from_text(text, table):
  60. flags = 0
  61. tokens = text.split()
  62. for t in tokens:
  63. flags = flags | table[t.upper()]
  64. return flags
  65. def _to_text(flags, table, order):
  66. text_flags = []
  67. for k, v in order:
  68. if flags & k != 0:
  69. text_flags.append(v)
  70. return ' '.join(text_flags)
  71. def from_text(text):
  72. """Convert a space-separated list of flag text values into a flags
  73. value.
  74. Returns an ``int``
  75. """
  76. return _from_text(text, _by_text)
  77. def to_text(flags):
  78. """Convert a flags value into a space-separated list of flag text
  79. values.
  80. Returns a ``text``.
  81. """
  82. return _to_text(flags, _by_value, _flags_order)
  83. def edns_from_text(text):
  84. """Convert a space-separated list of EDNS flag text values into a EDNS
  85. flags value.
  86. Returns an ``int``
  87. """
  88. return _from_text(text, _edns_by_text)
  89. def edns_to_text(flags):
  90. """Convert an EDNS flags value into a space-separated list of EDNS flag
  91. text values.
  92. Returns a ``text``.
  93. """
  94. return _to_text(flags, _edns_by_value, _edns_flags_order)