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 18import socket 19 20import dns.ipv4 21import dns.ipv6 22 23 24# We assume that AF_INET is always defined. 25 26AF_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 32try: 33 AF_INET6 = socket.AF_INET6 34except AttributeError: 35 AF_INET6 = 9999 36 37def 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 56def 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 74def 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 92def 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 109