2014-04-07 10:29:47 +00:00
|
|
|
# Copyright (C) 2006-2013 OpenWrt.org
|
|
|
|
|
2020-03-13 15:56:53 +00:00
|
|
|
. /lib/functions.sh
|
2019-11-04 19:44:41 +00:00
|
|
|
. /usr/share/libubox/jshn.sh
|
|
|
|
|
2018-01-26 21:54:06 +00:00
|
|
|
get_mac_binary() {
|
|
|
|
local path="$1"
|
|
|
|
local offset="$2"
|
|
|
|
|
2019-07-08 08:17:28 +00:00
|
|
|
if ! [ -e "$path" ]; then
|
2018-01-26 21:54:06 +00:00
|
|
|
echo "get_mac_binary: file $path not found!" >&2
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
hexdump -v -n 6 -s $offset -e '5/1 "%02x:" 1/1 "%02x"' $path 2>/dev/null
|
|
|
|
}
|
|
|
|
|
2019-11-04 19:44:41 +00:00
|
|
|
get_mac_label_dt() {
|
2019-08-15 13:13:21 +00:00
|
|
|
local basepath="/proc/device-tree"
|
|
|
|
local macdevice="$(cat "$basepath/aliases/label-mac-device" 2>/dev/null)"
|
|
|
|
local macaddr
|
|
|
|
|
2019-11-04 19:44:41 +00:00
|
|
|
[ -n "$macdevice" ] || return
|
|
|
|
|
|
|
|
macaddr=$(get_mac_binary "$basepath/$macdevice/mac-address" 0 2>/dev/null)
|
2019-08-15 13:13:21 +00:00
|
|
|
[ -n "$macaddr" ] || macaddr=$(get_mac_binary "$basepath/$macdevice/local-mac-address" 0 2>/dev/null)
|
2019-11-04 19:44:41 +00:00
|
|
|
|
|
|
|
echo $macaddr
|
|
|
|
}
|
|
|
|
|
|
|
|
get_mac_label_json() {
|
|
|
|
local cfg="/etc/board.json"
|
|
|
|
local macaddr
|
|
|
|
|
|
|
|
[ -s "$cfg" ] || return
|
|
|
|
|
|
|
|
json_init
|
|
|
|
json_load "$(cat $cfg)"
|
|
|
|
if json_is_a system object; then
|
|
|
|
json_select system
|
|
|
|
json_get_var macaddr label_macaddr
|
|
|
|
json_select ..
|
|
|
|
fi
|
|
|
|
|
|
|
|
echo $macaddr
|
|
|
|
}
|
|
|
|
|
|
|
|
get_mac_label() {
|
|
|
|
local macaddr=$(get_mac_label_dt)
|
|
|
|
|
|
|
|
[ -n "$macaddr" ] || macaddr=$(get_mac_label_json)
|
|
|
|
|
2019-08-15 13:13:21 +00:00
|
|
|
echo $macaddr
|
|
|
|
}
|
|
|
|
|
2014-04-07 10:29:47 +00:00
|
|
|
find_mtd_chardev() {
|
|
|
|
local INDEX=$(find_mtd_index "$1")
|
|
|
|
local PREFIX=/dev/mtd
|
|
|
|
|
|
|
|
[ -d /dev/mtd ] && PREFIX=/dev/mtd/
|
|
|
|
echo "${INDEX:+$PREFIX$INDEX}"
|
|
|
|
}
|
|
|
|
|
2018-08-11 08:48:08 +00:00
|
|
|
mtd_get_mac_ascii() {
|
2014-04-07 10:29:47 +00:00
|
|
|
local mtdname="$1"
|
|
|
|
local key="$2"
|
|
|
|
local part
|
|
|
|
local mac_dirty
|
|
|
|
|
|
|
|
part=$(find_mtd_part "$mtdname")
|
|
|
|
if [ -z "$part" ]; then
|
|
|
|
echo "mtd_get_mac_ascii: partition $mtdname not found!" >&2
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
mac_dirty=$(strings "$part" | sed -n 's/^'"$key"'=//p')
|
|
|
|
|
|
|
|
# "canonicalize" mac
|
|
|
|
[ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
|
|
|
|
}
|
|
|
|
|
2022-07-12 14:52:04 +00:00
|
|
|
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"
|
|
|
|
}
|
|
|
|
|
ath79: add support for TP-Link Deco S4
Add support for TP-Link Deco S4 wifi router
The label refers to the device as S4R and the TP-Link firmware
site calls it the Deco S4 v2. (There does not appear to be a v1)
Hardware (and FCC id) are identical to the Deco M4R v2 but the
flash layout is ordered differently and the OEM firmware encrypts
some config parameters (including the label mac address) in flash
In order to set the encrypted mac address, the wlan's caldata
node is removed from the DTS so the mac can be decrypted with
the help of the uencrypt tool and patched into the wlan fw
via hotplug
Specifications:
SoC: QCA9563-AL3A
RAM: Zentel A3R1GE40JBF
Wireless 2.4GHz: QCA9563-AL3A (main SoC)
Wireless 5GHz: QCA9886
Ethernet Switch: QCA8337N-AL3C
Flash: 16 MB SPI NOR
UART serial access (115200N1) on board via solder pads:
RX = TP1 pad
TX = TP2 pad
GND = C201 (pad nearest board edge)
The device's bootloader and web gui will only accept images that
were signed using TP-Link's RSA key, however a memory safety bug
in the bootloader can be leveraged to install openwrt without
accessing the serial console. See developer forum S4 support page
for link to a "firmware" file that starts a tftp client, or you
may generate one on your own like this:
```
python - > deco_s4_faux_fw_tftp.bin <<EOF
import sys
from struct import pack
b = pack('>I', 0x00008000) + b'X'*16 + b"fw-type:" \
+ b'x'*256 + b"S000S001S002" + pack('>I', 0x80060200) \
b += b"\x00"*(0x200-len(b)) \
+ pack(">33I", *[0x3c0887fc, 0x35083ddc, 0xad000000, 0x24050000,
0x3c048006, 0x348402a0, 0x3c1987f9, 0x373947f4,
0x0320f809, 0x00000000, 0x24050000, 0x3c048006,
0x348402d0, 0x3c1987f9, 0x373947f4, 0x0320f809,
0x00000000, 0x24050000, 0x3c048006, 0x34840300,
0x3c1987f9, 0x373947f4, 0x0320f809, 0x00000000,
0x24050000, 0x3c048006, 0x34840400, 0x3c1987f9,
0x373947f4, 0x0320f809, 0x00000000, 0x1000fff1,
0x00000000])
b += b"\xff"*(0x2A0-len(b)) + b"setenv serverip 192.168.0.2\x00"
b += b"\xff"*(0x2D0-len(b)) + b"setenv ipaddr 192.168.0.1\x00"
b += b"\xff"*(0x300-len(b)) + b"tftpboot 0x81000000 initramfs-kernel.bin\x00"
b += b"\xff"*(0x400-len(b)) + b"bootm 0x81000000\x00"
b += b"\xff"*(0x8000-len(b))
sys.stdout.buffer.write(b)
EOF
```
Installation:
1. Run tftp server on pc with static ip 192.168.0.2
2. Place openwrt "initramfs-kernel.bin" image in tftp root dir
3. Connect pc to router ethernet port1
4. While holding in reset button on bottom of router, power on router
5. From pc access router webgui at http://192.168.0.1
6. Upload deco_s4_faux_fw_tftp.bin
7. Router will load and execture in-memory openwrt
8. Switch pc back to dhcp or static 192.168.1.x
9. Flash openwrt sysupgrade image via luci/ssh at 192.168.1.1
Revert to stock:
Press and hold reset button while powering device to start the
bootloader's recovery mode, where stock firmware can be uploaded
via web gui at 192.168.0.1
Please note that one additional non-github commits is also needed:
firmware-utils: add tplink-safeloader support for Deco S4
Signed-off-by: Nick French <nickfrench@gmail.com>
2022-08-13 17:09:50 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2018-08-11 08:10:21 +00:00
|
|
|
mtd_get_mac_text() {
|
|
|
|
local mtdname=$1
|
2019-09-04 18:46:10 +00:00
|
|
|
local offset=$(($2))
|
2018-08-11 08:10:21 +00:00
|
|
|
local part
|
|
|
|
local mac_dirty
|
|
|
|
|
|
|
|
part=$(find_mtd_part "$mtdname")
|
|
|
|
if [ -z "$part" ]; then
|
|
|
|
echo "mtd_get_mac_text: partition $mtdname not found!" >&2
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -z "$offset" ]; then
|
|
|
|
echo "mtd_get_mac_text: offset missing!" >&2
|
|
|
|
return
|
|
|
|
fi
|
|
|
|
|
|
|
|
mac_dirty=$(dd if="$part" bs=1 skip="$offset" count=17 2>/dev/null)
|
|
|
|
|
|
|
|
# "canonicalize" mac
|
|
|
|
[ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
|
|
|
|
}
|
|
|
|
|
2014-04-07 10:29:47 +00:00
|
|
|
mtd_get_mac_binary() {
|
|
|
|
local mtdname="$1"
|
|
|
|
local offset="$2"
|
|
|
|
local part
|
|
|
|
|
|
|
|
part=$(find_mtd_part "$mtdname")
|
2018-01-26 21:54:06 +00:00
|
|
|
get_mac_binary "$part" "$offset"
|
2014-04-07 10:29:47 +00:00
|
|
|
}
|
|
|
|
|
2015-12-19 11:28:36 +00:00
|
|
|
mtd_get_mac_binary_ubi() {
|
|
|
|
local mtdname="$1"
|
|
|
|
local offset="$2"
|
|
|
|
|
|
|
|
. /lib/upgrade/nand.sh
|
|
|
|
|
|
|
|
local ubidev=$(nand_find_ubi $CI_UBIPART)
|
|
|
|
local part=$(nand_find_volume $ubidev $1)
|
|
|
|
|
2019-09-05 11:29:37 +00:00
|
|
|
get_mac_binary "/dev/$part" "$offset"
|
2015-12-19 11:28:36 +00:00
|
|
|
}
|
|
|
|
|
2014-04-07 10:29:47 +00:00
|
|
|
mtd_get_part_size() {
|
|
|
|
local part_name=$1
|
|
|
|
local first dev size erasesize name
|
|
|
|
while read dev size erasesize name; do
|
|
|
|
name=${name#'"'}; name=${name%'"'}
|
|
|
|
if [ "$name" = "$part_name" ]; then
|
|
|
|
echo $((0x$size))
|
|
|
|
break
|
|
|
|
fi
|
|
|
|
done < /proc/mtd
|
|
|
|
}
|
|
|
|
|
2020-09-01 23:18:16 +00:00
|
|
|
mmc_get_mac_binary() {
|
|
|
|
local part_name="$1"
|
|
|
|
local offset="$2"
|
|
|
|
local part
|
|
|
|
|
|
|
|
part=$(find_mmc_part "$part_name")
|
|
|
|
get_mac_binary "$part" "$offset"
|
|
|
|
}
|
|
|
|
|
2014-04-07 10:29:47 +00:00
|
|
|
macaddr_add() {
|
|
|
|
local mac=$1
|
|
|
|
local val=$2
|
|
|
|
local oui=${mac%:*:*:*}
|
|
|
|
local nic=${mac#*:*:*:}
|
|
|
|
|
2020-01-17 04:43:59 +00:00
|
|
|
nic=$(printf "%06x" $((0x${nic//:/} + val & 0xffffff)) | sed 's/^\(.\{2\}\)\(.\{2\}\)\(.\{2\}\)/\1:\2:\3/')
|
2014-04-07 10:29:47 +00:00
|
|
|
echo $oui:$nic
|
|
|
|
}
|
|
|
|
|
2022-12-23 21:03:14 +00:00
|
|
|
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}")")"
|
|
|
|
}
|
|
|
|
|
2019-11-04 19:44:41 +00:00
|
|
|
macaddr_geteui() {
|
|
|
|
local mac=$1
|
|
|
|
local sep=$2
|
|
|
|
|
|
|
|
echo ${mac:9:2}$sep${mac:12:2}$sep${mac:15:2}
|
|
|
|
}
|
|
|
|
|
2020-01-25 14:06:07 +00:00
|
|
|
macaddr_setbit() {
|
|
|
|
local mac=$1
|
|
|
|
local bit=${2:-0}
|
|
|
|
|
|
|
|
[ $bit -gt 0 -a $bit -le 48 ] || return
|
|
|
|
|
|
|
|
printf "%012x" $(( 0x${mac//:/} | 2**(48-bit) )) | sed -e 's/\(.\{2\}\)/\1:/g' -e 's/:$//'
|
|
|
|
}
|
|
|
|
|
|
|
|
macaddr_unsetbit() {
|
2014-04-07 10:29:47 +00:00
|
|
|
local mac=$1
|
2020-01-25 14:06:07 +00:00
|
|
|
local bit=${2:-0}
|
|
|
|
|
|
|
|
[ $bit -gt 0 -a $bit -le 48 ] || return
|
2014-04-07 10:29:47 +00:00
|
|
|
|
2020-01-25 14:06:07 +00:00
|
|
|
printf "%012x" $(( 0x${mac//:/} & ~(2**(48-bit)) )) | sed -e 's/\(.\{2\}\)/\1:/g' -e 's/:$//'
|
|
|
|
}
|
|
|
|
|
|
|
|
macaddr_setbit_la() {
|
|
|
|
macaddr_setbit $1 7
|
2014-04-07 10:29:47 +00:00
|
|
|
}
|
|
|
|
|
2020-07-11 11:48:40 +00:00
|
|
|
macaddr_unsetbit_mc() {
|
|
|
|
local mac=$1
|
|
|
|
|
|
|
|
printf "%02x:%s" $((0x${mac%%:*} & ~0x01)) ${mac#*:}
|
|
|
|
}
|
|
|
|
|
|
|
|
macaddr_random() {
|
|
|
|
local randsrc=$(get_mac_binary /dev/urandom 0)
|
|
|
|
|
|
|
|
echo "$(macaddr_unsetbit_mc "$(macaddr_setbit_la "${randsrc}")")"
|
|
|
|
}
|
|
|
|
|
2018-08-11 08:48:08 +00:00
|
|
|
macaddr_2bin() {
|
2014-04-07 10:29:47 +00:00
|
|
|
local mac=$1
|
|
|
|
|
|
|
|
echo -ne \\x${mac//:/\\x}
|
|
|
|
}
|
|
|
|
|
2018-08-11 08:48:08 +00:00
|
|
|
macaddr_canonicalize() {
|
2014-04-07 10:29:47 +00:00
|
|
|
local mac="$1"
|
|
|
|
local canon=""
|
|
|
|
|
2014-07-14 10:25:49 +00:00
|
|
|
mac=$(echo -n $mac | tr -d \")
|
2014-04-07 10:29:47 +00:00
|
|
|
[ ${#mac} -gt 17 ] && return
|
|
|
|
[ -n "${mac//[a-fA-F0-9\.: -]/}" ] && return
|
|
|
|
|
|
|
|
for octet in ${mac//[\.:-]/ }; do
|
|
|
|
case "${#octet}" in
|
|
|
|
1)
|
|
|
|
octet="0${octet}"
|
|
|
|
;;
|
|
|
|
2)
|
|
|
|
;;
|
|
|
|
4)
|
|
|
|
octet="${octet:0:2} ${octet:2:2}"
|
|
|
|
;;
|
|
|
|
12)
|
|
|
|
octet="${octet:0:2} ${octet:2:2} ${octet:4:2} ${octet:6:2} ${octet:8:2} ${octet:10:2}"
|
|
|
|
;;
|
|
|
|
*)
|
|
|
|
return
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
canon=${canon}${canon:+ }${octet}
|
|
|
|
done
|
|
|
|
|
|
|
|
[ ${#canon} -ne 17 ] && return
|
|
|
|
|
|
|
|
printf "%02x:%02x:%02x:%02x:%02x:%02x" 0x${canon// / 0x} 2>/dev/null
|
|
|
|
}
|
2022-09-30 17:19:51 +00:00
|
|
|
|
|
|
|
dt_is_enabled() {
|
|
|
|
grep -q okay "/proc/device-tree/$1/status"
|
|
|
|
}
|