blob: f37f7196d7c71c037a906b11db5bb4250af35c41 [file] [log] [blame]
#!/bin/bash
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[ -n "${network_init-}" ] && return
mac_to_bytes() {
local -n bytes="$1"
local str="$2"
# Verify that the MAC is Valid
[[ "$str" =~ ^[[:xdigit:]]{1,2}(:[[:xdigit:]]{1,2}){5}$ ]] || return
# Split the mac into hex bytes
local oldifs="$IFS"
IFS=:
local byte
for byte in $str; do
bytes+=(0x$byte)
done
IFS="$oldifs"
}
mac_to_eui48() {
local mac_bytes=()
mac_to_bytes mac_bytes "$1" || return
# Return the EUI-64 bytes in the IPv6 format
printf '%02x%02x:%02x%02x:%02x%02x\n' "${mac_bytes[@]}"
}
mac_to_eui64() {
local mac_bytes=()
mac_to_bytes mac_bytes "$1" || return
# Using EUI-64 conversion rules, create the suffix bytes from MAC bytes
# Invert bit-0 of the first byte, and insert 0xfffe in the middle.
local suffix_bytes=(
$((mac_bytes[0] ^ 1))
${mac_bytes[@]:1:2}
$((0xff)) $((0xfe))
${mac_bytes[@]:3:3}
)
# Return the EUI-64 bytes in the IPv6 format
printf '%02x%02x:%02x%02x:%02x%02x:%02x%02x\n' "${suffix_bytes[@]}"
}
ipv6_pfx_concat() {
local pfx="$1"
local sfx="$2"
# Validate the prefix
if ! [[ "$pfx" =~ ^(([0-9a-fA-F]{1,4}:)+):/([0-9]+)$ ]]; then
echo "Invalid IPv6 prefix: $pfx" >&2
return 1
fi
local addr="${BASH_REMATCH[1]}"
local cidr="${BASH_REMATCH[3]}"
# Ensure prefix doesn't have too many bytes
local nos="${addr//:/}"
if (( ${#addr} - ${#nos} > (cidr+7)/16 )); then
echo "Too many prefix bytes: $pfx" >&2
return 1
fi
# Validate the suffix
if ! [[ "$sfx" =~ ^[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4})*$ ]]; then
echo "Invalid IPv6 suffix: $sfx" >&2
return 1
fi
# Ensure suffix doesn't have too many bytes
local nos="${sfx//:/}"
if (( ${#sfx} - ${#nos} >= (128-cidr)/16 )); then
echo "Too many suffix bytes: $sfx" >&2
return 1
fi
local comb="$addr:$sfx"
local nos="${comb//:/}"
if (( ${#comb} - ${#nos} == 8 )); then
comb="$addr$sfx"
fi
echo "$comb/$cidr"
}
ipv6_pfx_to_cidr() {
[[ "$1" =~ ^[0-9a-fA-F:]+/([0-9]+)$ ]] || return
echo "${BASH_REMATCH[1]}"
}
network_init=1
return 0 2>/dev/null
echo "network is a library, not executed directly" >&2
exit 1