system.sh 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. # Copyright (C) 2006-2013 OpenWrt.org
  2. . /lib/functions.sh
  3. . /usr/share/libubox/jshn.sh
  4. get_mac_binary() {
  5. local path="$1"
  6. local offset="$2"
  7. if ! [ -e "$path" ]; then
  8. echo "get_mac_binary: file $path not found!" >&2
  9. return
  10. fi
  11. hexdump -v -n 6 -s $offset -e '5/1 "%02x:" 1/1 "%02x"' $path 2>/dev/null
  12. }
  13. get_mac_label_dt() {
  14. local basepath="/proc/device-tree"
  15. local macdevice="$(cat "$basepath/aliases/label-mac-device" 2>/dev/null)"
  16. local macaddr
  17. [ -n "$macdevice" ] || return
  18. macaddr=$(get_mac_binary "$basepath/$macdevice/mac-address" 0 2>/dev/null)
  19. [ -n "$macaddr" ] || macaddr=$(get_mac_binary "$basepath/$macdevice/local-mac-address" 0 2>/dev/null)
  20. echo $macaddr
  21. }
  22. get_mac_label_json() {
  23. local cfg="/etc/board.json"
  24. local macaddr
  25. [ -s "$cfg" ] || return
  26. json_init
  27. json_load "$(cat $cfg)"
  28. if json_is_a system object; then
  29. json_select system
  30. json_get_var macaddr label_macaddr
  31. json_select ..
  32. fi
  33. echo $macaddr
  34. }
  35. get_mac_label() {
  36. local macaddr=$(get_mac_label_dt)
  37. [ -n "$macaddr" ] || macaddr=$(get_mac_label_json)
  38. echo $macaddr
  39. }
  40. find_mtd_chardev() {
  41. local INDEX=$(find_mtd_index "$1")
  42. local PREFIX=/dev/mtd
  43. [ -d /dev/mtd ] && PREFIX=/dev/mtd/
  44. echo "${INDEX:+$PREFIX$INDEX}"
  45. }
  46. get_mac_ascii() {
  47. local part="$1"
  48. local key="$2"
  49. local mac_dirty
  50. mac_dirty=$(strings "$part" | sed -n 's/^'"$key"'=//p')
  51. # "canonicalize" mac
  52. [ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
  53. }
  54. mtd_get_mac_ascii() {
  55. local mtdname="$1"
  56. local key="$2"
  57. local part
  58. part=$(find_mtd_part "$mtdname")
  59. if [ -z "$part" ]; then
  60. echo "mtd_get_mac_ascii: partition $mtdname not found!" >&2
  61. return
  62. fi
  63. get_mac_ascii "$part" "$key"
  64. }
  65. mtd_get_mac_encrypted_arcadyan() {
  66. local iv="00000000000000000000000000000000"
  67. local key="2A4B303D7644395C3B2B7053553C5200"
  68. local mac_dirty
  69. local mtdname="$1"
  70. local part
  71. local size
  72. part=$(find_mtd_part "$mtdname")
  73. if [ -z "$part" ]; then
  74. echo "mtd_get_mac_encrypted_arcadyan: partition $mtdname not found!" >&2
  75. return
  76. fi
  77. # Config decryption and getting mac. Trying uencrypt and openssl utils.
  78. size=$((0x$(dd if=$part skip=9 bs=1 count=4 2>/dev/null | hexdump -v -e '1/4 "%08x"')))
  79. if [[ -f "/usr/bin/uencrypt" ]]; then
  80. mac_dirty=$(dd if=$part bs=1 count=$size skip=$((0x100)) 2>/dev/null | \
  81. uencrypt -d -n -k $key -i $iv | grep mac | cut -c 5-)
  82. elif [[ -f "/usr/bin/openssl" ]]; then
  83. mac_dirty=$(dd if=$part bs=1 count=$size skip=$((0x100)) 2>/dev/null | \
  84. openssl aes-128-cbc -d -nopad -K $key -iv $iv | grep mac | cut -c 5-)
  85. else
  86. echo "mtd_get_mac_encrypted_arcadyan: Neither uencrypt nor openssl was found!" >&2
  87. return
  88. fi
  89. # "canonicalize" mac
  90. [ -n "$mac_dirty" ] && macaddr_canonicalize "$mac_dirty"
  91. }
  92. mtd_get_mac_encrypted_deco() {
  93. local mtdname="$1"
  94. if ! [ -e "$mtdname" ]; then
  95. echo "mtd_get_mac_encrypted_deco: file $mtdname not found!" >&2
  96. return
  97. fi
  98. tplink_key="3336303032384339"
  99. key=$(dd if=$mtdname bs=1 skip=16 count=8 2>/dev/null | \
  100. uencrypt -n -d -k $tplink_key -c des-ecb | hexdump -v -n 8 -e '1/1 "%02x"')
  101. macaddr=$(dd if=$mtdname bs=1 skip=32 count=8 2>/dev/null | \
  102. uencrypt -n -d -k $key -c des-ecb | hexdump -v -n 6 -e '5/1 "%02x:" 1/1 "%02x"')
  103. echo $macaddr
  104. }
  105. mtd_get_mac_uci_config_ubi() {
  106. local volumename="$1"
  107. . /lib/upgrade/nand.sh
  108. local ubidev=$(nand_attach_ubi $CI_UBIPART)
  109. local part=$(nand_find_volume $ubidev $volumename)
  110. cat "/dev/$part" | sed -n 's/^\s*option macaddr\s*'"'"'\?\([0-9A-F:]\+\)'"'"'\?/\1/Ip'
  111. }
  112. mtd_get_mac_text() {
  113. local mtdname="$1"
  114. local offset=$((${2:-0}))
  115. local length="${3:-17}"
  116. local part
  117. part=$(find_mtd_part "$mtdname")
  118. if [ -z "$part" ]; then
  119. echo "mtd_get_mac_text: partition $mtdname not found!" >&2
  120. return
  121. fi
  122. [ $((offset + length)) -le $(mtd_get_part_size "$mtdname") ] || return
  123. macaddr_canonicalize $(dd bs=1 if="$part" skip="$offset" count="$length" 2>/dev/null)
  124. }
  125. mtd_get_mac_binary() {
  126. local mtdname="$1"
  127. local offset="$2"
  128. local part
  129. part=$(find_mtd_part "$mtdname")
  130. get_mac_binary "$part" "$offset"
  131. }
  132. mtd_get_mac_binary_ubi() {
  133. local mtdname="$1"
  134. local offset="$2"
  135. . /lib/upgrade/nand.sh
  136. local ubidev=$(nand_find_ubi $CI_UBIPART)
  137. local part=$(nand_find_volume $ubidev $1)
  138. get_mac_binary "/dev/$part" "$offset"
  139. }
  140. mtd_get_part_size() {
  141. local part_name=$1
  142. local first dev size erasesize name
  143. while read dev size erasesize name; do
  144. name=${name#'"'}; name=${name%'"'}
  145. if [ "$name" = "$part_name" ]; then
  146. echo $((0x$size))
  147. break
  148. fi
  149. done < /proc/mtd
  150. }
  151. mmc_get_mac_ascii() {
  152. local part_name="$1"
  153. local key="$2"
  154. local part
  155. part=$(find_mmc_part "$part_name")
  156. if [ -z "$part" ]; then
  157. echo "mmc_get_mac_ascii: partition $part_name not found!" >&2
  158. return
  159. fi
  160. get_mac_ascii "$part" "$key"
  161. }
  162. mmc_get_mac_binary() {
  163. local part_name="$1"
  164. local offset="$2"
  165. local part
  166. part=$(find_mmc_part "$part_name")
  167. get_mac_binary "$part" "$offset"
  168. }
  169. macaddr_add() {
  170. local mac=$1
  171. local val=$2
  172. local oui=${mac%:*:*:*}
  173. local nic=${mac#*:*:*:}
  174. nic=$(printf "%06x" $((0x${nic//:/} + val & 0xffffff)) | sed 's/^\(.\{2\}\)\(.\{2\}\)\(.\{2\}\)/\1:\2:\3/')
  175. echo $oui:$nic
  176. }
  177. macaddr_generate_from_mmc_cid() {
  178. local mmc_dev=$1
  179. local sd_hash=$(sha256sum /sys/class/block/$mmc_dev/device/cid)
  180. local mac_base=$(macaddr_canonicalize "$(echo "${sd_hash}" | dd bs=1 count=12 2>/dev/null)")
  181. echo "$(macaddr_unsetbit_mc "$(macaddr_setbit_la "${mac_base}")")"
  182. }
  183. macaddr_geteui() {
  184. local mac=$1
  185. local sep=$2
  186. echo ${mac:9:2}$sep${mac:12:2}$sep${mac:15:2}
  187. }
  188. macaddr_setbit() {
  189. local mac=$1
  190. local bit=${2:-0}
  191. [ $bit -gt 0 -a $bit -le 48 ] || return
  192. printf "%012x" $(( 0x${mac//:/} | 2**(48-bit) )) | sed -e 's/\(.\{2\}\)/\1:/g' -e 's/:$//'
  193. }
  194. macaddr_unsetbit() {
  195. local mac=$1
  196. local bit=${2:-0}
  197. [ $bit -gt 0 -a $bit -le 48 ] || return
  198. printf "%012x" $(( 0x${mac//:/} & ~(2**(48-bit)) )) | sed -e 's/\(.\{2\}\)/\1:/g' -e 's/:$//'
  199. }
  200. macaddr_setbit_la() {
  201. macaddr_setbit $1 7
  202. }
  203. macaddr_unsetbit_mc() {
  204. local mac=$1
  205. printf "%02x:%s" $((0x${mac%%:*} & ~0x01)) ${mac#*:}
  206. }
  207. macaddr_random() {
  208. local randsrc=$(get_mac_binary /dev/urandom 0)
  209. echo "$(macaddr_unsetbit_mc "$(macaddr_setbit_la "${randsrc}")")"
  210. }
  211. macaddr_canonicalize() {
  212. local mac="$1"
  213. local canon=""
  214. mac=$(echo -n $mac | tr -d \")
  215. [ ${#mac} -gt 17 ] && return
  216. [ -n "${mac//[a-fA-F0-9\.: -]/}" ] && return
  217. for octet in ${mac//[\.:-]/ }; do
  218. case "${#octet}" in
  219. 1)
  220. octet="0${octet}"
  221. ;;
  222. 2)
  223. ;;
  224. 4)
  225. octet="${octet:0:2} ${octet:2:2}"
  226. ;;
  227. 12)
  228. octet="${octet:0:2} ${octet:2:2} ${octet:4:2} ${octet:6:2} ${octet:8:2} ${octet:10:2}"
  229. ;;
  230. *)
  231. return
  232. ;;
  233. esac
  234. canon=${canon}${canon:+ }${octet}
  235. done
  236. [ ${#canon} -ne 17 ] && return
  237. printf "%02x:%02x:%02x:%02x:%02x:%02x" 0x${canon// / 0x} 2>/dev/null
  238. }
  239. dt_is_enabled() {
  240. grep -q okay "/proc/device-tree/$1/status"
  241. }