| 1 | # Copyright (C) 2003-2007, 2009, 2010 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 |
|
|---|
| 16 | """Generic Internet address helper functions."""
|
|---|
| 17 |
|
|---|
| 18 | import socket
|
|---|
| 19 |
|
|---|
| 20 | import dns.ipv4
|
|---|
| 21 | import dns.ipv6
|
|---|
| 22 |
|
|---|
| 23 |
|
|---|
| 24 | # We assume that AF_INET is always defined.
|
|---|
| 25 |
|
|---|
| 26 | AF_INET = socket.AF_INET
|
|---|
| 27 |
|
|---|
| 28 | # AF_INET6 might not be defined in the socket module, but we need it.
|
|---|
| 29 | # We'll try to use the socket module's value, and if it doesn't work,
|
|---|
| 30 | # we'll use our own value.
|
|---|
| 31 |
|
|---|
| 32 | try:
|
|---|
| 33 | AF_INET6 = socket.AF_INET6
|
|---|
| 34 | except AttributeError:
|
|---|
| 35 | AF_INET6 = 9999
|
|---|
| 36 |
|
|---|
| 37 | def inet_pton(family, text):
|
|---|
| 38 | """Convert the textual form of a network address into its binary form.
|
|---|
| 39 |
|
|---|
| 40 | @param family: the address family
|
|---|
| 41 | @type family: int
|
|---|
| 42 | @param text: the textual address
|
|---|
| 43 | @type text: string
|
|---|
| 44 | @raises NotImplementedError: the address family specified is not
|
|---|
| 45 | implemented.
|
|---|
| 46 | @rtype: string
|
|---|
| 47 | """
|
|---|
| 48 |
|
|---|
| 49 | if family == AF_INET:
|
|---|
| 50 | return dns.ipv4.inet_aton(text)
|
|---|
| 51 | elif family == AF_INET6:
|
|---|
| 52 | return dns.ipv6.inet_aton(text)
|
|---|
| 53 | else:
|
|---|
| 54 | raise NotImplementedError
|
|---|
| 55 |
|
|---|
| 56 | def inet_ntop(family, address):
|
|---|
| 57 | """Convert the binary form of a network address into its textual form.
|
|---|
| 58 |
|
|---|
| 59 | @param family: the address family
|
|---|
| 60 | @type family: int
|
|---|
| 61 | @param address: the binary address
|
|---|
| 62 | @type address: string
|
|---|
| 63 | @raises NotImplementedError: the address family specified is not
|
|---|
| 64 | implemented.
|
|---|
| 65 | @rtype: string
|
|---|
| 66 | """
|
|---|
| 67 | if family == AF_INET:
|
|---|
| 68 | return dns.ipv4.inet_ntoa(address)
|
|---|
| 69 | elif family == AF_INET6:
|
|---|
| 70 | return dns.ipv6.inet_ntoa(address)
|
|---|
| 71 | else:
|
|---|
| 72 | raise NotImplementedError
|
|---|
| 73 |
|
|---|
| 74 | def af_for_address(text):
|
|---|
| 75 | """Determine the address family of a textual-form network address.
|
|---|
| 76 |
|
|---|
| 77 | @param text: the textual address
|
|---|
| 78 | @type text: string
|
|---|
| 79 | @raises ValueError: the address family cannot be determined from the input.
|
|---|
| 80 | @rtype: int
|
|---|
| 81 | """
|
|---|
| 82 | try:
|
|---|
| 83 | junk = dns.ipv4.inet_aton(text)
|
|---|
| 84 | return AF_INET
|
|---|
| 85 | except:
|
|---|
| 86 | try:
|
|---|
| 87 | junk = dns.ipv6.inet_aton(text)
|
|---|
| 88 | return AF_INET6
|
|---|
| 89 | except:
|
|---|
| 90 | raise ValueError
|
|---|
| 91 |
|
|---|
| 92 | def is_multicast(text):
|
|---|
| 93 | """Is the textual-form network address a multicast address?
|
|---|
| 94 |
|
|---|
| 95 | @param text: the textual address
|
|---|
| 96 | @raises ValueError: the address family cannot be determined from the input.
|
|---|
| 97 | @rtype: bool
|
|---|
| 98 | """
|
|---|
| 99 | try:
|
|---|
| 100 | first = ord(dns.ipv4.inet_aton(text)[0])
|
|---|
| 101 | return (first >= 224 and first <= 239)
|
|---|
| 102 | except:
|
|---|
| 103 | try:
|
|---|
| 104 | first = ord(dns.ipv6.inet_aton(text)[0])
|
|---|
| 105 | return (first == 255)
|
|---|
| 106 | except:
|
|---|
| 107 | raise ValueError
|
|---|
| 108 |
|
|---|