blob: b3003cd0ded878385a817fa13930de058d0f48f1 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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
|