]> git.ipfire.org Git - people/stevee/network.git/commitdiff
Add support for batman-adv.
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 3 Mar 2013 13:43:21 +0000 (13:43 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 3 Mar 2013 13:43:21 +0000 (13:43 +0000)
functions.batman-adv [new file with mode: 0644]
functions.constants
functions.wireless
hooks/ports/batman-adv [new file with mode: 0755]

diff --git a/functions.batman-adv b/functions.batman-adv
new file mode 100644 (file)
index 0000000..f4a19c5
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+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}
+}
index 0a9718a5620d2ba9c29a19039fabbe04c21222c5..b7c4c52ebad5b52fa3bf26250e54780b24887c41 100644 (file)
@@ -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"
index 7cf0b3fcdb5ae9d0af776fbc0aed1a2af3aefc84..f6e6cb1d47e139571d42e8babbd02f7226449b93 100644 (file)
@@ -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 (executable)
index 0000000..cdbf733
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+. /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}
+}