Skip to content

Instantly share code, notes, and snippets.

@JM1
Last active November 15, 2017 18:51
Show Gist options
  • Save JM1/a11c21bc16581045f80909b8de9e5860 to your computer and use it in GitHub Desktop.
Save JM1/a11c21bc16581045f80909b8de9e5860 to your computer and use it in GitHub Desktop.
#!/bin/sh
# vim:set tabstop=8 shiftwidth=4 expandtab:
# kate: space-indent on; indent-width 4;
#
# Copyright (C) 2017 WEARENOTALONE
#
# Helper script for OpenWrt/LEDE configuration
# References:
# https://www.reddit.com/r/openwrt/comments/515oea/finally_got_80211r_roaming_working/
# https://forum.openwrt.org/viewtopic.php?id=56546
# https://wiki.openwrt.org/doc/uci/wireless
# https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf
set -e
#set -x
prg=$(basename "$0")
version() {
cat << ____EOF
$prg version 0.1
Copyright (C) 2017 WEARENOTALONE
____EOF
}
help() {
cat << ____EOF
Usage: $prg [OPTIONS] COMMAND [arg...]
$prg [ --help | -v | --version ]
A helper script for OpenWrt/LEDE configuration.
Options:
-h, --help Print usage
-v, --version Print version information and quit
Commands:
_80211r 802.11r fast BSS transition (FT)
bitrates Minimum wifi bitrates
help Print usage
____EOF
}
stderr() {
local _msg
while read -r _msg
do
echo $_msg 2>&1
done
}
error() {
stderr << ____EOF
ERROR: $*
____EOF
}
warn() {
stderr << ____EOF
WARN: $*
____EOF
}
_80211r() {
help() {
cat << ________EOF
Usage: $prg _80211r [OPTIONS]
Print configuration for 802.11r fast BSS transition (FT)
Options:
--debug Print commands issued by $prg
--mobility-domain [FFFF] Provide a 4-character Hex string as mobility domain
If no argument is given, a random string is generated
--passphrase [FF..FF] Provide a 32-character Hex string as passphrase for inter-AP communication
If no argument is given, a random string is generated
--bssids XX:..:XX,XX:..:XX,... Provide BSSIDs of all involved APs as a comma-seperated list
-h, --help Print usage
________EOF
}
local _mobility_domain=""
local _passphrase=""
local _bssids=""
local _debug=""
if [ -z "$1" ]; then
help
return 0
fi
while [ -n "$1" ]; do
case "$1" in
"--debug")
_debug="yes"
;;
"--mobility-domain")
if [ -z "$2" ]; then
error "flag is missing arg: --mobility-domain"
return 255
fi
if [ -n "$_mobility_domain" ]; then
error "flag already set: --mobility-domain"
return 255
fi
_mobility_domain="$2"
shift
;;
"--passphrase")
if [ -z "$2" ]; then
error "flag is missing arg: --passphrase"
return 255
fi
if [ -n "$_passphrase" ]; then
error "flag already set: --passphrase"
return 255
fi
_passphrase="$2"
shift
;;
"--bssids")
if [ -z "$2" ]; then
error "flag is missing arg: --bssids"
return 255
fi
if [ -n "$_bssids" ]; then
error "flag already set: --bssids"
return 255
fi
_bssids="$2"
shift
;;
"-h"|"--help")
help
return 0
;;
-*|*)
error "unknown flag: $1"
return 255
;;
esac
shift
done
if [ -z "$_bssids" ]; then
error "No BSSIDs given"
return 255
fi
if [ -z "$_mobility_domain" ]; then
_mobility_domain="$(openssl rand -hex 2)"
elif ! echo "$_mobility_domain" | grep -Eq ^[A-Fa-f0-9]{4}$; then
error "Mobility domain is not a 4-character Hex string"
return 255
fi
if [ -z "$_passphrase" ]; then
_passphrase="$(openssl rand -hex 16)"
elif ! echo "$_passphrase" | grep -Eq ^[A-Fa-f0-9]{32}$; then
error "Passphrase is not a 32-character Hex string"
return 255
fi
_bssids="$(echo $_bssids | sed -e 's/,/ /g')"
for _bssid in $_bssids; do
if ! echo "$_bssid" | grep -Eq '^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$'; then
error "'$_bssid' is not a valid BSSID"
return 255
fi
done
(
[ "$_debug" = "yes" ] && set -x
local _r0kh=""
local _r1kh=""
for _bssid in $_bssids; do
local _nasid="$(echo $_bssid | sed -e 's/://g')"
local _r1_key_holder="$_bssid"
_r0kh="${_r0kh}${_bssid},${_nasid},${_passphrase} "
_r1kh="${_r1kh}${_bssid},${_r1_key_holder},${_passphrase} "
done
for _bssid in $_bssids; do
local _nasid="$(echo $_bssid | sed -e 's/://g')"
local _r1_key_holder="$_bssid"
cat << ________EOF
config wifi-iface 'radio'
...
option ieee80211r '1'
option pmk_r1_push '1'
option wpa_disable_eapol_key_retries '1'
option mobility_domain '$_mobility_domain'
option nasid '$_nasid'
option r1_key_holder '$_r1_key_holder'
$(for _ in $_r0kh; do echo " list r0kh '$_'"; done)
$(for _ in $_r1kh; do echo " list r1kh '$_'"; done)
________EOF
done
)
}
bitrates() {
help() {
cat << ________EOF
Usage: $prg bitrates [OPTIONS]
Print configuration for setting minimum wifi bitrates, impacting only on legacy rates.
High throughput (HT) and Very high throughput (VHT) rates are not affected.
Options:
--debug Print commands issued by $prg
--protocol CODE Provide supported wifi protocol, valid codes are:
code | wifi protocol | bitrates (Mbps)
-----|------------------------|----------------------------------
g | IEEE 802.11g (2.4 GHz) | 1 2 5.5 11 6 9 12 18 24 36 48 54
b | IEEE 802.11b (2.4 GHz) | 1 2 5.5 11
--minimum-rate RATE Provide minimum wifi rate in Mbps
-h, --help Print usage
________EOF
}
local _protocol=""
local _minimum_rate=""
local _debug=""
if [ -z "$1" ]; then
help
return 0
fi
while [ -n "$1" ]; do
case "$1" in
"--debug")
_debug="yes"
;;
"--protocol")
if [ -z "$2" ]; then
error "flag is missing arg: --protocol"
return 255
fi
if [ -n "$_protocol" ]; then
error "flag already set: --protocol"
return 255
fi
_protocol="$2"
shift
;;
"--minimum-rate")
if [ -z "$2" ]; then
error "flag is missing arg: --minimum-rate"
return 255
fi
if [ -n "$_minimum_rate" ]; then
error "flag already set: --minimum-rate"
return 255
fi
_minimum_rate="$2"
shift
;;
"-h"|"--help")
help
return 0
;;
-*|*)
error "unknown flag: $1"
return 255
;;
esac
shift
done
if [ -z "$_protocol" ]; then
error "No supported wifi protocol given"
return 255
elif [ "$_protocol" != b ] && [ "$_protocol" != g ]; then
error "$_protocol is not a valid wifi protocol"
return 255
fi
if [ -z "$_minimum_rate" ]; then
error "No minimum rate given"
return 255
elif ! echo "$_minimum_rate" | grep -Eq '^[0-9]+(.[0-9]*)*$'; then
error "$_minimum_rate is not a valid rate"
return 255
fi
local _minimum_rate="$(expr "$_minimum_rate" \* 10)"
(
[ "$_debug" = "yes" ] && set -x
case "$_protocol" in
b)
local _bitrates="10 20 55 110"
;;
g)
local _bitrates="10 20 55 110 60 90 120 180 240 360 480 540"
;;
esac
local _supported_rates="$(for _ in $_bitrates; do echo -n "${_}00 "; done)"
local _basic_rate="$(for _ in $_bitrates; do if [ "$_" -ge "$_minimum_rate" ]; then echo -n "${_}00 "; fi; done)"
_supported_rates="$(echo $_supported_rates | sed -e 's/ $//g' )"
_basic_rate="$(echo $_basic_rate | sed -e 's/ $//g' )"
cat << ____EOF
config wifi-device 'radio'
#ensure that your device uses
# option hwmode '11g'
#or
# option hwmode '11b'
...
list supported_rates '$_supported_rates'
list basic_rate '$_basic_rate'
____EOF
)
}
if [ $# -eq 0 ]; then
help
exit 1
fi
while [ -n "$1" ]; do
case "$1" in
"_80211r"|"bitrates"|"help")
("$@")
exit $?
;;
"-v"|"--version")
version
exit 0
;;
"-h"|"--help")
help
exit 0
;;
-*)
error "unknown flag: $1"
exit 1
;;
*)
error "unknown command: $1"
exit 1
;;
esac
shift
done
exit $?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment