00001 """Classes to represent IP addresses. 00002 00003 Given some of the other operations we need to perform on them, it's 00004 most convenient to represent IP addresses as Python "long" values. 00005 The classes in this module just wrap suitable read/write syntax around 00006 the underlying "long" type. 00007 00008 These classes also supply a "bits" attribute for use by other code 00009 built on these classes; for the most part, IPv6 addresses really are 00010 just IPv4 addresses with more bits, so we supply the number of bits 00011 once, here, thus avoiding a lot of duplicate code elsewhere. 00012 00013 $Id: ipaddrs.py 1873 2008-06-12 02:49:41Z sra $ 00014 00015 Copyright (C) 2007--2008 American Registry for Internet Numbers ("ARIN") 00016 00017 Permission to use, copy, modify, and distribute this software for any 00018 purpose with or without fee is hereby granted, provided that the above 00019 copyright notice and this permission notice appear in all copies. 00020 00021 THE SOFTWARE IS PROVIDED "AS IS" AND ARIN DISCLAIMS ALL WARRANTIES WITH 00022 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 00023 AND FITNESS. IN NO EVENT SHALL ARIN BE LIABLE FOR ANY SPECIAL, DIRECT, 00024 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 00025 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 00026 OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00027 PERFORMANCE OF THIS SOFTWARE. 00028 """ 00029 00030 import socket, struct 00031 00032 class v4addr(long): 00033 """IPv4 address. 00034 00035 Derived from long, but supports IPv4 print syntax. 00036 """ 00037 00038 bits = 32 00039 00040 def __new__(cls, x): 00041 """Construct a v4addr object.""" 00042 if isinstance(x, str): 00043 x = ".".join(str(int(i)) for i in x.split(".")) 00044 y = struct.unpack("!I", socket.inet_pton(socket.AF_INET, x)) 00045 x = y[0] 00046 return long.__new__(cls, x) 00047 00048 def __str__(self): 00049 """Convert a v4addr object to string format.""" 00050 return socket.inet_ntop(socket.AF_INET, struct.pack("!I", long(self))) 00051 00052 class v6addr(long): 00053 """IPv6 address. 00054 00055 Derived from long, but supports IPv6 print syntax. 00056 """ 00057 00058 bits = 128 00059 00060 def __new__(cls, x): 00061 """Construct a v6addr object.""" 00062 if isinstance(x, str): 00063 y = struct.unpack("!QQ", socket.inet_pton(socket.AF_INET6, x)) 00064 x = (y[0] << 64) | y[1] 00065 return long.__new__(cls, x) 00066 00067 def __str__(self): 00068 """Convert a v6addr object to string format.""" 00069 return socket.inet_ntop(socket.AF_INET6, 00070 struct.pack("!QQ", long(self) >> 64, long(self) & 0xFFFFFFFFFFFFFFFF))