Discussion:
Thinking about writing something I'm calling wifid
(too old to reply)
Bryan Everly
2016-08-02 14:09:48 UTC
Permalink
Hi everyone,

I'm looking for feedback before I burn time on this project so please
let me know what you think.

I'm thinking about building a daemon that I'll write in C (looked at the
httpd code in /usr.sbin/httpd as a reference) that essentially monitors
your network connectivity in the background and, based on an
/etc/wifid.conf file (which contains an encrypted list of nwid's and
wpa-keys that you have loaded) looks for the presence of those nwid's
and will connect you to them (in a particular priority order you set) if
it finds them. I would then write a wifictl program that would
communicate with the daemon and allow you to manipulate the encrypted
list, etc.

The thought is that this would give us similar behavior to other
operating systems in making wifi more of a "set it and forget it"
capability in the system (versus running ifconfig and dhclient any time
I change to a new network).

The questions I have are as follows:

1. Is there something like this already that I'm not seeing in OpenBSD?

2. Would anyone other than me want something like this? If not, I will
likely write it much less "cleanly" and just use it locally for my
needs. Heck, I could probably write it as a shell script and just stuff
it in my crontab.

3. My initial thought was to do the same things in my daemon that are
going on in the source of ifconfig.c - specifically the setifnwid(),
setifwpakey() and setifflags() functions (as opposed to shell exec'ing
the commands themselves). I'd prefer not to be someone who does "editor
reuse" and cut & paste those functions into my code, but I'm not sure
how you would approach that from a "how we do it in OpenBSD"
perspective. Would I refactor that tool to put those methods I use in a
library and then modify it to call them out of the library so we can
both share it?

4. Same story as #3 on sbin/dhclient/dhclient.c (seems like most of the
code I'd lift is in the main() body and subsequent called functions.
I'd prefer not to duplicate it (see #3)

5. Assuming your personal answer to #2 is yes, what do you think a
"sane default" would be to poll the network to see if it is alive?
There is a fine balance between not burning lots of CPU checking every
second versus how long you go without a network connection when you are
changing networks.

6. Is there a way my daemon can be notified when the network becomes
unreachable versus having to poll? I'm thinking the answer to that is
"no" but I've been surprised at my own ignorance before (and will
continue to do so in the future I'm sure!) so I thought I would ask.

Thanks and sorry if this was tl;dr.
Raul Miller
2016-08-02 14:25:09 UTC
Permalink
Heck, I could probably write it as a shell script and just stuff it in my
crontab.
Good plan.

Though, personally, if I were in your situation, I'd skip the crontab part.

I happen to like knowing when my network endpoint changes.
--
Raul
Theo de Raadt
2016-08-02 14:29:16 UTC
Permalink
Post by Bryan Everly
3. My initial thought was to do the same things in my daemon that are
going on in the source of ifconfig.c - specifically the setifnwid(),
setifwpakey() and setifflags() functions (as opposed to shell exec'ing
the commands themselves). I'd prefer not to be someone who does "editor
reuse" and cut & paste those functions into my code, but I'm not sure
how you would approach that from a "how we do it in OpenBSD"
perspective. Would I refactor that tool to put those methods I use in a
library and then modify it to call them out of the library so we can
both share it?
There has been a lot of discussion about this. The model is not right.

Modern wireless chips/drivers can keep track of stations as they come and
go, but they have no way to expose this information. The old "scan" command
is an atrocity, and a daemon should not be built on top of it.

The kernel should have a better way of exporting stations it knows about
live, rather than userland forcing channel hops and station changes out
of sync with the kernel.
Jiri B
2016-08-02 14:57:27 UTC
Permalink
Post by Bryan Everly
Hi everyone,
I'm looking for feedback before I burn time on this project so please let me
know what you think.
I'm thinking about building a daemon that I'll write in C (looked at the
httpd code in /usr.sbin/httpd as a reference) that essentially monitors your
network connectivity in the background and, based on an /etc/wifid.conf file
(which contains an encrypted list of nwid's and wpa-keys that you have
loaded) looks for the presence of those nwid's and will connect you to them
(in a particular priority order you set) if it finds them. I would then
write a wifictl program that would communicate with the daemon and allow you
to manipulate the encrypted list, etc.
tl;dr but have you seen this paper?
http://www.openbsd.org/papers/eurobsdcon2015-raceless-network/index.html

j.
Kamil Cholewiński
2016-08-02 14:58:18 UTC
Permalink
Post by Theo de Raadt
The kernel should have a better way of exporting stations it knows about
live, rather than userland forcing channel hops and station changes out
of sync with the kernel.
Perhaps overloading kevent? EVFILT_IEEE80211?
Gilles Chehade
2016-08-02 20:02:13 UTC
Permalink
Post by Kamil Cholewiński
Post by Theo de Raadt
The kernel should have a better way of exporting stations it knows about
live, rather than userland forcing channel hops and station changes out
of sync with the kernel.
Perhaps overloading kevent? EVFILT_IEEE80211?
:-|
--
Gilles Chehade

https://www.poolp.org @poolpOrg
Bryan Everly
2016-08-03 12:26:24 UTC
Permalink
Post by Bryan Everly
Hi everyone,
I'm looking for feedback before I burn time on this project so please
let me know what you think.
I'm thinking about building a daemon that I'll write in C (looked at
the httpd code in /usr.sbin/httpd as a reference) that essentially
monitors your network connectivity in the background and, based on an
/etc/wifid.conf file (which contains an encrypted list of nwid's and
wpa-keys that you have loaded) looks for the presence of those nwid's
and will connect you to them (in a particular priority order you set)
if it finds them. I would then write a wifictl program that would
communicate with the daemon and allow you to manipulate the encrypted
list, etc.
The thought is that this would give us similar behavior to other
operating systems in making wifi more of a "set it and forget it"
capability in the system (versus running ifconfig and dhclient any
time I change to a new network).
1. Is there something like this already that I'm not seeing in OpenBSD?
2. Would anyone other than me want something like this? If not, I
will likely write it much less "cleanly" and just use it locally for
my needs. Heck, I could probably write it as a shell script and just
stuff it in my crontab.
3. My initial thought was to do the same things in my daemon that are
going on in the source of ifconfig.c - specifically the setifnwid(),
setifwpakey() and setifflags() functions (as opposed to shell exec'ing
the commands themselves). I'd prefer not to be someone who does
"editor reuse" and cut & paste those functions into my code, but I'm
not sure how you would approach that from a "how we do it in OpenBSD"
perspective. Would I refactor that tool to put those methods I use in
a library and then modify it to call them out of the library so we can
both share it?
4. Same story as #3 on sbin/dhclient/dhclient.c (seems like most of
the code I'd lift is in the main() body and subsequent called
functions. I'd prefer not to duplicate it (see #3)
5. Assuming your personal answer to #2 is yes, what do you think a
"sane default" would be to poll the network to see if it is alive?
There is a fine balance between not burning lots of CPU checking every
second versus how long you go without a network connection when you
are changing networks.
6. Is there a way my daemon can be notified when the network becomes
unreachable versus having to poll? I'm thinking the answer to that is
"no" but I've been surprised at my own ignorance before (and will
continue to do so in the future I'm sure!) so I thought I would ask.
Thanks and sorry if this was tl;dr.
Thank you to all of the people who replied in the list and privately.
As a result of that, it looks like someone has already done basically
what I'm looking for at:

https://github.com/farhaven/wireless

This was written by Gregor Best, jggimi and spedru.

I will reach out to them and see if they would like to see this added to
the ports tree and if so, will submit a patch to that list.

Thanks again everyone.
Walter Alejandro Iglesias
2016-08-03 14:51:48 UTC
Permalink
Hello,

Not what you asked for, but taking in care some people here complain
about not having a "desktop wireless connection app" as they got used by
the popular OSs, I'll share (shamelessly) what I improvised to solve my
specific needs with the aim to encourage others to write their own
solutions.

In my case, since I prefer to use ethernet cables and static IP
addresses for all machines in my home LAN, I wrote the following shell
scripts to connect my laptop in those occasions I'm out, in a bar or a
restaurant. They are also intended to be useful individually; if at
some place I have an ethernet cable available, I directly run the second
one (dhcp-connect.sh) to establish a provisional dhcp connection, then
(optionally) when I shutdown the machine before living the place, the
third one (reset-LAN.sh) restores the LAN version of /etc/hosts and
/etc/resolv.conf so I don't need to bother about reseting them manually
when I'm back home.

I'm new to openbsd, it surely offers simpler ways to accomplish the same
tasks that I still ignore (advices welcome).


=========================================================================
#!/bin/sh
# ~/bin/wifi.sh - occasional wireless connection in OpenBSD

[ "`whoami`" != "root" ] && { echo "You must be root"; exit 1; }

# PUT YOUR NORMAL USER HERE
user=morlock

# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi

[ ! -d $backdir ] && mkdir $backdir
rec=$backdir/stored
[ ! -e $rec ] && {
touch $rec
chmod 600 $rec
chown $user:$user $rec
}
tmp=/tmp/wifi-`date +%H%M%S`

# FUNCTIONS
cancel()
{
ifconfig $int -inet -inet6 -nwid -bssid -wpakey -nwkey
ifconfig $int down
[ -f $tmp ] && rm $tmp
[ -f $stored_tmp ] && rm $stored_tmp
exit 1
}

get_password()
{
if grep -i $bssid $rec; then
echo -n "Use the above \"$nwid\" stored password? [Y/n] "
read answer
if [ "$answer" != "n" ]; then
password=`grep -i $bssid $rec | awk '{ print $2 }'`
else
printf "$nwid $enc $message: "
read password
fi
else
printf "$nwid $enc $message: "
read password
fi
}

# SELECT WIRELESS INTERFACE
interfaces="`ifconfig wlan | awk -F: '/^[^\t]/ { print $1 }' | xargs`"
if [ ! "$interfaces" ]; then
echo "No wireless interfaces found." 1>&2
exit 1
elif [ `echo "$interfaces" | wc -w | xargs` -gt 1 ]; then
echo $interfaces
int=none
until echo $interfaces | grep -q $int; do
echo -n "Interface? "
read int
done
else
int=$interfaces
fi

trap cancel INT
ifconfig $int up
ifconfig $int -inet -inet6 -nwid -bssid -wpakey -nwkey

# SCAN AND CHOOSE AN ACCESS POINT
echo 'Scanning on '$int'...'
ifconfig $int scan | awk -F'\t' '/\tnwid/ { print $3 }' | nl -s') ' > $tmp
if [ `awk 'END { print NR }' $tmp` -eq 0 ]; then
echo "No access points found."
cancel
elif [ `awk 'END { print NR }' $tmp` -gt 1 ]; then
sed 's/\(.*\) nwid \(.*\) chan .*/\1 \2/' $tmp
ap=0
until egrep -q "^ *$ap\) nwid" $tmp ; do
echo -n "number? "
read ap
done
else
ap=`awk -F\) '{ print $1 }' $tmp | sed 's/ *//'`
fi

# GET AP DATA
bssid=`egrep '^ +'$ap')' $tmp | egrep -o '(..:){5}..' | tr "[a-f]" "[A-F]"`
nwid=`grep -i $bssid $tmp | sed 's/.* nwid \(.*\) chan .*/\1/' | sed 's/"//g'`
enc=`grep -i $bssid $tmp | awk -F, '{ print $NF }'`

case $enc in
wep)
key=nwkey
message="key (for HEX prefix 0x)"
get_password
;;
wpa*)
key=wpakey
message="passphrase"
get_password
;;
*)
key='-wpakey -nwkey'
password=''
;;
esac

# SET UP INTERFACE
ifconfig $int nwid "$nwid" $key $password || cancel

# CONNECTION ATTEMPT
/home/$user/bin/dhcp-connect.sh $int || cancel

# STORE PASSWORD
[ "$password" != "" ] && {
sed -i "/$bssid/d" $rec
echo -e "$bssid\t$password" > > $rec
}

# End of wifi.sh


=======================================================================
#!/bin/sh
# ~/bin/dhcp-connect.sh
# Connect using dhcp and set hostname (OpenBSD version)

[ "`whoami`" != "root" ] && { echo "You must be root"; exit 1; }

# PUT YOUR NORMAL USER HERE
user=morlock

# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi

int=$1
[ "$int" ] || {
echo "Usage: `basename $0` <interface>"
exit 1
}

clean_start()
{
for i in `ps xw | grep dhclient | grep $int | \
awk '{ print $1 }'`
do
[ $i ] && kill $i
done
}
cancel()
{
clean_start
[ -f $backdir/hosts ] && /home/$user/bin/reset-LAN.sh
exit 1
}
reset_LAN_at_shutdown()
{
[ ! -e /etc/rc.shutdown ] && {
echo "# /etc/rc.shutdown" > /etc/rc.shutdown
chmod 600 /etc/rc.shutdown
}
grep -q "# Reset LAN" /etc/rc.shutdown 2>/dev/null || {
echo > > /etc/rc.shutdown
echo '# Reset LAN' > >/etc/rc.shutdown
echo -n "[ -x /home/$user/bin/reset-LAN.sh ] && " \
/etc/rc.shutdown
echo "/home/$user/bin/reset-LAN.sh" > >/etc/rc.shutdown
}
}
dhclientConf()
{
grep -q "send host-name \"`hostname`\"" \
/etc/dhclient.conf 2>/dev/null ||
echo "send host-name \"`hostname`\";" \
/etc/dhclient.conf
}

clean_start
trap cancel INT

# Comment this if you think you don't need it
dhclientConf

# Attempt a connection
dhclient $int

ip=`ifconfig $int | awk '/inet/ { print $2 }'`
if [ "$ip" ]; then
[ -e $backdir/hosts ] && { # Set hosts file (Optional)
echo "# /etc/hosts" >/etc/hosts
echo "# (by $0)" > >/etc/hosts
echo -e "127.0.0.1\tlocalhost" > >/etc/hosts
echo -e "::1\tlocalhost" > >/etc/hosts
echo -e "$ip\t`hostname`\t`hostname -s`" > >/etc/hosts
reset_LAN_at_shutdown
/etc/rc.d/smtpd restart
grep -q ntpd /etc/rc.conf.local && /etc/rc.d/ntpd restart
}
else
echo "`basename $0`: could't establish the connection."
cancel
fi

# End of dhcp-connect.sh


=============================================================================
#!/bin/sh
# ~/bin/reset-LAN.sh - Reset your home LAN (OpenBSD version)

[ "`whoami`" != "root" ] && { echo "You must be root" 1>&2; exit 1; }

# PUT YOUR NORMAL USER HERE
user=morlock

# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi

diff -q $backdir/resolv.conf /etc/resolv.conf || {
cp $backdir/resolv.conf /etc || exit 1
echo "`basename $0`: restored LAN version of /etc/resolv.conf"
}
diff -q $backdir/hosts /etc/hosts || {
cp $backdir/hosts /etc || exit 1
echo "`basename $0`: restored LAN version of /etc/hosts"
}

# End of reset-LAN.sh



***


Finally, to add a menu entry to the window manager:

echo 'permit nopass <your_user> cmd /home/<your_user>/bin/wifi.sh' \
/etc/doas.conf
In ~/.cwmrc:

command wifi-connect "xterm -title wifi-connect \
-e \"doas /home/<your_user>/bin/wifi.sh; echo 'quiting...'; sleep 4\""

In a ~/.fvwmrc menu entry:

+ "WiFi connect" Exec exec xterm -title "WIFI Connect" \
-e "doas /home/<your_user>/bin/wifi.sh; echo 'quiting...'; sleep 4"



And that's all.



Walter
Walter Alejandro Iglesias
2016-08-03 15:21:07 UTC
Permalink
Sorry!

I have an entry in vimrc for my mail that replaces '>>' for '> >'. That
screwed the code, it was a bad idea. Here the corrected code:

=========================================================================
#!/bin/sh
# ~/bin/wifi.sh - occasional wireless connection in OpenBSD

[ "`whoami`" != "root" ] && { echo "You must be root"; exit 1; }

# PUT YOUR NORMAL USER HERE
user=morlock

# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi

[ ! -d $backdir ] && mkdir $backdir
rec=$backdir/stored
[ ! -e $rec ] && {
touch $rec
chmod 600 $rec
chown $user:$user $rec
}
tmp=/tmp/wifi-`date +%H%M%S`

# FUNCTIONS
cancel()
{
ifconfig $int -inet -inet6 -nwid -bssid -wpakey -nwkey
ifconfig $int down
[ -f $tmp ] && rm $tmp
[ -f $stored_tmp ] && rm $stored_tmp
exit 1
}

get_password()
{
if grep -i $bssid $rec; then
echo -n "Use the above \"$nwid\" stored password? [Y/n] "
read answer
if [ "$answer" != "n" ]; then
password=`grep -i $bssid $rec | awk '{ print $2 }'`
else
printf "$nwid $enc $message: "
read password
fi
else
printf "$nwid $enc $message: "
read password
fi
}

# SELECT WIRELESS INTERFACE
interfaces="`ifconfig wlan | awk -F: '/^[^\t]/ { print $1 }' | xargs`"
if [ ! "$interfaces" ]; then
echo "No wireless interfaces found." 1>&2
exit 1
elif [ `echo "$interfaces" | wc -w | xargs` -gt 1 ]; then
echo $interfaces
int=none
until echo $interfaces | grep -q $int; do
echo -n "Interface? "
read int
done
else
int=$interfaces
fi

trap cancel INT
ifconfig $int up
ifconfig $int -inet -inet6 -nwid -bssid -wpakey -nwkey

# SCAN AND CHOOSE AN ACCESS POINT
echo 'Scanning on '$int'...'
ifconfig $int scan | awk -F'\t' '/\tnwid/ { print $3 }' | nl -s') ' > $tmp
if [ `awk 'END { print NR }' $tmp` -eq 0 ]; then
echo "No access points found."
cancel
elif [ `awk 'END { print NR }' $tmp` -gt 1 ]; then
sed 's/\(.*\) nwid \(.*\) chan .*/\1 \2/' $tmp
ap=0
until egrep -q "^ *$ap\) nwid" $tmp ; do
echo -n "number? "
read ap
done
else
ap=`awk -F\) '{ print $1 }' $tmp | sed 's/ *//'`
fi

# GET AP DATA
bssid=`egrep '^ +'$ap')' $tmp | egrep -o '(..:){5}..' | tr "[a-f]" "[A-F]"`
nwid=`grep -i $bssid $tmp | sed 's/.* nwid \(.*\) chan .*/\1/' | sed 's/"//g'`
enc=`grep -i $bssid $tmp | awk -F, '{ print $NF }'`

case $enc in
wep)
key=nwkey
message="key (for HEX prefix 0x)"
get_password
;;
wpa*)
key=wpakey
message="passphrase"
get_password
;;
*)
key='-wpakey -nwkey'
password=''
;;
esac

# SET UP INTERFACE
ifconfig $int nwid "$nwid" $key $password || cancel

# CONNECTION ATTEMPT
/home/$user/bin/dhcp-connect.sh $int || cancel

# STORE PASSWORD
[ "$password" != "" ] && {
sed -i "/$bssid/d" $rec
echo -e "$bssid\t$password" >> $rec
}

# End of wifi.sh


=======================================================================
#!/bin/sh
# ~/bin/dhcp-connect.sh
# Connect using dhcp and set hostname (OpenBSD version)

[ "`whoami`" != "root" ] && { echo "You must be root"; exit 1; }

# PUT YOUR NORMAL USER HERE
user=morlock

# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi

int=$1
[ "$int" ] || {
echo "Usage: `basename $0` <interface>"
exit 1
}

clean_start()
{
for i in `ps xw | grep dhclient | grep $int | \
awk '{ print $1 }'`
do
[ $i ] && kill $i
done
}
cancel()
{
clean_start
[ -f $backdir/hosts ] && /home/$user/bin/reset-LAN.sh
exit 1
}
reset_LAN_at_shutdown()
{
[ ! -e /etc/rc.shutdown ] && {
echo "# /etc/rc.shutdown" > /etc/rc.shutdown
chmod 600 /etc/rc.shutdown
}
grep -q "# Reset LAN" /etc/rc.shutdown 2>/dev/null || {
echo >>/etc/rc.shutdown
echo '# Reset LAN' >>/etc/rc.shutdown
echo -n "[ -x /home/$user/bin/reset-LAN.sh ] && " \
Post by Walter Alejandro Iglesias
/etc/rc.shutdown
echo "/home/$user/bin/reset-LAN.sh" >>/etc/rc.shutdown
}
}
dhclientConf()
{
grep -q "send host-name \"`hostname`\"" \
/etc/dhclient.conf 2>/dev/null ||
echo "send host-name \"`hostname`\";" \
Post by Walter Alejandro Iglesias
/etc/dhclient.conf
}

clean_start
trap cancel INT

# Comment this if you think you don't need it
dhclientConf

# Attempt a connection
dhclient $int

ip=`ifconfig $int | awk '/inet/ { print $2 }'`
if [ "$ip" ]; then
[ -e $backdir/hosts ] && { # Set hosts file (Optional)
echo "# /etc/hosts" >/etc/hosts
echo "# (by $0)" >>/etc/hosts
echo -e "127.0.0.1\tlocalhost" >>/etc/hosts
echo -e "::1\tlocalhost" >>/etc/hosts
echo -e "$ip\t`hostname`\t`hostname -s`" >>/etc/hosts
reset_LAN_at_shutdown
/etc/rc.d/smtpd restart
grep -q ntpd /etc/rc.conf.local && /etc/rc.d/ntpd restart
}
else
echo "`basename $0`: could't establish the connection."
cancel
fi

# End of dhcp-connect.sh


=============================================================================
#!/bin/sh
# ~/bin/reset-LAN.sh - Reset your home LAN (OpenBSD version)

[ "`whoami`" != "root" ] && { echo "You must be root" 1>&2; exit 1; }

# PUT YOUR NORMAL USER HERE
user=morlock

# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi

diff -q $backdir/resolv.conf /etc/resolv.conf || {
cp $backdir/resolv.conf /etc || exit 1
echo "`basename $0`: restored LAN version of /etc/resolv.conf"
}
diff -q $backdir/hosts /etc/hosts || {
cp $backdir/hosts /etc || exit 1
echo "`basename $0`: restored LAN version of /etc/hosts"
}

# End of reset-LAN.sh



***


Finally, to add a menu entry to the window manager:

echo 'permit nopass <your_user> cmd /home/<your_user>/bin/wifi.sh' \
Post by Walter Alejandro Iglesias
/etc/doas.conf
In ~/.cwmrc:

command wifi-connect "xterm -title wifi-connect \
-e \"doas /home/<your_user>/bin/wifi.sh; echo 'quiting...'; sleep 4\""

In a ~/.fvwmrc menu entry:

+ "WiFi connect" Exec exec xterm -title "WIFI Connect" \
-e "doas /home/<your_user>/bin/wifi.sh; echo 'quiting...'; sleep 4"
Steven Dee
2016-08-03 16:51:28 UTC
Permalink
Cool. Maybe a good complement for <https://github.com/mrdomino/autonet>.

On Wed, Aug 3, 2016 at 11:30 AM Walter Alejandro Iglesias <
Post by Walter Alejandro Iglesias
Sorry!
I have an entry in vimrc for my mail that replaces '>>' for '> >'. That
=========================================================================
#!/bin/sh
# ~/bin/wifi.sh - occasional wireless connection in OpenBSD
[ "`whoami`" != "root" ] && { echo "You must be root"; exit 1; }
# PUT YOUR NORMAL USER HERE
user=morlock
# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi
[ ! -d $backdir ] && mkdir $backdir
rec=$backdir/stored
[ ! -e $rec ] && {
touch $rec
chmod 600 $rec
chown $user:$user $rec
}
tmp=/tmp/wifi-`date +%H%M%S`
# FUNCTIONS
cancel()
{
ifconfig $int -inet -inet6 -nwid -bssid -wpakey -nwkey
ifconfig $int down
[ -f $tmp ] && rm $tmp
[ -f $stored_tmp ] && rm $stored_tmp
exit 1
}
get_password()
{
if grep -i $bssid $rec; then
echo -n "Use the above \"$nwid\" stored password? [Y/n] "
read answer
if [ "$answer" != "n" ]; then
password=`grep -i $bssid $rec | awk '{ print $2 }'`
else
printf "$nwid $enc $message: "
read password
fi
else
printf "$nwid $enc $message: "
read password
fi
}
# SELECT WIRELESS INTERFACE
interfaces="`ifconfig wlan | awk -F: '/^[^\t]/ { print $1 }' | xargs`"
if [ ! "$interfaces" ]; then
echo "No wireless interfaces found." 1>&2
exit 1
elif [ `echo "$interfaces" | wc -w | xargs` -gt 1 ]; then
echo $interfaces
int=none
until echo $interfaces | grep -q $int; do
echo -n "Interface? "
read int
done
else
int=$interfaces
fi
trap cancel INT
ifconfig $int up
ifconfig $int -inet -inet6 -nwid -bssid -wpakey -nwkey
# SCAN AND CHOOSE AN ACCESS POINT
echo 'Scanning on '$int'...'
ifconfig $int scan | awk -F'\t' '/\tnwid/ { print $3 }' | nl -s') ' > $tmp
if [ `awk 'END { print NR }' $tmp` -eq 0 ]; then
echo "No access points found."
cancel
elif [ `awk 'END { print NR }' $tmp` -gt 1 ]; then
sed 's/\(.*\) nwid \(.*\) chan .*/\1 \2/' $tmp
ap=0
until egrep -q "^ *$ap\) nwid" $tmp ; do
echo -n "number? "
read ap
done
else
ap=`awk -F\) '{ print $1 }' $tmp | sed 's/ *//'`
fi
# GET AP DATA
bssid=`egrep '^ +'$ap')' $tmp | egrep -o '(..:){5}..' | tr "[a-f]" "[A-F]"`
nwid=`grep -i $bssid $tmp | sed 's/.* nwid \(.*\) chan .*/\1/' | sed
's/"//g'`
enc=`grep -i $bssid $tmp | awk -F, '{ print $NF }'`
case $enc in
wep)
key=nwkey
message="key (for HEX prefix 0x)"
get_password
;;
wpa*)
key=wpakey
message="passphrase"
get_password
;;
*)
key='-wpakey -nwkey'
password=''
;;
esac
# SET UP INTERFACE
ifconfig $int nwid "$nwid" $key $password || cancel
# CONNECTION ATTEMPT
/home/$user/bin/dhcp-connect.sh $int || cancel
# STORE PASSWORD
[ "$password" != "" ] && {
sed -i "/$bssid/d" $rec
echo -e "$bssid\t$password" >> $rec
}
# End of wifi.sh
=======================================================================
#!/bin/sh
# ~/bin/dhcp-connect.sh
# Connect using dhcp and set hostname (OpenBSD version)
[ "`whoami`" != "root" ] && { echo "You must be root"; exit 1; }
# PUT YOUR NORMAL USER HERE
user=morlock
# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi
int=$1
[ "$int" ] || {
echo "Usage: `basename $0` <interface>"
exit 1
}
clean_start()
{
for i in `ps xw | grep dhclient | grep $int | \
awk '{ print $1 }'`
do
[ $i ] && kill $i
done
}
cancel()
{
clean_start
[ -f $backdir/hosts ] && /home/$user/bin/reset-LAN.sh
exit 1
}
reset_LAN_at_shutdown()
{
[ ! -e /etc/rc.shutdown ] && {
echo "# /etc/rc.shutdown" > /etc/rc.shutdown
chmod 600 /etc/rc.shutdown
}
grep -q "# Reset LAN" /etc/rc.shutdown 2>/dev/null || {
echo >>/etc/rc.shutdown
echo '# Reset LAN' >>/etc/rc.shutdown
echo -n "[ -x /home/$user/bin/reset-LAN.sh ] && " \
Post by Walter Alejandro Iglesias
/etc/rc.shutdown
echo "/home/$user/bin/reset-LAN.sh" >>/etc/rc.shutdown
}
}
dhclientConf()
{
grep -q "send host-name \"`hostname`\"" \
/etc/dhclient.conf 2>/dev/null ||
echo "send host-name \"`hostname`\";" \
Post by Walter Alejandro Iglesias
/etc/dhclient.conf
}
clean_start
trap cancel INT
# Comment this if you think you don't need it
dhclientConf
# Attempt a connection
dhclient $int
ip=`ifconfig $int | awk '/inet/ { print $2 }'`
if [ "$ip" ]; then
[ -e $backdir/hosts ] && { # Set hosts file (Optional)
echo "# /etc/hosts" >/etc/hosts
echo "# (by $0)"
Post by Walter Alejandro Iglesias
/etc/hosts
echo -e "127.0.0.1\tlocalhost"
Post by Walter Alejandro Iglesias
/etc/hosts
echo -e "::1\tlocalhost"
Post by Walter Alejandro Iglesias
/etc/hosts
echo -e "$ip\t`hostname`\t`hostname -s`"
Post by Walter Alejandro Iglesias
/etc/hosts
reset_LAN_at_shutdown
/etc/rc.d/smtpd restart
grep -q ntpd /etc/rc.conf.local && /etc/rc.d/ntpd restart
}
else
echo "`basename $0`: could't establish the connection."
cancel
fi
# End of dhcp-connect.sh
=============================================================================
#!/bin/sh
# ~/bin/reset-LAN.sh - Reset your home LAN (OpenBSD version)
[ "`whoami`" != "root" ] && { echo "You must be root" 1>&2; exit 1; }
# PUT YOUR NORMAL USER HERE
user=morlock
# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi
diff -q $backdir/resolv.conf /etc/resolv.conf || {
cp $backdir/resolv.conf /etc || exit 1
echo "`basename $0`: restored LAN version of /etc/resolv.conf"
}
diff -q $backdir/hosts /etc/hosts || {
cp $backdir/hosts /etc || exit 1
echo "`basename $0`: restored LAN version of /etc/hosts"
}
# End of reset-LAN.sh
***
echo 'permit nopass <your_user> cmd /home/<your_user>/bin/wifi.sh' \
Post by Walter Alejandro Iglesias
/etc/doas.conf
command wifi-connect "xterm -title wifi-connect \
-e \"doas /home/<your_user>/bin/wifi.sh; echo 'quiting...'; sleep
4\""
+ "WiFi connect" Exec exec xterm -title "WIFI Connect" \
-e "doas /home/<your_user>/bin/wifi.sh; echo 'quiting...'; sleep 4"
Scott Bonds
2016-08-03 18:59:01 UTC
Permalink
I count myself among those who have taken a stab at automating wifi
roaming in userland:

https://github.com/bonds/winot

To be clear, winot is far, far from production ready, its more of an
excuse for me to play with Haskell at this point. But I've started
adding to the Further Reading and Alternatives sections of the README
when I see a thread on this topic, so maybe that could be useful to a
wider audience.
Post by Steven Dee
Cool. Maybe a good complement for <https://github.com/mrdomino/autonet>.
On Wed, Aug 3, 2016 at 11:30 AM Walter Alejandro Iglesias <
Post by Walter Alejandro Iglesias
Sorry!
I have an entry in vimrc for my mail that replaces '>>' for '> >'. That
=========================================================================
#!/bin/sh
# ~/bin/wifi.sh - occasional wireless connection in OpenBSD
[ "`whoami`" != "root" ] && { echo "You must be root"; exit 1; }
# PUT YOUR NORMAL USER HERE
user=morlock
# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi
[ ! -d $backdir ] && mkdir $backdir
rec=$backdir/stored
[ ! -e $rec ] && {
touch $rec
chmod 600 $rec
chown $user:$user $rec
}
tmp=/tmp/wifi-`date +%H%M%S`
# FUNCTIONS
cancel()
{
ifconfig $int -inet -inet6 -nwid -bssid -wpakey -nwkey
ifconfig $int down
[ -f $tmp ] && rm $tmp
[ -f $stored_tmp ] && rm $stored_tmp
exit 1
}
get_password()
{
if grep -i $bssid $rec; then
echo -n "Use the above \"$nwid\" stored password? [Y/n] "
read answer
if [ "$answer" != "n" ]; then
password=`grep -i $bssid $rec | awk '{ print $2 }'`
else
printf "$nwid $enc $message: "
read password
fi
else
printf "$nwid $enc $message: "
read password
fi
}
# SELECT WIRELESS INTERFACE
interfaces="`ifconfig wlan | awk -F: '/^[^\t]/ { print $1 }' | xargs`"
if [ ! "$interfaces" ]; then
echo "No wireless interfaces found." 1>&2
exit 1
elif [ `echo "$interfaces" | wc -w | xargs` -gt 1 ]; then
echo $interfaces
int=none
until echo $interfaces | grep -q $int; do
echo -n "Interface? "
read int
done
else
int=$interfaces
fi
trap cancel INT
ifconfig $int up
ifconfig $int -inet -inet6 -nwid -bssid -wpakey -nwkey
# SCAN AND CHOOSE AN ACCESS POINT
echo 'Scanning on '$int'...'
ifconfig $int scan | awk -F'\t' '/\tnwid/ { print $3 }' | nl -s') ' > $tmp
if [ `awk 'END { print NR }' $tmp` -eq 0 ]; then
echo "No access points found."
cancel
elif [ `awk 'END { print NR }' $tmp` -gt 1 ]; then
sed 's/\(.*\) nwid \(.*\) chan .*/\1 \2/' $tmp
ap=0
until egrep -q "^ *$ap\) nwid" $tmp ; do
echo -n "number? "
read ap
done
else
ap=`awk -F\) '{ print $1 }' $tmp | sed 's/ *//'`
fi
# GET AP DATA
bssid=`egrep '^ +'$ap')' $tmp | egrep -o '(..:){5}..' | tr "[a-f]" "[A-F]"`
nwid=`grep -i $bssid $tmp | sed 's/.* nwid \(.*\) chan .*/\1/' | sed
's/"//g'`
enc=`grep -i $bssid $tmp | awk -F, '{ print $NF }'`
case $enc in
wep)
key=nwkey
message="key (for HEX prefix 0x)"
get_password
;;
wpa*)
key=wpakey
message="passphrase"
get_password
;;
*)
key='-wpakey -nwkey'
password=''
;;
esac
# SET UP INTERFACE
ifconfig $int nwid "$nwid" $key $password || cancel
# CONNECTION ATTEMPT
/home/$user/bin/dhcp-connect.sh $int || cancel
# STORE PASSWORD
[ "$password" != "" ] && {
sed -i "/$bssid/d" $rec
echo -e "$bssid\t$password" >> $rec
}
# End of wifi.sh
=======================================================================
#!/bin/sh
# ~/bin/dhcp-connect.sh
# Connect using dhcp and set hostname (OpenBSD version)
[ "`whoami`" != "root" ] && { echo "You must be root"; exit 1; }
# PUT YOUR NORMAL USER HERE
user=morlock
# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi
int=$1
[ "$int" ] || {
echo "Usage: `basename $0` <interface>"
exit 1
}
clean_start()
{
for i in `ps xw | grep dhclient | grep $int | \
awk '{ print $1 }'`
do
[ $i ] && kill $i
done
}
cancel()
{
clean_start
[ -f $backdir/hosts ] && /home/$user/bin/reset-LAN.sh
exit 1
}
reset_LAN_at_shutdown()
{
[ ! -e /etc/rc.shutdown ] && {
echo "# /etc/rc.shutdown" > /etc/rc.shutdown
chmod 600 /etc/rc.shutdown
}
grep -q "# Reset LAN" /etc/rc.shutdown 2>/dev/null || {
echo >>/etc/rc.shutdown
echo '# Reset LAN' >>/etc/rc.shutdown
echo -n "[ -x /home/$user/bin/reset-LAN.sh ] && " \
Post by Walter Alejandro Iglesias
/etc/rc.shutdown
echo "/home/$user/bin/reset-LAN.sh" >>/etc/rc.shutdown
}
}
dhclientConf()
{
grep -q "send host-name \"`hostname`\"" \
/etc/dhclient.conf 2>/dev/null ||
echo "send host-name \"`hostname`\";" \
Post by Walter Alejandro Iglesias
/etc/dhclient.conf
}
clean_start
trap cancel INT
# Comment this if you think you don't need it
dhclientConf
# Attempt a connection
dhclient $int
ip=`ifconfig $int | awk '/inet/ { print $2 }'`
if [ "$ip" ]; then
[ -e $backdir/hosts ] && { # Set hosts file (Optional)
echo "# /etc/hosts" >/etc/hosts
echo "# (by $0)"
Post by Walter Alejandro Iglesias
/etc/hosts
echo -e "127.0.0.1\tlocalhost"
Post by Walter Alejandro Iglesias
/etc/hosts
echo -e "::1\tlocalhost"
Post by Walter Alejandro Iglesias
/etc/hosts
echo -e "$ip\t`hostname`\t`hostname -s`"
Post by Walter Alejandro Iglesias
/etc/hosts
reset_LAN_at_shutdown
/etc/rc.d/smtpd restart
grep -q ntpd /etc/rc.conf.local && /etc/rc.d/ntpd restart
}
else
echo "`basename $0`: could't establish the connection."
cancel
fi
# End of dhcp-connect.sh
=============================================================================
#!/bin/sh
# ~/bin/reset-LAN.sh - Reset your home LAN (OpenBSD version)
[ "`whoami`" != "root" ] && { echo "You must be root" 1>&2; exit 1; }
# PUT YOUR NORMAL USER HERE
user=morlock
# IMPORTANT: if you don't use dhcp in your home LAN save a copy of your
# LAN version of /etc/resolv.conf and /etc/hosts to this directory.
backdir=/home/$user/.wifi
diff -q $backdir/resolv.conf /etc/resolv.conf || {
cp $backdir/resolv.conf /etc || exit 1
echo "`basename $0`: restored LAN version of /etc/resolv.conf"
}
diff -q $backdir/hosts /etc/hosts || {
cp $backdir/hosts /etc || exit 1
echo "`basename $0`: restored LAN version of /etc/hosts"
}
# End of reset-LAN.sh
***
echo 'permit nopass <your_user> cmd /home/<your_user>/bin/wifi.sh' \
Post by Walter Alejandro Iglesias
/etc/doas.conf
command wifi-connect "xterm -title wifi-connect \
-e \"doas /home/<your_user>/bin/wifi.sh; echo 'quiting...'; sleep
4\""
+ "WiFi connect" Exec exec xterm -title "WIFI Connect" \
-e "doas /home/<your_user>/bin/wifi.sh; echo 'quiting...'; sleep 4"
Loading...