[#] Удобное подключение к Wifi
soko1(lenina,128) — All
2014-07-24 03:45:32


Один раз вписать точку доступа это конечно удобно, но не всегда, особенно когда точки доступа постоянно меняются.
Кто чем пользуется для этого? (ifconfig ес-но не предлагать)

Нашёл хороший скрипт, дописал пару строчек и решил с вами поделиться, вдруг понадобится: https://github.com/soko1/OpenBSD/blob/master/scripts/auto-wifi.sh

[#] Re: Удобное подключение к Wifi
51t(lenina,1) — soko1
2014-07-24 05:54:21


зачем ifconfig. /etc/networks и используем :) так было, так есть и так будет всегда :)

а вообще, на gsoc была такая задача... но, по-моему, она не была взята, надо бы найти и перепостить, что именно взято на gsoc.

[#] Re: Удобное подключение к Wifi
soko1(lenina,128) — 51t
2014-07-24 14:37:18


А поясни как именно этот конфиг используешь, плз. Я в курсе только /etc/hostname.* , но оно не всегда удобно когда точек доступа дофига и часто меняются. Ну или может там можно сразу несколько вписывать - не пробовал ещё.

[#] Re: Удобное подключение к Wifi
51t(lenina,1) — soko1
2014-07-24 14:39:55


> Ну или может там можно сразу несколько вписывать - не пробовал ещё.

честно говоря, не знаю, можно ли там вписать много :) обычно использую, как в faq написано...

[#] Re: Удобное подключение к Wifi
ssh(lenina,126) — soko1
2014-07-25 07:32:19


Самое смешное, что раньше я просто писал все пары SSID/пароль и останавливалось на первой успешной. :)
А потом перестало.

[#] Re: Удобное подключение к Wifi
solus(lenina,130) — soko1
2014-07-25 08:49:41


Я уже писал как то на obsd.ru ставил и пользовался вот этим http://undeadly.org/cgi?action=article&sid=20120113172334
В принципе меня устраивало.

[#] Re: Удобное подключение к Wifi
51t(lenina,1) — solus
2014-07-25 08:58:40


пусть тогда скрипт тут и лежит, для коллекции :)

#!/bin/sh
#
# v.9.5 2/7/2012 17:30
#
# Copyright (c) 2012 Daniel Melameth <daniel@melameth.com>
#
# Permission to use, copy, modify and distribute this software for any purpose
# with or without fee is hereby granted, provided that the above copyright
# notice and this permission notice appear in all copies.
#
# This software is provided by the regents and contributors "as is" and any
# express or implied warranties, including, but not limited to, the implied
# warranties of merchantability and fitness for a particular purpose are
# disclaimed.  In no event shall the regents or contributors be liable for any
# direct, indirect, incidental, special, exemplary or consequential damages
# (including, but not limited to, procurement of substitute goods or services;
# loss of use, data or profits; or business interruption) however caused and on
# any theory of liability, whether in contract, strict liability or tort
# (including negligence or otherwise) arising in any way out of the use of this
# software even if advised of the possibility of such damage.
# 
# NAME
#	wiconfig - simplifies the configuration of wireless interfaces 
#
# SYNOPSIS
#	wiconfig [-dqs] interface
#
# EXAMPLE
#	Manually configure a wireless interface
#
#		# sh /etc/wiconfig iwi0 
#
#	Automatically scan for wireless networks and, using previous manual
#	configurations, configure the wireless interface based on the strongest
#	wireless signal (for use with hostname.if(5) files)
#
#		$ cat /etc/hostname.iwi0
#		!/bin/sh /etc/wiconfig -q \$if
#
#	With the above /etc/hostname.iwi0 in place, iwi0 will be configured
#	upon startup or whenever /etc/netstart iwi0 is invoked.
#
#	wiconfig can also be used in conjunction with apmd(8).  In the
#	following example, upon resume, it'll check the status of the wireless
#	connection and, if there is no network connection, it'll automatically
#	scan for wireless networks and, using previous manual configurations,
#	configure the wireless interface based on the strongest wireless
#	signal.
#
#		$ cat /etc/apmd/resume
#		#!/bin/sh
#		/bin/sh /etc/wiconfig -qs iwi0
#
#	apmd will need this file to be executable so you'll want to do this as
#	well
#
#		# chmod 0744 /etc/apm/resume
#
# FILES
#	/etc/wiconfig.db	Wireless network database
#
# CAVEATS
#	1) Only DHCP is supported
#	2) No user-defined nwid prioritization--the nwid with the strongest
#		signal will always be preferred
#	3) Only the first 20 nwids with the strongest signals are used
#	4) When used within a hostname.if(5), host startup will be delayed
#		slightly while a wireless network scan is performed
#	5) Database records are never purged--existing entries will be updated,
#		but unwanted entries need to be removed manually  
#	6) Hidden nwids are not supported

# set -x

# Save default IFS
oIFS=$IFS
myname=$0

max=20
# Number of seconds to wait before checking interface status
seconds=3
wiconfigdb="/etc/wiconfig.db"

function usage {
	echo "usage: $myname [-dqs] interface"
	exit 1
}

# Determine network status and name
function review {
	# Assume we are not connected to a network
	typeset _i=1 _status=false _ifconfig _nwid _yn
	# We are being called from apmd
	$quiet && sleep 2
	# Need to use a co-process here to handle _status (and _nwid?)
	ifconfig "$if" |& while read -p _ifconfig; do
		case $_i in
			# Sixth line/status
			6)	active $_ifconfig && _status=true;;
			# Seventh line/nwid
			7)	# Connected to an active network
				if $_status; then
					set $_ifconfig
        				_nwid=${3#\"}
				        # nwid begins with a quote
				        if [ ${#3} -gt ${#_nwid} ]; then
				                # nwid is not hidden
                				if [ ${#3} -gt 2 ]; then
				                        IFS='"'
                        				set $_ifconfig
                        				_nwid="$2"
                        				IFS=$oIFS
                				else
                        				unset _nwid
                				fi
        				fi
				fi
				break;;
		esac
		_i=$(($_i+1))
	done

	if $_status; then
		if $quiet; then
			exit
		else
			different "$_nwid"
		fi
	else
		start
	fi
}

# Determine if the network is active
function active {
	typeset _status=$*
	typeset _length=${#_status}
	_status=${_status%active}
	# Network is active
	if [ ${#_status} -lt $_length ]; then
		return
	fi
	return 1
}

function different {
	typeset _yn
	echo "Currently connected to $*."
	read _yn?"Would you like to connect to a different network (y/n)? "
	case $_yn in
		y)	start;;
		n)	exit;;
		*)	different "$*";;
	esac
}

function start {
	readdb
	scan
	createarray
	match
	# Position of nwid in db
	typeset _n=$?
	# Automatically configuring interface
	if $quiet; then
		# Found an nwid match 
		if [ $_n -ne 0 ]; then
			echo "connecting to wireless network ${r[$_n]}"
			configure "${r[$_n]}" "${r[$_n+2]}"
		else
			exit 1
		fi
	else
		if [ $_n -ne 0 ]; then
			# Reconnection desired
			if $(reconnect $_n); then
				configure "${r[$_n]}" "${r[$_n+2]}"
				exit
			fi
		fi
		menu
	fi
}

function readdb {
	# If db exists and is readable
	if [ -r $wiconfigdb ]; then
		typeset _i=1
		while read r[$_i]; do
			_i=$((_i+1))
		done < $wiconfigdb
		# Remove newline from array as it's counted in ${#r[@]}
		unset r[$_i]
	fi
}

# Parse and sort ifconfig nwid output
function scan {
	# Need to include a quote to account for nwids with spaces
	# IFS=' "'
	# IFS=$oIFS
	echo -n > "$output"
	typeset _nwids _args _nwid

	! $quiet && echo "Performing wireless scan..."
	# Parse ifconfig nwid output for sorting
	ifconfig $if scan | grep ^[[:space:]]*nwid | while read _nwids; do
		# nwid name chan channel bssid mac db speed options
		# Required to set positional parameters
		set $_nwids
        	_args=$#
		# Remove possible leading double quote
                _nwid=${2#\"}
                # nwid begins with a quote
		if [ ${#2} -gt ${#_nwid} ]; then
			# nwid is not hidden
			if [ ${#2} -gt 2 ]; then
				IFS='"'
				set $_nwids
				_nwid=$2
				shift 2
				_nwids=$*
				IFS=$oIFS
				set $_nwids
			else
				continue
			fi
		else
			shift 2
		fi

		# shift
        	# nwid has one or more spaces
        	# if [ $_args -gt 9 ]; then
                #	# Remove possible leading double quote
                #	_nwid=${1#\"}
                #	shift
                #	_args=$(($_args-1))
                #	while [ $_args -gt 9 ]; do
		#		_nwid=$_nwid $1
                #        	# _nwid=$_nwid\ $1
                #        	shift
                #        	_args=$(($_args-1))
                #	done
		#	# Append and remove trailing double quote
                #	_nwid=$_nwid\ ${1%\"}
        	# else
                #	_nwid=$1
        	# fi

		# shift
		# unset _nwid
		# nwid might contain one or more spaces
		# while [ $_args -ge 9 ]; do
		#	_nwid="${_nwid:-$1} ${_nwid:+$1}"
		#	shift
		#	_args=$(($_args-1))
		# done

		# nwid is hidden?
		# [[ X$4 = X00:00:00:00:00:00 ]] && continue	

		echo -n "$_nwid" >> $output
		# Channel
		echo -n "|$2" >> $output
		# MAC
		echo -n "|$4" >> $output
		# Signal quality
		echo -n "|${5%dB}" >> $output
		# Speed
		echo -n "|$6" >> $output
		# Options
		echo "|$7" >> $output
		# echo $name $number $chan $mac $db $speed $options
	done
	IFS=$oIFS

	# Wireless network(s) found
	if [ -s "$output" ]; then
		# Sort nwids by greatest signal quality
		sort -brk 4 -o "$input" -t "|" "$output"
	else
		if ! $quiet; then
			rescan
		else
			exit 1
		fi
	fi
}

function rescan {
	typeset _rq
	read _rq?"No wireless networks found.  Enter r to rescan or q to quit: "
	case $_rq in
		r)	scan;;
		q)	exit;;
		*)	rescan;;
	esac
}

# Create sorted array of top $max nwids
function createarray {
	IFS='|'
	typeset _i=1 _length
	# If the array exists
	[[ -n ${index[1]} ]] && \
		unset nwid chan mac db speed options index access
	while read nwid[$_i] chan[$_i] mac[$_i] db[$_i] speed[$_i] options[$_i] && [ $_i -le $max ]; do
		index[$_i]=$_i
		# Determine if access is secure
		_length=${#options[$_i]}
		options=${options[$_i]#privacy}
		# Access is secure
		if [ ${#options} -lt $_length ]; then
			access[$_i]="Secured"
		else
			access[$_i]="Unsecured"
		fi
		_i=$(($_i+1))
	done < "$input"
	IFS=$oIFS
}

# Linear search for best nwid match
function match {
	typeset _i _m
	# Start with the nwid with the strongest signal
	for _i in ${index[@]}; do
		matchdb "${nwid[$_i]}" "${mac[$_i]}"
		_m=$?
		# Match found
		[[ $_m -ne 0 ]] && return $_m
	done
	return 0
}

# Return match in the db
function matchdb {
	# Start with last MAC in db
	typeset _i=$((${#r[@]}-1))
	# More records in the db
	while [ $_i -gt 0 ]; do 
		# MAC and nwid matches
		if [ "X$2" = "X${r[$_i]}" ] && \
			[ "X$1" = "X${r[$_i-1]}" ]; then
			# Return position of nwid in db
			return $(($_i-1))
		fi
		# Move to previous MAC (and network) in db
		_i=$(($_i-3))
	done
}

# Configure interface
function configure {
	ifconfig $if -nwid -nwkey -wpakey down > /dev/null 2>&1
	# Apparently we need to use eval and single quotes to handle nwids with
	# spaces
	eval ifconfig $if nwid \'$1\' $2 up > /dev/null 2>&1
	dhclient $if
}

function reconnect {
	typeset _yn
	read _yn?"${r[$1]} found.  Would you like to reconnect (y/n)? "
	case $_yn in
		y)	return;;
		n)	return 1;;
		*)	reconnect;;
	esac
}

function menu {
	typeset _i
	echo
	printf "     %-40s %-6s %-10s\n" "Network Name" "Signal" "Access"
	echo
	for _i in ${index[@]}; do
		printf "%3d) %-40s %-6s %-10s\n" \
			$_i "${nwid[$_i]}" "${db[$_i]}dB" "${access[$_i]}"
	done
	echo
	read choice?"Enter the number of the network to connect to (or r to rescan or q to quit): "
	if [ $choice -ge 1 ] && [ $choice -le ${#index[@]} ]; then
		if [ "X${access[$choice]}" = XSecured ]; then
			password
			determine
		else
			configure "${nwid[$choice]}"
			update
		fi
	elif [ "X$choice" = "Xr" ]; then
		start
	elif [ "X$choice" = "Xq" ]; then
		exit
	else
		echo "Invalid choice"
		sleep 1
		menu
	fi
}

function password {
	stty -echo
	read -r pass1?"Enter the password for ${nwid[$choice]} (will not echo): "
	echo
	read -r pass2?"Enter the password for ${nwid[$choice]} (again): "
	echo
	stty echo
	# If passwords do not match or are blank
	if [ "X$pass1" != "X$pass2" ] || [ "X$pass1" = X ]; then
		echo "Passwords do not match or are invalid"
		sleep 1
		password
	fi
}

# Determine if we are using WPA or WEP
function determine {
	echo "Connecting to wireless network ${nwid[$choice]}..." 
	ifconfig "$if" -nwid -nwkey -wpakey down > /dev/null 2>&1
	# Must bring interface up for status to become active
	ifconfig "$if" nwid "${nwid[$choice]}" wpakey "$pass1" up > /dev/null 2>&1
	typeset _status=$?
	# Lackluster workaround for athn taking a while to become active
	[[ $if = athn? ]] && seconds=11
	sleep $seconds
	# Network is active
	if [ $_status -eq 0 ] && active $(ifconfig "$if" | fgrep status); then
		update wpa
	else
		ifconfig "$if" -nwid -wpakey down > /dev/null 2>&1
		ifconfig "$if" nwid "${nwid[$choice]}" nwkey "$pass1" up > /dev/null 2>&1
		_status=$?
		sleep $seconds
		if [ $_status -eq 0 ] && \
			active $(ifconfig "$if" | fgrep status); then
			update wep
		else
			echo "Unable to connect"
			exit 1
		fi
	fi
	dhclient $if
}

# Update existing db record, if it exists, or create a new one
function update {
	# Number of entries in db
	typeset _i=${#r[@]} _m
	# db is not empty
	if [ $_i -gt 0 ]; then
		matchdb "${nwid[$choice]}" "${mac[$choice]}"
		_m=$?
		# Match found
		if [ $_m -ne 0 ]; then
			secure $(($_m+2)) $1
			createdb
			return
		fi
	fi
	r[$_i+1]="${nwid[$choice]}"
	r[$_i+2]="${mac[$choice]}"
	secure $(($_i+3)) $1
	createdb
}

# Set nwid access parameters for db record
function secure {
	case $2 in
		wpa)	r[$1]="wpakey \"$pass1\"";;
		wep)	r[$1]="nwkey $pass1";;
		# Open nwid
		*)	r[$1]="";;
	esac
}

function createdb {
	# If the db does not exist, create and secure it
	if [ ! -a "$wiconfigdb" ]; then
		touch "$wiconfigdb"
		chmod 640 "$wiconfigdb"
	fi

	echo -n > "$wiconfigdb"
	typeset _i=1
	while [ $_i -le ${#r[@]} ]; do
		echo "${r[$_i]}" >> "$wiconfigdb"
		_i=$(($_i+1))
	done
}

function end {
	rm -f "$output" "$input"
}

trap end EXIT ERR INT KILL TERM

# Debugging for functions (must be specified after the function declaration)
# typeset -ft review
# typeset -ft active
# typeset -ft different
# typeset -ft start
# typeset -ft readdb 
# typeset -ft scan
# typeset -ft rescan 
# typeset -ft createarray
# typeset -ft match
# typeset -ft matchdb
# typeset -ft configure
# typeset -ft reconnect
# typeset -ft menu 
# typeset -ft password
# typeset -ft determine
# typeset -ft update
# typeset -ft secure
# typeset -ft createdb

debug=false
# Assume we are being used interactively
quiet=false
# Do not check the wireless network status before configuring the interface
# (expected in the hostname.if(5) case)
status=false

if [ "X$(whoami)" != Xroot ]; then
	echo "$myname must be run as root"
	exit 1
fi

while getopts dqs opt; do
	case $opt in
		d)	debug=true;;
		q)	quiet=true;; 
		s)	status=true;;
		?)	usage;;
	esac
done

if $debug; then
	set -x
	typeset -ft review active different start readdb \
	scan rescan createarray match matchdb configure reconnect menu \
	password determine update secure createdb
fi

shift $(($OPTIND-1))

# No interface specified
[[ -z "$1" ]] && usage

if="$1"
ifconfig "$if" > /dev/null 2>&1

# Interface does not exist
if [ $? -ne 0 ]; then
	# Manually configuring interface
	if ! $quiet; then
		echo "Interface $if does not exist"
	fi
	exit 1
fi

output=$(mktemp)
input=$(mktemp)

# Running from hostname.if
if $quiet && ! $status; then
	start
else
	review
fi