summaryrefslogtreecommitdiff
path: root/meta-google
diff options
context:
space:
mode:
authorWilliam A. Kennington III <wak@google.com>2021-05-07 13:07:31 +0300
committerWilliam A. Kennington III <wak@google.com>2021-05-10 22:11:03 +0300
commit70264b98c0362f850c3122966995db8ce4e8f0e8 (patch)
treee89405dbd6cd4ebf53e0757d79ac204d52077b37 /meta-google
parentaa43483ca920e70bb20efd5f0161b05e93f89a60 (diff)
downloadopenbmc-70264b98c0362f850c3122966995db8ce4e8f0e8.tar.xz
meta-google: network-sh: Add ip_to_bytes function
This will be used to compare parts of addresses instead of applying regexes to them. Change-Id: Ide7366cab967e31a74cbb4002bad1046432037e3 Signed-off-by: William A. Kennington III <wak@google.com>
Diffstat (limited to 'meta-google')
-rw-r--r--meta-google/recipes-google/networking/network-sh/lib.sh96
-rwxr-xr-xmeta-google/recipes-google/networking/network-sh/test.sh73
2 files changed, 166 insertions, 3 deletions
diff --git a/meta-google/recipes-google/networking/network-sh/lib.sh b/meta-google/recipes-google/networking/network-sh/lib.sh
index f37f7196d..2dc5103e0 100644
--- a/meta-google/recipes-google/networking/network-sh/lib.sh
+++ b/meta-google/recipes-google/networking/network-sh/lib.sh
@@ -57,6 +57,102 @@ mac_to_eui64() {
printf '%02x%02x:%02x%02x:%02x%02x:%02x%02x\n' "${suffix_bytes[@]}"
}
+ip_to_bytes() {
+ local -n bytes_out="$1"
+ local str="$2"
+
+ local bytes=()
+ local oldifs="$IFS"
+ # Heuristic for V4 / V6, validity will be checked as it is parsed
+ if [[ "$str" == *.* ]]; then
+ # Ensure we don't start or end with IFS
+ [ "${str:0:1}" != '.' ] || return 1
+ [ "${str: -1}" != '.' ] || return 1
+
+ local v
+ # Split IPv4 address into octets
+ IFS=.
+ for v in $str; do
+ # IPv4 digits are always decimal numbers
+ if ! [[ "$v" =~ ^[0-9]+$ ]]; then
+ IFS="$oldifs"
+ return 1
+ fi
+ # Each octet is a single byte, make sure the number isn't larger
+ if (( v > 0xff )); then
+ IFS="$oldifs"
+ return 1
+ fi
+ bytes+=($v)
+ done
+ # IPv4 addresses must have all 4 bytes present
+ if (( "${#bytes[@]}" != 4 )); then
+ IFS="$oldifs"
+ return 1
+ fi
+ else
+ # Ensure we bound the padding in an outer byte for
+ # IFS splitting to work correctly
+ [ "${str:0:2}" = '::' ] && str="0$str"
+ [ "${str: -2}" = '::' ] && str="${str}0"
+
+ # Ensure we don't start or end with IFS
+ [ "${str:0:1}" != ':' ] || return 1
+ [ "${str: -1}" != ':' ] || return 1
+
+ # Stores the bytes that come before ::, if it exists
+ local bytesBeforePad=()
+ local v
+ # Split the Address into hextets
+ IFS=:
+ for v in $str; do
+ # Handle ::, which translates to an empty string
+ if [ -z "$v" ]; then
+ # Only allow a single :: sequence in an address
+ if (( "${#bytesBeforePad[@]}" > 0 )); then
+ IFS="$oldifs"
+ return 1
+ fi
+ # Store the already parsed upper bytes separately
+ # This allows us to calculate and insert padding
+ bytesBeforePad=("${bytes[@]}")
+ bytes=()
+ continue
+ fi
+ # IPv6 digits are always hex
+ if ! [[ "$v" =~ ^[[:xdigit:]]+$ ]]; then
+ IFS="$oldifs"
+ return 1
+ fi
+ # Ensure the number is no larger than a hextet
+ v="0x$v"
+ if (( v > 0xffff )); then
+ IFS="$oldifs"
+ return 1
+ fi
+ # Split the hextet into 2 bytes
+ bytes+=($(( v >> 8 )))
+ bytes+=($(( v & 0xff )))
+ done
+ # If we have ::, add padding
+ if (( "${#bytesBeforePad[@]}" > 0 )); then
+ # Fill the middle bytes with padding and store in `bytes`
+ while (( "${#bytes[@]}" + "${#bytesBeforePad[@]}" < 16 )); do
+ bytesBeforePad+=(0)
+ done
+ bytes=("${bytesBeforePad[@]}" "${bytes[@]}")
+ fi
+ # IPv6 addresses must have all 16 bytes present
+ if (( "${#bytes[@]}" != 16 )); then
+ IFS="$oldifs"
+ return 1
+ fi
+ fi
+
+ IFS="$oldifs"
+ bytes_out=("${bytes[@]}")
+}
+
ipv6_pfx_concat() {
local pfx="$1"
local sfx="$2"
diff --git a/meta-google/recipes-google/networking/network-sh/test.sh b/meta-google/recipes-google/networking/network-sh/test.sh
index 57387c47c..2361cfe3e 100755
--- a/meta-google/recipes-google/networking/network-sh/test.sh
+++ b/meta-google/recipes-google/networking/network-sh/test.sh
@@ -21,6 +21,21 @@ else
fi
source lib.sh
+expect_array_numeq() {
+ local -n a1="$1"
+ local -n a2="$2"
+
+ if (( "${#a1[@]}" != "${#a2[@]}" )); then
+ echo " Line ${BASH_LINENO[0]} Array Size ${#a1[@]} != ${#a2[@]}" >&2
+ test_err=1
+ else
+ local i
+ for (( i=0; i < ${#a1[@]}; ++i )); do
+ expect_numeq "${a1[$i]}" "${a2[$i]}"
+ done
+ fi
+}
+
test_mac_to_bytes() {
out=()
expect_err 1 mac_to_bytes out ''
@@ -32,9 +47,7 @@ test_mac_to_bytes() {
expect_err 0 mac_to_bytes out 'a2:0:f:de:0:29'
expected=(0xa2 0 0xf 0xde 0 0x29)
- for (( i=0; i < ${#expected[@]}; ++i )); do
- expect_numeq "${out[$i]}" "${expected[$i]}"
- done
+ expect_array_numeq out expected
}
test_mac_to_eui_48() {
@@ -47,6 +60,60 @@ test_eui_64() {
expect_streq "$str" '1334:56ff:fe78:90af'
}
+test_ip4_to_bytes() {
+ out=()
+ expect_err 1 ip_to_bytes out ''
+ expect_err 1 ip_to_bytes out '10.0.0.'
+ expect_err 1 ip_to_bytes out '.0.1.1'
+ expect_err 1 ip_to_bytes out '10.0.0'
+ expect_err 1 ip_to_bytes out '10.0..0'
+ expect_err 1 ip_to_bytes out '.10.0.0.0'
+ expect_err 1 ip_to_bytes out '10.0.0.0.'
+ expect_err 1 ip_to_bytes out '10.0.0.256'
+ expect_err 1 ip_to_bytes out '10.0.0.0.256'
+ expect_err 1 ip_to_bytes out '10.0.0.0.1'
+
+ expect_err 0 ip_to_bytes out '10.0.0.1'
+ expected=(10 0 0 1)
+ expect_array_numeq out expected
+}
+
+test_ip6_to_bytes() {
+ out=()
+ expect_err 1 ip_to_bytes out ''
+ expect_err 1 ip_to_bytes out ':::'
+ expect_err 1 ip_to_bytes out '::z'
+ expect_err 1 ip_to_bytes out '1::1::1'
+ expect_err 1 ip_to_bytes out '1:1:1'
+ expect_err 1 ip_to_bytes out ':1::1'
+ expect_err 1 ip_to_bytes out '1::1:'
+
+ expect_err 0 ip_to_bytes out '::'
+ expected=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
+ expect_array_numeq out expected
+ out=()
+
+ expect_err 0 ip_to_bytes out '::1'
+ expected=(0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1)
+ expect_array_numeq out expected
+ out=()
+
+ expect_err 0 ip_to_bytes out 'fd00::'
+ expected=(0xfd 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
+ expect_array_numeq out expected
+ out=()
+
+ expect_err 0 ip_to_bytes out 'fd00:ffee::ddff:22'
+ expected=(0xfd 0 0xff 0xee 0 0 0 0 0 0 0 0 0xdd 0xff 0 0x22)
+ expect_array_numeq out expected
+ out=()
+
+ expect_err 0 ip_to_bytes out '1:2:3:4:5:6:7:8'
+ expected=(0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8)
+ expect_array_numeq out expected
+ out=()
+}
+
test_ipv6_pfx_concat() {
# Invalid inputs
expect_err 1 ipv6_pfx_concat 'fd/64' '1234:5678:90af'