Re: New: netctl(8) - cli network-location manager

2017-09-27 Thread Aaron Poffenberger
* Aaron Poffenberger  [2017-09-26 21:53:24 -0500]:

> I should add, I thought about adding commands like rcctl's
> `get|getdef|set` commands to do full interface configuration (`set
> nwid wapname` or `set bssid `) but wanted to get feedback on
> the current approach before going to far down the rabbit hole.
> 
> --Aaron
> 
> * Aaron Poffenberger  [2017-09-26 20:39:29 -0500]:
> 
> > Attached is a cli utility to manage network locations. It's modeled
> > after rcctl(8).
> > 
> > It doesn't attempt to replace netstart(8) or ifconfig(8). It works
> > with them by storing location information in a directory and
> > symlinking the hostname.if files to the hostname.if for the selected
> > location.
> > 
> > At the moment if doesn't handle auto discovery of WAPs, but I have
> > code I wrote earlier I'm rewriting and integrating.
> > 
> > netctl is written in pure shell so in theory it could be called at
> > boot time. To do that, I'd probably split netctl into two pieces
> > similar to the way rcctl(8) and rc.subr(8) work. One file for
> > inclusion in /etc and the main ctl for /usr.
> > 
> > The code could be integrated into netstart at some later date.
> > 
> > In addition to the netctl utility I've included a man page.
> > 
> > Comments or feedback would be appreciated.
> > 
> > --Aaron

Below is a new unified diff. I added auto-detection and joining of
wireless networks.

I haven't done the work to allow boot-time auto-detect and joining of
wireless networks, yet. It's on my todo list.

I added a simple example script to the man page showing how to use it
with apmd(8) for resuming.

I also included the Makefile and README which were not in the original
posting.

--Aaron

--- /dev/null   Wed Sep 27 22:09:14 2017
+++ MakefileWed Sep 27 21:40:26 2017
@@ -0,0 +1,11 @@
+#  $OpenBSD$
+
+MAN=   netctl.8
+
+SCRIPT=netctl.sh
+
+realinstall:
+   ${INSTALL} ${INSTALL_COPY} -o ${BINOWN} -g ${BINGRP} -m ${BINMODE} \
+   ${.CURDIR}/${SCRIPT} ${DESTDIR}${BINDIR}/netctl
+
+.include 
--- /dev/null   Wed Sep 27 22:09:14 2017
+++ README.md   Wed Sep 27 20:43:01 2017
@@ -0,0 +1,159 @@
+About netctl
+
+
+`netctl` is a utility to manage network locations, interface
+configuration files, and to start, stop, or restart interfaces on
+OpenBSD.
+
+`netctl` is not a replacement for `ifconfig(8)` or `netstart(8)`. It's
+utility to make managing locations easier. `netstart` and `ifconfig`
+still do the work. `netctl` makes the user's life, especially portable
+users, easier.
+
+
+Features
+
++ Create, delete and switch between **locations** (including restarting
+  **interfaces**)
++ Enable and disable **configurations**.
++ Start, stop and restart **interfaces**.
++ Detect and join known wireless networks (**waps**).
++ Scan for wireless access points.
++ List **locations**, **configurations**, **interfaces**, and **waps**.
+
+See the man page for further details.
+
+
+Install
+---
+
+There's no installer for `netctl` at the moment. `doas make install`
+will install to **/usr/local** unless you override the PREFIX
+variable.
+
+`make install` will also create **/etc/hostname.d/** and
+**/etc/hostname.d/nwids/**
+
+
+Locations
+-
+
+`netctl` works by symlinking **hostname.if** files in location
+directories to **/etc/hostname.if** so that the normal `netstart(8)`
+code can do what it already does well.
+
+`netctl` will create **location** directories for you by calling `doas
+netctl create location_name`. `netctl` will **not** at this time
+create the **hostname.if** files. They have to be created the same
+ways as documented in `hostname.if(5)`. See the `man` page for more
+details.
+
+
+Auto Detecting and Joining Networks
+---
+
+Auto detecting and joining requires some setup. `netctl` will not
+connect to wireless access points that are not known. To create a
+*known* wap, a standard wireless **hostname.if** files should be
+created in **/etc/hostname.d/nwids**. *E.g.,*
+
+```
+   $ cat /etc/hostname.d/nwids/Silly\ Wap.nwid
+   nwid "Silly Wap"
+   wpakey '$w@pau7h99'
+   dhcp
+```
+
+The filename **must** be the same as the **nwid** in the file which
+**must** match the **ESSID** of the wireless access point. Any valid
+configuration directive `ifconfig(8)` will accept may be placed in the
+file.
+
+Executing `doas netctl -a start iwm0` will cause `netctl` to scan the
+local network (with `ifconfig iwm0 scan`) and attempt to match the
+results with the names of the **nwids** found by `ls`-ing
+**/etc/hostname.d/nwids**.
+
+**N.B.** `ifconfig scan` is called dwith *each* wlan device unless one
+is specified after the **start** parameter.
+
+
+Auto Detecting and Joining Networks When Resuming
+-
+
+`netctl` is not a daemon so it doesn't know when a computer has
+resumed from sleep. `apmd(8)` does know and will call a script called
+**resume** if it exists in **/etc/apm** and is 

Re: New: netctl(8) - cli network-location manager

2017-09-26 Thread Aaron Poffenberger
I should add, I thought about adding commands like rcctl's
`get|getdef|set` commands to do full interface configuration (`set
nwid wapname` or `set bssid `) but wanted to get feedback on
the current approach before going to far down the rabbit hole.

--Aaron

* Aaron Poffenberger  [2017-09-26 20:39:29 -0500]:

> Attached is a cli utility to manage network locations. It's modeled
> after rcctl(8).
> 
> It doesn't attempt to replace netstart(8) or ifconfig(8). It works
> with them by storing location information in a directory and
> symlinking the hostname.if files to the hostname.if for the selected
> location.
> 
> At the moment if doesn't handle auto discovery of WAPs, but I have
> code I wrote earlier I'm rewriting and integrating.
> 
> netctl is written in pure shell so in theory it could be called at
> boot time. To do that, I'd probably split netctl into two pieces
> similar to the way rcctl(8) and rc.subr(8) work. One file for
> inclusion in /etc and the main ctl for /usr.
> 
> The code could be integrated into netstart at some later date.
> 
> In addition to the netctl utility I've included a man page.
> 
> Comments or feedback would be appreciated.
> 
> --Aaron
> 
> --- /dev/null Tue Sep 26 20:26:45 2017
> +++ netctlTue Sep 26 20:16:28 2017
> @@ -0,0 +1,450 @@
> +#!/bin/sh
> +#
> +# $OpenBSD$
> +#
> +# Copyright (c) 2017 Aaron Poffenberger 
> +#
> +# 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.
> +#
> +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> +# cmd OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS cmd, ARISING OUT OF
> +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> +#
> +
> +# Turn off Strict Bourne shell mode.
> +set +o sh
> +
> +readonly __progname="netctl"
> +readonly TRUE=0
> +readonly FALSE=1
> +readonly HN_DIR=${HN_DIR:-/etc/hostname.d}
> +
> +# Log an error
> +# Usage: log_err msg [exit code]
> +# Cheerfully copied from rc.subr(8)
> +# Copyright (c) 2010, 2011, 2014-2017 Antoine Jacoutot 
> 
> +# Copyright (c) 2010, 2011 Ingo Schwarze 
> +# Copyright (c) 2010, 2011, 2014 Robert Nagy 
> +log_err() {
> + [ -n "${1}" ] && echo "${1}" 1>&2
> + [ -n "${2}" ] && exit "${2}" || exit 1
> +}
> +
> +# Log a warning
> +# Usage: log_err msg [exit code]
> +log_warning() {
> + log_msg "${1}" 1>&2
> +}
> +
> +# Log a message
> +# Usage: log_msg msg [right justify length]
> +log_msg() {
> + local -R${2:-0} _msg="${1}"
> +
> + [ -n "${_msg}" ] && echo "${_msg}"
> +}
> +
> +# Log a message to stdout or stderr
> +# Usage: usage [2]
> +usage() {
> + echo \
> + "usage:  netctl [-h]
> + netctl ls [lsarg ...]
> + netctl create|delete location ...
> + netctl [-dr] switch location [interface ...]
> + netctl enable|disable [configuration ...]
> + netctl start|stop|restart [interface ...]
> + netctl [-v] scan [interface ...]" 1>&${1:-1}
> +}
> +
> +# Get interface configuration
> +# Expects variables to be typeset/local from calling fn
> +# Usage: get_if_conf if1
> +get_if_conf() {
> + # use co-process to preserve values set in while loop
> + ifconfig $1 |&
> + while IFS=' ' read -r -p _l; do
> + _key=${_l%%*([[:blank:]])*(:) *}
> + _val=${_l##*([[:blank:]])*${_key}*(:)*([[:blank:]])}
> +
> + [[ ${_key} == 'groups' ]] && _groups=${_val}
> + [[ ${_key} == 'media' ]] && _media=${_val}
> + [[ ${_key} == 'status' ]] && _status=${_val}
> + [[ ${_key} == 'ieee80211' ]] && _ieee80211=${_val}
> + [[ ${_key} == 'inet' ]] && _inet=${_val}
> + [[ ${_key} == 'inet6' ]] && _inet6=${_val}
> + done
> +}
> +
> +# Get interfaces
> +# Expects variable _ifs to be typeset/local from calling fn
> +# Usage: get_ifs if1
> +get_ifs() {
> + local _if _excl_keys
> + # exclude network pseudo-devices
> + set -A _pseudo_devices $(ifconfig -C)
> +
> + # use co-process to preserve values set in while loop
> + ifconfig $1 |&
> + while IFS=' ' read -r -p _l; do
> + [[ "${_l}" == *flags* ]] || continue
> +
> + _if=${_l%%*([[:blank:]])*():*}
> +
> + [ -z "${_if}" ] && continue
> +
> + #_if=${_l%%*([[:blank:]])*():*}
> +
> + # exclude if-type (san _if num) in pseudo-devices
> + [[ " ${_pseudo_devices[*]}0 " == *" ${_if%%*([[:digit:]])} "* 
> ]] &&
> + continue
> +
> + _ifs[${#_ifs[*]}]="${_if}"
> + done
> +
> + [ -n "${_ifs}" ] || return

New: netctl(8) - cli network-location manager

2017-09-26 Thread Aaron Poffenberger
Attached is a cli utility to manage network locations. It's modeled
after rcctl(8).

It doesn't attempt to replace netstart(8) or ifconfig(8). It works
with them by storing location information in a directory and
symlinking the hostname.if files to the hostname.if for the selected
location.

At the moment if doesn't handle auto discovery of WAPs, but I have
code I wrote earlier I'm rewriting and integrating.

netctl is written in pure shell so in theory it could be called at
boot time. To do that, I'd probably split netctl into two pieces
similar to the way rcctl(8) and rc.subr(8) work. One file for
inclusion in /etc and the main ctl for /usr.

The code could be integrated into netstart at some later date.

In addition to the netctl utility I've included a man page.

Comments or feedback would be appreciated.

--Aaron

--- /dev/null   Tue Sep 26 20:26:45 2017
+++ netctl  Tue Sep 26 20:16:28 2017
@@ -0,0 +1,450 @@
+#!/bin/sh
+#
+# $OpenBSD$
+#
+# Copyright (c) 2017 Aaron Poffenberger 
+#
+# 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.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# cmd OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS cmd, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+# Turn off Strict Bourne shell mode.
+set +o sh
+
+readonly __progname="netctl"
+readonly TRUE=0
+readonly FALSE=1
+readonly HN_DIR=${HN_DIR:-/etc/hostname.d}
+
+# Log an error
+# Usage: log_err msg [exit code]
+# Cheerfully copied from rc.subr(8)
+# Copyright (c) 2010, 2011, 2014-2017 Antoine Jacoutot 
+# Copyright (c) 2010, 2011 Ingo Schwarze 
+# Copyright (c) 2010, 2011, 2014 Robert Nagy 
+log_err() {
+   [ -n "${1}" ] && echo "${1}" 1>&2
+   [ -n "${2}" ] && exit "${2}" || exit 1
+}
+
+# Log a warning
+# Usage: log_err msg [exit code]
+log_warning() {
+   log_msg "${1}" 1>&2
+}
+
+# Log a message
+# Usage: log_msg msg [right justify length]
+log_msg() {
+   local -R${2:-0} _msg="${1}"
+
+   [ -n "${_msg}" ] && echo "${_msg}"
+}
+
+# Log a message to stdout or stderr
+# Usage: usage [2]
+usage() {
+   echo \
+   "usage:  netctl [-h]
+   netctl ls [lsarg ...]
+   netctl create|delete location ...
+   netctl [-dr] switch location [interface ...]
+   netctl enable|disable [configuration ...]
+   netctl start|stop|restart [interface ...]
+   netctl [-v] scan [interface ...]" 1>&${1:-1}
+}
+
+# Get interface configuration
+# Expects variables to be typeset/local from calling fn
+# Usage: get_if_conf if1
+get_if_conf() {
+   # use co-process to preserve values set in while loop
+   ifconfig $1 |&
+   while IFS=' ' read -r -p _l; do
+   _key=${_l%%*([[:blank:]])*(:) *}
+   _val=${_l##*([[:blank:]])*${_key}*(:)*([[:blank:]])}
+
+   [[ ${_key} == 'groups' ]] && _groups=${_val}
+   [[ ${_key} == 'media' ]] && _media=${_val}
+   [[ ${_key} == 'status' ]] && _status=${_val}
+   [[ ${_key} == 'ieee80211' ]] && _ieee80211=${_val}
+   [[ ${_key} == 'inet' ]] && _inet=${_val}
+   [[ ${_key} == 'inet6' ]] && _inet6=${_val}
+   done
+}
+
+# Get interfaces
+# Expects variable _ifs to be typeset/local from calling fn
+# Usage: get_ifs if1
+get_ifs() {
+   local _if _excl_keys
+   # exclude network pseudo-devices
+   set -A _pseudo_devices $(ifconfig -C)
+
+   # use co-process to preserve values set in while loop
+   ifconfig $1 |&
+   while IFS=' ' read -r -p _l; do
+   [[ "${_l}" == *flags* ]] || continue
+
+   _if=${_l%%*([[:blank:]])*():*}
+
+   [ -z "${_if}" ] && continue
+
+   #_if=${_l%%*([[:blank:]])*():*}
+
+   # exclude if-type (san _if num) in pseudo-devices
+   [[ " ${_pseudo_devices[*]}0 " == *" ${_if%%*([[:digit:]])} "* 
]] &&
+   continue
+
+   _ifs[${#_ifs[*]}]="${_if}"
+   done
+
+   [ -n "${_ifs}" ] || return 1
+}
+
+get_locations() {
+   local _l
+
+   ls -p "${HN_DIR}" |&
+   # use co-process to preserve values set in while loop
+   while IFS='  ' read -r -p _l ; do
+   [[ "${_l}" == *([[:blank:]])*/ ]] || continue
+   _locations[${#_locations[*]}]="${_l%%/}"
+   done
+}
+
+get_configurations() {
+   local _l _location
+
+   _location="$1"
+
+   ls -p "${HN_DIR}/${_location}" |&
+   # use co-process to preserve values set in while loop
+