codekingpro/portable-devtools
114k
1# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license2 3# Copyright (C) 2006-2017 Nominum, Inc.4#5# Permission to use, copy, modify, and distribute this software and its6# documentation for any purpose with or without fee is hereby granted,7# provided that the above copyright notice and this permission notice8# appear in all copies.9#10# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES11# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF12# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR13# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES14# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN15# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT16# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.17 18"""DNS Reverse Map Names."""19 20import binascii21 22import dns.ipv423import dns.ipv624import dns.name25 26ipv4_reverse_domain = dns.name.from_text("in-addr.arpa.")27ipv6_reverse_domain = dns.name.from_text("ip6.arpa.")28 29 30def from_address(31 text: str,32 v4_origin: dns.name.Name = ipv4_reverse_domain,33 v6_origin: dns.name.Name = ipv6_reverse_domain,34) -> dns.name.Name:35 """Convert an IPv4 or IPv6 address in textual form into a Name object whose36 value is the reverse-map domain name of the address.37 38 *text*, a ``str``, is an IPv4 or IPv6 address in textual form39 (e.g. '127.0.0.1', '::1')40 41 *v4_origin*, a ``dns.name.Name`` to append to the labels corresponding to42 the address if the address is an IPv4 address, instead of the default43 (in-addr.arpa.)44 45 *v6_origin*, a ``dns.name.Name`` to append to the labels corresponding to46 the address if the address is an IPv6 address, instead of the default47 (ip6.arpa.)48 49 Raises ``dns.exception.SyntaxError`` if the address is badly formed.50 51 Returns a ``dns.name.Name``.52 """53 54 try:55 v6 = dns.ipv6.inet_aton(text)56 if dns.ipv6.is_mapped(v6):57 parts = ["%d" % byte for byte in v6[12:]]58 origin = v4_origin59 else:60 parts = [x for x in str(binascii.hexlify(v6).decode())]61 origin = v6_origin62 except Exception:63 parts = ["%d" % byte for byte in dns.ipv4.inet_aton(text)]64 origin = v4_origin65 return dns.name.from_text(".".join(reversed(parts)), origin=origin)66 67 68def to_address(69 name: dns.name.Name,70 v4_origin: dns.name.Name = ipv4_reverse_domain,71 v6_origin: dns.name.Name = ipv6_reverse_domain,72) -> str:73 """Convert a reverse map domain name into textual address form.74 75 *name*, a ``dns.name.Name``, an IPv4 or IPv6 address in reverse-map name76 form.77 78 *v4_origin*, a ``dns.name.Name`` representing the top-level domain for79 IPv4 addresses, instead of the default (in-addr.arpa.)80 81 *v6_origin*, a ``dns.name.Name`` representing the top-level domain for82 IPv4 addresses, instead of the default (ip6.arpa.)83 84 Raises ``dns.exception.SyntaxError`` if the name does not have a85 reverse-map form.86 87 Returns a ``str``.88 """89 90 if name.is_subdomain(v4_origin):91 name = name.relativize(v4_origin)92 text = b".".join(reversed(name.labels))93 # run through inet_ntoa() to check syntax and make pretty.94 return dns.ipv4.inet_ntoa(dns.ipv4.inet_aton(text))95 elif name.is_subdomain(v6_origin):96 name = name.relativize(v6_origin)97 labels = list(reversed(name.labels))98 parts = []99 for i in range(0, len(labels), 4):100 parts.append(b"".join(labels[i : i + 4]))101 text = b":".join(parts)102 # run through inet_ntoa() to check syntax and make pretty.103 return dns.ipv6.inet_ntoa(dns.ipv6.inet_aton(text))104 else:105 raise dns.exception.SyntaxError("unknown reverse-map address family")106 