mirror of
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git
synced 2024-11-24 10:23:40 +08:00
447 lines
9.8 KiB
Bash
447 lines
9.8 KiB
Bash
#!/bin/bash
|
|
#
|
|
# dhclient-script for Linux.
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version
|
|
# 2 of the License, or (at your option) any later version.
|
|
#
|
|
# Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
|
|
#
|
|
# Probably, I did not understand, what this funny feature as "alias"
|
|
# means exactly. For now I suppose, that it is a static address, which
|
|
# we should install and preserve.
|
|
#
|
|
|
|
exec >> /tmp/DHS.log 2>&1
|
|
|
|
echo dhc-script $* reason=$reason
|
|
set | grep "^\(old_\|new_\|check_\)"
|
|
|
|
LOG () {
|
|
echo LOG $* ;
|
|
}
|
|
|
|
# convert 8bit mask to length
|
|
# arg: $1 = mask
|
|
#
|
|
Mask8ToLen() {
|
|
local l=0;
|
|
|
|
while [ $l -le 7 ]; do
|
|
if [ $[ ( 1 << $l ) + $1 ] -eq 256 ]; then
|
|
return $[ 8 - $l ]
|
|
fi
|
|
l=$[ $l + 1 ]
|
|
done
|
|
return 0;
|
|
}
|
|
|
|
# convert inet dotted quad mask to length
|
|
# arg: $1 = dotquad mask
|
|
#
|
|
MaskToLen() {
|
|
local masklen=0
|
|
local mask8=$1
|
|
|
|
case $1 in
|
|
0.0.0.0)
|
|
return 0;
|
|
;;
|
|
255.*.0.0)
|
|
masklen=8
|
|
mask8=${mask8#255.}
|
|
mask8=${mask8%.0.0}
|
|
;;
|
|
255.255.*.0)
|
|
masklen=16
|
|
mask8=${mask8#255.255.}
|
|
mask8=${mask8%.0}
|
|
;;
|
|
255.255.255.*)
|
|
masklen=24
|
|
mask8=${mask8#255.255.255.}
|
|
;;
|
|
*)
|
|
return 255
|
|
;;
|
|
esac
|
|
Mask8ToLen $mask8
|
|
return $[ $? + $masklen ]
|
|
}
|
|
|
|
# calculate ABC "natural" mask
|
|
# arg: $1 = dotquad address
|
|
#
|
|
ABCMask () {
|
|
local class;
|
|
|
|
class=${1%%.*}
|
|
|
|
if [ "$1" = "255.255.255.255" ]; then
|
|
echo $1
|
|
elif [ "$1" = "0.0.0.0" ]; then
|
|
echo $1
|
|
elif [ $class -ge 224 ]; then
|
|
echo 240.0.0.0
|
|
elif [ $class -ge 192 ]; then
|
|
echo 255.255.255.0
|
|
elif [ $class -ge 128 ]; then
|
|
echo 255.255.0.0
|
|
else
|
|
echo 255.0.0.0
|
|
fi
|
|
}
|
|
|
|
# calculate ABC "natural" mask length
|
|
# arg: $1 = dotquad address
|
|
#
|
|
ABCMaskLen () {
|
|
local class;
|
|
|
|
class=${1%%.*}
|
|
|
|
if [ "$1" = "255.255.255.255" ]; then
|
|
return 32
|
|
elif [ "$1" = "0.0.0.0" ]; then
|
|
return 0
|
|
elif [ $class -ge 224 ]; then
|
|
return 4;
|
|
elif [ $class -ge 192 ]; then
|
|
return 24;
|
|
elif [ $class -ge 128 ]; then
|
|
return 16;
|
|
else
|
|
return 8;
|
|
fi
|
|
}
|
|
|
|
# Delete IP address
|
|
# args: $1 = interface
|
|
# $2 = address
|
|
# $3 = mask
|
|
# $4 = broadcast
|
|
# $5 = label
|
|
#
|
|
DelINETAddr () {
|
|
local masklen=32
|
|
local addrid=$1
|
|
|
|
LOG DelINETAddr $*
|
|
|
|
if [ "$5" ]; then
|
|
addrid=$addrid:$5
|
|
fi
|
|
LOG ifconfig $addrid down
|
|
ifconfig $addrid down
|
|
}
|
|
|
|
# Add IP address
|
|
# args: $1 = interface
|
|
# $2 = address
|
|
# $3 = mask
|
|
# $4 = broadcast
|
|
# $5 = label
|
|
#
|
|
AddINETAddr () {
|
|
local mask_arg
|
|
local brd_arg
|
|
local addrid=$1
|
|
|
|
LOG AddINETAddr $*
|
|
|
|
if [ "$5" ]; then
|
|
addrid=$addrid:$5
|
|
fi
|
|
if [ "$3" ]; then
|
|
mask_arg="netmask $3"
|
|
fi
|
|
if [ "$4" ]; then
|
|
brd_arg="broadcast $4"
|
|
fi
|
|
|
|
LOG ifconfig $addrid $2 $mask_arg $brd_arg up
|
|
ifconfig $addrid $2 $mask_arg $brd_arg up
|
|
}
|
|
|
|
# Add default routes
|
|
# args: $1 = routers list
|
|
#
|
|
AddDefaultRoutes() {
|
|
local router
|
|
|
|
if [ "$1" ]; then
|
|
LOG AddDefaultRoutes $*
|
|
for router in $1; do
|
|
LOG route add default gw $router
|
|
route add default gw $router
|
|
done ;
|
|
fi
|
|
}
|
|
|
|
# Delete default routes
|
|
# args: $1 = routers list
|
|
#
|
|
DelDefaultRoutes() {
|
|
local router
|
|
|
|
if [ "$1" ]; then
|
|
LOG DelDefaultRoutes $*
|
|
|
|
for router in $1; do
|
|
LOG route del default gw $router
|
|
route del default gw $router
|
|
done
|
|
fi
|
|
}
|
|
|
|
# ping a host
|
|
# args: $1 = dotquad address of the host
|
|
#
|
|
PingNode() {
|
|
LOG PingNode $*
|
|
if ping -q -c 1 -w 2 $1 ; then
|
|
return 0;
|
|
fi
|
|
return 1;
|
|
}
|
|
|
|
# Check (and add route, if alive) default routers
|
|
# args: $1 = routers list
|
|
# returns: 0 if at least one router is alive.
|
|
#
|
|
CheckRouterList() {
|
|
local router
|
|
local succeed=1
|
|
|
|
LOG CheckRouterList $*
|
|
|
|
for router in $1; do
|
|
if PingNode $router ; then
|
|
succeed=0
|
|
route add default gw $router
|
|
fi
|
|
done
|
|
return $succeed
|
|
}
|
|
|
|
# Delete/create static routes.
|
|
# args: $1 = operation (del/add)
|
|
# $2 = routes list in format "dst1 nexthop1 dst2 ..."
|
|
#
|
|
# BEWARE: this feature of DHCP is obsolete, because does not
|
|
# support subnetting.
|
|
#
|
|
X-StaticRouteList() {
|
|
local op=$1
|
|
local lst="$2"
|
|
local masklen
|
|
|
|
LOG X-StaticRouteList $*
|
|
|
|
if [ "$lst" ]; then
|
|
set $lst
|
|
while [ $# -gt 1 ]; do
|
|
route $op -net $1 netmask `ABCMask "$1"` gw $2
|
|
shift; shift;
|
|
done
|
|
fi
|
|
}
|
|
|
|
# Create static routes.
|
|
# arg: $1 = routes list in format "dst1 nexthop1 dst2 ..."
|
|
#
|
|
AddStaticRouteList() {
|
|
LOG AddStaticRouteList $*
|
|
X-StaticRouteList add "$1"
|
|
}
|
|
|
|
# Delete static routes.
|
|
# arg: $1 = routes list in format "dst1 nexthop1 dst2 ..."
|
|
#
|
|
DelStaticRouteList() {
|
|
LOG DelStaticRouteList $*
|
|
X-StaticRouteList del "$1"
|
|
}
|
|
|
|
# Broadcast unsolicited ARP to update neighbours' caches.
|
|
# args: $1 = interface
|
|
# $2 = address
|
|
#
|
|
UnsolicitedARP() {
|
|
if [ -f /sbin/arping ]; then
|
|
/sbin/arping -A -c 1 -I "$1" "$2" &
|
|
(sleep 2 ; /sbin/arping -U -c 1 -I "$1" "$2" ) &
|
|
fi
|
|
}
|
|
|
|
# Duplicate address detection.
|
|
# args: $1 = interface
|
|
# $2 = test address
|
|
# returns: 0, if DAD succeeded.
|
|
DAD() {
|
|
if [ -f /sbin/arping ]; then
|
|
/sbin/arping -c 2 -w 3 -D -I "$1" "$2"
|
|
return $?
|
|
fi
|
|
return 0
|
|
}
|
|
|
|
|
|
# Setup resolver.
|
|
# args: NO
|
|
# domain and nameserver list are passed in global variables.
|
|
#
|
|
# NOTE: we try to be careful and not to break user supplied resolv.conf.
|
|
# The script mangles it, only if it has dhcp magic signature.
|
|
#
|
|
UpdateDNS() {
|
|
local nameserver
|
|
local idstring="#### Generated by DHCPCD"
|
|
|
|
LOG UpdateDNS $*
|
|
|
|
if [ "$new_domain_name" = "" -a "$new_domain_name_servers" = "" ]; then
|
|
return 0;
|
|
fi
|
|
|
|
echo $idstring > /etc/resolv.conf.dhcp
|
|
if [ "$new_domain_name" ]; then
|
|
echo search $new_domain_name >> /etc/resolv.conf.dhcp
|
|
fi
|
|
echo options ndots:1 >> /etc/resolv.conf.dhcp
|
|
|
|
if [ "$new_domain_name_servers" ]; then
|
|
for nameserver in $new_domain_name_servers; do
|
|
echo nameserver $nameserver >> /etc/resolv.conf.dhcp
|
|
done
|
|
else
|
|
echo nameserver 127.0.0.1 >> /etc/resolv.conf.dhcp
|
|
fi
|
|
|
|
if [ -f /etc/resolv.conf ]; then
|
|
if [ "`head -1 /etc/resolv.conf`" != "$idstring" ]; then
|
|
return 0
|
|
fi
|
|
if [ "$old_domain_name" = "$new_domain_name" -a
|
|
"$new_domain_name_servers" = "$old_domain_name_servers" ]; then
|
|
return 0
|
|
fi
|
|
fi
|
|
mv /etc/resolv.conf.dhcp /etc/resolv.conf
|
|
}
|
|
|
|
case $reason in
|
|
NBI)
|
|
exit 1
|
|
;;
|
|
|
|
MEDIUM)
|
|
exit 0
|
|
;;
|
|
|
|
PREINIT)
|
|
ifconfig $interface:dhcp down
|
|
ifconfig $interface:dhcp1 down
|
|
if [ -d /proc/sys/net/ipv4/conf/$interface ]; then
|
|
ifconfig $interface:dhcp 10.10.10.10 netmask 255.255.255.255
|
|
ifconfig $interface:dhcp down
|
|
if [ -d /proc/sys/net/ipv4/conf/$interface ]; then
|
|
LOG The interface $interface already configured.
|
|
fi
|
|
fi
|
|
ifconfig $interface:dhcp up
|
|
exit 0
|
|
;;
|
|
|
|
ARPSEND)
|
|
exit 0
|
|
;;
|
|
|
|
ARPCHECK)
|
|
if DAD "$interface" "$check_ip_address" ; then
|
|
exit 0
|
|
fi
|
|
exit 1
|
|
;;
|
|
|
|
BOUND|RENEW|REBIND|REBOOT)
|
|
if [ "$old_ip_address" -a "$alias_ip_address" -a \
|
|
"$alias_ip_address" != "$old_ip_address" ]; then
|
|
DelINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1
|
|
fi
|
|
if [ "$old_ip_address" -a "$old_ip_address" != "$new_ip_address" ]; then
|
|
DelINETAddr "$interface" "$old_ip_address" "$old_subnet_mask" "$old_broadcast_address" dhcp
|
|
DelDefaultRoutes "$old_routers"
|
|
DelStaticRouteList "$old_static_routes"
|
|
fi
|
|
if [ "$old_ip_address" = "" -o "$old_ip_address" != "$new_ip_address" -o \
|
|
"$reason" = "BOUND" -o "$reason" = "REBOOT" ]; then
|
|
AddINETAddr "$interface" "$new_ip_address" "$new_subnet_mask" "$new_broadcast_address" dhcp
|
|
AddStaticRouteList "$new_static_routes"
|
|
AddDefaultRoutes "$new_routers"
|
|
UnsolicitedARP "$interface" "$new_ip_address"
|
|
fi
|
|
if [ "$new_ip_address" != "$alias_ip_address" -a "$alias_ip_address" ]; then
|
|
AddINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1
|
|
fi
|
|
UpdateDNS
|
|
exit 0
|
|
;;
|
|
|
|
EXPIRE|FAIL)
|
|
if [ "$alias_ip_address" ]; then
|
|
DelINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1
|
|
fi
|
|
if [ "$old_ip_address" ]; then
|
|
DelINETAddr "$interface" "$old_ip_address" "$old_subnet_mask" "$old_broadcast_address" dhcp
|
|
DelDefaultRoutes "$old_routers"
|
|
DelStaticRouteList "$old_static_routes"
|
|
fi
|
|
if [ "$alias_ip_address" ]; then
|
|
AddINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1
|
|
fi
|
|
exit 0
|
|
;;
|
|
|
|
TIMEOUT)
|
|
if [ "$alias_ip_address" ]; then
|
|
DelINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1
|
|
fi
|
|
# Seems, <null address> means, that no more old leases found.
|
|
# Or does it mean bug in dhcpcd? 8) Fail for now.
|
|
if [ "$new_ip_address" = "<null address>" ]; then
|
|
if [ "$old_ip_address" ]; then
|
|
DelINETAddr "$interface" "$old_ip_address" "$old_subnet_mask" "$old_broadcast_address" dhcp
|
|
fi
|
|
if [ "$alias_ip_address" ]; then
|
|
AddINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1
|
|
fi
|
|
exit 1
|
|
fi
|
|
if DAD "$interface" "$new_ip_address" ; then
|
|
AddINETAddr "$interface" "$new_ip_address" "$new_subnet_mask" "$new_broadcast_address" dhcp
|
|
UnsolicitedARP "$interface" "$new_ip_address"
|
|
if [ "$alias_ip_address" -a "$alias_ip_address" != "$new_ip_address" ]; then
|
|
AddINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1
|
|
UnsolicitedARP "$interface" "$alias_ip_address"
|
|
fi
|
|
if CheckRouterList "$new_routers" ; then
|
|
AddStaticRouteList "$new_static_routes"
|
|
UpdateDNS
|
|
exit 0
|
|
fi
|
|
fi
|
|
DelINETAddr "$interface" "$new_ip_address" "$new_subnet_mask" "$new_broadcast_address" dhcp
|
|
DelDefaultRoutes "$old_routers"
|
|
DelStaticRouteList "$old_static_routes"
|
|
if [ "$alias_ip_address" ]; then
|
|
AddINETAddr "$interface" "$alias_ip_address" "$alias_subnet_mask" "$alias_broadcast_address" dhcp1
|
|
fi
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
exit 0
|