diff options
author | James Rayner <james@archlinux.org> | 2007-11-10 00:43:57 +0100 |
---|---|---|
committer | James Rayner <james@archlinux.org> | 2007-11-10 00:43:57 +0100 |
commit | e9f9e4d54cb3afb6d78a12e85035a24d346c381d (patch) | |
tree | b3971b8737ab56b6055d2440f5b78c74fc2adb25 | |
download | netctl-e9f9e4d54cb3afb6d78a12e85035a24d346c381d.tar.gz netctl-e9f9e4d54cb3afb6d78a12e85035a24d346c381d.tar.xz |
Initial Import
-rw-r--r-- | LICENSE | 20 | ||||
-rw-r--r-- | Makefile | 48 | ||||
-rw-r--r-- | README | 0 | ||||
-rwxr-xr-x | contrib/netcfg-wireless-auto | 43 | ||||
-rw-r--r-- | examples/complete.example | 46 | ||||
-rw-r--r-- | examples/ethernet-static.example | 8 | ||||
-rw-r--r-- | examples/ethernet.example | 5 | ||||
-rw-r--r-- | examples/loopback.example | 5 | ||||
-rw-r--r-- | examples/ppp.example | 4 | ||||
-rw-r--r-- | examples/wep-static.example | 12 | ||||
-rw-r--r-- | examples/wep.example | 8 | ||||
-rw-r--r-- | examples/wpa.example | 8 | ||||
-rw-r--r-- | man/netcfg.8 | 57 | ||||
-rw-r--r-- | src/ethernet.subr | 111 | ||||
-rw-r--r-- | src/iftab | 20 | ||||
-rwxr-xr-x | src/net-profiles | 57 | ||||
-rwxr-xr-x | src/net-rename | 25 | ||||
-rw-r--r-- | src/netcfg | 78 | ||||
-rwxr-xr-x | src/netcfg-menu | 57 | ||||
-rw-r--r-- | src/network.subr | 252 | ||||
-rw-r--r-- | src/ppp.subr | 21 | ||||
-rw-r--r-- | src/wireless.subr | 204 |
22 files changed, 1089 insertions, 0 deletions
@@ -0,0 +1,20 @@ +Copyright (c) 2007, James Rayner + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Neither the name of the Arch Linux nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..327c639 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +DESTDIR= +VERSION=2.0.0 + + +install: + install -d $(DESTDIR)/usr/lib/network/ $(DESTDIR)/etc/network.d/examples \ + $(DESTDIR)/var/run/network/{interfaces,profiles} \ + $(DESTDIR)/usr/bin/ $(DESTDIR)/etc/rc.d/ \ + $(DESTDIR)/usr/man/{man5,man8} + # Documentation + install -m644 examples/*example $(DESTDIR)/etc/network.d/examples/ + install -m644 src/iftab $(DESTDIR)/etc/iftab + install -m644 man/*.8 $(DESTDIR)/usr/man/man8 + # Libs + install -m644 src/*subr $(DESTDIR)/usr/lib/network + # 'Binaries' + install -m755 src/netcfg $(DESTDIR)/usr/bin/netcfg2 + install -m755 src/netcfg-menu $(DESTDIR)/usr/bin/netcfg-menu + # Daemons + install -m755 src/net-profiles src/net-rename $(DESTDIR)/etc/rc.d + + +install-contrib: + install -m744 contrib/netcfg-wireless-auto $(DESTDIR)/usr/bin + +tarball: + sed -i "s/NETCFG_VER=.*/NETCFG_VER=$(VERSION)/g" src/netcfg + mkdir -p netcfg-$(VERSION) + cp -r src examples contrib man Makefile LICENSE README netcfg-$(VERSION) + tar -zcvf netcfg-$(VERSION).tar.gz netcfg-$(VERSION) + rm -rf netcfg-$(VERSION) + md5sum netcfg-$(VERSION)*gz > MD5SUMS.$(VERSION) + +pkg: tarball + sed -i "s/pkgver=.*/pkgver=$(VERSION)/g" PKGBUILD + makepkg + rm -rf pkg + rm -rf src/netcfg-$(VERSION)* + md5sum netcfg-$(VERSION)*gz > MD5SUMS.$(VERSION) + +upload: + scp netcfg-$(VERSION)*gz MD5SUMS.$(VERSION) archlinux.org:~/public_html/netcfg/ + +clean: + rm *gz + rm -rf netcfg-$(VERSION) + rm -rf pkg + rm MD5SUMS* diff --git a/contrib/netcfg-wireless-auto b/contrib/netcfg-wireless-auto new file mode 100755 index 0000000..036cd12 --- /dev/null +++ b/contrib/netcfg-wireless-auto @@ -0,0 +1,43 @@ +#! /bin/bash +# Originally contributed by Neuro: http://bbs.archlinux.org/viewtopic.php?pid=278148#p278148 + +. /usr/lib/network/network.subr +. /usr/lib/network/wireless.subr + +# wifi_auto +# autoconnect wireless interface +# $1 - wireless interface + +wifi_auto() +{ + INTERFACE=$1; RETRIES=6 + + while read essid; do + # awfully long grep that finds a file which has: + # CONNECTION=wireless, ESSID=$essid, INTERFACE=$INTERFACE + profile=$(grep -rlP "CONNECTION=\"?wireless\"?(\n|.)*INTERFACE=\"?$INTERFACE\"?(\n|.)*ESSID=\"?$essid\"?" $PROFILE_DIR/|head -n 1) + if [[ -n "$profile" ]]; then + break # If we found a profile, use it. + fi + done < "$(list_networks $IFACE)" + + # If there's a profile, connect, else fail. + if [[ -n "$profile" ]]; then + netcfg2 $(basename $profile) + exit $? + else + err "No network found" + exit 1 + fi +} + +if [[ $(id -u) -ne 0 ]]; then + err "This script needs to be run with root priviledges" + exit 1 +fi +if [[ -z $1 ]]; then + err "Please supply an interface to connect" + exit 1 +fi + +wifi_auto $1 diff --git a/examples/complete.example b/examples/complete.example new file mode 100644 index 0000000..61e76ef --- /dev/null +++ b/examples/complete.example @@ -0,0 +1,46 @@ +CONNECTION="wireless" +DESCRIPTION="Very verbose complete wireless example" + +INTERFACE=eth0 +HOSTNAME=myhost + +# Interface Settings (use IFOPTS="dhcp" for DHCP) +IFOPTS="192.168.0.2 netmask 255.255.255.0 broadcast 192.168.0.255" +GATEWAY=192.168.0.1 + +# DHCP Example +#IFOPTS=dhcp +#DHCP_TIMEOUT=20 # Default is 10. +#DHCP_OPTIONS="" # Extra arguments for dhcpcd + +# DNS Settings (optional) +DOMAIN=localdomain +DNS1=192.168.0.1 +DNS2= +SEARCH= + +# Standard Wireless Settings +ESSID=MyNetwork +SECURITY=wpa # One of wep, wpa, wpa-config, none +KEY="SomePasskey" + +# Scans to see if network is available before connecting (reccomended) +SCAN="YES" + +# Time to wait to connect to a network. Default 15. +TIMEOUT=10 + +# Pass *custom* options to iwconfig. Usually not needed (optional) +IWOPTS="mode managed essid $ESSID channel 6 key restricted $KEY" + +# Any extra arguments for wpa_supplicant +WPA_OPTS= + +# For SECURITY='wpa-config' only - filename of a wpa-supplicant config +WPA_CONF= + +# Commands to run at various stages of configuration +PRE_UP= +POST_UP= +PRE_DOWN= +POST_DOWN="some command" diff --git a/examples/ethernet-static.example b/examples/ethernet-static.example new file mode 100644 index 0000000..b50cf36 --- /dev/null +++ b/examples/ethernet-static.example @@ -0,0 +1,8 @@ +CONNECTION="ethernet" +DESCRIPTION="A less basic ethernet profile, using static configuration" +INTERFACE=eth0 +IP="static" +IFOPTS="192.168.1.23 netmask 255.255.255.0 broadcast 192.168.1.255" +GATEWAY="192.168.1.1" +DNS1=192.168.1.1 +DNS2=dns1.dreamhost.com diff --git a/examples/ethernet.example b/examples/ethernet.example new file mode 100644 index 0000000..2db6072 --- /dev/null +++ b/examples/ethernet.example @@ -0,0 +1,5 @@ +CONNECTION="ethernet" +DESCRIPTION="A very basic ethernet profile, using dhcp" +INTERFACE=eth0 +IP="dhcp" +DHCP_TIMEOUT=10 diff --git a/examples/loopback.example b/examples/loopback.example new file mode 100644 index 0000000..e9dcca9 --- /dev/null +++ b/examples/loopback.example @@ -0,0 +1,5 @@ +CONNECTION="ethernet" +DESCRIPTION="A very basic ethernet profile, using dhcp" +INTERFACE=lo +IP="static" +IFOPTS="127.0.0.1" diff --git a/examples/ppp.example b/examples/ppp.example new file mode 100644 index 0000000..f26bb03 --- /dev/null +++ b/examples/ppp.example @@ -0,0 +1,4 @@ +CONNECTION="ppp" +INTERFACE="ignore" +PEER="/etc/ppp/peers/provider" +PPP_TIMEOUT=10 diff --git a/examples/wep-static.example b/examples/wep-static.example new file mode 100644 index 0000000..4474ba7 --- /dev/null +++ b/examples/wep-static.example @@ -0,0 +1,12 @@ +CONNECTION="wireless" +DESCRIPTION="A wep encrypted wireless connection using static ip" +INTERFACE=wlan0 +SCAN="yes" +SECURITY="wep" +ESSID="MyNetwork" +KEY="1234567890" +IP="static" +IFOPTS="192.168.1.23 netmask 255.255.255.0 broadcast 192.168.1.255" +GATEWAY="192.168.1.1" +DNS1=192.168.1.1 +DNS2=dns1.dreamhost.com diff --git a/examples/wep.example b/examples/wep.example new file mode 100644 index 0000000..4dad0e1 --- /dev/null +++ b/examples/wep.example @@ -0,0 +1,8 @@ +CONNECTION="wireless" +DESCRIPTION="A simple WEP encrypted wireless connection" +INTERFACE=wlan0 +SCAN="yes" +SECURITY="wep" +ESSID="MyNetwork" +KEY="1234567890" +IP="dhcp" diff --git a/examples/wpa.example b/examples/wpa.example new file mode 100644 index 0000000..f165945 --- /dev/null +++ b/examples/wpa.example @@ -0,0 +1,8 @@ +CONNECTION="wireless" +INTERFACE=wlan0 +SCAN="yes" +SECURITY="wpa" +ESSID="mynetwork" +KEY="SomePasskey" +IP="dhcp" +TIMEOUT=20 diff --git a/man/netcfg.8 b/man/netcfg.8 new file mode 100644 index 0000000..f07e12a --- /dev/null +++ b/man/netcfg.8 @@ -0,0 +1,57 @@ +.TH NETCFG 8 "MAY 2007" "Arch Linux" "Network Scripts" +.\" groff -man -Tascii foo.1 +.SH NAME +netcfg \- start/stop/control network profiles +.SH SYNOPSIS +netcfg [\fIoptions\fR] \fBprofile\fR + +netcfg \fBprofile\fR +.SH DESCRIPTION +\fBnetcfg\fP is used to configure and manage network connections via profiles. It has pluggable support for a range of connection types, such as wireless, ethernet. ppp. It is also capable of starting/stopping many to one connections, that is, multiple connections within the same profile, optionally with bonding. + +It may be run at boot, by enabling the \fI/etc/rc.d/net-profiles\fP daemon in \fI/etc/rc.conf\fP \fBDAEMONS\fP line. After boot time, it may be used to start profiles, simply by passing only the profile name. + +.SH OPTIONS +.TP +.B \-c, check-iface \fIprofile\fP +Start the specified profile, only if it's interface is not currently up. +.TP +.B \-d, down \fIprofile\fP +Stop the specified profile +.TP +.B \-i, iface-down \fBinterface\fP +Stop the profile up on the specified interface. +.TP +.B \-a, all-down +Stop all connected profiles +.TP +.B all-suspend +Suspend and store the name of all active profiles. +.TP +.B all-resume +Reconnect any profiles that have been suspended. +.TP +.B \-v, --version +Display version information and exit +.TP +.B \-h, --help +Display help message and exit + +.SH FILES +.TP +.I /usr/lib/network/ +Currently installed network profile types. +.TP +.I /etc/network.d/examples +Example configurations for this script + +.SH BUGS +None, hopefully, but if you do find one of these elusive things, please submit at http://bugs.archlinux.org/ or email one of the authors below. +.SH AUTHOR +James Rayner <james@archlinux.org> + +Others listed in AUTHORS file in source. +.SH SEE ALSO +.BR ethernet (5), +.BR iwconfig (8), +.BR wireless (5) diff --git a/src/ethernet.subr b/src/ethernet.subr new file mode 100644 index 0000000..62f944f --- /dev/null +++ b/src/ethernet.subr @@ -0,0 +1,111 @@ +#! /bin/bash + +mii_check() { + local conn_state=$(mii-tool $1 2> /dev/null) + local ret=$? + if echo $conn_state|grep "no link" &> /dev/null; then + if [ $ret -eq 0 ]; then + return 1 + fi + fi + return 0 +} + +ethernet_up() { + + + if [ ! -e /sys/class/net/$INTERFACE ]; then + if ! echo "$INTERFACE"|grep ":"; then + err "Interface $INTERFACE does not exist" + fi + fi + + if ! mii_check $INTERFACE; then + err "No connection available" + return 1 + fi + + case $IP in + dhcp) + # Check if DHCP_TIMEOUT was set if not set a default value + [ -z $DHCP_TIMEOUT ] && DHCP_TIMEOUT=10 + + if checkyesno $DHCLIENT; then + rm -r /var/run/dhclient-${INTERFACE}.pid >/dev/null 2>&1 + if ! dhclient -q -e TIMEOUT=$DHCP_TIMEOUT -pf /var/run/dhclient-${INTERFACE}.pid; then + err "DHCP IP lease attempt failed" + return 1 + fi + else + # Clear remaining pid files. + rm -f /var/run/dhcpcd-${INTERFACE}.{pid,cache} >/dev/null 2>&1 + # If using own dns, tell dhcpcd to NOT replace resolv.conf + [ -n $DNS1 ] && DHCP_OPTIONS="-R $DHCP_OPTIONS" + # Start dhcpcd + if ! dhcpcd -L -t $DHCP_TIMEOUT $DHCP_OPTIONS $INTERFACE; then + err "DHCP IP lease attempt failed" + return 1 + fi + fi + # TODO: add support for $section:ifconfig for other stuff, like mtu or mac? + ;; + static) + if ! ifconfig $INTERFACE $IFOPTS up; then + err "Could not bring interface up" + return 1 + fi + + # bring up the default route (gateway) + if [ "$GATEWAY" ]; then + if ! route add default gw $GATEWAY; then + err "Adding gateway $GATEWAY failed" + return 1 + fi + fi + ;; + esac + + # set the hostname + if [ "$HOSTNAME" ]; then + if ! hostname $HOSTNAME; then + err "Cannot set hostname" + return 1 + fi + fi + + # Generate a new resolv.conf + if [ "$DNS1" ]; then + : >/etc/resolv.conf + [ "$DOMAIN" ] && echo "domain $DOMAIN" >>/etc/resolv.conf + [ "$SEARCH" ] && echo "search $SEARCH" >>/etc/resolv.conf + [ "$DNS1" ] && echo "nameserver $DNS1" >>/etc/resolv.conf + [ "$DNS2" ] && echo "nameserver $DNS2" >>/etc/resolv.conf + fi +} + +ethernet_down() { + case $IP in + dhcp) + if checkyesno $DHCLIENT; then + if [ -f /var/run/dhclient-${INTERFACE}.pid ]; then + kill `cat /var/run/dhclient-${INTERFACE}.pid` + fi + else + if [ -f /var/run/dhcpcd-${INTERFACE}.pid ]; then + dhcpcd -x $INTERFACE + fi + fi + ;; + static) + [ "$GATEWAY" ] && route del default gw $GATEWAY + ;; + esac + ifconfig $INTERFACE 0.0.0.0 +} + +ethernet_clean_scope() { + unset DOMAIN SEARCH DNS1 DNS2 + unset GATEWAY IFOPTS HOSTNAME DHCP_OPTIONS DHCP_TIMEOUT DHCLIENT + unset INTERFACE CONNECTION +} +# vim: set ts=4 et sw=4: diff --git a/src/iftab b/src/iftab new file mode 100644 index 0000000..e016644 --- /dev/null +++ b/src/iftab @@ -0,0 +1,20 @@ +# Example iftab + +# Format: {New name} {Criteria} + +# Match on driver +#ipw0 driver ipw2100 +#eth9 driver ndiswrapper +#rl0 driver 8139too + +# Match on MAC address +#wlan0 mac 00:11:22:33:44:%5 +#eth1 mac 11:22:33:44:55:66 + +# Match on sysfs attribute +#myvpn SYSFS{address} 00:10:83:* + +# Automatically number +#eth* ipw2100 + +## More examples in 'man iftab' diff --git a/src/net-profiles b/src/net-profiles new file mode 100755 index 0000000..0047fa7 --- /dev/null +++ b/src/net-profiles @@ -0,0 +1,57 @@ +#!/bin/bash + +. /etc/rc.conf +. /etc/rc.d/functions + +case "$1" in + start) + if ! ck_daemon net-profiles; then + echo "Network Profiles are already running. Try '/etc/rc.d/net-profiles restart'" + exit + fi + + # Ensure any device renaming has occurred as intended + for daemon in "${DAEMONS[@]}"; do + if [ "$daemon" = "${daemon#!}" -a "$daemon" = "net-rename" ]; then + if ck_daemon net-rename; then + /etc/rc.d/net-rename start + fi + fi + done + + # $NET env var is passed from the kernel boot line + if [ "$NET" = "menu" -o "$NETWORKS" = "menu" ]; then + /usr/bin/netcfg-menu 5 + elif [ "$NET" ]; then + /usr/bin/netcfg2 $NET + elif [ "$NETWORKS" ]; then + for prof in ${NETWORKS[@]}; do + if [ "$prof" = "${prof#!}" ]; then + /usr/bin/netcfg2 -c $prof + fi + done + fi + + add_daemon net-profiles + + ;; + stop) + # shutdown any profiles started by netcfg (or from NET_PROFILES in rc.conf) + status "Stopping Network Profiles" /usr/bin/netcfg2 -a + rm_daemon net-profiles + ;; + restart) + $0 stop + /bin/sleep 1 + $0 start + ;; + hotplug_ifup|ifup|ifdown|iflist|rtup|rtdown|rtlist) + $1 $2 + ;; + *) + echo "usage: $0 {start|stop|restart}" + echo " $0 {ifup|ifdown|iflist|rtup|rtdown|rtlist}" +esac + +# vim: set ts=2 noet: +# vim: set ts=4 et sw=4: diff --git a/src/net-rename b/src/net-rename new file mode 100755 index 0000000..db2c461 --- /dev/null +++ b/src/net-rename @@ -0,0 +1,25 @@ +#!/bin/bash + +. /etc/rc.conf +. /etc/rc.d/functions + +case "$1" in + start) + stat_busy "Renaming network devices" + ifrename -p -t + stat_done + + add_daemon net-rename + ;; + stop) + rm_daemon net-rename + # No stop neccesary, but add one to look nice on shutdown. + /bin/true + ;; + restart) + $0 start + ;; + *) + echo "usage: $0 {start|stop|restart}" +esac +# vim: set ts=4 et sw=4: diff --git a/src/netcfg b/src/netcfg new file mode 100644 index 0000000..9265cee --- /dev/null +++ b/src/netcfg @@ -0,0 +1,78 @@ +#!/bin/bash + +. /etc/rc.conf +. /etc/rc.d/functions +. /usr/lib/network/network.subr + +err() { + stat_append " - $*" +} + +NETCFG_VER=2.0.0 +PROFILE_DIR="/etc/network.d/" +SUBR_DIR="/usr/lib/network/" +STATE_DIR="/var/run/network/" + +version() +{ + echo "netcfg v$NETCFG_VER" +} + +usage() +{ + version + echo "Usage:" + echo " Start specified profile: netcfg profile " + echo " Other functions: netcfg argument profile" + echo "Arguments:" + echo "-c, check-iface Do not start profile if interface is already up" + echo "-d, down Take specified profile down" + echo "-a, all-down Take all active profiles down" + echo "-i, iface-down Take down profile active on specified interface" + echo " all-resume Resume previously suspended profiles and reconnect them" + echo " all-suspend Store a list of current running profiles and suspend them" + echo "-h, --help This message" + echo "-v, --version Output version information and exit" +} + +if [ "`id -u`" != "0" ]; then + err "This script should be run as root." + exit 1 +fi + +case $1 in + --version|-v) + version;; + --help|-h) + usage;; + -c|check-iface) + CHECK="YES"; + profile_up $2;; + clean) + rm /var/run/network/interfaces/* + rm /var/run/network/profiles/* + killall wpa_supplicant + killall dhcpcd + ;; + -d|down) + profile_down $2;; + -i|iface-down) + interface_down $2;; + -a|all-down) + all_down;; + all-resume) + all_resume;; + all-suspend) + all_suspend;; + -*|--*) + usage;; + *) + if [ -n "$1" ]; then + profile_up $1 + else + usage + fi + ;; +esac +exit $? +# vim: set ts=2 noet: diff --git a/src/netcfg-menu b/src/netcfg-menu new file mode 100755 index 0000000..0970a01 --- /dev/null +++ b/src/netcfg-menu @@ -0,0 +1,57 @@ +#! /bin/bash + +. /etc/rc.conf +. /etc/rc.d/functions +. /usr/lib/network/network.subr + +# Scan all profiles +i=0 +for prof in `find -L $PROFILE_DIR -maxdepth 1 -type f -printf "%f\n"`; do + # if there is a profile called "main", Use as default + [ "$prof" = "main" ] && DEFAULT=$prof + unset DESCRIPTION + . $PROFILE_DIR/$prof + profiles[$i]=$prof + i=$((i+1)) + profiles[$i]=$DESCRIPTION + i=$((i+1)) +done + +if [ ${#profiles} -eq 0 ]; then + echo "No profiles were found in $PROFILE_DIR" + return 1 +fi + +# if no default yet, use the first entry +[ "$DEFAULT" = "" ] && DEFAULT=${profiles[0]} +ANSWER=$(mktemp) || exit 1 + +# Set timeout +if [ "$1" = "" ]; then + TIMEOUT="0" +else + TIMEOUT="$1" +fi + +# Display Dialog +dialog --timeout $TIMEOUT --default-item $DEFAULT \ + --menu "Select the network profile you wish to use" \ + 13 50 6 "${profiles[@]}" 2>$ANSWER + +ret=$? + +case $ret in + 1) ;; # Cancel - do nothing + 255) # timeout - use default + netcfg2 $DEFAULT + ;; + 0) # User selection + netcfg2 $(cat $ANSWER) + ;; + *) # Shouldnt happen + echo "Abnormal ret code from dialog: $ret" + ;; +esac +rm $ANSWER + +# vim: set ts=4 et sw=4: diff --git a/src/network.subr b/src/network.subr new file mode 100644 index 0000000..69477bc --- /dev/null +++ b/src/network.subr @@ -0,0 +1,252 @@ +### Globals +PROFILE_DIR="/etc/network.d" + +### Messages +## +# err msg +# output specified message +err() { +echo $* +} + + +### Profile loading +## +# load_profile profile +# source the profile +load_profile() { + validate_profile $1 || return 1 + . $PROFILE_DIR/$1 +} +# validate_profile profile +# check whether profile exists and is usable +validate_profile() +{ + [ -z "$1" ] && return 1 + if [ ! -f $PROFILE_DIR/$1 ]; then + err "Profile \"$1\" does not exist" + return 1 + fi + . $PROFILE_DIR/$1 + if [ -z "$INTERFACE" ]; then + err "Profile missing an interface to configure" + return 1 + fi + if [ ! -f $SUBR_DIR/$CONNECTION.subr ]; then + err "$CONNECTION is not a valid connection, check spelling or look at examples" + return 1 + fi +} + +### Profile up/down +## +# all_down +# take all profiles down +# +all_down() +{ + ls -1 $STATE_DIR/profiles/ | while read prof; do + profile_down $prof + done +} + +# all_suspend +# store a list of running profiles and take them down +# +all_suspend() +{ + [ ! -d $STATE_DIR/suspend ] && mkdir $STATE_DIR/suspend + + ls -1 $STATE_DIR/profiles/ | while read prof; do + cp $STATE_DIR/profiles/$prof $STATE_DIR/suspend/ + profile_down $prof + done +} + +# all_suspend +# store a list of running profiles and take them down +# +all_resume() +{ + ls -1 $STATE_DIR/suspend/ | while read prof; do + profile_up $prof + rm $STATE_DIR/suspend/$prof + done +} + +# profile_up profile +# put all profiles up +# +profile_up() +{ + + load_profile $1 || return 1 + + check_profile $1 && err "$1 already connected" && return 1 + + stat_busy "$1 up" + + if check_iface $INTERFACE; then + if checkyesno $CHECK; then + err "Interface $INTERFACE already in use" + stat_fail && return 1 + else + interface_down $INTERFACE || return 1 + load_profile $1 + fi + fi + + + eval $PRE_UP || return 1 + + . $SUBR_DIR/${CONNECTION}.subr + if ! ${CONNECTION}_up $1; then + stat_fail + return 1 + fi + + eval $POST_UP || return 1 + + set_profile up $1 + ${CONNECTION}_clean_scope + add_daemon net-profiles + stat_done +} + +# profile_down profile +# take profile down +# +profile_down() +{ + load_profile $1 || return 1 + + if ! check_profile $1; then + err "Profile not connected" + return 1 + fi + + stat_busy "$1 down" + if [ "$(get_iface_prof $INTERFACE)" == "external" ]; then + err "$interface was connected by another application" + stat_fail + return 1 + fi + + eval $PRE_DOWN || return 1 + + . $SUBR_DIR/${CONNECTION}.subr + if ! ${CONNECTION}_down $1; then + stat_fail + return 1 + fi + + eval $POST_DOWN || return 1 + + set_profile down $1 + ${CONNECTION}_clean_scope + stat_done +} + +# interface_down interface +# take interface down +# +interface_down() +{ + local prof=$(get_iface_prof $1) + profile_down $prof + return $? +} + + +### Query functions +## +# check_iface interface +# Return 0 if interface up +# Return 1 if interface down +# +check_iface() { + [ -f $STATE_DIR/interfaces/$1 ] && return 0 + return 1 +} + +# get_iface_prof interface +# Echo interface profile and return 0 if up +# Return 1 if down. +# +get_iface_prof() { + if check_iface $1; then + . $STATE_DIR/interfaces/$1 + echo $PROFILE + else + return 1 + fi +} + +# check_profile profile +# Return 0 if profile up +# Return 1 if profile down +# +check_profile() { + [ -f $STATE_DIR/profiles/$1 ] && return 0 + return 1 +} + +### Status setting functions +## +# set_profile up/down profile +# Set profile state, either up or down +# +set_profile() { + if [ "$1" == "up" ]; then + . $PROFILE_DIR/$2 + cp $PROFILE_DIR/$2 $STATE_DIR/profiles/ + set_iface up $INTERFACE $2 + elif [ "$1" == "down" ]; then + . $STATE_DIR/profiles/$2 + rm $STATE_DIR/profiles/$2 + set_iface down $INTERFACE $2 + fi +} + +# set_iface up/down interface [profile] +# Set interface status to up/down +# optionally link it to a profile. +# +set_iface() { + PROFILE=$3 + [ -z "$PROFILE" ] && PROFILE=external + if [ "$1" == "up" ]; then + echo "PROFILE=$PROFILE" > $STATE_DIR/interfaces/$2 + elif [ "$1" == "down" ]; then + rm $STATE_DIR/interfaces/$2 + fi +} + + +### From FreeBSD's /etc/rc.subr +## +# checkyesno var +# Test $1 variable, and warn if not set to YES or NO. +# Return 0 if it's "yes" (et al), nonzero otherwise. +# +checkyesno() +{ + _value=${1} + #debug "checkyesno: $1 is set to $_value." + case $_value in + + # "yes", "true", "on", or "1" + [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) + return 0 + ;; + + # "no", "false", "off", or "0" + [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) + return 1 + ;; + *) + #warn "\$${1} is not set properly - see ${rcvar_manpage}." + return 1 + ;; + esac +} diff --git a/src/ppp.subr b/src/ppp.subr new file mode 100644 index 0000000..c05ebd7 --- /dev/null +++ b/src/ppp.subr @@ -0,0 +1,21 @@ +#! /bin/bash +ppp_up() { + [ -z "$PEER" ] && PEER="/etc/ppp/peers/provider" + [ -z "$PPP_TIMEOUT" ] && PPP_TIMEOUT=30 + + /usr/sbin/pppd call $PEER updetach child-timeout $PPP_TIMEOUT linkname $(basename $PEER) + + if [ $? -ne 0 ]; then + err "pppd connection failed" + exit 1 + fi +} + +ppp_down() { + kill $(cat /var/run/ppp-$(basename $PEER)) +} + +ppp_clean_scope() { + unset PPP_PEER PPP_TIMEOUT +} +# vim: set ts=4 et sw=4: diff --git a/src/wireless.subr b/src/wireless.subr new file mode 100644 index 0000000..5b9bd57 --- /dev/null +++ b/src/wireless.subr @@ -0,0 +1,204 @@ +#! /bin/bash + +# Uses wpa_supplicant to check for association to a network +# wpa_check interface [timeout] +wpa_check() +{ + INTERFACE=$1; TIMEOUT=$2 + + [ -z $TIMEOUT ] && TIMEOUT=15 + let timeout=0 + while [ $timeout -ne $TIMEOUT ]; do + eval `wpa_cli status|grep wpa_state` + [ "$wpa_state" = "COMPLETED" ] && return 0 + sleep 1 + let timeout++ + done + + wpa_cli terminate >/dev/null 2>&1 + err "Wireless association failed." + return 1 +} + +# Uses wireless_tools, to check for association to a network. +# wep_check interface [timeout] +wep_check() +{ + INTERFACE=$1; TIMEOUT=$2 + + [ -z $TIMEOUT ] && TIMEOUT=15 + let timeout=0 + while [ $timeout -ne $TIMEOUT ]; do + bssid=`iwgetid $INTERFACE -ra` + [ ! "$bssid" = "00:00:00:00:00:00" ] && return 0 + sleep 1 + let timeout++ + done + + err "Wireless association failed." + return 1 +} + +# Check if a particular network is within range +# find_essid interface essid +find_essid() +{ + INTERFACE=$1; ESSID=$2; RETRIES=4 + try=0; + while [ $try -ne $RETRIES ]; do + if iwlist $INTERFACE scan|sed "s/ESSID://g"|grep -q "\"$ESSID\""; then + return 0 # network found + fi + sleep 0.5 + let try++ + done + return 1 +} + +# Return a filename containing a list of network ESSID's found. +# list_networks interface +list_networks() +{ + # temp file used, as keeping ESSID's with spaces in their name in arrays + # is hard, obscure and kinda nasty. This is simpler and clearer. + + [[ -z "$1" ]] && return 1 + essids=$(mktemp /tmp/essid.XXXXX) + + let try 0; + while [[ $try -ne $RETRIES ]]; do + iwlist $1 scan 2> /dev/null|grep ESSID|sed 's/.*ESSID:"\([^"]\+\)".*/\1/' > $essids + sleep 0.5; let try++ + done + sort -u $essids -o $essids + + # File of 0 length, ie. no ssid's. + if [[ ! -s $essids ]]; then + return 1 + fi + + echo $essids + return 0 +} + +start_wpa() +{ + INTERFACE=$1; WPA_CONF=$2; WPA_OPTS=$3 + + [ "$WPA_OPTS" == "" ] && WPA_OPTS="-Dwext" + + wpa_supplicant -wB -P/var/run/wpa_supplicant_${INTERFACE}.pid -i${INTERFACE} -c $WPA_CONF $WPA_OPTS + sleep 1 + + if [ ! -f /var/run/wpa_supplicant_${INTERFACE}.pid ]; then + err "wpa_supplicant did not start, possible configuration error" + return 1 + fi +} + +wireless_up() { + + load_profile $1 + + if [ ! -d /sys/class/net/$INTERFACE/wireless ]; then + err "Interface $INTERFACE is not a wireless interface" + return 1 + fi + + # Was required by broadcom + # iwlist $INTERFACE scan &> /dev/null + + # Required by atheros to enable device + ifconfig $INTERFACE up + + # Required by ipw3945 to properly re-associate + eval "iwconfig $INTERFACE mode managed essid \"$ESSID\"" + + # Kill any lingering wpa_supplicants. + if [ -f /var/run/wpa_supplicant_$INTERFACE.pid ]; then + kill $(cat /var/run/wpa_supplicant_$INTERFACE.pid) + fi + + if checkyesno $SCAN; then + if ! find_essid $INTERFACE "$ESSID"; then + err "Network unavailable" + return 1 + fi + fi + + case $SECURITY in + wep|none) + # 'none' security uses iwconfig, like wep, so use same code, minus keysetting. + # Use sane default if no alternative is specified + if [ "$SECURITY" = "wep" -a "$WEP_OPTS" = "" ]; then + WEP_OPTS="mode managed essid \"$ESSID\" key open $KEY" + elif [ "$SECURITY" = "none" -a "$WEP_OPTS" = "" ]; then + WEP_OPTS="mode managed essid \"$ESSID\"" + fi + + if ! eval iwconfig $INTERFACE $WEP_OPTS; then + err "Could not set wireless configuration" + return 1 + fi + + wep_check $INTERFACE $TIMEOUT|| return 1 + ;; + wpa) + local WPA_CONF=`mktemp /tmp/wpa.XXXXXXXX` + + # Temporary bugfix for broken drivers... http://bbs.archlinux.org/viewtopic.php?id=36384 + if ! eval iwconfig $INTERFACE mode managed essid "\"$ESSID\""; then + err "Could not set wireless configuration" + return 1 + fi + + # Create a random file to store configuration, make it root only. + chmod 600 $WPA_CONF + echo "ctrl_interface=/var/run/wpa_supplicant" >> $WPA_CONF + echo "ctrl_interface_group=0" >> $WPA_CONF + + # Generate configuration + if ! wpa_passphrase "$ESSID" "$KEY" >> $WPA_CONF; then + err "Configuration generation failed: `cat $WPA_CONF`" + return 1 + fi + + # Connect! + start_wpa $INTERFACE $WPA_CONF $WPA_OPTS || return 1 + wpa_check $INTERFACE $TIMEOUT || return 1 + ;; + wpa-config) + # If user hasnt defined one, use stock config. + [ -z "$WPA_CONF" ] && WPA_CONF="/etc/wpa_supplicant.conf" + start_wpa $INTERFACE $WPA_CONF $WPA_OPTS || return 1 + wpa_check $INTERFACE $TIMEOUT || return 1 + ;; + esac + + . $SUBR_DIR/ethernet.subr + if ! ethernet_up $1; then + wireless_down $1 YES + return 1 + fi +} + +wireless_down() { + PROFILE=$1 NOETHERNETDOWN=$2 + if ! checkyesno $2; then + . $SUBR_DIR/ethernet.subr + ethernet_down $1 + fi + wpa_cli terminate &> /dev/null + iwconfig $INTERFACE essid off key off &> /dev/null + ifconfig $INTERFACE down +} + +wireless_clean_scope() { + unset INTERFACE CONNECTION + unset TIMEOUT WPA_CONF WPA_OPTS KEY ESSID SECURITY WEP_OPTS + . $SUBR_DIR/ethernet.subr + ethernet_clean_scope +} + + +# vim: set ts=4 et sw=4: |