def test_ipv6(self): """Test IPv6 functions.""" i = _Iface({ 'name': 'NAME', 'ipv6/default/address': '1:2:3:4:5:6:7:8', 'ipv6/default/prefix': '64', 'ipv6/other/address': '2:3:4:5:6:7:8:9', 'ipv6/other/prefix': '80', }) self.assertEqual('NAME', i.name) self.assertEqual(None, i.ipv4_address()) self.assertEqual(IPv6Network('1:2:3:4:5:6:7:8/64'), i.ipv6_address()) self.assertEqual(IPv6Network('1:2:3:4:5:6:7:8/64'), i.ipv6_address('default')) self.assertEqual(IPv6Network('2:3:4:5:6:7:8:9/80'), i.ipv6_address('other'))
def test_v6(self): addr = "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/16" # 0xffff:0000:0000:0000:0000:0000:0000:0000 obj = IPv6Network(addr, strict=False) self.assertEqual(int(obj.network_address), 340277174624079928635746076935438991360) self.assertEqual(str(hex(int(obj.network_address))), "0xffff0000000000000000000000000000")
def get_assignment(self, bundle: TransactionBundle) -> Assignment: """ Look up the assignment based on DUID, Interface-ID of the relay closest to the client and Remote-ID of the relay closest to the client, in that order. :param bundle: The transaction bundle :return: The assignment, if any """ # Gather all possible IDs possible_ids = [] # Look up based on DUID duid_option = bundle.request.get_option_of_type(ClientIdOption) duid = 'duid:' + codecs.encode(duid_option.duid.save(), 'hex').decode('ascii') possible_ids.append(duid) # Look up based on Interface-ID interface_id_option = bundle.incoming_relay_messages[0].get_option_of_type(InterfaceIdOption) if interface_id_option: interface_id = 'interface-id:' + codecs.encode(interface_id_option.interface_id, 'hex').decode('ascii') possible_ids.append(interface_id) # Look up based on Remote-ID remote_id_option = bundle.incoming_relay_messages[0].get_option_of_type(RemoteIdOption) if remote_id_option: remote_id = 'remote-id:{}:{}'.format(remote_id_option.enterprise_number, codecs.encode(remote_id_option.remote_id, 'hex').decode('ascii')) possible_ids.append(remote_id) # Look up based on Subscriber-ID subscriber_id_option = bundle.incoming_relay_messages[0].get_option_of_type(SubscriberIdOption) if subscriber_id_option: subscriber_id = 'subscriber-id:{}'.format( codecs.encode(subscriber_id_option.subscriber_id, 'hex').decode('ascii') ) possible_ids.append(subscriber_id) # Look up based on LinkLayer-ID linklayer_id_option = bundle.incoming_relay_messages[0].get_option_of_type(LinkLayerIdOption) if linklayer_id_option: linklayer_id = 'linklayer-id:{}:{}'.format( linklayer_id_option.link_layer_type, codecs.encode(linklayer_id_option.link_layer_address, 'hex').decode('ascii') ) possible_ids.append(linklayer_id) # Search placeholders = ', '.join(['?'] * len(possible_ids)) query = "SELECT address, prefix FROM assignments WHERE id IN (" + placeholders + ") ORDER BY id LIMIT 1" results = self.db.execute(query, possible_ids).fetchone() if results: address = results[0] and IPv6Address(results[0]) or None prefix = results[1] and IPv6Network(results[1]) or None return Assignment(address=address, prefix=prefix) # Nothing found return Assignment(address=None, prefix=None)
def test_toascii(self, field: 'SubnetType', expected): v4 = IPv4Network('192.168.0.0/24') v6 = IPv6Network('2001:db8::1000/124') for data, expected in [ (v4, '192.168.0.0/24'), (v6, '2001:db8::1000/124'), (None, expected['unset_field']), ]: assert field.toascii(data) == expected
def test_tojson(self, field: 'SubnetType'): v4 = IPv4Network('192.168.0.0/24') v6 = IPv6Network('2001:db8::1000/124') for data, expected in [ (v4, '192.168.0.0/24'), (v6, '2001:db8::1000/124'), (None, None), ]: assert field.tojson(data) == expected
def convert_udm_subnet_to_ipv6_network(subnet): prefix = subnet.replace(":", "") count = len(prefix) assert 1 <= count <= 32 prefix_length = 4 * count address = subnet if count <= 28: address += "::" return IPv6Network(u"%s/%d" % (address, prefix_length), False)
def __init__(self, address): """Initializer""" # validate the arguments passed self.__validate(address) # call the parent initializer IPv6Network.__init__(self, address) # set some object variables self.pn_network = IPv6Network(address) self.pn_network_address = PyNIPv6Address(self.network_address) self.pn_hostmask = PyNIPv6Address(self.hostmask.exploded) self.pn_netmask = PyNIPv6Address(self.netmask.exploded) self.pn_hosts = self.num_addresses self.pn_hostmin = PyNIPv6Address(self.pn_network_address) self.pn_hostmax = PyNIPv6Address(self.broadcast_address)
def __validate(self, address): """Validates that the arguments passed in the initializer are valid """ try: IPv6Network(address) return True except: raise TypeError("Invalid IPv6 network address passed")
def test_unpack(self) -> None: field = gateaux.IPv6NetworkField() with self.assertRaises(gateaux.errors.ValidationError): field.unpack('not bytes') # type: ignore with self.assertRaises(gateaux.errors.ValidationError): field.unpack(b'not 17 bytes') self.assertEqual(field.unpack( b'\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@'), IPv6Network('1::/64'))
def _check_if_private(address: str, address_type: str) -> bool: if address_type == "ipv6": ip_list = [str(ip) for ip in IPv6Network(address)] else: ip_list = [str(ip) for ip in IPv4Network(address)] if ip_address(ip_list[0]).is_private and ip_address(ip_list[-1]).is_private: return True return False
def __init__(self, **kwargs): super().__init__(ICMPv6OptionNumber.PrefixInformation) self._l = 1 self._a = 1 self._valid_lifetime = 25920000 self._preferred_lifetime = 604800 self._prefix = IPv6Network('::/64') for k, v in kwargs.items(): setattr(self, k, v)
def load_from(self, buffer: bytes, offset: int = 0, length: int = None) -> int: """ Load the internal state of this object from the given buffer. The buffer may contain more data after the structured element is parsed. This data is ignored. :param buffer: The buffer to read data from :param offset: The offset in the buffer where to start reading :param length: The amount of data we are allowed to read from the buffer :return: The number of bytes used from the buffer """ my_offset, option_len = self.parse_option_header(buffer, offset, length, min_length=5) header_offset = my_offset # IPv4 address self.ipv4_address = IPv4Address(buffer[offset + my_offset:offset + my_offset + 4]) my_offset += 4 # IPv6 prefix ipv6_prefix_length = buffer[offset + my_offset] my_offset += 1 if not (0 <= ipv6_prefix_length <= 128): raise ValueError( "IPv6 prefix length must be in range from 0 to 128") included_octets = math.ceil(ipv6_prefix_length / 8) ipv6_address = IPv6Address(buffer[offset + my_offset:offset + my_offset + included_octets].ljust( 16, b'\x00')) my_offset += included_octets self.ipv6_prefix = IPv6Network('{!s}/{:d}'.format( ipv6_address, ipv6_prefix_length), strict=False) # Parse the options self.options = [] max_offset = option_len + header_offset # The option_len field counts bytes *after* the header fields while max_offset > my_offset: used_buffer, option = Option.parse(buffer, offset=offset + my_offset) self.options.append(option) my_offset += used_buffer if my_offset != max_offset: raise ValueError( 'Option length does not match the combined length of the parsed options' ) return my_offset
def setUp(self): self.option_bytes = bytes.fromhex( '002d' # Option type 45: OPTION_CLIENT_DATA '0099' # Option length: 153 '0001' # Option type 1: OPTION_CLIENT_ID '0015' # Option length: 21 '0002' # DUID type: DUID_EN '00009d10' # Enterprise ID: 40208 '303132333435363738396162636465' # Identifier: '0123456789abcde' '0005' # Option type: OPTION_IAADDR '0018' # Option length: 24 '20010db800000000000000000000cafe' # IPv6 address: 2001:db8::cafe '00000708' # Preferred lifetime: 1800 '00000e10' # Valid lifetime: 3600 '001a' # Option type: OPTION_IAPREFIX '0019' # Option length: 25 '00000708' # Preferred lifetime: 1800 '00000e10' # Valid lifetime: 3600 '30' # Prefix length: 48 '20010db8000100000000000000000000' '002e' # Option type: OPTION_CLT_TIME '0004' # Option length: 4 '00000384' # Client-Last-Transaction time: 900 '002f' # Option type: OPTION_LQ_RELAY_DATA '003b' # Option length: 59 '20010db8000000000000000000000002' # Peer address: 2001:db8::2 '0c' # Message type: MSG_RELAY_FORW '00' # Hop count: 0 '20010db8000000000000000000000002' # Link address: 2001:db8::2 'fe800000000000000000000000000022' # Peer address: fe80::22 '0012' # Option type: OPTION_INTERFACE_ID '0005' # Option length: 5 '4661322f33' # Interface ID: 'Fa2/3' ) self.option_object = ClientDataOption(options=[ ClientIdOption(EnterpriseDUID(40208, b'0123456789abcde')), IAAddressOption(address=IPv6Address('2001:db8::cafe'), preferred_lifetime=1800, valid_lifetime=3600), IAPrefixOption(prefix=IPv6Network('2001:db8:1::/48'), preferred_lifetime=1800, valid_lifetime=3600), CLTTimeOption(clt_time=900), LQRelayDataOption(peer_address=IPv6Address('2001:db8::2'), relay_message=RelayForwardMessage( hop_count=0, link_address=IPv6Address('2001:db8::2'), peer_address=IPv6Address('fe80::22'), options=[ InterfaceIdOption(interface_id=b'Fa2/3'), ] )) ]) self.parse_option()
def __init__(self, spine=2, leaf=2, fanout=2, **opts): Topo.__init__(self, **opts) spines = {} leafs = {} """ We calculate the offset from /120 and from /24 in order to have a number of /120 and /24 subnets == leaf """ offset = int(math.ceil(math.sqrt(leaf))) """ We calculate the subnets to use and set options """ ipv6SubnetClass = unicode('2000::/%s' % (IP6_SUBNET_CLASS - offset)) ipv6Subnets = list( IPv6Network(ipv6SubnetClass).subnets(new_prefix=IP6_SUBNET_CLASS)) ipv4SubnetClass = unicode('10.0.0.0/%s' % (IP4_SUBNET_CLASS - offset)) ipv4Subnets = list( IPv4Network(ipv4SubnetClass).subnets(new_prefix=IP4_SUBNET_CLASS)) linkopts = dict(bw=100) """ We create the spine switches """ for s in range(spine): spines[s] = self.addSwitch('spine10%s' % (s + 1), dpid="00000000010%s" % (s + 1)) """ We create the leaf switches """ for ls in range(leaf): leafs[ls] = self.addSwitch('leaf%s' % (ls + 1), dpid="00000000000%s" % (1 + ls)) ipv6Subnet = ipv6Subnets[ls] ipv6Hosts = list(ipv6Subnet.hosts()) ipv4Subnet = ipv4Subnets[ls] ipv4Hosts = list(ipv4Subnet.hosts()) """ We add the hosts """ for f in range(fanout): ipv6 = ipv6Hosts[f] ipv6Gateway = ipv6Hosts[len(ipv6Hosts) - 1] ipv4 = ipv4Hosts[f] ipv4Gateway = ipv4Hosts[len(ipv4Hosts) - 1] host = self.addHost(name='h%s' % (ls * fanout + f + 1), cls=Ipv6Host, ip="%s/%s" % (ipv4, IP4_SUBNET_CLASS), gateway='%s' % ipv4Gateway, ipv6="%s/%s" % (ipv6, IP6_SUBNET_CLASS), ipv6Gateway="%s" % ipv6Gateway) self.addLink(host, leafs[ls], **linkopts) """ Connect leaf to all spines """ for s in range(spine): switch = spines[s] self.addLink(leafs[ls], switch, **linkopts)
def ipv6(self, network: bool = False) -> str: """Produce a random IPv6 address or network with a valid CIDR""" address = str( IPv6Address( self.generator.random.randint(2**IPV4LENGTH, (2**IPV6LENGTH) - 1))) if network: address += "/" + str(self.generator.random.randint(0, IPV6LENGTH)) address = str(IPv6Network(address, strict=False)) return address
def ipv6_eui64(mac, prefix=IPv6Network("fe80::/64")): """ Create IPv6 EUI64 address """ assert prefix.prefixlen == 64 eui64 = sub(r"[.:-]", "", mac).lower() eui64 = eui64[0:6] + "fffe" + eui64[6:] eui64 = hex(int(eui64[0:2], 16) ^ 2)[2:].zfill(2) + eui64[2:] eui64 = ":".join(eui64[_ : _ + 4] for _ in range(0, 16, 4)) return IPv6Interface(prefix.network_address.exploded[0:20] + eui64 + "/" + str(prefix.prefixlen))
def testGet3(self): if sys.version_info.major == 3 and sys.version_info.minor >= 4: from ipaddress import IPv6Address, IPv6Network pyt = pytricia.PyTricia(128) pyt.insert(IPv6Network('2001:218:200e::/56'), "def") pyt.insert(IPv6Network("fe80:abcd::0/96"), "xyz") pyt.insert(IPv6Address("fe80:beef::"), 96, "abc") addrlist = sorted([x for x in pyt.keys()]) self.assertEqual( addrlist, ['2001:218:200e::/56', 'fe80:abcd::/96', 'fe80:beef::/96']) self.assertEqual(pyt.get("fe80:abcd::0/96"), "xyz") self.assertEqual(pyt.get("fe80:beef::0/96"), "abc") self.assertEqual(pyt.get(IPv6Network("fe80:abcd::0/96")), "xyz") self.assertEqual(pyt.get(IPv6Network("fe80:beef::0/96")), "abc")
def get_random_ip6_address(subnet): """ :param: Chosen subnet in which to find an address :return: IPv6 Address Object """ subnet = str(subnet) if isinstance(subnet, str) else subnet seed() network = IPv6Network(subnet) return IPv6Address(network.network_address + getrandbits(network.max_prefixlen - network.prefixlen))
def validate(cls, value: NetworkType) -> Union[IPv4Network, IPv6Network]: # Assume IP Network is defined with a default value for ``strict`` argument. # Define your own class if you want to specify network address check strictness. try: return IPv4Network(value) except ValueError: pass with change_exception(errors.IPvAnyNetworkError, ValueError): return IPv6Network(value)
def unpack(self, v: bytes) -> IPv6Network: ''' Unpack bytes into an IPv6Network. ''' if not isinstance(v, bytes): raise ValidationError(f'unpack() expected bytes, got: {type(v)}') if len(v) != 17: raise ValidationError( f'unpack() expected exactly 17 bytes, got: {len(v)}') network: IPv6Network = IPv6Network((v[0:16], v[16])) return self.validate_unpacked(network)
def test_ipv6_order(self): """Test IPv6 ordering.""" t = Interfaces( ucr={ 'interfaces/eth0/ipv6/default/address': '1:2:3:4:5:6:7:8', 'interfaces/eth0/ipv6/default/prefix': '64', 'interfaces/eth1/ipv6/default/address': '2:3:4:5:6:7:8:9', 'interfaces/eth1/ipv6/default/prefix': '72', 'interfaces/eth2/order': '1', 'interfaces/eth2/ipv6/default/address': '3:4:5:6:7:8:9:a', 'interfaces/eth2/ipv6/default/prefix': '80', }) self.assertEqual([], [s.name for _n, s in t.ipv4_interfaces]) self.assertEqual(['eth2', 'eth0', 'eth1'], [s.name for s, _n in t.ipv6_interfaces]) self.assertEqual(IPv6Network('1:2:3:4:5:6:7:8/64'), t.get_default_ip_address()) self.assertEqual(None, t.get_default_ipv4_address()) self.assertEqual(IPv6Network('1:2:3:4:5:6:7:8/64'), t.get_default_ipv6_address())
def test_select_in_list_network(self): ips = [ IPv6Address('42e::1'), IPv6Address('42e::2'), IPv6Address('a42e::3'), IPv6Address('f42e::ffff') ] with self.create_table(self.table): self.session.execute(self.table.insert(), [{ 'x': ip } for ip in ips]) self.assertEqual( self.session.query(self.table.c.x).filter( self.table.c.x.in_( [IPv6Network('42e::/64'), IPv6Network('a42e::/48')])).all(), [(IPv6Address('42e::1'), ), (IPv6Address('42e::2'), ), (IPv6Address('a42e::3'), )])
def jails_network6(): try: cloned_if_params = output('sysrc', '-n', 'ifconfig_%s_ipv6' % cloned_if()) except CalledProcessError: raise NoIPv6JailNetwork else: gd = (re.match( r'^inet6\s+(?P<inet6>{ip6_reg})\s+prefixlen\s+(?P<prefixlen>\d+)'. format(ip6_reg=_ip6_reg), cloned_if_params).groupdict()) return IPv6Network(gd['inet6'] + '/' + gd['prefixlen'], strict=False)
def reparse_record_from_exports(record_host, unpack_network): add_block = {} _tmp = None add_block['ipv4'] = [] add_block['ipv6'] = [] if '/' in record_host and ':' not in record_host: try: add_block['network_v4'] = str(IPv4Network(record_host)) if unpack_network: add_block['ipv4'] = [_ip for _ip in map(str, _tmp)] else: add_block['ipv4'] = [str(IPv4Network(record_host)[0])] except: try: _ip = record_host.split('/')[0] _ip = str(IPv4Address(_ip)) add_block['ipv4'].append(_ip) except: pass elif '/' in record_host and ':' in record_host: try: add_block['network_v6'] = str(IPv6Network(record_host)) except: pass elif '/' not in record_host and ':' in record_host: try: add_block['ipv6'].append(str(IPv6Address(record_host))) except: pass else: try: add_block['ipv4'].append(str(IPv4Address(record_host))) except: if 'everyone' not in record_host and record_host != '*' and record_host != 'unknown': if all(c in printable for c in record_host): add_block['host'] = record_host add_block['status'] = record_host result = [] if len(add_block['ipv6']) > 0: add_block['ipv6'] = add_block['ipv6'][0] result.append(add_block) else: add_block['ipv6'] = '' if len(add_block['ipv4']) == 0: add_block['ipv4'] = '' else: for ipv4 in add_block['ipv4']: _c = add_block.copy() _c['ipv4'] = ipv4 result.append(_c) if len(add_block['ipv4']) == 0 and len(add_block['ipv6']) == 0: result.append(add_block) return result
def is_subnet_address(ip_address): if ".onion" in ip_address: return False if ":" in ip_address: # ipv6 return any([ IPv6Address(ip_address) in IPv6Network(net) for net in ipv6nets ]) else: # ipv4 return any([ IPv4Address(ip_address) in IPv4Network(net) for net in ipv4nets ])
def get_ipv6_host(self, host): """Convert the host to IPv6Network""" try: host = u'{0}'.format(host) return IPv6Network(host, strict=False) except ValueError as e: error_msg = "Given host {0} is an invalid IPv6 format -- " \ "error {1}".format(host, str(e)) LOG.error(error_msg) self.module.fail_json(msg=error_msg)
def test_validate_ipv6_prefix(self): with self.assertRaisesRegex(ValueError, 'IPv6Network'): self.option.ipv6_prefix = None self.option.validate() with self.assertRaisesRegex(ValueError, 'IPv6Network'): self.option.ipv6_prefix = IPv6Address('2001:db8::1') self.option.validate() self.option.ipv6_prefix = IPv6Network('2001:db8::/32') self.option.validate()
def test_validate_br_address(self): with self.assertRaisesRegex(ValueError, 'IPv6Address'): self.option.br_address = None self.option.validate() with self.assertRaisesRegex(ValueError, 'IPv6Address'): self.option.br_address = IPv6Network('2001:db8::1/128') self.option.validate() self.option.br_address = IPv6Address('2001:db8::1') self.option.validate()
def __init__(self, flags: int = 0, ea_len: int = 0, ipv4_prefix: IPv4Network = None, ipv6_prefix: IPv6Network = None, options: Iterable[Option] = None): self.flags = flags self.ea_len = ea_len self.ipv4_prefix = ipv4_prefix or IPv4Network('0.0.0.0/0') self.ipv6_prefix = ipv6_prefix or IPv6Network('::/0') self.options = list(options or [])
def set_interfaces(): path = os.path.join(GEN_PATH, NETWORKS_FILE) with open(path, 'r') as f: for l in f.readlines(): split = l.split("= ") if (len(split) < 2): continue address = split[1] addr = IPv6Address(address[:-1]) if addr in IPv6Network(DEFAULT6_NETWORK): ip_add(str(addr), DEFAULT6_MASK)
def prefix_overlaps_prefixes(prefix: IPv6Network, prefixes: [IPv6Network]) -> bool: """ Check whether the given address is part of one of the given prefixes :param prefix: The IPv6 prefix to check :param prefixes: The list of IPv6 prefixes :type prefixes: list[IPv6Network] :return: Whether the address is part of one of the prefixes """ for other_prefix in prefixes: if prefix.overlaps(other_prefix): return True return False