[package] hostap-driver: Add support for multiple interfaces
[openwrt/svn-archive/archive.git] / package / hostap-driver / files / lib / wifi / hostap.sh
1 #!/bin/sh
2 append DRIVERS "prism2"
3
4 find_prism2_phy() {
5 local device="$1"
6
7 local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
8 config_get phy "$device" phy
9 [ -z "$phy" -a -n "$macaddr" ] && {
10 cd /proc/net/hostap
11 for phy in $(ls -d wlan* 2>&-); do
12 [ "$macaddr" = "$(cat /sys/class/net/${phy}/address)" ] || continue
13 config_set "$device" phy "$phy"
14 break
15 done
16 config_get phy "$device" phy
17 }
18 [ -n "$phy" -a -d "/proc/net/hostap/$phy" ] || {
19 echo "phy for wifi device $1 not found"
20 return 1
21 }
22 [ -z "$macaddr" ] && {
23 config_set "$device" macaddr "$(cat /sys/class/net/${phy}/address)"
24 }
25 return 0
26 }
27
28 scan_prism2() {
29 local device="$1"
30 local mainvif
31 local wds
32
33 [ ${device%[0-9]} = "wlan" ] && config_set "$device" phy "$device" || find_prism2_phy "$device" || {
34 config_unset "$device" vifs
35 return 0
36 }
37 config_get phy "$device" phy
38
39 config_get vifs "$device" vifs
40 local _c=0
41 for vif in $vifs; do
42 config_get mode "$vif" mode
43 case "$mode" in
44 adhoc|sta|ap|monitor)
45 # Only one vif is allowed on AP, station, Ad-hoc or monitor mode
46 [ -z "$mainvif" ] && {
47 mainvif="$vif"
48 config_set "$vif" ifname "$phy"
49 }
50 ;;
51 wds)
52 config_get ssid "$vif" ssid
53 [ -z "$ssid" ] && continue
54 config_set "$vif" ifname "${phy}wds${_c}"
55 _c=$(($_c + 1))
56 addr="$ssid"
57 ${addr:+append wds "$vif"}
58 ;;
59 *) echo "$device($vif): Invalid mode, ignored."; continue;;
60 esac
61 done
62 config_set "$device" vifs "${mainvif:+$mainvif }${wds:+$wds}"
63 }
64
65 disable_prism2() (
66 local device="$1"
67
68 find_prism2_phy "$device" || return 0
69 config_get phy "$device" phy
70
71 set_wifi_down "$device"
72
73 include /lib/network
74 while read line < /proc/net/hostap/${phy}/wds; do
75 set $line
76 [ -f "/var/run/wifi-${1}.pid" ] &&
77 kill "$(cat "/var/run/wifi-${1}.pid")"
78 ifconfig "$1" down
79 unbridge "$1"
80 iwpriv "$phy" wds_del "$2"
81 done
82 unbridge "$phy"
83 return 0
84 )
85
86 enable_prism2() {
87 local device="$1"
88
89 find_prism2_phy "$device" || return 0
90 config_get phy "$device" phy
91
92 config_get rxantenna "$device" rxantenna
93 config_get txantenna "$device" txantenna
94 config_get_bool diversity "$device" diversity
95 [ -n "$diversity" ] && {
96 rxantenna="1"
97 txantenna="1"
98 }
99 [ -n "$rxantenna" ] && iwpriv "$phy" antsel_rx "$rxantenna"
100 [ -n "$txantenna" ] && iwpriv "$phy" antsel_tx "$txantenna"
101
102 config_get channel "$device" channel
103 [ -n "$channel" ] && iwconfig "$phy" channel "$channel" >/dev/null 2>/dev/null
104
105 config_get txpower "$device" txpower
106 [ -n "$txpower" ] && iwconfig "$phy" txpower "${txpower%%.*}"
107
108 config_get vifs "$device" vifs
109 local first=1
110 for vif in $vifs; do
111 config_get ifname "$vif" ifname
112 config_get ssid "$vif" ssid
113 config_get mode "$vif" mode
114
115 [ "$mode" = "wds" ] || iwconfig "$phy" essid -- "$ssid"
116
117 case "$mode" in
118 sta)
119 iwconfig "$phy" mode managed
120 config_get addr "$device" bssid
121 [ -z "$addr" ] || {
122 iwconfig "$phy" ap "$addr"
123 }
124 ;;
125 ap) iwconfig "$phy" mode master;;
126 wds) iwpriv "$phy" wds_add "$ssid";;
127 *) iwconfig "$phy" mode "$mode";;
128 esac
129
130 [ "$first" = 1 ] && {
131 config_get rate "$vif" rate
132 [ -n "$rate" ] && iwconfig "$phy" rate "${rate%%.*}"
133
134 config_get_bool hidden "$vif" hidden 0
135 iwpriv "$phy" enh_sec "$hidden"
136
137 config_get frag "$vif" frag
138 [ -n "$frag" ] && iwconfig "$phy" frag "${frag%%.*}"
139
140 config_get rts "$vif" rts
141 [ -n "$rts" ] && iwconfig "$phy" rts "${rts%%.*}"
142
143 config_get maclist "$vif" maclist
144 [ -n "$maclist" ] && {
145 # flush MAC list
146 iwpriv "$phy" maccmd 3
147 for mac in $maclist; do
148 iwpriv "$phy" addmac "$mac"
149 done
150 }
151 config_get macpolicy "$vif" macpolicy
152 case "$macpolicy" in
153 allow)
154 iwpriv "$phy" maccmd 2
155 ;;
156 deny)
157 iwpriv "$phy" maccmd 1
158 ;;
159 *)
160 # default deny policy if mac list exists
161 [ -n "$maclist" ] && iwpriv "$phy" maccmd 1
162 ;;
163 esac
164 # kick all stations if we have policy explicitly set
165 [ -n "$macpolicy" ] && iwpriv "$phy" maccmd 4
166 }
167
168 config_get enc "$vif" encryption
169 case "$enc" in
170 WEP|wep)
171 for idx in 1 2 3 4; do
172 config_get key "$vif" "key${idx}"
173 iwconfig "$ifname" enc "[$idx]" "${key:-off}"
174 done
175 config_get key "$vif" key
176 key="${key:-1}"
177 case "$key" in
178 [1234]) iwconfig "$ifname" enc "[$key]";;
179 *) iwconfig "$ifname" enc "$key";;
180 esac
181 ;;
182 psk*|wpa*)
183 start_hostapd=1
184 config_get key "$vif" key
185 ;;
186 esac
187
188 local net_cfg bridge
189 net_cfg="$(find_net_config "$vif")"
190 [ -z "$net_cfg" ] || {
191 bridge="$(bridge_interface "$net_cfg")"
192 config_set "$vif" bridge "$bridge"
193 start_net "$ifname" "$net_cfg"
194 }
195 set_wifi_up "$vif" "$ifname"
196
197 case "$mode" in
198 ap)
199 if [ -n "$start_hostapd" ] && eval "type hostapd_setup_vif" 2>/dev/null >/dev/null; then
200 hostapd_setup_vif "$vif" hostap || {
201 echo "enable_prism2($device): Failed to set up hostapd for interface $ifname" >&2
202 # make sure this wifi interface won't accidentally stay open without encryption
203 ifconfig "$ifname" down
204 continue
205 }
206 fi
207 ;;
208 wds|sta)
209 if eval "type wpa_supplicant_setup_vif" 2>/dev/null >/dev/null; then
210 wpa_supplicant_setup_vif "$vif" hostap || {
211 echo "enable_prism2($device): Failed to set up wpa_supplicant for interface $ifname" >&2
212 ifconfig "$ifname" down
213 continue
214 }
215 fi
216 ;;
217 esac
218 first=0
219 done
220
221 }
222
223 check_device() {
224 [ ${1%[0-9]} = "wlan" ] && config_set "$1" phy "$1"
225 config_get phy "$1" phy
226 [ -z "$phy" ] && {
227 find_prism2_phy "$1" >/dev/null || return 0
228 config_get phy "$1" phy
229 }
230 [ "$phy" = "$dev" ] && found=1
231 }
232
233 detect_prism2() {
234 devidx=0
235 config_load wireless
236 while :; do
237 config_get type "radio$devidx" type
238 [ -n "$type" ] || break
239 devidx=$(($devidx + 1))
240 done
241 cd /proc/net/hostap
242 [ -d wlan* ] || return
243 for dev in $(ls -d wlan* 2>&-); do
244 found=0
245 config_foreach check_device wifi-device
246 [ "$found" -gt 0 ] && continue
247 cat <<EOF
248
249 config wifi-device radio$devidx
250 option type prism2
251 option channel 11
252 option macaddr $(cat /sys/class/net/${dev}/address)
253
254 # REMOVE THIS LINE TO ENABLE WIFI:
255 option disabled 1
256
257 config wifi-iface
258 option device radio$devidx
259 option network lan
260 option mode ap
261 option ssid OpenWrt
262 option encryption none
263 EOF
264 devidx=$(($devidx + 1))
265 done
266 }