1
0
mirror of https://github.com/CumulusNetworks/ifupdown2.git synced 2024-05-06 15:54:50 +00:00
Julien Fortin 7c8627f876 SONAR: Specify an exception class to catch or reraise the exception
Signed-off-by: Julien Fortin <jfortin@nvidia.com>
2023-05-04 13:21:55 +02:00

190 lines
5.0 KiB
Python

# Copyright (C) 2019, 2020 Cumulus Networks, Inc. all rights reserved
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; version 2.
#
# This program 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
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# https://www.gnu.org/licenses/gpl-2.0-standalone.html
#
# Author:
# Julien Fortin, julien@cumulusnetworks.com
#
import ipaddress
class IPNetwork:
__INIT_WITH_PREFIXLEN = 0b01
ip_family_handler = {
0: ipaddress.ip_address,
4: ipaddress.IPv4Address,
6: ipaddress.IPv6Address
}
def __init__(self, ip, prefixlen=None, scope=0, family=0):
if isinstance(ip, IPNetwork):
prefixlen = ip.prefixlen
scope = ip.scope
family = ip.version
ip = ip.ip
self.__scope = scope
self.__flags = 0
if isinstance(ip, int):
self._ip = self.ip_family_handler[family](ip)
else:
if not prefixlen:
try:
ip, prefixlen = ip.split("/")
except ValueError:
prefixlen = None
self._ip = ipaddress.ip_address(ip)
if not prefixlen:
self.__prefixlen = 32 if self.ip.version == 4 else 128
else:
try:
self.__prefixlen = int(prefixlen)
except ValueError:
if isinstance(prefixlen, str) and "." in prefixlen:
self.__prefixlen = ipaddress.ip_network("{}/{}".format(self.ip, prefixlen), strict=False).prefixlen
else:
raise
if (self.ip.version == 4 and self.prefixlen != 32) or (self.ip.version == 6 and self.prefixlen != 128):
self.__flags |= self.__INIT_WITH_PREFIXLEN
def __hash__(self):
return int(self._ip) ^ self.__prefixlen ^ self.version
def __eq__(self, other) -> bool:
return other \
and self.version == other.version \
and self._ip == other.ip \
and self.__prefixlen == other.prefixlen
def __repr__(self):
return "{}/{}".format(self._ip, self.__prefixlen)
def __int__(self):
return int(self._ip)
__str__ = __repr__
@property
def ip(self):
return self._ip
@property
def packed(self):
return self._ip.packed
@property
def is_multicast(self):
return self._ip.is_multicast
@property
def prefixlen(self) -> int:
return self.__prefixlen
@property
def version(self) -> int:
return self._ip.version
@property
def scope(self) -> int:
return self.__scope
@property
def initialized_with_prefixlen(self) -> int:
return self.__flags & self.__INIT_WITH_PREFIXLEN
def ignore_prefixlen(self):
self.__prefixlen = 32 if self.ip.version == 4 else 128
class IPv4Network(IPNetwork):
def __init__(self, *args, **kwargs):
super(IPv4Network, self).__init__(family=4, *args, **kwargs)
if self.version != 4:
self._ip = ipaddress.IPv4Address(self._ip)
class IPv6Network(IPNetwork):
def __init__(self, *args, **kwargs):
super(IPv6Network, self).__init__(family=6, *args, **kwargs)
if self.version != 6:
self._ip = ipaddress.IPv6Address(self._ip)
class IPAddress(IPNetwork):
def __init__(self, ip, prefixlen=None, *args, **kwargs):
if isinstance(ip, int):
raise NotImplementedError
if prefixlen is not None:
self.__raise_exception("{}/{}".format(ip, prefixlen))
elif "/" in ip:
self.__raise_exception(ip)
super(IPAddress, self).__init__(ip, prefixlen, *args, **kwargs)
self.ignore_prefixlen()
def __repr__(self):
return str(self._ip)
def __raise_exception(self, ip):
raise ValueError(
"'%s' does not appear to be an IPv4 or IPv6 address"
% ip
)
class IPv4Address(IPv4Network):
def __init__(self, *args, **kwargs):
super(IPv4Address, self).__init__(*args, **kwargs)
self.ignore_prefixlen()
def __repr__(self):
return str(self._ip)
def __str__(self):
return str(self._ip)
class IPv6Address(IPv6Network):
def __init__(self, *args, **kwargs):
super(IPv6Address, self).__init__(*args, **kwargs)
self.ignore_prefixlen()
def __repr__(self):
return str(self._ip)
def __str__(self):
return str(self._ip)
def ip_address(ip):
try:
return IPv4Address(ip)
except Exception:
return IPv6Address(ip)