Source code for constants

"""
The constants module defines the various DNS constants, and also
provides some utility functions for dealing with these.
"""

import enum


# The DNS QR header flag can be either 0 (query) or 1 (response).
[docs]@enum.unique class QR(enum.IntEnum): """ Enumerates the possible QR bit values. """ QUERY = 0 #: QR flag for queries RESPONSE = 1 #: QR flag for responses
# Possible DNS operation code values are listed on the IANA DNS # parameters page: # https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-5
[docs]@enum.unique class OpCode(enum.IntEnum): """ Enumerates the defined DNS operation codes. """ QUERY = 0 #: OpCode for queries IQUERY = 1 #: OpCode for inverse queries STATUS = 2 #: OpCode for status queries # 3 is unassigned NOTIFY = 4 #: OpCode for NOTIFY messages UPDATE = 5 #: OpCode for UPDATE messages DSO = 6 #: OpCode for DNS Stateful Operation (DSO) messages
# Possible DNS result code values are listed on the IANA DNS # parameters page: # https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-6 # # Note that we do not include the extended RCODE values here, which # are returned in the EDNS OPT record, if present. # # We define two versions of each number, starting with the mixed # capitalization used on the IANA page. This is so that the name # attribute provided returns the IANA version: # # >>> foo = RCODE(2) # >>> foo.name # 'ServFail' # >>> bar = RCODE.SERVFAIL # >>> bar.name # 'ServFail' # >>> bar == foo # True # >>> baz = RCODE['SERVFAIL'] # >>> baz # <RCODE.ServFail: 2>
[docs]class RCODE(enum.IntEnum): """ Enumerates the defined DNS response codes. """ # pylint: disable=invalid-name NoError = 0 #: No Error RCODE NOERROR = NoError FormErr = 1 #: Format Error RCODE FORMERR = FormErr ServFail = 2 #: Server Failure RCODE SERVFAIL = ServFail NXDomain = 3 #: Non-Existent Domain RCODE NXDOMAIN = NXDomain NotImp = 4 #: Not Implemented RCODE NOTIMP = NotImp Refused = 5 #: Query Refused RCODE REFUSED = Refused YXDomain = 6 #: Name Exists when it should not RCODE YXDOMAIN = YXDomain YXRRSet = 7 #: RR Set Exists when it should not RCODE YXRRSET = YXRRSet NXRRSet = 8 #: RR Set that should exist does not RCODE NXRRSET = NXRRSet NotAuth = 9 #: Server Not Authoritative for zone / Not Authorized RCODE NOTAUTH = NotAuth NotZone = 10 #: Name not contained in zone RCODE NOTZONE = NotZone DSOTYPENI = 11 #: DSO-TYPE Not Implemented RCODE
# Resource record (RR) types are documented on the IANA DNS parameters # page: # https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4
[docs]@enum.unique class Type(enum.IntEnum): """ Enumerates the defined DNS types. """ A = 1 #: a host address RTYPE NS = 2 #: an authoritative name server RTYPE MD = 3 #: a mail destination RTYPE MF = 4 #: a mail forwarder RTYPE CNAME = 5 #: the canonical name for an alias RTYPE SOA = 6 #: marks the start of a zone of authority RTYPE MB = 7 #: a mailbox domain name RTYPE MG = 8 #: a mail group member RTYPE MR = 9 #: a mail rename domain name RTYPE NULL = 10 #: a null RR RTYPE WKS = 11 #: a well known service description RTYPE PTR = 12 #: a domain name pointer RTYPE HINFO = 13 #: host information RTYPE MINFO = 14 #: mailbox or mail list information RTYPE MX = 15 #: mail exchange RTYPE TXT = 16 #: text strings RTYPE RP = 17 #: for Responsible Person RTYPE AFSDB = 18 #: for AFS Data Base location RTYPE X25 = 19 #: for X.25 PSDN address RTYPE ISDN = 20 #: for ISDN address RTYPE RT = 21 #: for Route Through RTYPE NSAP = 22 #: for NSAP address, NSAP style A record RTYPE NSAP_PTR = 23 #: for domain name pointer, NSAP style RTYPE SIG = 24 #: for security signature RTYPE KEY = 25 #: for security key RTYPE PX = 26 #: X.400 mail mapping information RTYPE GPOS = 27 #: Geographical Position RTYPE AAAA = 28 #: IP6 Address RTYPE OPT = 41 #: OPT RTYPE RRSIG = 46 #: RRSIG RTYPE TSIG = 250 #: Transaction Signature IXFR = 251 #: incremental transfer AXFR = 252 #: transfer of an entire zone ANY = 255
#: A request for some or all record the server has available RTYPE
[docs]def type_name(dns_type: int) -> str: """ Converts a numeric type value to a name. This is the symbolic name if we know it (like `NS` or `AAAA`), otherwise the `RFC 3597 <https://tools.ietf.org/html/rfc3597>`_ version (`TYPE####`). Numbers out of range raise a :py:class:`ValueError` exception. :param dns_type: Numeric value of a DNS type to convert to string. :type dns_type: str :return: String version of the type identifier. :rtype: str :raises: :py:class:`ValueError` if `dns_type` is not an unsigned 16-bit value. """ # Special case NSAP-PTR, since the '-' is not allowed in Python # variable names. if dns_type == Type.NSAP_PTR: return "NSAP-PTR" # For other defined types return the enum type name. try: return Type(dns_type).name except ValueError: if 0 <= dns_type <= 65535: return f"TYPE{dns_type}" msg = f"DNS type not between 0 and 65535: {dns_type}" raise ValueError(msg) from None
# DNS classes are documented on the IANA DNS parameters page: # https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-2
[docs]@enum.unique class Class(enum.IntEnum): """ Enumerates the defined DNS classes. """ IN = 1 #: Internet class # 2 is unassigned CH = 3 #: Chaos class HS = 4 #: Hesiod class NONE = 254 #: "NONE" class ANY = 255 #: "ANY" class
[docs]def class_name(dns_class: int) -> str: """ Converts a numeric class value to a name. This is the symbolic name if we know it (like `IN` or `CH`), otherwise the `RFC 3597 <https://tools.ietf.org/html/rfc3597>`_ version (`CLASS####`). Numbers out of range raise a :py:class:`ValueError` exception. :param dns_class: Numeric value of a DNS class to convert to string. :type dns_class: str :return: String version of the class identifier. :rtype: str :raises: :py:class:`ValueError` if `dns_class` is not an unsigned 16-bit value. """ try: return Class(dns_class).name except ValueError: if 0 <= dns_class <= 65535: return f"CLASS{dns_class}" msg = f"DNS class not between 0 and 65535: {dns_class}" raise ValueError(msg) from None