123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- NETIFD_MAIN_DIR="${NETIFD_MAIN_DIR:-/lib/netifd}"
- . /usr/share/libubox/jshn.sh
- . $NETIFD_MAIN_DIR/utils.sh
- CMD_UP=0
- CMD_SET_DATA=1
- CMD_PROCESS_ADD=2
- CMD_PROCESS_KILL_ALL=3
- CMD_SET_RETRY=4
- add_driver() {
- return
- }
- wireless_setup_vif_failed() {
- local error="$1"
- echo "Interface $_w_iface setup failed: $error"
- }
- wireless_setup_failed() {
- local error="$1"
- echo "Device setup failed: $error"
- wireless_set_retry 0
- }
- prepare_key_wep() {
- local key="$1"
- local hex=1
- echo -n "$key" | grep -qE "[^a-fA-F0-9]" && hex=0
- [ "${#key}" -eq 10 -a $hex -eq 1 ] || \
- [ "${#key}" -eq 26 -a $hex -eq 1 ] || {
- [ "${key:0:2}" = "s:" ] && key="${key#s:}"
- key="$(echo -n "$key" | hexdump -ve '1/1 "%02x" ""')"
- }
- echo "$key"
- }
- _wdev_prepare_channel() {
- json_get_vars channel hwmode
- auto_channel=0
- enable_ht=0
- htmode=
- hwmode="${hwmode##11}"
- hwmode_n="${hwmode##n}"
- case "$channel" in
- ""|0|auto)
- channel=0
- auto_channel=1
- ;;
- [0-9]*) ;;
- *)
- wireless_setup_failed "INVALID_CHANNEL"
- ;;
- esac
- [[ "$hwmode_n" = "$hwmode" ]] || {
- enable_ht=1
- hwmode="$hwmode_n"
- json_get_vars htmode
- case "$htmode" in
- HT20|HT40+|HT40-);;
- *) htmode= ;;
- esac
- }
- case "$hwmode" in
- a|b|g) ;;
- *)
- if [ "$channel" -gt 14 ]; then
- hwmode=a
- else
- hwmode=g
- fi
- ;;
- esac
- }
- _wdev_handler() {
- json_load "$data"
- json_select config
- _wdev_prepare_channel
- json_select ..
- eval "drv_$1_$2 \"$interface\""
- }
- _wdev_msg_call() {
- local old_cb
- json_set_namespace wdev old_cb
- "$@"
- json_set_namespace $old_cb
- }
- _wdev_wrapper() {
- while [ -n "$1" ]; do
- eval "$1() { _wdev_msg_call _$1 \"\$@\"; }"
- shift
- done
- }
- _wdev_notify_init() {
- local command="$1"
- local interface="$2"
- json_init
- json_add_int "command" "$command"
- json_add_string "device" "$__netifd_device"
- [ -n "$interface" ] && json_add_string "interface" "$interface"
- json_add_object "data"
- }
- _wdev_notify() {
- local options="$1"
- json_close_object
- ubus $options call network.wireless notify "$(json_dump)"
- }
- _wdev_add_variables() {
- while [ -n "$1" ]; do
- local var="${1%%=*}"
- local val="$1"
- shift
- [[ "$var" = "$val" ]] && continue
- val="${val#*=}"
- json_add_string "$var" "$val"
- done
- }
- _wireless_add_vif() {
- local name="$1"; shift
- local ifname="$1"; shift
- _wdev_notify_init $CMD_SET_DATA "$name"
- json_add_string "ifname" "$ifname"
- _wdev_add_variables "$@"
- _wdev_notify
- }
- _wireless_set_up() {
- _wdev_notify_init $CMD_UP
- _wdev_notify
- }
- _wireless_set_data() {
- _wdev_notify_init $CMD_SET_DATA
- _wdev_add_variables "$@"
- _wdev_notify
- }
- _wireless_add_process() {
- _wdev_notify_init $CMD_PROCESS_ADD
- local exe="$2"
- [ -L "$exe" ] && exe="$(readlink -f "$exe")"
- json_add_int pid "$1"
- json_add_string exe "$exe"
- [ -n "$3" ] && json_add_boolean required 1
- exe2="$(readlink -f /proc/$1/exe)"
- [ "$exe" != "$exe2" ] && echo "WARNING (wireless_add_process): executable path $exe does not match process $1 path ($exe2)"
- _wdev_notify
- }
- _wireless_process_kill_all() {
- _wdev_notify_init $CMD_PROCESS_KILL_ALL
- [ -n "$1" ] && json_add_int signal "$1"
- _wdev_notify
- }
- _wireless_set_retry() {
- _wdev_notify_init $CMD_SET_RETRY
- json_add_int retry "$1"
- _wdev_notify
- }
- _wdev_wrapper \
- wireless_add_vif \
- wireless_set_up \
- wireless_set_data \
- wireless_add_process \
- wireless_process_kill_all \
- wireless_set_retry \
- wireless_vif_parse_encryption() {
- json_get_vars encryption
- set_default encryption none
- auth_mode_open=1
- auth_mode_shared=0
- auth_type=none
- wpa_cipher=CCMP
- case "$encryption" in
- *tkip+aes|*tkip+ccmp|*aes+tkip|*ccmp+tkip) wpa_cipher="CCMP TKIP";;
- *aes|*ccmp) wpa_cipher="CCMP";;
- *tkip) wpa_cipher="TKIP";;
- esac
- # 802.11n requires CCMP for WPA
- [ "$enable_ht:$wpa_cipher" = "1:TKIP" ] && wpa_cipher="CCMP TKIP"
- # Examples:
- # psk-mixed/tkip => WPA1+2 PSK, TKIP
- # wpa-psk2/tkip+aes => WPA2 PSK, CCMP+TKIP
- # wpa2/tkip+aes => WPA2 RADIUS, CCMP+TKIP
- case "$encryption" in
- wpa2*|wpa3*|*psk2*|psk3*|sae*|owe*)
- wpa=2
- ;;
- wpa*mixed*|*psk*mixed*)
- wpa=3
- ;;
- wpa*|*psk*)
- wpa=1
- ;;
- *)
- wpa=0
- wpa_cipher=
- ;;
- esac
- wpa_pairwise="$wpa_cipher"
- case "$encryption" in
- owe*)
- auth_type=owe
- ;;
- wpa3-mixed*)
- auth_type=eap-eap192
- ;;
- wpa3*)
- auth_type=eap192
- ;;
- psk3-mixed*|sae-mixed*)
- auth_type=psk-sae
- ;;
- psk3*|sae*)
- auth_type=sae
- ;;
- *psk*)
- auth_type=psk
- ;;
- *wpa*|*8021x*)
- auth_type=eap
- ;;
- *wep*)
- auth_type=wep
- case "$encryption" in
- *shared*)
- auth_mode_open=0
- auth_mode_shared=1
- ;;
- *mixed*)
- auth_mode_shared=1
- ;;
- esac
- ;;
- esac
- }
- _wireless_set_brsnoop_isolation() {
- local multicast_to_unicast="$1"
- local isolate
- json_get_var isolate isolate
- [ ${isolate:-0} -gt 0 -o -z "$network_bridge" ] && return
- [ ${multicast_to_unicast:-1} -gt 0 ] && json_add_boolean isolate 1
- }
- for_each_interface() {
- local _w_types="$1"; shift
- local _w_ifaces _w_iface
- local _w_type
- local _w_found
- local multicast_to_unicast
- json_get_keys _w_ifaces interfaces
- json_select interfaces
- for _w_iface in $_w_ifaces; do
- json_select "$_w_iface"
- if [ -n "$_w_types" ]; then
- json_get_var network_bridge bridge
- json_get_var multicast_to_unicast multicast_to_unicast
- json_select config
- _wireless_set_brsnoop_isolation "$multicast_to_unicast"
- json_get_var _w_type mode
- json_select ..
- _w_types=" $_w_types "
- [[ "${_w_types%$_w_type*}" = "$_w_types" ]] && {
- json_select ..
- continue
- }
- fi
- "$@" "$_w_iface"
- json_select ..
- done
- json_select ..
- }
- _wdev_common_device_config() {
- config_add_string channel hwmode htmode noscan
- }
- _wdev_common_iface_config() {
- config_add_string mode ssid encryption 'key:wpakey'
- }
- init_wireless_driver() {
- name="$1"; shift
- cmd="$1"; shift
- case "$cmd" in
- dump)
- add_driver() {
- eval "drv_$1_cleanup"
- json_init
- json_add_string name "$1"
- json_add_array device
- _wdev_common_device_config
- eval "drv_$1_init_device_config"
- json_close_array
- json_add_array iface
- _wdev_common_iface_config
- eval "drv_$1_init_iface_config"
- json_close_array
- json_dump
- }
- ;;
- setup|teardown)
- interface="$1"; shift
- data="$1"; shift
- export __netifd_device="$interface"
- add_driver() {
- [[ "$name" == "$1" ]] || return 0
- _wdev_handler "$1" "$cmd"
- }
- ;;
- esac
- }
|