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.

124 lines
3.3 KiB

4 years ago
  1. # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
  2. # Copyright (C) 2003-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. """Generic Internet address helper functions."""
  17. import socket
  18. import dns.ipv4
  19. import dns.ipv6
  20. from ._compat import maybe_ord
  21. # We assume that AF_INET is always defined.
  22. AF_INET = socket.AF_INET
  23. # AF_INET6 might not be defined in the socket module, but we need it.
  24. # We'll try to use the socket module's value, and if it doesn't work,
  25. # we'll use our own value.
  26. try:
  27. AF_INET6 = socket.AF_INET6
  28. except AttributeError:
  29. AF_INET6 = 9999
  30. def inet_pton(family, text):
  31. """Convert the textual form of a network address into its binary form.
  32. *family* is an ``int``, the address family.
  33. *text* is a ``text``, the textual address.
  34. Raises ``NotImplementedError`` if the address family specified is not
  35. implemented.
  36. Returns a ``binary``.
  37. """
  38. if family == AF_INET:
  39. return dns.ipv4.inet_aton(text)
  40. elif family == AF_INET6:
  41. return dns.ipv6.inet_aton(text)
  42. else:
  43. raise NotImplementedError
  44. def inet_ntop(family, address):
  45. """Convert the binary form of a network address into its textual form.
  46. *family* is an ``int``, the address family.
  47. *address* is a ``binary``, the network address in binary form.
  48. Raises ``NotImplementedError`` if the address family specified is not
  49. implemented.
  50. Returns a ``text``.
  51. """
  52. if family == AF_INET:
  53. return dns.ipv4.inet_ntoa(address)
  54. elif family == AF_INET6:
  55. return dns.ipv6.inet_ntoa(address)
  56. else:
  57. raise NotImplementedError
  58. def af_for_address(text):
  59. """Determine the address family of a textual-form network address.
  60. *text*, a ``text``, the textual address.
  61. Raises ``ValueError`` if the address family cannot be determined
  62. from the input.
  63. Returns an ``int``.
  64. """
  65. try:
  66. dns.ipv4.inet_aton(text)
  67. return AF_INET
  68. except Exception:
  69. try:
  70. dns.ipv6.inet_aton(text)
  71. return AF_INET6
  72. except:
  73. raise ValueError
  74. def is_multicast(text):
  75. """Is the textual-form network address a multicast address?
  76. *text*, a ``text``, the textual address.
  77. Raises ``ValueError`` if the address family cannot be determined
  78. from the input.
  79. Returns a ``bool``.
  80. """
  81. try:
  82. first = maybe_ord(dns.ipv4.inet_aton(text)[0])
  83. return first >= 224 and first <= 239
  84. except Exception:
  85. try:
  86. first = maybe_ord(dns.ipv6.inet_aton(text)[0])
  87. return first == 255
  88. except Exception:
  89. raise ValueError