#!/bin/sh # shellcheck source=/dev/null # shellcheck disable=1090 # script for udhcpc # Copyright (c) 2008 Natanael Copa # Copyright (c) 2020 Cem Keylan # I have made some minor changes, POSIX shell fixes, and linting. # Rest of the script is pretty much the same. # - Cem [ -f "${UDHCPC:=/etc/udhcpc.d}/udhcpc.conf" ] && . "$UDHCPC/udhcpc.conf" RESOLV_CONF="/etc/resolv.conf" # Export variables so that hooks can also make use of them. export broadcast export dns export domain export interface export ip export mask export metric export router export search export subnet run_scripts() { for file in "$1/"*; do [ -f "$file" ] && "$file" done } deconfig() { ip -4 addr flush dev "$interface" ;} is_wifi() { [ -e "/sys/class/net/$interface/phy80211" ] ;} if_index() { if [ -e "/sys/class/net/$interface/ifindex" ]; then read -r ifindex < "/sys/class/net/$interface/ifindex" else ifindex="$(ip -4 link show dev "$interface")" fi printf '%s\n' "${ifindex%%:*}" } calc_metric() { is_wifi && { printf '%s\n' "$(( 300 + $(if_index) ))"; return ;} printf '%s\n' "$(( 200 + $(if_index) ))" } routes() { [ "$router" ] || return for i in $NO_GATEWAY; do [ "$i" = "$interface" ] && return done while ip -4 route del default via dev "$interface" 2>/dev/null; do : done num=-1 for gw in $router; do if [ "$subnet" = "255.255.255.255" ]; then # special case for /32 subnets: # /32 instructs kernel to always use routing for all outgoing packets # (they can never be sent to local subnet - there is no local subnet for /32). # Used in datacenters, avoids the need for private ip-addresses between two hops. ip -4 route add "$gw" dev "$interface" fi ip -4 route add 0.0.0.0/0 via "$gw" dev "$interface" \ metric $(( (num += 1) + ${IF_METRIC:-$(calc_metric)} )) done } resolvconf() { case "$IF_PEER_DNS" in yes|'') ;; *) return; esac case "$RESOLV_CONF" in [Nn][Oo]|'') return; esac case " $NO_DNS " in *" $interface "*) return; esac :> "$RESOLV_CONF.$$" if [ "$search" ]; then printf 'search %s\n' "$search" >> "$RESOLV_CONF.$$" elif [ "$domain" ]; then printf 'search %s\n' "$domain" >> "$RESOLV_CONF.$$" fi # Word-splitting is intentional # shellcheck disable=2086 printf 'nameserver %s\n' $dns >> "$RESOLV_CONF.$$" chmod a+r "$RESOLV_CONF.$$" mv "$RESOLV_CONF.$$" "$RESOLV_CONF" } bound() { ip -4 addr add "$ip/$mask" ${broadcast:+broadcast $broadcast} dev "$interface" ip -4 link set dev "$interface" up routes resolvconf } renew() { ip -4 addr show dev "$interface" | grep -q "$ip/$mask" || { ip -4 addr flush dev "$interface" ip -4 addr add "$ip/$mask" ${broadcast:+broadcast $broadcast} dev "$interface" } for i in $router; do ip -4 route show | grep ^default | grep -q "$i" || { routes break } done if ! grep -q "^search $domain" "$RESOLV_CONF" ; then resolvconf return fi for i in $dns; do if ! grep -q "^nameserver $i" "$RESOLV_CONF" ; then resolvconf return fi done } case "$1" in deconfig|renew|bound) run_scripts "$UDHCPC/pre-$1" $1 run_scripts "$UDHCPC/post-$1" ;; leasefail) echo "udhcpc failed to get a DHCP lease" >&2 ;; nak) echo "udhcpc received DHCP NAK" >&2 ;; *) echo "Error: this script should be called from udhcpc" >&2 exit 1 ;; esac exit 0