blob: f37f7196d7c71c037a906b11db5bb4250af35c41 [file] [log] [blame]
William A. Kennington III1e268102021-03-08 13:00:12 -08001#!/bin/bash
2# Copyright 2021 Google LLC
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16[ -n "${network_init-}" ] && return
17
18mac_to_bytes() {
19 local -n bytes="$1"
20 local str="$2"
21
22 # Verify that the MAC is Valid
23 [[ "$str" =~ ^[[:xdigit:]]{1,2}(:[[:xdigit:]]{1,2}){5}$ ]] || return
24
25 # Split the mac into hex bytes
26 local oldifs="$IFS"
27 IFS=:
28 local byte
29 for byte in $str; do
30 bytes+=(0x$byte)
31 done
32 IFS="$oldifs"
33}
34
35mac_to_eui48() {
36 local mac_bytes=()
37 mac_to_bytes mac_bytes "$1" || return
38
39 # Return the EUI-64 bytes in the IPv6 format
40 printf '%02x%02x:%02x%02x:%02x%02x\n' "${mac_bytes[@]}"
41}
42
43mac_to_eui64() {
44 local mac_bytes=()
45 mac_to_bytes mac_bytes "$1" || return
46
47 # Using EUI-64 conversion rules, create the suffix bytes from MAC bytes
48 # Invert bit-0 of the first byte, and insert 0xfffe in the middle.
49 local suffix_bytes=(
50 $((mac_bytes[0] ^ 1))
51 ${mac_bytes[@]:1:2}
52 $((0xff)) $((0xfe))
53 ${mac_bytes[@]:3:3}
54 )
55
56 # Return the EUI-64 bytes in the IPv6 format
57 printf '%02x%02x:%02x%02x:%02x%02x:%02x%02x\n' "${suffix_bytes[@]}"
58}
59
60ipv6_pfx_concat() {
61 local pfx="$1"
62 local sfx="$2"
63
64 # Validate the prefix
65 if ! [[ "$pfx" =~ ^(([0-9a-fA-F]{1,4}:)+):/([0-9]+)$ ]]; then
66 echo "Invalid IPv6 prefix: $pfx" >&2
67 return 1
68 fi
69 local addr="${BASH_REMATCH[1]}"
70 local cidr="${BASH_REMATCH[3]}"
71 # Ensure prefix doesn't have too many bytes
72 local nos="${addr//:/}"
73 if (( ${#addr} - ${#nos} > (cidr+7)/16 )); then
74 echo "Too many prefix bytes: $pfx" >&2
75 return 1
76 fi
77
78 # Validate the suffix
79 if ! [[ "$sfx" =~ ^[0-9a-fA-F]{1,4}(:[0-9a-fA-F]{1,4})*$ ]]; then
80 echo "Invalid IPv6 suffix: $sfx" >&2
81 return 1
82 fi
83 # Ensure suffix doesn't have too many bytes
84 local nos="${sfx//:/}"
85 if (( ${#sfx} - ${#nos} >= (128-cidr)/16 )); then
86 echo "Too many suffix bytes: $sfx" >&2
87 return 1
88 fi
89
90 local comb="$addr:$sfx"
91 local nos="${comb//:/}"
92 if (( ${#comb} - ${#nos} == 8 )); then
93 comb="$addr$sfx"
94 fi
95 echo "$comb/$cidr"
96}
97
98ipv6_pfx_to_cidr() {
99 [[ "$1" =~ ^[0-9a-fA-F:]+/([0-9]+)$ ]] || return
100 echo "${BASH_REMATCH[1]}"
101}
102
103network_init=1
104return 0 2>/dev/null
105echo "network is a library, not executed directly" >&2
106exit 1