from PLC.NetworkMethods import NetworkMethod, NetworkMethods
import PLC.Nodes
-def valid_ip(ip):
+def valid_ipv4(ip):
try:
ip = socket.inet_ntoa(socket.inet_aton(ip))
return True
except socket.error:
return False
-def in_same_network(address1, address2, netmask):
+def valid_ipv6(ip):
+ try:
+ ip = socket.inet_ntop(socket.AF_INET6, socket.inet_pton(socket.AF_INET6, ip))
+ return True
+ except socket.error:
+ return False
+
+def valid_ip(ip):
+ return valid_ipv4(ip) or valid_ipv6(ip)
+
+def in_same_network_ipv4(address1, address2, netmask):
"""
Returns True if two IPv4 addresses are in the same network. Faults
if an address is invalid.
"""
-
address1 = struct.unpack('>L', socket.inet_aton(address1))[0]
address2 = struct.unpack('>L', socket.inet_aton(address2))[0]
netmask = struct.unpack('>L', socket.inet_aton(netmask))[0]
return (address1 & netmask) == (address2 & netmask)
+def in_same_network_ipv6(address1, address2, netmask):
+ """
+ Returns True if two IPv6 addresses are in the same network. Faults
+ if an address is invalid.
+ """
+ address1 = struct.unpack('>2Q', socket.inet_pton(socket.AF_INET6, address1))[0]
+ address2 = struct.unpack('>2Q', socket.inet_pton(socket.AF_INET6, address2))[0]
+ netmask = struct.unpack('>2Q', socket.inet_pton(socket.AF_INET6, netmask))[0]
+
+ return (address1 & netmask) == (address2 & netmask)
+
+def in_same_network(address1, address2, netmask):
+ return in_same_network_ipv4(address1, address2, netmask) or \
+ in_same_network_ipv6(address1, address2, netmask)
+
class Interface(Row):
"""
Representation of a row in the interfaces table. To use, optionally
# DHCP!
elif method == "static":
- for key in ['gateway', 'dns1']:
- if key not in self or not self[key]:
- if 'is_primary' in self and self['is_primary'] is True:
- raise PLCInvalidArgument, "For static method primary network, %s is required" % key
- else:
+ if self['type'] == 'ipv4':
+ for key in ['gateway', 'dns1']:
+ if key not in self or not self[key]:
+ if 'is_primary' in self and self['is_primary'] is True:
+ raise PLCInvalidArgument, "For static method primary network, %s is required" % key
+ else:
+ globals()[key] = self[key]
+ for key in ['ip', 'network', 'broadcast', 'netmask']:
+ if key not in self or not self[key]:
+ raise PLCInvalidArgument, "For static method, %s is required" % key
+ globals()[key] = self[key]
+ if not in_same_network(ip, network, netmask):
+ raise PLCInvalidArgument, "IP address %s is inconsistent with network %s/%s" % \
+ (ip, network, netmask)
+ if not in_same_network(broadcast, network, netmask):
+ raise PLCInvalidArgument, "Broadcast address %s is inconsistent with network %s/%s" % \
+ (broadcast, network, netmask)
+ if 'gateway' in globals() and not in_same_network(ip, gateway, netmask):
+ raise PLCInvalidArgument, "Gateway %s is not reachable from %s/%s" % \
+ (gateway, ip, netmask)
+ elif self['type'] == 'ipv6':
+ for key in ['ip', 'gateway']:
+ if key not in self or not self[key]:
+ raise PLCInvalidArgument, "For static ipv6 method, %s is required" % key
globals()[key] = self[key]
- for key in ['ip', 'network', 'broadcast', 'netmask']:
- if key not in self or not self[key]:
- raise PLCInvalidArgument, "For static method, %s is required" % key
- globals()[key] = self[key]
- if not in_same_network(ip, network, netmask):
- raise PLCInvalidArgument, "IP address %s is inconsistent with network %s/%s" % \
- (ip, network, netmask)
- if not in_same_network(broadcast, network, netmask):
- raise PLCInvalidArgument, "Broadcast address %s is inconsistent with network %s/%s" % \
- (broadcast, network, netmask)
- if 'gateway' in globals() and not in_same_network(ip, gateway, netmask):
- raise PLCInvalidArgument, "Gateway %s is not reachable from %s/%s" % \
- (gateway, ip, netmask)
-
elif method == "ipmi":
if 'ip' not in self or not self['ip']:
raise PLCInvalidArgument, "For ipmi method, ip is required"