#!/bin/bash ############################################################################### # # # IPFire.org - A linux based firewall # # Copyright (C) 2012 IPFire Network Development Team # # # # This program is free software: you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation, either version 3 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # # You should have received a copy of the GNU General Public License # # along with this program. If not, see . # # # ############################################################################### HOSTAPD_CONTROL_INTERFACE_DIR="/run/hostapd/ctrl" HOSTAPD_SUPPORTED_MODES="802.11a 802.11a/n 802.11ac 802.11g 802.11g/n" hostapd_config_write() { local device=${1} assert isset device local file=${2} assert isset file # Shift the device and file argument. shift 2 local broadcast_ssid local channel local channel_bandwidth local country_code="$(wireless_get_reg_domain)" local dfs="on" local encryption local environment="${WIRELESS_DEFAULT_ENVIRONMENT}" local key local mode local ssid local wmm="1" while [ $# -gt 0 ]; do case "${1}" in --broadcast-ssid=*) broadcast_ssid=$(cli_get_val "${1}") ;; --channel=*) channel=$(cli_get_val "${1}") ;; --channel-bandwidth=*) channel_bandwidth="$(cli_get_val "${1}")" ;; --dfs=*) dfs="$(cli_get_val "${1}")" ;; --encryption=*) encryption=$(cli_get_val "${1}") ;; --environment=*) environment="$(cli_get_val "${1}")" ;; --key=*) key=$(cli_get_val "${1}") ;; --mode=*) mode=$(cli_get_val "${1}") if ! isoneof mode ${HOSTAPD_SUPPORTED_MODES}; then error "Unsupported mode: ${mode}" return ${EXIT_ERROR} fi ;; --ssid=*) ssid=$(cli_get_val "${1}") ;; --wmm=*) local val="$(cli_get_val "${1}")" if enabled val; then wmm="1" else wmm="0" fi ;; *) warning_log "Ignoring unknown argument '${1}'." ;; esac shift done # Check if mode is set if ! isset mode; then error "Mode is not set" return ${EXIT_ERROR} fi assert isset broadcast_ssid assert isbool broadcast_ssid assert isset channel assert isinteger channel assert isset mode assert isset ssid # Check if key is set when encryption is used. if isset encryption; then assert isoneof encryption WPA WPA2 WPA/WPA2 assert isset key fi # Check wireless environment if ! wireless_environment_is_valid "${environment}"; then error "Invalid wireless environment: ${environment}" return ${EXIT_ERROR} fi # With channel 0, ACS must be supported if [ ${channel} -eq 0 ] && ! wireless_supports_acs "${device}"; then error "ACS requested, but not supported by ${device}" return ${EXIT_ERROR} fi # Check channel bandwidth for validity if isset channel_bandwidth && ! wireless_channel_bandwidth_is_valid "${mode}" "${channel_bandwidth}"; then error "Invalid channel bandwidth for ${mode}: ${channel_bandwidth}" return ${EXIT_ERROR} fi # 802.11ac/n flags local ieee80211ac local ieee80211n local vht_caps local vht_oper_chwidth="0" local ht_caps local hw_mode case "${mode}" in 802.11a) hw_mode="a" ;; 802.11a/n) hw_mode="a" ieee80211n="1" # Fetch HT caps ht_caps="$(wireless_get_ht_caps "${device}")" ;; 802.11g) hw_mode="g" ;; 802.11g/n) hw_mode="g" ieee80211n="1" # Fetch HT caps ht_caps="$(wireless_get_ht_caps "${device}")" ;; 802.11ac) hw_mode="a" ieee80211ac="1" ieee80211n="1" # Fetch VHT caps vht_caps="$(wireless_get_vht_caps "${device}")" # Fetch HT caps ht_caps="$(wireless_get_ht_caps "${device}")" case "${channel_bandwidth}" in 80) vht_oper_chwidth="1" ;; 160) vht_oper_chwidth="2" ;; 80+80) vht_oper_chwidth="3" ;; esac ;; esac # Create configuration directory. local config_dir=$(dirname ${file}) mkdir -p ${HOSTAPD_CONTROL_INTERFACE_DIR} ${config_dir} 2>/dev/null config_header "hostapd" > ${file} # Interface configuration ( print "# Interface configuration" print "driver=nl80211" print "interface=${device}" print ) >> ${file} # Wireless configuration local ignore_broadcast_ssid if enabled broadcast_ssid; then ignore_broadcast_ssid="0" else ignore_broadcast_ssid="1" fi ( print "# Default settings" # Advertise country code and maximum transmission power print "ieee80211d=1" print "country_code=${country_code}" # Wireless Environment case "${environment}" in indoor) print "country3=0x49" country3 ;; outdoor) print "country3=0x4f" ;; indoor+outdoor) print "country3=0x20" ;; esac # Enable Radar Detection if enabled dfs && wireless_supports_dfs "${device}"; then print "ieee80211h=1" else print "ieee80211h=0" fi print # empty line print "# Wireless configuration" print "hw_mode=${hw_mode}" if isset ieee80211ac; then print "ieee80211ac=${ieee80211ac}" fi if isset ieee80211n; then print "ieee80211n=${ieee80211n}" fi print "channel=${channel}" print "ignore_broadcast_ssid=${ignore_broadcast_ssid}" if contains_spaces "${ssid}"; then print "ssid=\"${ssid}\"" else print "ssid=${ssid}" fi # WMM print "wmm_enabled=${wmm}" # Enable VHT caps if isset vht_caps; then print "vht_capab=${vht_caps}" fi # Enable HT caps print "ht_capab=${ht_caps}" # Wider Channels print "vht_oper_chwidth=${vht_oper_chwidth}" print ) >> ${file} # Control interface. ( print "# Control interface" print "ctrl_interface=${HOSTAPD_CONTROL_INTERFACE_DIR}" print "ctrl_interface_group=0" print ) >> ${file} # Encryption settings if isset encryption; then local encryption_mode=0 case "${encryption}" in WPA) encryption_mode=1 ;; WPA2) encryption_mode=2 ;; WPA/WPA2) encryption_mode=3 ;; esac ( print "# Encryption settings" print "wpa=${encryption_mode}" print "wpa_passphrase=${key}" print "wpa_key_mgmt=WPA-PSK" print "wpa_pairwise=TKIP" print "rsn_pairwise=CCMP" print ) >> ${file} fi return ${EXIT_OK} } hostapd_start() { local device=${1} assert isset device service_start "hostapd@${device}.service" local ret=$? if [ ${ret} -eq ${EXIT_OK} ]; then log DEBUG "hostapd has been successfully started on '${device}'" else log ERROR "Could not start hostapd on '${device}': ${ret}" return ${EXIT_ERROR} fi return ${EXIT_OK} } hostapd_stop() { local device=${1} assert isset device service_stop "hostapd@${device}.service" }