rcode.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  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 Result Codes."""
  17. from typing import Tuple
  18. import dns.enum
  19. import dns.exception
  20. class Rcode(dns.enum.IntEnum):
  21. #: No error
  22. NOERROR = 0
  23. #: Format error
  24. FORMERR = 1
  25. #: Server failure
  26. SERVFAIL = 2
  27. #: Name does not exist ("Name Error" in RFC 1025 terminology).
  28. NXDOMAIN = 3
  29. #: Not implemented
  30. NOTIMP = 4
  31. #: Refused
  32. REFUSED = 5
  33. #: Name exists.
  34. YXDOMAIN = 6
  35. #: RRset exists.
  36. YXRRSET = 7
  37. #: RRset does not exist.
  38. NXRRSET = 8
  39. #: Not authoritative.
  40. NOTAUTH = 9
  41. #: Name not in zone.
  42. NOTZONE = 10
  43. #: DSO-TYPE Not Implemented
  44. DSOTYPENI = 11
  45. #: Bad EDNS version.
  46. BADVERS = 16
  47. #: TSIG Signature Failure
  48. BADSIG = 16
  49. #: Key not recognized.
  50. BADKEY = 17
  51. #: Signature out of time window.
  52. BADTIME = 18
  53. #: Bad TKEY Mode.
  54. BADMODE = 19
  55. #: Duplicate key name.
  56. BADNAME = 20
  57. #: Algorithm not supported.
  58. BADALG = 21
  59. #: Bad Truncation
  60. BADTRUNC = 22
  61. #: Bad/missing Server Cookie
  62. BADCOOKIE = 23
  63. @classmethod
  64. def _maximum(cls):
  65. return 4095
  66. @classmethod
  67. def _unknown_exception_class(cls):
  68. return UnknownRcode
  69. class UnknownRcode(dns.exception.DNSException):
  70. """A DNS rcode is unknown."""
  71. def from_text(text: str) -> Rcode:
  72. """Convert text into an rcode.
  73. *text*, a ``str``, the textual rcode or an integer in textual form.
  74. Raises ``dns.rcode.UnknownRcode`` if the rcode mnemonic is unknown.
  75. Returns a ``dns.rcode.Rcode``.
  76. """
  77. return Rcode.from_text(text)
  78. def from_flags(flags: int, ednsflags: int) -> Rcode:
  79. """Return the rcode value encoded by flags and ednsflags.
  80. *flags*, an ``int``, the DNS flags field.
  81. *ednsflags*, an ``int``, the EDNS flags field.
  82. Raises ``ValueError`` if rcode is < 0 or > 4095
  83. Returns a ``dns.rcode.Rcode``.
  84. """
  85. value = (flags & 0x000F) | ((ednsflags >> 20) & 0xFF0)
  86. return Rcode.make(value)
  87. def to_flags(value: Rcode) -> Tuple[int, int]:
  88. """Return a (flags, ednsflags) tuple which encodes the rcode.
  89. *value*, a ``dns.rcode.Rcode``, the rcode.
  90. Raises ``ValueError`` if rcode is < 0 or > 4095.
  91. Returns an ``(int, int)`` tuple.
  92. """
  93. if value < 0 or value > 4095:
  94. raise ValueError("rcode must be >= 0 and <= 4095")
  95. v = value & 0xF
  96. ev = (value & 0xFF0) << 20
  97. return (v, ev)
  98. def to_text(value: Rcode, tsig: bool = False) -> str:
  99. """Convert rcode into text.
  100. *value*, a ``dns.rcode.Rcode``, the rcode.
  101. Raises ``ValueError`` if rcode is < 0 or > 4095.
  102. Returns a ``str``.
  103. """
  104. if tsig and value == Rcode.BADVERS:
  105. return "BADSIG"
  106. return Rcode.to_text(value)
  107. ### BEGIN generated Rcode constants
  108. NOERROR = Rcode.NOERROR
  109. FORMERR = Rcode.FORMERR
  110. SERVFAIL = Rcode.SERVFAIL
  111. NXDOMAIN = Rcode.NXDOMAIN
  112. NOTIMP = Rcode.NOTIMP
  113. REFUSED = Rcode.REFUSED
  114. YXDOMAIN = Rcode.YXDOMAIN
  115. YXRRSET = Rcode.YXRRSET
  116. NXRRSET = Rcode.NXRRSET
  117. NOTAUTH = Rcode.NOTAUTH
  118. NOTZONE = Rcode.NOTZONE
  119. DSOTYPENI = Rcode.DSOTYPENI
  120. BADVERS = Rcode.BADVERS
  121. BADSIG = Rcode.BADSIG
  122. BADKEY = Rcode.BADKEY
  123. BADTIME = Rcode.BADTIME
  124. BADMODE = Rcode.BADMODE
  125. BADNAME = Rcode.BADNAME
  126. BADALG = Rcode.BADALG
  127. BADTRUNC = Rcode.BADTRUNC
  128. BADCOOKIE = Rcode.BADCOOKIE
  129. ### END generated Rcode constants