Last active
November 15, 2017 18:51
-
-
Save JM1/a11c21bc16581045f80909b8de9e5860 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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