From: Michael Tremer Date: Sun, 3 Mar 2013 13:43:21 +0000 (+0000) Subject: Add support for batman-adv. X-Git-Tag: 006~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91987cc57b035f906df56b44e1abfbd023d55369;p=network.git Add support for batman-adv. --- diff --git a/functions.batman-adv b/functions.batman-adv new file mode 100644 index 00000000..f4a19c55 --- /dev/null +++ b/functions.batman-adv @@ -0,0 +1,34 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2013 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 . # +# # +############################################################################### + +function batman_adv_interface_add() { + local device=${1} + assert isset device + + cmd_quiet batctl interface add ${device} +} + +function batman_adv_interface_del() { + local device=${1} + assert isset device + + cmd_quiet batctl interface del ${device} +} diff --git a/functions.constants b/functions.constants index 0a9718a5..b7c4c52e 100644 --- a/functions.constants +++ b/functions.constants @@ -80,4 +80,5 @@ DEVICE_PRINT_LINE1=" %-24s %s\n" PORT_PATTERN="pN" PORT_PATTERN_ACCESSPOINT="apN" +PORT_PATTERN_BATMANADV="bN" PORT_PATTERN_WIRELESS="wN" diff --git a/functions.wireless b/functions.wireless index 7cf0b3fc..f6e6cb1d 100644 --- a/functions.wireless +++ b/functions.wireless @@ -51,7 +51,7 @@ function wireless_create() { shift done - assert isoneof type managed __ap + assert isoneof type ibss managed __ap assert phy_exists ${phy} isset address || address=$(mac_generate) @@ -95,6 +95,38 @@ function wireless_remove() { return ${ret} } +function 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} +} + function wireless_set_channel() { local device=${1} assert isset device @@ -106,3 +138,54 @@ function wireless_set_channel() { cmd_quiet iw dev ${device} set channel ${channel} } + +function 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}" +} + +function wireless_ibss_leave() { + local device=${1} + assert isset device + + log INFO "${device} leaving ibss network" + cmd_quiet iw dev "${device}" ibss leave +} diff --git a/hooks/ports/batman-adv b/hooks/ports/batman-adv new file mode 100755 index 00000000..cdbf7335 --- /dev/null +++ b/hooks/ports/batman-adv @@ -0,0 +1,199 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2013 Michael Tremer # +# # +# 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 . # +# # +############################################################################### + +. /usr/lib/network/header-port + +HOOK_SETTINGS="HOOK ADDRESS MESH_ID SSID CHANNEL COUNTRY_CODE PHY" + +ADDRESS=$(mac_generate) +CHANNEL=1 +COUNTRY_CODE="US" +MESH_ID= +SSID= + +# batman-adv inserts an additional header of 28 bytes, so we set the MTU +# to 1528, that normal ethernet packets with 1500 bytes can pass the network. +MTU=1528 +MTU=1500 + +function _check() { + assert isset ADDRESS + assert ismac ADDRESS + assert isset CHANNEL + assert isset COUNTRY_CODE + assert isset MESH_ID + assert ismac MESH_ID + assert isset PHY + assert ismac PHY + assert isset SSID +} + +function _create() { + while [ $# -gt 0 ]; do + case "${1}" in + --address=*) + ADDRESS=$(cli_get_val ${1}) + ;; + --channel=*) + CHANNEL=$(cli_get_val ${1}) + ;; + --country-code=*) + COUNTRY_CODE=$(cli_get_val ${1}) + ;; + --phy=*) + PHY=$(cli_get_val ${1}) + ;; + --ssid=*) + SSID=$(cli_get_val ${1}) + ;; + --mesh-id=*) + MESH_ID=$(cli_get_val ${1}) + ;; + *) + warning "Ignoring unknown argument '${1}'" + ;; + esac + shift + done + + # Save address of phy do identify it again + PHY=$(phy_get ${PHY}) + PHY=$(phy_get_address ${PHY}) + + local port=$(port_find_free ${PORT_PATTERN_BATMANADV}) + assert isset port + + config_write $(port_file ${port}) ${HOOK_SETTINGS} + + exit ${EXIT_OK} +} + +function _edit() { + local port=${1} + assert isset port + shift + + config_read $(port_file ${port}) + + while [ $# -gt 0 ]; do + case "${1}" in + --channel=*) + CHANNEL=$(cli_get_val ${1}) + ;; + --country-code=*) + COUNTRY_CODE=$(cli_get_val ${1}) + ;; + --mesh-id=*) + MESH_ID=$(cli_get_val ${1}) + ;; + --ssid=*) + SSID=$(cli_get_val ${1}) + ;; + *) + warning "Unknown argument '${1}'" + ;; + esac + shift + done + + config_write $(port_file ${port}) ${HOOK_SETTINGS} + + exit ${EXIT_OK} +} + +function _up() { + local port=${1} + assert isset port + + config_read $(port_file ${port}) + + # Check if the PHY is present. + local phy=$(phy_get ${PHY}) + if ! isset phy; then + log DEBUG "phy '${PHY}' is not present" + exit ${EXIT_ERROR} + fi + + # Create the wireless device, if it does not exist, yet. + if ! device_exists ${port}; then + wireless_create ${port} \ + --address="${ADDRESS}" \ + --phy="${phy}" \ + --type="ibss" + fi + + # Set the MTU. + device_set_mtu "${port}" "${MTU}" + + # Join the ad-hoc network. + wireless_ibss_join "${port}" --channel="${CHANNEL}" \ + --bssid="${MESH_ID}" --essid="${SSID}" + + # Add the device as a batman-adv device. + batman_adv_interface_add "${port}" + + exit ${EXIT_OK} +} + +function _down() { + local port=${1} + assert isset port + + # Remove the batman-adv device. + batman_adv_interface_del "${port}" + + # Leave the ad-hoc network. + wireless_ibss_leave "${port}" + + # Remove the device if it is still present. + if device_exists ${port}; then + wireless_remove ${port} + fi + + exit ${EXIT_OK} +} + +function _hotplug() { + local port=${1} + assert isset port + + local phy=${2} + assert isset phy + + assert port_exists ${port} + + # Read configuration of port. + config_read $(port_file ${port}) + + # Get the address of the phy. + local phy_address=$(phy_get_address ${phy}) + + # Check if the phy is the same we have + # read from the configuration file. + if [ "${PHY}" = "${phy_address}" ]; then + wireless_create ${port} \ + --address="${ADDRESS}" \ + --phy="${phy_address}" \ + --type="ibss" + fi + + exit ${EXIT_OK} +}