<template> <div id="ip-tools"> <h1>{{ $t('system.ip_tools') }}</h1> <p>{{ $t('views.tools.ip_tools.note') }}</p> <b-card :title="$t('views.tools.ip_tools.expand_compress_address')"> <b-form-group :label="$t('system.ipv6_address')"> <b-form-input v-model="ip_expand_compress" :placeholder="$t('system.ipv6_address')" :state="checkIPExpandCompress" required></b-form-input> <b-form-invalid-feedback id="input-live-feedback-expand"> {{ $t('system.invalid_ipv6') }} </b-form-invalid-feedback> </b-form-group> <b-form-group :label="$t('views.tools.ip_tools.expanded_address')"> <CopyField :text="expandIP" code/> </b-form-group> <b-form-group :label="$t('views.tools.ip_tools.compressed_address')"> <CopyField :text="compressIP" code/> </b-form-group> </b-card> <br> <b-card :title="$t('views.tools.ip_tools.subnet_calculator')"> <b-form-group :label="$t('views.tools.ip_tools.ipv6_subnet')"> <b-form-input v-model="subnet" :placeholder="$t('views.tools.ip_tools.ipv6_subnet')" :state="checkIPSubnet" required></b-form-input> <b-form-invalid-feedback id="input-live-feedback-compress"> {{ $t('views.tools.ip_tools.invalid_ipv6_subnet') }} </b-form-invalid-feedback> </b-form-group> <b-form-group :label="$t('system.start')"> <CopyField :text="calculateRange.start" code/> </b-form-group> <b-form-group :label="$t('system.end')"> <CopyField :text="calculateRange.end" code/> </b-form-group> </b-card> <br> <b-card :title="$t('views.tools.ip_tools.mac_to_eui64')"> <b-form-group :label="$t('system.mac_address')"> <b-form-input v-model="mac_to_local_link" :placeholder="$t('system.mac_address')" :state="checkMacAddress" required></b-form-input> <b-form-invalid-feedback id="input-live-feedback-compress"> {{ $t('views.tools.ip_tools.invalid_mac_address') }} </b-form-invalid-feedback> </b-form-group> <b-form-group :label="$t('system.network_address')"> <div class="form-row m-0" > <b-form-select class="col-md-3 pr-4 mb-0" v-model="selected_eui_prefix" :options="available_eui_prefixes" v-if="this.$store.state.user"></b-form-select> <b-form-input :state="checkEUI_Subnet" class="mb-0" :class="[this.$store.state.user ? 'col-md-9' : 'col-md-12']" v-model="selected_eui_prefix"></b-form-input> <b-form-invalid-feedback id="input-live-feedback-compress"> {{ isEUI64PrefixToLong ? $t('views.tools.ip_tools.eui64_prefix_too_long') : $t('views.tools.ip_tools.invalid_network_address') }} </b-form-invalid-feedback> </div> </b-form-group> <b-form-group :label="$t('views.tools.ip_tools.eui64')"> <CopyField :text="macToEUI64" code/> </b-form-group> </b-card> <br> <b-card :title="$t('views.tools.ip_tools.ipv6_to_mac')"> <b-form-group :label="$t('system.ipv6_address')"> <b-form-input v-model="local_link_to_mac" :placeholder="$t('system.ipv6_address')" :state="checkEUIIPv6Address" required></b-form-input> <b-form-invalid-feedback id="input-live-feedback-compress"> <span v-if="checkEUI_IPv6"> {{ $t('views.tools.ip_tools.ipv6_no_eui') }} </span> <span v-else> {{ $t('system.invalid_ipv6') }} </span> </b-form-invalid-feedback> </b-form-group> <b-form-group :label="$t('system.mac_address')"> <CopyField :text="macAddress" code/> </b-form-group> </b-card> <br> <b-card :title="$t('views.tools.ip_tools.ipv4_mapped_ipv6')"> <b-form-group :label="$t('system.ip_address')"> <b-form-input v-model="v4_mapped_v6_input" :placeholder="$t('system.ip_address')" :state="ipaddress().is_ip_v4(this.v4_mapped_v6_input)" required></b-form-input> <div class="form-row m-0" > <b-form-select class="col-md-3 pr-4 mb-0" v-model="selected_v4_mapped_v6_prefix" :options="available_eui_prefixes" v-if="this.$store.state.user"></b-form-select> <b-form-input :state="checkEUI_Subnet" class="mb-0" :class="[this.$store.state.user ? 'col-md-9' : 'col-md-12']" v-model="selected_v4_mapped_v6_prefix"></b-form-input> <b-form-invalid-feedback id="input-live-feedback-compress"> <!-- TODO! --> <span v-if="checkEUI_IPv6"> {{ $t('views.tools.ip_tools.ipv6_no_eui') }} </span> <span v-else> {{ $t('system.invalid_ip') }} </span> </b-form-invalid-feedback> </div> </b-form-group> <b-form-group :label="$t('system.ipv6_address')"> <CopyField :text="v4_mapped_v6" code/> </b-form-group> </b-card> </div> </template> <script> import CopyField from '@/components/CopyField.vue' import Dns_bcdService from '@/api-services/dns_bcd.service' import ipaddress from '@/util/ipaddress' export default { name: 'IPv6', components: { CopyField }, computed: { expandIP() { return ipaddress.normalize_ipv6(this.ip_expand_compress) }, compressIP() { return ipaddress.abbreviate_ipv6(this.ip_expand_compress) }, calculateRange() { if (ipaddress.check_ipv6_subnet(this.subnet)) { const split = this.subnet.split('/') return ipaddress.ipv6_range(split[0], split[1], 128) } else { return { start: '', end: '', size: 0 } } }, macToEUI64() { return ipaddress.mac_to_eui_ipv6(this.mac_to_local_link, this.selected_eui_prefix) }, macAddress() { return ipaddress.eui_ipv6_to_mac(this.local_link_to_mac) }, v4_mapped_v6() { // todo: add prefix selection // todo check prefix length... return ipaddress.map_v4_v6(this.selected_v4_mapped_v6_prefix, this.v4_mapped_v6_input) }, checkIPExpandCompress() { return ipaddress.is_ip_v6(this.ip_expand_compress) }, checkIPSubnet() { return ipaddress.check_ipv6_subnet(this.subnet) }, checkMacAddress() { return ipaddress.is_mac_address(this.mac_to_local_link) }, checkEUIIPv6Address() { return ipaddress.is_ip_v6(this.local_link_to_mac) && ipaddress.is_eui_ipv6(this.local_link_to_mac) }, checkEUI_IPv6() { return ipaddress.is_ip_v6(this.local_link_to_mac) }, checkEUI_Subnet() { return ipaddress.check_ipv6_subnet(this.selected_eui_prefix) && !this.isEUI64PrefixToLong }, isEUI64PrefixToLong() { return ipaddress.get_ipv6_prefix_length(this.selected_eui_prefix) > 64 } }, methods: { create_option_from_subnet(subnet) { return { value: subnet.cidr, text: `${subnet.bcd} (${subnet.cidr})` } }, ipaddress() { return ipaddress } }, async created() { var result = [] if (this.$store.state.user != null) { // load own subnets when user exists const resp = await Dns_bcdService.getOverview(this.$store.state.netdb_axios_config) const bcd2ou_lookup = {} const ous = {} for (const bcd_ou of resp.data.bcd2ou_list) { bcd2ou_lookup[bcd_ou.bcd_name] = bcd_ou ous[bcd_ou.ou_short_name] = [] } resp.data.ip_subnet_list .filter(subnet => subnet.type === '6') .filter(subnet => ipaddress.get_ipv6_prefix_length(subnet.cidr) <= 64) .forEach(subnet => { ous[bcd2ou_lookup[subnet.bcd].ou_short_name].push(subnet) }) result = Object.entries(ous) .filter(([, ou]) => ou.length > 0) .map(([name, ou]) => { return { label: name, options: ou.sort((s1, s2) => s1.bcd > s2.bcd).map(this.create_option_from_subnet) } }) .sort((o1, o2) => o1.label.localeCompare(o2.label)) } this.available_eui_prefixes = [{value: 'fe80::/10', text: 'Link-Local (fe80::/10)'}].concat(result) }, data() { return { ip_expand_compress: '', subnet: '', mac_to_local_link: '', local_link_to_mac: '', selected_eui_prefix: 'fe80::/10', selected_v4_mapped_v6_prefix: '::ffff:0000:0000/96', available_eui_prefixes: [ {value: 'fe80::/10', text: 'Link-Local (fe80::/10)'}, ], v4_mapped_v6_input: '', } } } </script> <style scoped> </style>