summaryrefslogtreecommitdiff
path: root/meta-google/recipes-google/networking/network-sh/lib.sh
blob: f37f7196d7c71c037a906b11db5bb4250af35c41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/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