Skip to content
Snippets Groups Projects
Commit f2c2996e authored by Yas Naoi's avatar Yas Naoi
Browse files

Release 6.x-1.x-dev (2011/06/10)

Change-Id: I036ba059b9beb91647dc4baae1166b763104f454
parent a9b0ccdf
No related branches found
No related tags found
No related merge requests found
<?php
/**
* Class to provide IPv4 calculations
*
* PHP versions 4 and 5
*
* LICENSE: This source file is subject to version 3.01 of the PHP license
* that is available through the world-wide-web at the following URI:
* http://www.php.net/license/3_01.txt. If you did not receive a copy of
* the PHP License and are unable to obtain it through the web, please
* send a note to license@php.net so we can mail you a copy immediately.
*
* @category Net
* @package Net_IPv4
* @author Eric Kilfoil <edk@ypass.net>
* @author Marco Kaiser <bate@php.net>
* @author Florian Anderiasch <fa@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: $Id: IPv4.php 288425 2009-09-18 02:05:39Z clockwerx $
* @link http://pear.php.net/package/Net_IPv4
*/
//require_once 'PEAR.php';
// {{{ GLOBALS
/**
* Map of bitmasks to subnets
*
* This array contains every valid netmask. The index of the dot quad
* netmask value is the corresponding CIDR notation (bitmask).
*
* @global array $GLOBALS['Net_IPv4_Netmask_Map']
*/
$GLOBALS['Net_IPv4_Netmask_Map'] = array(
0 => "0.0.0.0",
1 => "128.0.0.0",
2 => "192.0.0.0",
3 => "224.0.0.0",
4 => "240.0.0.0",
5 => "248.0.0.0",
6 => "252.0.0.0",
7 => "254.0.0.0",
8 => "255.0.0.0",
9 => "255.128.0.0",
10 => "255.192.0.0",
11 => "255.224.0.0",
12 => "255.240.0.0",
13 => "255.248.0.0",
14 => "255.252.0.0",
15 => "255.254.0.0",
16 => "255.255.0.0",
17 => "255.255.128.0",
18 => "255.255.192.0",
19 => "255.255.224.0",
20 => "255.255.240.0",
21 => "255.255.248.0",
22 => "255.255.252.0",
23 => "255.255.254.0",
24 => "255.255.255.0",
25 => "255.255.255.128",
26 => "255.255.255.192",
27 => "255.255.255.224",
28 => "255.255.255.240",
29 => "255.255.255.248",
30 => "255.255.255.252",
31 => "255.255.255.254",
32 => "255.255.255.255"
);
// }}}
// {{{ Net_IPv4
/**
* Class to provide IPv4 calculations
*
* Provides methods for validating IP addresses, calculating netmasks,
* broadcast addresses, network addresses, conversion routines, etc.
*
* @category Net
* @package Net_IPv4
* @author Eric Kilfoil <edk@ypass.net>
* @author Marco Kaiser <bate@php.net>
* @author Florian Anderiasch <fa@php.net>
* @copyright 1997-2005 The PHP Group
* @license http://www.php.net/license/3_01.txt PHP License 3.01
* @version CVS: @package_version@
* @link http://pear.php.net/package/Net_IPv4
* @access public
*/
class Net_IPv4
{
// {{{ properties
var $ip = "";
var $bitmask = false;
var $netmask = "";
var $network = "";
var $broadcast = "";
var $long = 0;
// }}}
// {{{ validateIP()
/**
* Validate the syntax of the given IP adress
*
* Using the PHP long2ip() and ip2long() functions, convert the IP
* address from a string to a long and back. If the original still
* matches the converted IP address, it's a valid address. This
* function does not allow for IP addresses to be formatted as long
* integers.
*
* @param string $ip IP address in the format x.x.x.x
* @return bool true if syntax is valid, otherwise false
*/
function validateIP($ip)
{
if ($ip == long2ip(ip2long($ip))) {
return true;
}
else {
return false;
}
}
// }}}
// {{{ check_ip()
/**
* Validate the syntax of the given IP address (compatibility)
*
* This function is identical to Net_IPv4::validateIP(). It is included
* merely for compatibility reasons.
*
* @param string $ip IP address
* @return bool true if syntax is valid, otherwise false
*/
function check_ip($ip)
{
return $this->validateIP($ip);
}
// }}}
// {{{ validateNetmask()
/**
* Validate the syntax of a four octet netmask
*
* There are 33 valid netmask values. This function will compare the
* string passed as $netmask to the predefined 33 values and return
* true or false. This is most likely much faster than performing the
* calculation to determine the validity of the netmask.
*
* @param string $netmask Netmask
* @return bool true if syntax is valid, otherwise false
*/
function validateNetmask($netmask)
{
if (! in_array($netmask, $GLOBALS['Net_IPv4_Netmask_Map'])) {
return false;
}
return true;
}
// }}}
// {{{ parseAddress()
/**
* Parse a formatted IP address
*
* Given a network qualified IP address, attempt to parse out the parts
* and calculate qualities of the address.
*
* The following formats are possible:
*
* [dot quad ip]/[ bitmask ]
* [dot quad ip]/[ dot quad netmask ]
* [dot quad ip]/[ hex string netmask ]
*
* The first would be [IP Address]/[BitMask]:
* 192.168.0.0/16
*
* The second would be [IP Address] [Subnet Mask in dot quad notation]:
* 192.168.0.0/255.255.0.0
*
* The third would be [IP Address] [Subnet Mask as Hex string]
* 192.168.0.0/ffff0000
*
* Usage:
*
* $cidr = '192.168.0.50/16';
* $net = Net_IPv4::parseAddress($cidr);
* echo $net->network; // 192.168.0.0
* echo $net->ip; // 192.168.0.50
* echo $net->broadcast; // 192.168.255.255
* echo $net->bitmask; // 16
* echo $net->long; // 3232235520 (long/double version of 192.168.0.50)
* echo $net->netmask; // 255.255.0.0
*
* @param string $ip IP address netmask combination
* @return object true if syntax is valid, otherwise false
*/
function parseAddress($address)
{
$myself = new Net_IPv4;
if (strchr($address, "/")) {
$parts = explode("/", $address);
if (! $myself->validateIP($parts[0])) {
return PEAR::raiseError("invalid IP address");
}
$myself->ip = $parts[0];
// Check the style of netmask that was entered
/*
* a hexadecimal string was entered
*/
if (eregi("^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$", $parts[1], $regs)) {
// hexadecimal string
$myself->netmask = hexdec($regs[1]) . "." . hexdec($regs[2]) . "." .
hexdec($regs[3]) . "." . hexdec($regs[4]);
/*
* a standard dot quad netmask was entered.
*/
} else if (strchr($parts[1], ".")) {
if (! $myself->validateNetmask($parts[1])) {
return PEAR::raiseError("invalid netmask value");
}
$myself->netmask = $parts[1];
/*
* a CIDR bitmask type was entered
*/
} else if (ctype_digit($parts[1]) && $parts[1] >= 0 && $parts[1] <= 32) {
// bitmask was entered
$myself->bitmask = $parts[1];
/*
* Some unknown format of netmask was entered
*/
}
else {
return PEAR::raiseError("invalid netmask value");
}
$myself->calculate();
return $myself;
} else if ($myself->validateIP($address)) {
$myself->ip = $address;
return $myself;
}
else {
return PEAR::raiseError("invalid IP address");
}
}
// }}}
// {{{ calculate()
/**
* Calculates network information based on an IP address and netmask.
*
* Fully populates the object properties based on the IP address and
* netmask/bitmask properties. Once these two fields are populated,
* calculate() will perform calculations to determine the network and
* broadcast address of the network.
*
* @return mixed true if no errors occured, otherwise PEAR_Error object
*/
function calculate()
{
$validNM = $GLOBALS['Net_IPv4_Netmask_Map'];
if (! is_a($this, "net_ipv4")) {
$myself = new Net_IPv4;
return PEAR::raiseError("cannot calculate on uninstantiated Net_IPv4 class");
}
/* Find out if we were given an ip address in dot quad notation or
* a network long ip address. Whichever was given, populate the
* other field
*/
if (strlen($this->ip)) {
if (! $this->validateIP($this->ip)) {
return PEAR::raiseError("invalid IP address");
}
$this->long = $this->ip2double($this->ip);
} else if (is_numeric($this->long)) {
$this->ip = long2ip($this->long);
}
else {
return PEAR::raiseError("ip address not specified");
}
/*
* Check to see if we were supplied with a bitmask or a netmask.
* Populate the other field as needed.
*/
if (strlen($this->bitmask)) {
$this->netmask = $validNM[$this->bitmask];
} else if (strlen($this->netmask)) {
$validNM_rev = array_flip($validNM);
$this->bitmask = $validNM_rev[$this->netmask];
}
else {
return PEAR::raiseError("netmask or bitmask are required for calculation");
}
$this->network = long2ip(ip2long($this->ip) & ip2long($this->netmask));
$this->broadcast = long2ip(ip2long($this->ip) |
(ip2long($this->netmask) ^ ip2long("255.255.255.255")));
return true;
}
// }}}
// {{{ getNetmask()
function getNetmask($length)
{
if (! PEAR::isError($ipobj = Net_IPv4::parseAddress("0.0.0.0/" . $length))) {
$mask = $ipobj->netmask;
unset($ipobj);
return $mask;
}
return false;
}
// }}}
// {{{ getNetLength()
function getNetLength($netmask)
{
if (! PEAR::isError($ipobj = Net_IPv4::parseAddress("0.0.0.0/" . $netmask))) {
$bitmask = $ipobj->bitmask;
unset($ipobj);
return $bitmask;
}
return false;
}
// }}}
// {{{ getSubnet()
function getSubnet($ip, $netmask)
{
if (! PEAR::isError($ipobj = Net_IPv4::parseAddress($ip . "/" . $netmask))) {
$net = $ipobj->network;
unset($ipobj);
return $net;
}
return false;
}
// }}}
// {{{ inSameSubnet()
function inSameSubnet($ip1, $ip2)
{
if (! is_object($ip1) || strcasecmp(get_class($ip1), 'net_ipv4') <> 0) {
$ipobj1 = Net_IPv4::parseAddress($ip1);
if (PEAR::isError($ipobj)) {
return PEAR::raiseError("IP addresses must be an understood format or a Net_IPv4 object");
}
}
if (! is_object($ip2) || strcasecmp(get_class($ip2), 'net_ipv4') <> 0) {
$ipobj2 = Net_IPv4::parseAddress($ip2);
if (PEAR::isError($ipobj)) {
return PEAR::raiseError("IP addresses must be an understood format or a Net_IPv4 object");
}
}
if ($ipobj1->network == $ipobj2->network &&
$ipobj1->bitmask == $ipobj2->bitmask) {
return true;
}
return false;
}
// }}}
// {{{ atoh()
/**
* Converts a dot-quad formatted IP address into a hexadecimal string
* @param string $addr IP-adress in dot-quad format
* @return mixed false if invalid IP and hexadecimal representation as string if valid
*/
function atoh($addr)
{
if (! Net_IPv4::validateIP($addr)) {
return false;
}
$ap = explode(".", $addr);
return sprintf("%02x%02x%02x%02x", $ap[0], $ap[1], $ap[2], $ap[3]);
}
// }}}
// {{{ htoa()
/**
* Converts a hexadecimal string into a dot-quad formatted IP address
* @param string $addr IP-adress in hexadecimal format
* @return mixed false if invalid IP and dot-quad formatted IP as string if valid
*/
function htoa($addr)
{
if (eregi("^([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$",
$addr, $regs)) {
return hexdec($regs[1]) . "." . hexdec($regs[2]) . "." .
hexdec($regs[3]) . "." . hexdec($regs[4]);
}
return false;
}
// }}}
// {{{ ip2double()
/**
* Converts an IP address to a PHP double. Better than ip2long because
* a long in PHP is a signed integer.
* @param string $ip dot-quad formatted IP adress
* @return float IP adress as double - positive value unlike ip2long
*/
function ip2double($ip)
{
return (double)(sprintf("%u", ip2long($ip)));
}
// }}}
// {{{ ipInNetwork()
/**
* Determines whether or not the supplied IP is within the supplied network.
*
* This function determines whether an IP address is within a network.
* The IP address ($ip) must be supplied in dot-quad format, and the
* network ($network) may be either a string containing a CIDR
* formatted network definition, or a Net_IPv4 object.
*
* @param string $ip A dot quad representation of an IP address
* @param string $network A string representing the network in CIDR format or a Net_IPv4 object.
* @return bool true if the IP address exists within the network
*/
function ipInNetwork($ip, $network)
{
if (! is_object($network) || strcasecmp(get_class($network), 'net_ipv4') <> 0) {
$network = Net_IPv4::parseAddress($network);
}
$net = Net_IPv4::ip2double($network->network);
$bcast = Net_IPv4::ip2double($network->broadcast);
$ip = Net_IPv4::ip2double($ip);
unset($network);
if ($ip >= $net && $ip <= $bcast) {
return true;
}
return false;
}
// }}}
}
// }}}
/*
* vim: sts=4 ts=4 sw=4 cindent fdm=marker
*/
?>
#============================================================================
# This library is free software; you can redistribute it and/or
# modify it under the terms of version 2.1 of the GNU Lesser General Public
# License as published by the Free Software Foundation.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#============================================================================
# Copyright (C) 2006-2007 XenSource Inc.
#============================================================================
#
# Parts of this file are based upon xmlrpclib.py, the XML-RPC client
# interface included in the Python distribution.
#
# Copyright (c) 1999-2002 by Secret Labs AB
# Copyright (c) 1999-2002 by Fredrik Lundh
#
# By obtaining, using, and/or copying this software and/or its
# associated documentation, you agree that you have read, understood,
# and will comply with the following terms and conditions:
#
# Permission to use, copy, modify, and distribute this software and
# its associated documentation for any purpose and without fee is
# hereby granted, provided that the above copyright notice appears in
# all copies, and that both that copyright notice and this permission
# notice appear in supporting documentation, and that the name of
# Secret Labs AB or the author not be used in advertising or publicity
# pertaining to distribution of the software without specific, written
# prior permission.
#
# SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
# TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANT-
# ABILITY AND FITNESS. IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR
# BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
# OF THIS SOFTWARE.
# --------------------------------------------------------------------
import gettext
import xmlrpclib
import httplib
import socket
translation = gettext.translation('xen-xm', fallback = True)
API_VERSION_1_1 = '1.1'
API_VERSION_1_2 = '1.2'
class Failure(Exception):
def __init__(self, details):
self.details = details
def __str__(self):
try:
return str(self.details)
except Exception, exn:
import sys
print >>sys.stderr, exn
return "Xen-API failure: %s" % str(self.details)
def _details_map(self):
return dict([(str(i), self.details[i])
for i in range(len(self.details))])
_RECONNECT_AND_RETRY = (lambda _ : ())
class UDSHTTPConnection(httplib.HTTPConnection):
"""HTTPConnection subclass to allow HTTP over Unix domain sockets. """
def connect(self):
path = self.host.replace("_", "/")
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.sock.connect(path)
class UDSHTTP(httplib.HTTP):
_connection_class = UDSHTTPConnection
class UDSTransport(xmlrpclib.Transport):
def __init__(self, use_datetime=0):
self._use_datetime = use_datetime
self._extra_headers=[]
def add_extra_header(self, key, value):
self._extra_headers += [ (key, value) ]
def make_connection(self, host):
return UDSHTTP(host)
def send_request(self, connection, handler, request_body):
connection.putrequest("POST", handler)
for key, value in self._extra_headers:
connection.putheader(key, value)
class Session(xmlrpclib.ServerProxy):
"""A server proxy and session manager for communicating with xapi using
the Xen-API.
Example:
session = Session('http://localhost/')
session.login_with_password('me', 'mypassword')
session.xenapi.VM.start(vm_uuid)
session.xenapi.session.logout()
"""
def __init__(self, uri, transport=None, encoding=None, verbose=1,
allow_none=1):
xmlrpclib.ServerProxy.__init__(self, uri, transport, encoding,
verbose, allow_none)
self.transport = transport
self._session = None
self.last_login_method = None
self.last_login_params = None
self.API_version = API_VERSION_1_1
def xenapi_request(self, methodname, params):
if methodname.startswith('login'):
self._login(methodname, params)
return None
elif methodname == 'logout' or methodname == 'session.logout':
self._logout()
return None
else:
retry_count = 0
while retry_count < 3:
full_params = (self._session, ) + params
result = _parse_result(getattr(self, methodname)(*full_params))
if result == _RECONNECT_AND_RETRY:
retry_count += 1
if self.last_login_method:
self._login(self.last_login_method,
self.last_login_params)
else:
raise xmlrpclib.Fault(401, 'You must log in')
else:
return result
raise xmlrpclib.Fault(
500, 'Tried 3 times to get a valid session, but failed')
def _login(self, method, params):
result = _parse_result(getattr(self, 'session.%s' % method)(*params))
if result == _RECONNECT_AND_RETRY:
raise xmlrpclib.Fault(
500, 'Received SESSION_INVALID when logging in')
self._session = result
self.last_login_method = method
self.last_login_params = params
self.API_version = self._get_api_version()
def _logout(self):
try:
if self.last_login_method.startswith("slave_local"):
return _parse_result(self.session.local_logout(self._session))
else:
return _parse_result(self.session.logout(self._session))
finally:
self._session = None
self.last_login_method = None
self.last_login_params = None
self.API_version = API_VERSION_1_1
def _get_api_version(self):
pool = self.xenapi.pool.get_all()[0]
host = self.xenapi.pool.get_master(pool)
major = self.xenapi.host.get_API_version_major(host)
minor = self.xenapi.host.get_API_version_minor(host)
return "%s.%s"%(major, minor)
def __getattr__(self, name):
if name == 'handle':
return self._session
elif name == 'xenapi':
return _Dispatcher(self.API_version, self.xenapi_request, None)
elif name.startswith('login') or name.startswith('slave_local'):
return lambda *params: self._login(name, params)
else:
return xmlrpclib.ServerProxy.__getattr__(self, name)
def xapi_local():
return Session("http://172.21.98.21/", transport=UDSTransport())
def _parse_result(result):
if type(result) != dict or 'Status' not in result:
raise xmlrpclib.Fault(500, 'Missing Status in response from server' + result)
if result['Status'] == 'Success':
if 'Value' in result:
return result['Value']
else:
raise xmlrpclib.Fault(500,
'Missing Value in response from server')
else:
if 'ErrorDescription' in result:
if result['ErrorDescription'][0] == 'SESSION_INVALID':
return _RECONNECT_AND_RETRY
else:
raise Failure(result['ErrorDescription'])
else:
raise xmlrpclib.Fault(
500, 'Missing ErrorDescription in response from server')
# Based upon _Method from xmlrpclib.
class _Dispatcher:
def __init__(self, API_version, send, name):
self.__API_version = API_version
self.__send = send
self.__name = name
def __repr__(self):
if self.__name:
return '<XenAPI._Dispatcher for %s>' % self.__name
else:
return '<XenAPI._Dispatcher>'
def __getattr__(self, name):
if self.__name is None:
return _Dispatcher(self.__API_version, self.__send, name)
else:
return _Dispatcher(self.__API_version, self.__send, "%s.%s" % (self.__name, name))
def __call__(self, *args):
return self.__send(self.__name, args)
File deleted
File deleted
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment