###############################################################################
# #
# IPFire.org - A linux based firewall #
-# Copyright (C) 2010 Michael Tremer & Christian Schmidt #
+# 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 #
# #
###############################################################################
-PHY_DIR="/sys/class/ieee80211"
-
-function phy_dir() {
- local phy=${1}
-
- echo "${PHY_DIR}/${phy}"
-}
-
-function phy_exists() {
- local phy=${1}
-
- [ -d "$(phy_dir ${phy})" ]
-}
-
-function phy_list() {
- local phy
- for phy in $(phy_dir)/*; do
- phy=$(basename ${phy})
- echo "${phy}"
- done
-}
-
-function phy_get() {
- local info=${1}
-
- local phy
-
- if listmatch ${info} $(phy_list); then
- phy="${info}"
- elif device_exists ${info}; then
- info=$(device_get_address ${info})
- fi
-
- if [ -z "${phy}" ] && mac_is_valid ${info}; then
- local i
- for i in $(phy_list); do
- if [ "${info}" = "$(phy_get_address ${i})" ]; then
- phy=${i}
- break
- fi
- done
- fi
-
- if [ -z "${phy}" ]; then
- return ${EXIT_ERROR}
- fi
-
- echo "${phy}"
- return ${EXIT_OK}
-}
-
-function phy_get_address() {
- local phy=${1}
-
- assert isset phy
-
- cat $(phy_dir ${phy})/macaddress 2>/dev/null
-}
-
function wireless_create() {
local device=${1}
- local phy=$(phy_get ${2})
- local type=${3}
- local mac=${4}
-
assert isset device
- assert isset phy
- assert isset type
-
- isset mac || mac=$(mac_generate)
-
- assert phy_exists ${phy}
- assert isoneof type managed __ap
-
- iw phy ${phy} interface add ${device} type ${type}
-
- if device_exists ${device}; then
- device_set_address ${device} ${mac}
- fi
-
- device_set_up ${device}
-}
-
-function wireless_remove() {
- local device=${1}
-
- assert device_exists ${device}
-
- device_set_down ${device}
-
- iw dev ${device} del
-}
-
-function wireless_set_channel() {
- local device=${1}
- local channel=${2}
-
- assert isset device
- assert device_exists ${device}
- assert isset channel
-
- iw dev ${device} set channel ${channel} $@
-}
-
-function hostapd_config_dir() {
- local device=${1}
-
- echo "${RUN_DIR}/hostapd/${device}"
-}
-
-function hostapd_config_write() {
- local device=${1}
shift
- assert device_exists ${device}
-
- local broadcast_ssid
- local channel
- local country_code
- local encryption
- local key
- local mode
- local ssid
+ local address
+ local phy
+ local type="managed"
while [ $# -gt 0 ]; do
case "${1}" in
- --broadcast-ssid=*)
- broadcast_ssid=${1#--broadcast-ssid=}
- ;;
- --channel=*)
- channel=${1#--channel=}
- ;;
- --country-code=*)
- country_code=${1#--country-code=}
- ;;
- --mode=*)
- mode=${1#--mode=}
- ;;
- --ssid=*)
- ssid=${1#--ssid=}
+ --address=*)
+ address=$(cli_get_val ${1})
;;
- --encryption=*)
- encryption=$(cli_get_val ${1})
+ --phy=*)
+ phy=$(cli_get_val ${1})
+ phy=$(phy_get ${phy})
;;
- --key=*)
- key=$(cli_get_val ${1})
+ --type=*)
+ type=$(cli_get_val ${1})
+
+ # ap --> __ap
+ [ "${type}" = "ap" ] && type="__ap"
;;
*)
- warning_log "Ignoring unknown argument '${1}'."
- ;;
+ error "Unrecognized argument: ${1}"
+ return ${EXIT_ERROR}
+ ;;
esac
shift
done
- assert isset broadcast_ssid
- assert isbool broadcast_ssid
-
- assert isset channel
- assert isinteger channel
-
- assert isset country_code
- assert isset mode
- assert isset ssid
+ assert isoneof type ibss managed __ap
+ assert phy_exists ${phy}
+ isset address || address=$(mac_generate)
- # Check if key is set when encryption is used.
- if isset encryption; then
- assert isoneof encryption WPA WPA2 WPA/WPA2
- assert isset key
- fi
+ cmd_quiet iw phy ${phy} interface add ${device} type ${type}
+ local ret=$?
- local ignore_broadcast_ssid
- if enabled broadcast_ssid; then
- ignore_broadcast_ssid="0"
- else
- ignore_broadcast_ssid="1"
- fi
+ if [ ${ret} -eq ${EXIT_OK} ]; then
+ log DEBUG "created wireless device '${device}' (${type})"
- local hw_mode ieee80211n="0"
- if [ "${mode}" = "n" ]; then
- if [ ${channel} -le 15 ]; then
- hw_mode="g"
- else
- hw_mode="a"
+ if isset address; then
+ device_set_address ${device} ${address}
fi
- ieee80211n="1"
+ else
+ log ERROR "could not create wireless device '${device}' (${type}): ${ret}"
fi
- cat <<EOF
-### Hostapd configuration for ${device}
-
-# Interface configuration
-driver=nl80211
-interface=${device}
-
-# Wireless configuration
-channel=${channel}
-country_code=${country_code}
-hw_mode=${hw_mode}
-ieee80211n=${ieee80211n}
-ignore_broadcast_ssid=${ignore_broadcast_ssid}
-ssid=${ssid}
+ return ${ret}
+}
-# Dump file
-dump_file=$(hostapd_config_dir ${device}/dump)
+function wireless_remove() {
+ local device=${1}
+ assert isset device
-ctrl_interface=/var/run/hostapd
-ctrl_interface_group=0
+ if ! device_exists ${device}; then
+ return ${EXIT_OK}
+ fi
-EOF
+ # Tear down the device (if necessary).
+ device_set_down ${device}
- 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
+ # Remove it.
+ cmd_quiet iw dev ${device} del
+ local ret=$?
- 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
+ if [ ${ret} -eq ${EXIT_OK} ]; then
+ log DEBUG "removed wireless device '${device}'"
+ else
+ log ERROR "could not remove wireless device '${device}': ${ret}"
fi
- return ${EXIT_OK}
+ return ${ret}
}
-function hostapd_start() {
- local device=${1}
- shift
-
- assert isset device
+function wireless_channel_to_frequency() {
+ # http://en.wikipedia.org/wiki/List_of_WLAN_channels
- local config_dir=$(hostapd_config_dir ${device})
- mkdir -p ${config_dir}
-
- local config_file=${config_dir}/config
- hostapd_config_write ${device} $@ > ${config_file}
+ local channel=${1}
+ assert isset channel
- service_start "hostapd@${device}.service"
- local ret=$?
+ # Channel number must be positive.
+ assert [ "${channel}" -gt 0 ]
- case "${ret}" in
- 0)
- log DEBUG "Hostapd was successfully started for '${device}'."
+ # 2.4 GHz band
+ case "${channel}" in
+ [123456789]|1[0123])
+ print "$(( 2407 + (${channel} * 5)))"
return ${EXIT_OK}
;;
- 1)
- error_log "Could not start hostapd properly for '${device}'."
-
- error_log "Configuration file dump:"
- local line
- while read line; do
- error_log " ${line}"
- done < ${config_file}
-
- return ${EXIT_ERROR}
+ 14)
+ print "2484"
+ return ${EXIT_OK}
;;
esac
-}
-
-function hostapd_stop() {
- local device=${1}
- assert isset device
- service_stop "hostapd@${device}.service"
+ # 5 GHz band
+ case "${channel}" in
+ 3[68]|4[02468]|5[26]|6[04]|10[048]|11[26]|12[048]|13[26]|14[09]|15[37]|16[15])
+ print "$(( 5000 + (${channel} * 5)))"
+ return ${EXIT_OK}
+ ;;
+ esac
- rm -rf $(hostapd_config_dir ${device})
+ return ${EXIT_ERROR}
}
-function hostapd_get_pid() {
+function wireless_set_channel() {
local device=${1}
-
assert isset device
- local pid_file="$(hostapd_config_dir ${device})/pid"
+ local channel=${2}
+ assert isset channel
- [ -e "${pid_file}" ] || return ${EXIT_ERROR}
+ device_exists ${device} || return ${EXIT_ERROR}
- cat ${pid_file} 2>/dev/null
- return ${EXIT_OK}
+ cmd_quiet iw dev ${device} set channel ${channel}
}
-function hostapd_is_running() {
+function wireless_ibss_join() {
local device=${1}
-
assert isset device
-
- local pid=$(hostapd_get_pid ${device})
-
- if isset pid && [ -d "/proc/${pid}" ]; then
- return ${EXIT_OK}
- fi
-
- return ${EXIT_ERROR}
-}
-
-function wpa_supplicant_config_write() {
- local device=${1}
shift
- assert isset device
-
- local ssid
- local encryption
- local key
+ local bssid
+ local essid
+ local frequency
while [ $# -gt 0 ]; do
case "${1}" in
- --ssid=*)
- ssid=${1#--ssid=}
+ --bssid=*)
+ bssid="$(cli_get_val ${1})"
;;
- --encryption=*)
- encryption=${1#--encryption=}
+ --essid=*)
+ essid="$(cli_get_val ${1})"
;;
- --key=*)
- key=${1#--key=}
+ --channel=*)
+ local channel="$(cli_get_val ${1})"
+
+ # Save the frequency of the channel instead
+ # of the channel itself.
+ if isset channel; then
+ frequency="$(wireless_channel_to_frequency ${channel})"
+ fi
;;
esac
shift
done
- assert isset ssid
- assert isset encryption
- assert isset key
-
- cat <<EOF
-# WPA supplicant configuration for ${device}.
-# DO NOT EDIT.
-
-network={
- ssid="${ssid}"
- proto=RSN
- key_mgmt=${encryption}
- pairwise=CCMP
- group=TKIP
- psk="${key}"
-}
+ # Check input.
+ assert ismac bssid
+ assert isset essid
+ assert isinteger frequency
-EOF
-}
-
-function wpa_supplicant_config_dir() {
- local device=${1}
+ # Set device up.
+ device_set_up "${device}"
- assert isset device
-
- echo "${RUN_DIR}/wireless/${device}"
-}
-
-function wpa_supplicant_start() {
- local device=${1}
- shift
-
- assert device_exists ${device}
-
- local config_dir=$(wpa_supplicant_config_dir ${device})
- mkdir -p ${config_dir}
-
- local config_file=${config_dir}/config
- wpa_supplicant_config_write ${device} $@ > ${config_file}
-
- wpa_supplicant -i ${device} -D wext -B -c ${config_file} \
- -P ${config_dir}/pid
-}
-
-function wpa_supplicant_stop() {
- local device=${1}
-
- assert isset device
-
- local pid=$(wpa_supplicant_get_pid ${device})
-
- if isset pid; then
- process_kill ${pid}
- else
- warning_log "Could not find pid file for wpa_supplicant process running for ${device}."
- fi
-
- rm -rf $(wpa_supplicant_config_dir ${device})
-}
-
-function wpa_supplicant_get_pid() {
- local device=${1}
-
- assert isset device
-
- local pid_file="$(wpa_supplicant_config_dir ${device})/pid"
-
- [ -e "${pid_file}" ] || return ${EXIT_ERROR}
-
- cat ${pid_file} 2>/dev/null
- return ${EXIT_OK}
+ log INFO "${device} joining ibss network: ${essid} (${bssid})"
+ cmd_quiet iw dev "${device}" ibss join "${essid}" \
+ "${frequency}" fixed-freq "${bssid}"
}
-function wpa_supplicant_is_running() {
+function wireless_ibss_leave() {
local device=${1}
-
assert isset device
- local pid=$(wpa_supplicant_get_pid ${device})
-
- if isset pid && [ -d "/proc/${pid}" ]; then
- return ${EXIT_OK}
- fi
-
- return ${EXIT_ERROR}
-}
-
-function wpa_supplicant_get_pid() {
- local zone=${1}
- shift
-
-
-}
-
-function wpa_supplicant_stop() {
- local zone=${1}
- shift
-
- killall wpa_supplicant
+ log INFO "${device} leaving ibss network"
+ cmd_quiet iw dev "${device}" ibss leave
}