inet.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc.
  2. #
  3. # Permission to use, copy, modify, and distribute this software and its
  4. # documentation for any purpose with or without fee is hereby granted,
  5. # provided that the above copyright notice and this permission notice
  6. # appear in all copies.
  7. #
  8. # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
  9. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
  11. # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12. # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13. # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  14. # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15. """Generic Internet address helper functions."""
  16. import socket
  17. import dns.ipv4
  18. import dns.ipv6
  19. # We assume that AF_INET is always defined.
  20. AF_INET = socket.AF_INET
  21. # AF_INET6 might not be defined in the socket module, but we need it.
  22. # We'll try to use the socket module's value, and if it doesn't work,
  23. # we'll use our own value.
  24. try:
  25. AF_INET6 = socket.AF_INET6
  26. except AttributeError:
  27. AF_INET6 = 9999
  28. def inet_pton(family, text):
  29. """Convert the textual form of a network address into its binary form.
  30. @param family: the address family
  31. @type family: int
  32. @param text: the textual address
  33. @type text: string
  34. @raises NotImplementedError: the address family specified is not
  35. implemented.
  36. @rtype: string
  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. @param family: the address family
  47. @type family: int
  48. @param address: the binary address
  49. @type address: string
  50. @raises NotImplementedError: the address family specified is not
  51. implemented.
  52. @rtype: string
  53. """
  54. if family == AF_INET:
  55. return dns.ipv4.inet_ntoa(address)
  56. elif family == AF_INET6:
  57. return dns.ipv6.inet_ntoa(address)
  58. else:
  59. raise NotImplementedError
  60. def af_for_address(text):
  61. """Determine the address family of a textual-form network address.
  62. @param text: the textual address
  63. @type text: string
  64. @raises ValueError: the address family cannot be determined from the input.
  65. @rtype: int
  66. """
  67. try:
  68. dns.ipv4.inet_aton(text)
  69. return AF_INET
  70. except Exception:
  71. try:
  72. dns.ipv6.inet_aton(text)
  73. return AF_INET6
  74. except:
  75. raise ValueError
  76. def is_multicast(text):
  77. """Is the textual-form network address a multicast address?
  78. @param text: the textual address
  79. @raises ValueError: the address family cannot be determined from the input.
  80. @rtype: bool
  81. """
  82. try:
  83. first = ord(dns.ipv4.inet_aton(text)[0])
  84. return first >= 224 and first <= 239
  85. except Exception:
  86. try:
  87. first = ord(dns.ipv6.inet_aton(text)[0])
  88. return first == 255
  89. except Exception:
  90. raise ValueError