about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/dns/inet.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/dns/inet.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-4a52a71956a8d46fcb7294ac71734504bb09bcc2.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/dns/inet.py')
-rw-r--r--.venv/lib/python3.12/site-packages/dns/inet.py197
1 files changed, 197 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/dns/inet.py b/.venv/lib/python3.12/site-packages/dns/inet.py
new file mode 100644
index 00000000..4a03f996
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/inet.py
@@ -0,0 +1,197 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2017 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""Generic Internet address helper functions."""
+
+import socket
+from typing import Any, Optional, Tuple
+
+import dns.ipv4
+import dns.ipv6
+
+# We assume that AF_INET and AF_INET6 are always defined.  We keep
+# these here for the benefit of any old code (unlikely though that
+# is!).
+AF_INET = socket.AF_INET
+AF_INET6 = socket.AF_INET6
+
+
+def inet_pton(family: int, text: str) -> bytes:
+    """Convert the textual form of a network address into its binary form.
+
+    *family* is an ``int``, the address family.
+
+    *text* is a ``str``, the textual address.
+
+    Raises ``NotImplementedError`` if the address family specified is not
+    implemented.
+
+    Returns a ``bytes``.
+    """
+
+    if family == AF_INET:
+        return dns.ipv4.inet_aton(text)
+    elif family == AF_INET6:
+        return dns.ipv6.inet_aton(text, True)
+    else:
+        raise NotImplementedError
+
+
+def inet_ntop(family: int, address: bytes) -> str:
+    """Convert the binary form of a network address into its textual form.
+
+    *family* is an ``int``, the address family.
+
+    *address* is a ``bytes``, the network address in binary form.
+
+    Raises ``NotImplementedError`` if the address family specified is not
+    implemented.
+
+    Returns a ``str``.
+    """
+
+    if family == AF_INET:
+        return dns.ipv4.inet_ntoa(address)
+    elif family == AF_INET6:
+        return dns.ipv6.inet_ntoa(address)
+    else:
+        raise NotImplementedError
+
+
+def af_for_address(text: str) -> int:
+    """Determine the address family of a textual-form network address.
+
+    *text*, a ``str``, the textual address.
+
+    Raises ``ValueError`` if the address family cannot be determined
+    from the input.
+
+    Returns an ``int``.
+    """
+
+    try:
+        dns.ipv4.inet_aton(text)
+        return AF_INET
+    except Exception:
+        try:
+            dns.ipv6.inet_aton(text, True)
+            return AF_INET6
+        except Exception:
+            raise ValueError
+
+
+def is_multicast(text: str) -> bool:
+    """Is the textual-form network address a multicast address?
+
+    *text*, a ``str``, the textual address.
+
+    Raises ``ValueError`` if the address family cannot be determined
+    from the input.
+
+    Returns a ``bool``.
+    """
+
+    try:
+        first = dns.ipv4.inet_aton(text)[0]
+        return first >= 224 and first <= 239
+    except Exception:
+        try:
+            first = dns.ipv6.inet_aton(text, True)[0]
+            return first == 255
+        except Exception:
+            raise ValueError
+
+
+def is_address(text: str) -> bool:
+    """Is the specified string an IPv4 or IPv6 address?
+
+    *text*, a ``str``, the textual address.
+
+    Returns a ``bool``.
+    """
+
+    try:
+        dns.ipv4.inet_aton(text)
+        return True
+    except Exception:
+        try:
+            dns.ipv6.inet_aton(text, True)
+            return True
+        except Exception:
+            return False
+
+
+def low_level_address_tuple(
+    high_tuple: Tuple[str, int], af: Optional[int] = None
+) -> Any:
+    """Given a "high-level" address tuple, i.e.
+    an (address, port) return the appropriate "low-level" address tuple
+    suitable for use in socket calls.
+
+    If an *af* other than ``None`` is provided, it is assumed the
+    address in the high-level tuple is valid and has that af.  If af
+    is ``None``, then af_for_address will be called.
+    """
+    address, port = high_tuple
+    if af is None:
+        af = af_for_address(address)
+    if af == AF_INET:
+        return (address, port)
+    elif af == AF_INET6:
+        i = address.find("%")
+        if i < 0:
+            # no scope, shortcut!
+            return (address, port, 0, 0)
+        # try to avoid getaddrinfo()
+        addrpart = address[:i]
+        scope = address[i + 1 :]
+        if scope.isdigit():
+            return (addrpart, port, 0, int(scope))
+        try:
+            return (addrpart, port, 0, socket.if_nametoindex(scope))
+        except AttributeError:  # pragma: no cover  (we can't really test this)
+            ai_flags = socket.AI_NUMERICHOST
+            ((*_, tup), *_) = socket.getaddrinfo(address, port, flags=ai_flags)
+            return tup
+    else:
+        raise NotImplementedError(f"unknown address family {af}")
+
+
+def any_for_af(af):
+    """Return the 'any' address for the specified address family."""
+    if af == socket.AF_INET:
+        return "0.0.0.0"
+    elif af == socket.AF_INET6:
+        return "::"
+    raise NotImplementedError(f"unknown address family {af}")
+
+
+def canonicalize(text: str) -> str:
+    """Verify that *address* is a valid text form IPv4 or IPv6 address and return its
+    canonical text form.  IPv6 addresses with scopes are rejected.
+
+    *text*, a ``str``, the address in textual form.
+
+    Raises ``ValueError`` if the text is not valid.
+    """
+    try:
+        return dns.ipv6.canonicalize(text)
+    except Exception:
+        try:
+            return dns.ipv4.canonicalize(text)
+        except Exception:
+            raise ValueError