aboutsummaryrefslogtreecommitdiffstats
path: root/package/base-files/files/lib/functions
diff options
context:
space:
mode:
Diffstat (limited to 'package/base-files/files/lib/functions')
-rw-r--r--package/base-files/files/lib/functions/caldata.sh13
-rw-r--r--package/base-files/files/lib/functions/ipv4.sh268
-rw-r--r--package/base-files/files/lib/functions/leds.sh31
-rw-r--r--package/base-files/files/lib/functions/network.sh14
-rw-r--r--package/base-files/files/lib/functions/system.sh122
-rw-r--r--package/base-files/files/lib/functions/uci-defaults.sh59
6 files changed, 490 insertions, 17 deletions
diff --git a/package/base-files/files/lib/functions/caldata.sh b/package/base-files/files/lib/functions/caldata.sh
index 2177cf84153..d7b88c7dcef 100644
--- a/package/base-files/files/lib/functions/caldata.sh
+++ b/package/base-files/files/lib/functions/caldata.sh
@@ -48,6 +48,19 @@ caldata_extract_ubi() {
caldata_die "failed to extract calibration data from $ubi"
}
+caldata_extract_mmc() {
+ local part=$1
+ local offset=$(($2))
+ local count=$(($3))
+ local mmc_part
+
+ mmc_part=$(find_mmc_part $part)
+ [ -n "$mmc_part" ] || caldata_die "no mmc partition found for partition $part"
+
+ caldata_dd $mmc_part /lib/firmware/$FIRMWARE $count $offset || \
+ caldata_die "failed to extract calibration data from $mmc_part"
+}
+
caldata_extract_reverse() {
local part=$1
local offset=$2
diff --git a/package/base-files/files/lib/functions/ipv4.sh b/package/base-files/files/lib/functions/ipv4.sh
new file mode 100644
index 00000000000..d0b93dbcb9b
--- /dev/null
+++ b/package/base-files/files/lib/functions/ipv4.sh
@@ -0,0 +1,268 @@
+uint_max=4294967295
+
+d_10_0_0_0=167772160
+d_10_255_255_255=184549375
+
+d_172_16_0_0=2886729728
+d_172_31_255_255=2887778303
+
+d_192_168_0_0=3232235520
+d_192_168_255_255=3232301055
+
+d_169_254_0_0=2851995648
+d_169_254_255_255=2852061183
+
+d_127_0_0_0=2130706432
+d_127_255_255_255=2147483647
+
+d_224_0_0_0=3758096384
+d_239_255_255_255=4026531839
+
+# check that $1 is only base 10 digits, and that it doesn't
+# exceed 2^32-1
+assert_uint32() {
+ local __n="$1"
+
+ if [ -z "$__n" -o -n "${__n//[0-9]/}" ]; then
+ printf "Not a decimal integer (%s)\n" "$__n ">&2
+ return 1
+ fi
+
+ if [ "$__n" -gt $uint_max ]; then
+ printf "Out of range (%s)\n" "$__n" >&2
+ return 1
+ fi
+
+ if [ "$((__n + 0))" != "$__n" ]; then
+ printf "Not normalized notation (%s)\n" "$__n" >&2
+ return 1
+ fi
+
+ return 0
+}
+
+# return a count of the number of bits set in $1
+bitcount() {
+ local __var="$1" __c="$2"
+ assert_uint32 "$__c" || return 1
+
+ __c=$((((__c >> 1) & 0x55555555) + (__c & 0x55555555)))
+ __c=$((((__c >> 2) & 0x33333333) + (__c & 0x33333333)))
+ __c=$((((__c >> 4) & 0x0f0f0f0f) + (__c & 0x0f0f0f0f)))
+ __c=$((((__c >> 8) & 0x00ff00ff) + (__c & 0x00ff00ff)))
+ __c=$((((__c >> 16) & 0x0000ffff) + (__c & 0x0000ffff)))
+
+ export -- "$__var=$__c"
+}
+
+# tedious but portable with busybox's limited shell
+# we check each octet to be in the range of 0..255,
+# and also make sure there's no extaneous characters.
+str2ip() {
+ local __var="$1" __ip="$2" __n __val=0
+
+ case "$__ip" in
+ [0-9].*)
+ __n="${__ip:0:1}"
+ __ip="${__ip:2}"
+ ;;
+ [1-9][0-9].*)
+ __n="${__ip:0:2}"
+ __ip="${__ip:3}"
+ ;;
+ 1[0-9][0-9].*|2[0-4][0-9].*|25[0-5].*)
+ __n="${__ip:0:3}"
+ __ip="${__ip:4}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__n << 24))
+
+ case "$__ip" in
+ [0-9].*)
+ __n="${__ip:0:1}"
+ __ip="${__ip:2}"
+ ;;
+ [1-9][0-9].*)
+ __n="${__ip:0:2}"
+ __ip="${__ip:3}"
+ ;;
+ 1[0-9][0-9].*|2[0-4][0-9].*|25[0-5].*)
+ __n="${__ip:0:3}"
+ __ip="${__ip:4}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__val + (__n << 16)))
+
+ case "$__ip" in
+ [0-9].*)
+ __n="${__ip:0:1}"
+ __ip="${__ip:2}"
+ ;;
+ [1-9][0-9].*)
+ __n="${__ip:0:2}"
+ __ip="${__ip:3}"
+ ;;
+ 1[0-9][0-9].*|2[0-4][0-9].*|25[0-5].*)
+ __n="${__ip:0:3}"
+ __ip="${__ip:4}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__val + (__n << 8)))
+
+ case "$__ip" in
+ [0-9])
+ __n="${__ip:0:1}"
+ __ip="${__ip:1}"
+ ;;
+ [1-9][0-9])
+ __n="${__ip:0:2}"
+ __ip="${__ip:2}"
+ ;;
+ 1[0-9][0-9]|2[0-4][0-9]|25[0-5])
+ __n="${__ip:0:3}"
+ __ip="${__ip:3}"
+ ;;
+ *)
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ ;;
+ esac
+
+ __val=$((__val + __n))
+
+ if [ -n "$__ip" ]; then
+ printf "Not a dotted quad (%s)\n" "$2" >&2
+ return 1
+ fi
+
+ export -- "$__var=$__val"
+ return 0
+}
+
+# convert back from an integer to dotted-quad.
+ip2str() {
+ local __var="$1" __n="$2"
+ assert_uint32 "$__n" || return 1
+
+ export -- "$__var=$((__n >> 24)).$(((__n >> 16) & 255)).$(((__n >> 8) & 255)).$((__n & 255))"
+}
+
+# convert prefix into an integer bitmask
+prefix2netmask() {
+ local __var="$1" __n="$2"
+ assert_uint32 "$__n" || return 1
+
+ if [ "$__n" -gt 32 ]; then
+ printf "Prefix out-of-range (%s)" "$__n" >&2
+ return 1
+ fi
+
+ export -- "$__var=$(((~(uint_max >> __n)) & uint_max))"
+}
+
+_is_contiguous() {
+ local __x="$1" # no checking done
+ local __y=$((~__x & uint_max))
+ local __z=$(((__y + 1) & uint_max))
+
+ [ $((__z & __y)) -eq 0 ]
+}
+
+# check argument as being contiguous upper bits (and yes,
+# 0 doesn't have any discontiguous bits).
+is_contiguous() {
+ local __var="$1" __x="$2" __val=0
+ assert_uint32 "$__x" || return 1
+
+ local __y=$((~__x & uint_max))
+ local __z=$(((__y + 1) & uint_max))
+
+ [ $((__z & __y)) -eq 0 ] && __val=1
+
+ export -- "$__var=$__val"
+}
+
+# convert mask to prefix, validating that it's a conventional
+# (contiguous) netmask.
+netmask2prefix() {
+ local __var="$1" __n="$2" __cont __bits
+ assert_uint32 "$__n" || return 1
+
+ is_contiguous __cont "$__n" || return 1
+ if [ $__cont -eq 0 ]; then
+ printf "Not a contiguous netmask (%08x)\n" "$__n" >&2
+ return 1
+ fi
+
+ bitcount __bits "$__n" # already checked
+
+ export -- "$__var=$__bits"
+}
+
+# check the argument as being an rfc-1918 address
+is_rfc1918() {
+ local __var="$1" __x="$2" __val=0
+ assert_uint32 "$__x" || return 1
+
+ if [ $d_10_0_0_0 -le $__x ] && [ $__x -le $d_10_255_255_255 ]; then
+ __val=1
+ elif [ $d_172_16_0_0 -le $__x ] && [ $__x -le $d_172_31_255_255 ]; then
+ __val=1
+ elif [ $d_192_168_0_0 -le $__x ] && [ $__x -le $d_192_168_255_255 ]; then
+ __val=1
+ fi
+
+ export -- "$__var=$__val"
+}
+
+# check the argument as being an rfc-3927 address
+is_rfc3927() {
+ local __var="$1" __x="$2" __val=0
+ assert_uint32 "$__x" || return 1
+
+ if [ $d_169_254_0_0 -le $__x ] && [ $__x -le $d_169_254_255_255 ]; then
+ __val=1
+ fi
+
+ export -- "$__var=$__val"
+}
+
+# check the argument as being an rfc-1122 loopback address
+is_loopback() {
+ local __var="$1" __x="$2" __val=0
+ assert_uint32 "$__x" || return 1
+
+ if [ $d_127_0_0_0 -le $__x ] && [ $__x -le $d_127_255_255_255 ]; then
+ __val=1
+ fi
+
+ export -- "$__var=$__val"
+}
+
+# check the argument as being a multicast address
+is_multicast() {
+ local __var="$1" __x="$2" __val=0
+ assert_uint32 "$__x" || return 1
+
+ if [ $d_224_0_0_0 -le $__x ] && [ $__x -le $d_239_255_255_255 ]; then
+ __val=1
+ fi
+
+ export -- "$__var=$__val"
+}
+
diff --git a/package/base-files/files/lib/functions/leds.sh b/package/base-files/files/lib/functions/leds.sh
index a7532faa2fd..333d900df0c 100644
--- a/package/base-files/files/lib/functions/leds.sh
+++ b/package/base-files/files/lib/functions/leds.sh
@@ -11,6 +11,36 @@ get_dt_led_path() {
echo "$ledpath"
}
+get_dt_led_color_func() {
+ local enum
+ local func
+ local idx
+ local label
+
+ [ -e "$1/function" ] && func=$(cat "$1/function")
+ [ -e "$1/color" ] && idx=$((0x$(hexdump -n 4 -e '4/1 "%02x"' "$1/color")))
+ [ -e "$1/function-enumerator" ] && \
+ enum=$((0x$(hexdump -n 4 -e '4/1 "%02x"' "$1/function-enumerator")))
+
+ [ -z "$idx" ] && [ -z "$func" ] && return 2
+
+ if [ -n "$idx" ]; then
+ for color in "white" "red" "green" "blue" "amber" \
+ "violet" "yellow" "ir" "multicolor" "rgb" \
+ "purple" "orange" "pink" "cyan" "lime"
+ do
+ [ $idx -eq 0 ] && label="$color" && break
+ idx=$((idx-1))
+ done
+ fi
+
+ label="$label:$func"
+ [ -n "$enum" ] && label="$label-$enum"
+ echo "$label"
+
+ return 0
+}
+
get_dt_led() {
local label
local ledpath=$(get_dt_led_path $1)
@@ -18,6 +48,7 @@ get_dt_led() {
[ -n "$ledpath" ] && \
label=$(cat "$ledpath/label" 2>/dev/null) || \
label=$(cat "$ledpath/chan-name" 2>/dev/null) || \
+ label=$(get_dt_led_color_func "$ledpath") || \
label=$(basename "$ledpath")
echo "$label"
diff --git a/package/base-files/files/lib/functions/network.sh b/package/base-files/files/lib/functions/network.sh
index 055f18c11e0..4851a5817ad 100644
--- a/package/base-files/files/lib/functions/network.sh
+++ b/package/base-files/files/lib/functions/network.sh
@@ -90,6 +90,13 @@ network_get_prefix6() {
__network_ifstatus "$1" "$2" "['ipv6-prefix'][0]['address','mask']" "/"
}
+# determine first IPv6 prefix assignment of given logical interface
+# 1: destination variable
+# 2: interface
+network_get_prefix_assignment6() {
+ __network_ifstatus "$1" "$2" "['ipv6-prefix-assignment'][0]['address','mask']" "/"
+}
+
# determine all IPv4 addresses of given logical interface
# 1: destination variable
# 2: interface
@@ -187,6 +194,13 @@ network_get_prefixes6() {
__network_ifstatus "$1" "$2" "['ipv6-prefix'][*]['address','mask']" "/ "
}
+# determine all IPv6 prefix assignments of given logical interface
+# 1: destination variable
+# 2: interface
+network_get_prefix_assignments6() {
+ __network_ifstatus "$1" "$2" "['ipv6-prefix-assignment'][*]['address','mask']" "/ "
+}
+
# determine IPv4 gateway of given logical interface
# 1: destination variable
# 2: interface
diff --git a/package/base-files/files/lib/functions/system.sh b/package/base-files/files/lib/functions/system.sh
index 80e417182a2..107e67835a2 100644
--- a/package/base-files/files/lib/functions/system.sh
+++ b/package/base-files/files/lib/functions/system.sh
@@ -61,11 +61,21 @@ find_mtd_chardev() {
echo "${INDEX:+$PREFIX$INDEX}"
}
+get_mac_ascii() {
+ local part="$1"
+ local key="$2"
+ local mac_dirty
+
+ mac_dirty=$(strings "$part" | sed -n 's/^'"$key"'=//p')
+
+ # "canonicalize" mac
+ [ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
+}
+
mtd_get_mac_ascii() {
local mtdname="$1"
local key="$2"
local part
- local mac_dirty
part=$(find_mtd_part "$mtdname")
if [ -z "$part" ]; then
@@ -73,17 +83,75 @@ mtd_get_mac_ascii() {
return
fi
- mac_dirty=$(strings "$part" | sed -n 's/^'"$key"'=//p')
+ get_mac_ascii "$part" "$key"
+}
+
+mtd_get_mac_encrypted_arcadyan() {
+ local iv="00000000000000000000000000000000"
+ local key="2A4B303D7644395C3B2B7053553C5200"
+ local mac_dirty
+ local mtdname="$1"
+ local part
+ local size
+
+ part=$(find_mtd_part "$mtdname")
+ if [ -z "$part" ]; then
+ echo "mtd_get_mac_encrypted_arcadyan: partition $mtdname not found!" >&2
+ return
+ fi
+
+ # Config decryption and getting mac. Trying uencrypt and openssl utils.
+ size=$((0x$(dd if=$part skip=9 bs=1 count=4 2>/dev/null | hexdump -v -e '1/4 "%08x"')))
+ if [[ -f "/usr/bin/uencrypt" ]]; then
+ mac_dirty=$(dd if=$part bs=1 count=$size skip=$((0x100)) 2>/dev/null | \
+ uencrypt -d -n -k $key -i $iv | grep mac | cut -c 5-)
+ elif [[ -f "/usr/bin/openssl" ]]; then
+ mac_dirty=$(dd if=$part bs=1 count=$size skip=$((0x100)) 2>/dev/null | \
+ openssl aes-128-cbc -d -nopad -K $key -iv $iv | grep mac | cut -c 5-)
+ else
+ echo "mtd_get_mac_encrypted_arcadyan: Neither uencrypt nor openssl was found!" >&2
+ return
+ fi
# "canonicalize" mac
[ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
}
+mtd_get_mac_encrypted_deco() {
+ local mtdname="$1"
+
+ if ! [ -e "$mtdname" ]; then
+ echo "mtd_get_mac_encrypted_deco: file $mtdname not found!" >&2
+ return
+ fi
+
+ tplink_key="3336303032384339"
+
+ key=$(dd if=$mtdname bs=1 skip=16 count=8 2>/dev/null | \
+ uencrypt -n -d -k $tplink_key -c des-ecb | hexdump -v -n 8 -e '1/1 "%02x"')
+
+ macaddr=$(dd if=$mtdname bs=1 skip=32 count=8 2>/dev/null | \
+ uencrypt -n -d -k $key -c des-ecb | hexdump -v -n 6 -e '5/1 "%02x:" 1/1 "%02x"')
+
+ echo $macaddr
+}
+
+mtd_get_mac_uci_config_ubi() {
+ local volumename="$1"
+
+ . /lib/upgrade/nand.sh
+
+ local ubidev=$(nand_attach_ubi $CI_UBIPART)
+ local part=$(nand_find_volume $ubidev $volumename)
+
+ cat "/dev/$part" | sed -n 's/^\s*option macaddr\s*'"'"'\?\([0-9A-F:]\+\)'"'"'\?/\1/Ip'
+}
+
mtd_get_mac_text() {
- local mtdname=$1
- local offset=$(($2))
+ local mtdname="$1"
+ local offset=$((${2:-0}))
+ local length="${3:-17}"
local part
- local mac_dirty
part=$(find_mtd_part "$mtdname")
if [ -z "$part" ]; then
@@ -91,15 +159,9 @@ mtd_get_mac_text() {
return
fi
- if [ -z "$offset" ]; then
- echo "mtd_get_mac_text: offset missing!" >&2
- return
- fi
+ [ $((offset + length)) -le $(mtd_get_part_size "$mtdname") ] || return
- mac_dirty=$(dd if="$part" bs=1 skip="$offset" count=17 2>/dev/null)
-
- # "canonicalize" mac
- [ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
+ macaddr_canonicalize $(dd bs=1 if="$part" skip="$offset" count="$length" 2>/dev/null)
}
mtd_get_mac_binary() {
@@ -135,6 +197,28 @@ mtd_get_part_size() {
done < /proc/mtd
}
+mmc_get_mac_ascii() {
+ local part_name="$1"
+ local key="$2"
+ local part
+
+ part=$(find_mmc_part "$part_name")
+ if [ -z "$part" ]; then
+ echo "mmc_get_mac_ascii: partition $part_name not found!" >&2
+ fi
+
+ get_mac_ascii "$part" "$key"
+}
+
+mmc_get_mac_binary() {
+ local part_name="$1"
+ local offset="$2"
+ local part
+
+ part=$(find_mmc_part "$part_name")
+ get_mac_binary "$part" "$offset"
+}
+
macaddr_add() {
local mac=$1
local val=$2
@@ -145,6 +229,14 @@ macaddr_add() {
echo $oui:$nic
}
+macaddr_generate_from_mmc_cid() {
+ local mmc_dev=$1
+
+ local sd_hash=$(sha256sum /sys/class/block/$mmc_dev/device/cid)
+ local mac_base=$(macaddr_canonicalize "$(echo "${sd_hash}" | dd bs=1 count=12 2>/dev/null)")
+ echo "$(macaddr_unsetbit_mc "$(macaddr_setbit_la "${mac_base}")")"
+}
+
macaddr_geteui() {
local mac=$1
local sep=$2
@@ -224,3 +316,7 @@ macaddr_canonicalize() {
printf "%02x:%02x:%02x:%02x:%02x:%02x" 0x${canon// / 0x} 2>/dev/null
}
+
+dt_is_enabled() {
+ grep -q okay "/proc/device-tree/$1/status"
+}
diff --git a/package/base-files/files/lib/functions/uci-defaults.sh b/package/base-files/files/lib/functions/uci-defaults.sh
index 02882f43ca4..b89cc8e9e30 100644
--- a/package/base-files/files/lib/functions/uci-defaults.sh
+++ b/package/base-files/files/lib/functions/uci-defaults.sh
@@ -96,7 +96,7 @@ ucidef_set_interfaces_lan_wan() {
ucidef_set_bridge_device() {
json_select_object bridge
- json_add_string name "${1:switch0}"
+ json_add_string name "${1:-switch0}"
json_select ..
}
@@ -106,14 +106,30 @@ ucidef_set_bridge_mac() {
json_select ..
}
-ucidef_set_network_device_mac() {
- json_select_object "network-device"
+_ucidef_set_network_device_common() {
+ json_select_object "network_device"
json_select_object "${1}"
- json_add_string macaddr "${2}"
+ json_add_string "${2}" "${3}"
json_select ..
json_select ..
}
+ucidef_set_network_device_mac() {
+ _ucidef_set_network_device_common $1 macaddr $2
+}
+
+ucidef_set_network_device_path() {
+ _ucidef_set_network_device_common $1 path $2
+}
+
+ucidef_set_network_device_gro() {
+ _ucidef_set_network_device_common $1 gro $2
+}
+
+ucidef_set_network_device_conduit() {
+ _ucidef_set_network_device_common $1 conduit $2
+}
+
_ucidef_add_switch_port() {
# inherited: $num $device $need_tag $want_untag $role $index $prev_role
# inherited: $n_cpu $n_ports $n_vlan $cpu0 $cpu1 $cpu2 $cpu3 $cpu4 $cpu5
@@ -418,6 +434,15 @@ ucidef_set_led_default() {
json_select ..
}
+ucidef_set_led_heartbeat() {
+ _ucidef_set_led_common "$1" "$2" "$3"
+
+ json_add_string trigger heartbeat
+ json_select ..
+
+ json_select ..
+}
+
ucidef_set_led_gpio() {
local gpio="$4"
local inverted="$5"
@@ -629,6 +654,32 @@ ucidef_set_ntpserver() {
json_select ..
}
+ucidef_set_poe() {
+ json_select_object poe
+ json_add_string "budget" "$1"
+ json_select_array ports
+ for port in $2; do
+ json_add_string "" "$port"
+ done
+ json_select ..
+ json_select ..
+}
+
+ucidef_add_wlan() {
+ local path="$1"; shift
+
+ ucidef_wlan_idx=${ucidef_wlan_idx:-0}
+
+ json_select_object wlan
+ json_select_object "wl$ucidef_wlan_idx"
+ json_add_string path "$path"
+ json_add_fields "$@"
+ json_select ..
+ json_select ..
+
+ ucidef_wlan_idx="$((ucidef_wlan_idx + 1))"
+}
+
board_config_update() {
json_init
[ -f ${CFG} ] && json_load "$(cat ${CFG})"