9024ab25aea538adfc8234fda9d2dea4a0b5b57c
[people/ms/network.git] / src / functions / functions.hostapd
1 #!/bin/bash
2 ###############################################################################
3 #                                                                             #
4 # IPFire.org - A linux based firewall                                         #
5 # Copyright (C) 2012  IPFire Network Development Team                         #
6 #                                                                             #
7 # This program is free software: you can redistribute it and/or modify        #
8 # it under the terms of the GNU General Public License as published by        #
9 # the Free Software Foundation, either version 3 of the License, or           #
10 # (at your option) any later version.                                         #
11 #                                                                             #
12 # This program is distributed in the hope that it will be useful,             #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of              #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
15 # GNU General Public License for more details.                                #
16 #                                                                             #
17 # You should have received a copy of the GNU General Public License           #
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
19 #                                                                             #
20 ###############################################################################
21
22 HOSTAPD_CONTROL_INTERFACE_DIR="/run/hostapd/ctrl"
23
24 HOSTAPD_SUPPORTED_MODES="802.11a 802.11a/n 802.11ac 802.11g 802.11g/n"
25
26 hostapd_config_write() {
27         local device=${1}
28         assert isset device
29
30         local file=${2}
31         assert isset file
32
33         # Shift the device and file argument.
34         shift 2
35
36         local broadcast_ssid
37         local channel
38         local channel_bandwidth
39         local country_code="$(wireless_get_reg_domain)"
40         local dfs="on"
41         local encryption
42         local key
43         local mode
44         local ssid
45         local wmm="1"
46
47         while [ $# -gt 0 ]; do
48                 case "${1}" in
49                         --broadcast-ssid=*)
50                                 broadcast_ssid=$(cli_get_val "${1}")
51                                 ;;
52                         --channel=*)
53                                 channel=$(cli_get_val "${1}")
54                                 ;;
55                         --channel-bandwidth=*)
56                                 channel_bandwidth="$(cli_get_val "${1}")"
57                                 ;;
58                         --dfs=*)
59                                 dfs="$(cli_get_val "${1}")"
60                                 ;;
61                         --encryption=*)
62                                 encryption=$(cli_get_val "${1}")
63                                 ;;
64                         --key=*)
65                                 key=$(cli_get_val "${1}")
66                                 ;;
67                         --mode=*)
68                                 mode=$(cli_get_val "${1}")
69
70                                 if ! isoneof mode ${HOSTAPD_SUPPORTED_MODES}; then
71                                         error "Unsupported mode: ${mode}"
72                                         return ${EXIT_ERROR}
73                                 fi
74                                 ;;
75                         --ssid=*)
76                                 ssid=$(cli_get_val "${1}")
77                                 ;;
78                         --wmm=*)
79                                 local val="$(cli_get_val "${1}")"
80                                 if enabled val; then
81                                         wmm="1"
82                                 else
83                                         wmm="0"
84                                 fi
85                                 ;;
86                         *)
87                                 warning_log "Ignoring unknown argument '${1}'."
88                                 ;;                      
89                 esac
90                 shift
91         done
92
93         # Check if mode is set
94         if ! isset mode; then
95                 error "Mode is not set"
96                 return ${EXIT_ERROR}
97         fi
98
99         assert isset broadcast_ssid
100         assert isbool broadcast_ssid
101
102         assert isset channel
103         assert isinteger channel
104
105         assert isset mode
106         assert isset ssid
107
108         # Check if key is set when encryption is used.
109         if isset encryption; then
110                 assert isoneof encryption WPA WPA2 WPA/WPA2
111                 assert isset key
112         fi
113
114         # With channel 0, ACS must be supported
115         if [ ${channel} -eq 0 ] && ! wireless_supports_acs "${device}"; then
116                 error "ACS requested, but not supported by ${device}"
117                 return ${EXIT_ERROR}
118         fi
119
120         # Check channel bandwidth for validity
121         if isset channel_bandwidth && ! wireless_channel_bandwidth_is_valid "${mode}" "${channel_bandwidth}"; then
122                 error "Invalid channel bandwidth for ${mode}: ${channel_bandwidth}"
123                 return ${EXIT_ERROR}
124         fi
125
126         # 802.11ac/n flags
127         local ieee80211ac
128         local ieee80211n
129         local vht_caps
130         local vht_oper_chwidth="0"
131         local ht_caps
132
133         local hw_mode
134         case "${mode}" in
135                 802.11a)
136                         hw_mode="a"
137                         ;;
138
139                 802.11a/n)
140                         hw_mode="a"
141                         ieee80211n="1"
142
143                         # Fetch HT caps
144                         ht_caps="$(wireless_get_ht_caps "${device}")"
145                         ;;
146
147                 802.11g)
148                         hw_mode="g"
149                         ;;
150
151                 802.11g/n)
152                         hw_mode="g"
153                         ieee80211n="1"
154
155                         # Fetch HT caps
156                         ht_caps="$(wireless_get_ht_caps "${device}")"
157                         ;;
158
159                 802.11ac)
160                         hw_mode="a"
161                         ieee80211ac="1"
162                         ieee80211n="1"
163
164                         # Fetch VHT caps
165                         vht_caps="$(wireless_get_vht_caps "${device}")"
166
167                         # Fetch HT caps
168                         ht_caps="$(wireless_get_ht_caps "${device}")"
169
170                         case "${channel_bandwidth}" in
171                                 80)
172                                         vht_oper_chwidth="1"
173                                         ;;
174                                 160)
175                                         vht_oper_chwidth="2"
176                                         ;;
177                                 80+80)
178                                         vht_oper_chwidth="3"
179                                         ;;
180                         esac
181                         ;;
182         esac
183
184         # Create configuration directory.
185         local config_dir=$(dirname ${file})
186         mkdir -p ${HOSTAPD_CONTROL_INTERFACE_DIR} ${config_dir} 2>/dev/null
187
188         config_header "hostapd" > ${file}
189
190         # Interface configuration
191         (
192                 print "# Interface configuration"
193                 print "driver=nl80211"
194                 print "interface=${device}"
195                 print
196         ) >> ${file}
197
198         # Wireless configuration
199         local ignore_broadcast_ssid
200         if enabled broadcast_ssid; then
201                 ignore_broadcast_ssid="0"
202         else
203                 ignore_broadcast_ssid="1"
204         fi
205
206         (
207                 print "# Default settings"
208
209                 # Advertise country code and maximum transmission power
210                 print "ieee80211d=1"
211
212                 # Enable Radar Detection
213                 if enabled dfs && wireless_supports_dfs "${device}"; then
214                         print "ieee80211h=1"
215                 else
216                         print "ieee80211h=0"
217                 fi
218
219                 print # empty line
220
221                 print "# Wireless configuration"
222                 print "hw_mode=${hw_mode}"
223
224                 if isset ieee80211ac; then
225                         print "ieee80211ac=${ieee80211ac}"
226                 fi
227
228                 if isset ieee80211n; then
229                         print "ieee80211n=${ieee80211n}"
230                 fi
231
232                 print "channel=${channel}"
233                 print "country_code=${country_code}"
234                 print "ignore_broadcast_ssid=${ignore_broadcast_ssid}"
235
236                 if contains_spaces "${ssid}"; then
237                         print "ssid=\"${ssid}\""
238                 else
239                         print "ssid=${ssid}"
240                 fi
241
242                 # WMM
243                 print "wmm_enabled=${wmm}"
244
245                 # Enable VHT caps
246                 if isset vht_caps; then
247                         print "vht_capab=${vht_caps}"
248                 fi
249
250                 # Enable HT caps
251                 print "ht_capab=${ht_caps}"
252
253                 # Wider Channels
254                 print "vht_oper_chwidth=${vht_oper_chwidth}"
255
256                 print
257         ) >> ${file}
258
259         # Control interface.
260         (
261                 print "# Control interface"
262                 print "ctrl_interface=${HOSTAPD_CONTROL_INTERFACE_DIR}"
263                 print "ctrl_interface_group=0"
264                 print
265         ) >> ${file}
266
267         # Encryption settings
268         if isset encryption; then
269                 local encryption_mode=0
270                 case "${encryption}" in
271                         WPA)
272                                 encryption_mode=1
273                                 ;;
274                         WPA2)
275                                 encryption_mode=2
276                                 ;;
277                         WPA/WPA2)
278                                 encryption_mode=3
279                                 ;;
280                 esac
281
282                 (
283                         print "# Encryption settings"
284                         print "wpa=${encryption_mode}"
285                         print "wpa_passphrase=${key}"
286                         print "wpa_key_mgmt=WPA-PSK"
287                         print "wpa_pairwise=TKIP"
288                         print "rsn_pairwise=CCMP"
289                         print
290                 ) >> ${file}
291         fi
292
293         return ${EXIT_OK}
294 }
295
296 hostapd_start() {
297         local device=${1}
298         assert isset device
299
300         service_start "hostapd@${device}.service"
301         local ret=$?
302
303         if [ ${ret} -eq ${EXIT_OK} ]; then
304                 log DEBUG "hostapd has been successfully started on '${device}'"
305         else
306                 log ERROR "Could not start hostapd on '${device}': ${ret}"
307                 return ${EXIT_ERROR}
308         fi
309
310         return ${EXIT_OK}
311 }
312
313 hostapd_stop() {
314         local device=${1}
315         assert isset device
316
317         service_stop "hostapd@${device}.service"
318 }