diff options
Diffstat (limited to 'package/base-files/files/lib/functions')
| -rw-r--r-- | package/base-files/files/lib/functions/caldata.sh | 13 | ||||
| -rw-r--r-- | package/base-files/files/lib/functions/ipv4.sh | 268 | ||||
| -rw-r--r-- | package/base-files/files/lib/functions/leds.sh | 31 | ||||
| -rw-r--r-- | package/base-files/files/lib/functions/network.sh | 14 | ||||
| -rw-r--r-- | package/base-files/files/lib/functions/system.sh | 122 | ||||
| -rw-r--r-- | package/base-files/files/lib/functions/uci-defaults.sh | 59 |
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})" |
