aboutsummaryrefslogtreecommitdiff
path: root/core/busybox/files/udhcpc.script
diff options
context:
space:
mode:
Diffstat (limited to 'core/busybox/files/udhcpc.script')
-rw-r--r--core/busybox/files/udhcpc.script140
1 files changed, 140 insertions, 0 deletions
diff --git a/core/busybox/files/udhcpc.script b/core/busybox/files/udhcpc.script
new file mode 100644
index 00000000..b3003cd0
--- /dev/null
+++ b/core/busybox/files/udhcpc.script
@@ -0,0 +1,140 @@
+#!/bin/sh
+# shellcheck source=/dev/null
+# shellcheck disable=1090
+
+# script for udhcpc
+# Copyright (c) 2008 Natanael Copa <natanael.copa@gmail.com>
+# Copyright (c) 2020 Cem Keylan <cem@ckyln.com>
+
+# 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