#!/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 . # # # ############################################################################### # Sets the global wireless country code. Default is 00 = world. WIRELESS_REGULATORY_DOMAIN="00" NETWORK_SETTINGS_FILE_PARAMS="${NETWORK_SETTINGS_FILE_PARAMS} WIRELESS_REGULATORY_DOMAIN" wireless_create() { local device=${1} assert isset device shift local address local phy local type="managed" while [ $# -gt 0 ]; do case "${1}" in --address=*) address=$(cli_get_val ${1}) ;; --phy=*) phy=$(cli_get_val ${1}) phy=$(phy_get ${phy}) ;; --type=*) type=$(cli_get_val ${1}) # ap --> __ap [ "${type}" = "ap" ] && type="__ap" ;; *) error "Unrecognized argument: ${1}" return ${EXIT_ERROR} ;; esac shift done assert isoneof type ibss managed monitor __ap assert phy_exists ${phy} isset address || address=$(mac_generate) cmd_quiet iw phy ${phy} interface add ${device} type ${type} local ret=$? if [ ${ret} -eq ${EXIT_OK} ]; then log DEBUG "created wireless device '${device}' (${type})" if isset address; then device_set_address ${device} ${address} fi else log ERROR "could not create wireless device '${device}' (${type}): ${ret}" fi return ${ret} } wireless_remove() { local device=${1} assert isset device if ! device_exists ${device}; then return ${EXIT_OK} fi # Tear down the device (if necessary). device_set_down ${device} # Remove it. cmd_quiet iw dev ${device} del local ret=$? if [ ${ret} -eq ${EXIT_OK} ]; then log DEBUG "removed wireless device '${device}'" else log ERROR "could not remove wireless device '${device}': ${ret}" fi return ${ret} } wireless_get_reg_domain() { # Returns the country code for the wireless device. # Defaults to 00 = world if unset. print "${WIRELESS_REGULATORY_DOMAIN:-00}" } wireless_init_reg_domain() { local country_code="$(wireless_get_reg_domain)" wireless_set_reg_domain "${country_code}" --no-reset } wireless_set_reg_domain() { local country_code local reset="true" while [ $# -gt 0 ]; do case "${1}" in --no-reset) reset="false" ;; -*) log ERROR "Ignoring invalid option: ${1}" ;; *) country_code="${1}" ;; esac shift done assert isset country_code # Before the wireless reg domain is set, it helps to reset to 00 first. if enabled reset; then iw reg set 00 &>/dev/null fi log INFO "Setting wireless regulatory domain country to '${country_code}'" iw reg set "${country_code}" } wireless_channel_to_frequency() { # http://en.wikipedia.org/wiki/List_of_WLAN_channels local channel=${1} assert isset channel # Channel number must be positive. assert [ "${channel}" -gt 0 ] # 2.4 GHz band case "${channel}" in [123456789]|1[0123]) print "$(( 2407 + (${channel} * 5)))" return ${EXIT_OK} ;; 14) print "2484" return ${EXIT_OK} ;; esac # 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 return ${EXIT_ERROR} } wireless_set_channel() { local device=${1} assert isset device local channel=${2} assert isset channel device_exists ${device} || return ${EXIT_ERROR} log DEBUG "Setting wireless channel on device '${device}' to channel '${channel}'" cmd_quiet iw dev ${device} set channel ${channel} } wireless_ibss_join() { local device=${1} assert isset device shift local bssid local essid local frequency while [ $# -gt 0 ]; do case "${1}" in --bssid=*) bssid="$(cli_get_val ${1})" ;; --essid=*) essid="$(cli_get_val ${1})" ;; --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 # Check input. assert ismac bssid assert isset essid assert isinteger frequency # Set device up. device_set_up "${device}" log INFO "${device} joining ibss network: ${essid} (${bssid})" cmd_quiet iw dev "${device}" ibss join "${essid}" \ "${frequency}" fixed-freq "${bssid}" } wireless_ibss_leave() { local device=${1} assert isset device log INFO "${device} leaving ibss network" cmd_quiet iw dev "${device}" ibss leave } wireless_is_radar_frequency() { local frequency="${1}" assert isset frequency [[ ${frequency} -ge 5260 ]] && [[ ${frequency} -le 5700 ]] } wireless_monitor() { local device="${1}" assert isset device shift local monitor_device="$(port_find_free "${PORT_PATTERN_WIRELESS_MONITOR}")" # Create an 802.11 monitoring device wireless_create "${monitor_device}" --phy="${device}" --type="monitor" local ret=$? case "${ret}" in 0) # Bring up the device device_set_up "${monitor_device}" # Starting tcpdump tcpdump -i "${monitor_device}" "$@" # Remove the monitoring interface. wireless_remove "${monitor_device}" ;; *) log ERROR "Could not create a monitoring interface on ${device}" return ${EXIT_ERROR} ;; esac return ${EXIT_OK} }