--- /dev/null
+#!/bin/sh
+# A simple wrapper around udhcpc so that we are able to dynamically specify
+# which options it should ask for.
+
+# note: ifupdown does not allow VERBOSITY through. can be set in OPTS_FILE.
+VERBOSITY="${VERBOSITY:-0}"
+
+. ${CIRROS_SHLIB:=/lib/cirros/shlib} ||
+ { echo "failed to read ${CIRROS_SHLIB}" 1>&2; exit 1; }
+
+set -f
+
+# ensure PATH has /sbin in it.
+path_has /sbin || PATH="$PATH:/sbin"
+
+OPTS_FILE="/etc/default/udhcpc"
+RESOLV_CONF="/etc/resolv.conf"
+
+apply_static_routes() {
+ # routes are pairs of network and gateway
+ # 169.254.169.254/32 10.65.0.128
+ local net="" router="" err=0
+ while [ $# -ne 0 ]; do
+ net="$1"
+ router="$2"
+ [ -n "$net" ] || continue
+ debug 1 "adding net $net with router $router"
+ route add -net "$net" gw "$router" || {
+ error "WARN: failed: route add -net \"$net\" gw \"$router\""
+ err=$(($err+1));
+ }
+ shift 2 || {
+ error "apply_static_routes: failed shift 2. odd number of args?"
+ return 1;
+ }
+ done
+ return $err
+}
+
+
+readconfig() {
+ [ ! -f "$OPTS_FILE" ] || . "$OPTS_FILE" ||
+ { error "failed to read $OPTS_FILE"; return 1; }
+ # these are expected to be set.
+ OPTIONS=${OPTIONS:-staticroutes mtu}
+ TIMEOUT=${TIMEOUT:-60}
+ MTU=${MTU:-1500}
+}
+
+up() {
+ [ $# -ge 1 ] || { error "$0 up: must provide interface"; return 1; }
+ local iface="$1" opts="" hostname=""
+
+ readconfig || return
+ hostname=$(hostname 2>/dev/null)
+
+ # Gather all options and start udhcpc.
+ for opt in $OPTIONS; do
+ opts="-O $opt $opts"
+ done
+
+ debug 1 "Starting udhcpc on $iface, asking for options {$OPTIONS}"
+ udhcpc -p "/var/run/udhcpc.${iface}.pid" -R -n \
+ ${TIMEOUT:+-T "${TIMEOUT}"} -i "$iface" -s "$0" \
+ $opts ${hostname:+-x "hostname:${hostname}"}
+}
+
+down() {
+ local iface="$1" pidfile="" pid=""
+ [ $# -ge 1 ] || { error "$0 down: must provide interface"; return 1; }
+ pidfile="/var/run/udhcpc.$iface.pid"
+ [ -f "$pidfile" ] ||
+ { error "$iface: no pidfile"; return 1; }
+ read pid < "$pidfile" ||
+ { error "failed to read pid from '$pidfile' for '$iface'"; return 1; }
+ kill $pid >/dev/null
+ return
+}
+
+renew_bound() {
+ local flags="" mode="$1" i=""
+ shift;
+ [ -n "$interface" ] ||
+ { error "$0 $mode: 'interface' not provided"; return 1; }
+
+ [ -n "$ip" ] ||
+ { error "$0 $mode: 'ip' not set in environment"; return 1; }
+
+ readconfig || return
+
+ [ -n "$broadcast" ] && flags="${flags}broadcast $broadcast "
+ [ -n "$subnet" ] && flags="${flags}netmask $subnet "
+ flags="${flags}mtu ${mtu:-${MTU}} "
+ flags=${flags% }
+
+ debug 1 "ifconfig $interface $ip $flags"
+ ifconfig $interface $ip $flags || {
+ error "$0 $mode: failed: 'ifconfig $interface $ip $flags'";
+ return 1;
+ }
+
+ if [ -n "$router" ] ; then
+ local out="" ret=""
+ debug 2 "deleting routers"
+ while :; do
+ out=$(route del default gw 0.0.0.0 dev $interface 2>&1)
+ ret=$?
+ [ $ret -eq 0 ] && break
+ case "$out" in
+ *SIOCDELRT*[Nn]o\ such\ process*) break;;
+ esac
+ error "deleting routes failed: $out" 1>&2
+ done
+
+ for i in $router; do
+ debug 1 "route add default gw $i dev $interface"
+ route add default gw $i dev $interface
+ done
+ fi
+
+ local msg="configuring $RESOLV_CONF for $interface. domain=$domain"
+ msg="$msg nameservers: $dns"
+ debug 1 "$msg"
+ {
+ [ -n "$domain" ] && echo "search $domain"
+ for i in $dns ; do
+ echo nameserver $i
+ done
+ } > "$RESOLV_CONF"
+
+ apply_static_routes $staticroutes
+}
+
+case "$1" in
+ up)
+ shift
+ up "$@"
+ ;;
+ down)
+ shift;
+ down "$@"
+ ;;
+ deconfig)
+ ifconfig $interface 0.0.0.0
+ ;;
+ renew|bound)
+ renew_bound "$@";
+ ;;
+ *)
+ error "Usage: $0 <up|down>"
+ exit 1
+ ;;
+esac
+
+exit
+# vi: ts=4 noexpandtab syntax=sh