516dcae1c7
'limit' is actually the number of IP addresses to serve. See the use of ipcalc.sh. For getting the expected number of IP addresses served, we have to decrement limit by one. Patch from: kentarou matsuyama <matsuyama@thinktube.com> SVN-Revision: 25100
403 lines
9.2 KiB
Bash
403 lines
9.2 KiB
Bash
#!/bin/sh /etc/rc.common
|
|
# Copyright (C) 2007 OpenWrt.org
|
|
|
|
START=60
|
|
DNS_SERVERS=""
|
|
DOMAIN=""
|
|
|
|
dhcp_calc() {
|
|
local ip="$1"
|
|
local res=0
|
|
|
|
while [ -n "$ip" ]; do
|
|
part="${ip%%.*}"
|
|
res="$(($res * 256))"
|
|
res="$(($res + $part))"
|
|
[ "${ip%.*}" != "$ip" ] && ip="${ip#*.}" || ip=
|
|
done
|
|
echo "$res"
|
|
}
|
|
|
|
append_bool() {
|
|
local section="$1"
|
|
local option="$2"
|
|
local value="$3"
|
|
local _loctmp
|
|
config_get_bool _loctmp "$section" "$option" 0
|
|
[ $_loctmp -gt 0 ] && append args "$value"
|
|
}
|
|
|
|
append_parm() {
|
|
local section="$1"
|
|
local option="$2"
|
|
local switch="$3"
|
|
local _loctmp
|
|
config_get _loctmp "$section" "$option"
|
|
[ -z "$_loctmp" ] && return 0
|
|
append args "$switch $_loctmp"
|
|
}
|
|
|
|
append_server() {
|
|
append args "-S $1"
|
|
}
|
|
|
|
append_interface() {
|
|
local ifname=$(uci_get_state network "$1" ifname "$1")
|
|
append args "-i $ifname"
|
|
}
|
|
|
|
append_notinterface() {
|
|
local ifname=$(uci_get_state network "$1" ifname "$1")
|
|
append args "-I $ifname"
|
|
}
|
|
|
|
append_addnhosts() {
|
|
append args "-H $1"
|
|
}
|
|
|
|
append_bogusnxdomain() {
|
|
append args "-B $1"
|
|
}
|
|
|
|
dnsmasq() {
|
|
local cfg="$1"
|
|
append_bool "$cfg" authoritative "-K"
|
|
append_bool "$cfg" nodaemon "-d"
|
|
append_bool "$cfg" domainneeded "-D"
|
|
append_bool "$cfg" filterwin2k "-f"
|
|
append_bool "$cfg" nohosts "-h"
|
|
append_bool "$cfg" nonegcache "-N"
|
|
append_bool "$cfg" strictorder "-o"
|
|
append_bool "$cfg" logqueries "-q"
|
|
append_bool "$cfg" noresolv "-R"
|
|
append_bool "$cfg" localise_queries "-y"
|
|
append_bool "$cfg" readethers "-Z"
|
|
append_bool "$cfg" dbus "-1"
|
|
append_bool "$cfg" boguspriv "-b"
|
|
append_bool "$cfg" expandhosts "-E"
|
|
append_bool "$cfg" enable_tftp "--enable-tftp"
|
|
append_bool "$cfg" nonwildcard "-z"
|
|
|
|
append_parm "$cfg" cachesize "-c"
|
|
append_parm "$cfg" dnsforwardmax "-0"
|
|
append_parm "$cfg" port "-p"
|
|
append_parm "$cfg" ednspacket_max "-P"
|
|
append_parm "$cfg" dhcpleasemax "-X"
|
|
append_parm "$cfg" "queryport" "-Q"
|
|
append_parm "$cfg" "domain" "-s"
|
|
append_parm "$cfg" "local" "-S"
|
|
config_list_foreach "$cfg" "server" append_server
|
|
config_list_foreach "$cfg" "interface" append_interface
|
|
config_list_foreach "$cfg" "notinterface" append_notinterface
|
|
config_list_foreach "$cfg" "addnhosts" append_addnhosts
|
|
config_list_foreach "$cfg" "bogusnxdomain" append_bogusnxdomain
|
|
append_parm "$cfg" "leasefile" "-l"
|
|
append_parm "$cfg" "resolvfile" "-r"
|
|
append_parm "$cfg" "tftp_root" "--tftp-root"
|
|
append_parm "$cfg" "dhcp_boot" "--dhcp-boot"
|
|
|
|
config_get DOMAIN "$cfg" domain
|
|
|
|
config_get_bool readethers "$cfg" readethers
|
|
[ "$readethers" = "1" ] && [ -e "/etc/ethers" ] || touch /etc/ethers
|
|
|
|
config_get leasefile $cfg leasefile
|
|
[ -n "$leasefile" ] && [ -e "$leasefile" ] || touch "$leasefile"
|
|
config_get_bool cachelocal "$cfg" cachelocal 1
|
|
|
|
config_get hostsfile "$cfg" dhcphostsfile
|
|
[ -e "$hostsfile" ] && append args "--dhcp-hostsfile=$hostsfile"
|
|
|
|
local rebind
|
|
config_get_bool rebind "$cfg" rebind_protection 1
|
|
[ $rebind -gt 0 ] && {
|
|
logger -t dnsmasq \
|
|
"DNS rebinding protection is active," \
|
|
"will discard upstream RFC1918 responses!"
|
|
append args "--stop-dns-rebind"
|
|
|
|
local rebind_localhost
|
|
config_get_bool rebind_localhost "$cfg" rebind_localhost 0
|
|
[ $rebind_localhost -gt 0 ] && {
|
|
logger -t dnsmasq "Allowing 127.0.0.0/8 responses"
|
|
append args "--rebind-localhost-ok"
|
|
}
|
|
|
|
append_rebind_domain() {
|
|
logger -t dnsmasq "Allowing RFC1918 responses for domain $1"
|
|
append args "--rebind-domain-ok=$1"
|
|
}
|
|
|
|
config_list_foreach "$cfg" rebind_domain append_rebind_domain
|
|
}
|
|
}
|
|
|
|
dhcp_subscrid_add() {
|
|
local cfg="$1"
|
|
|
|
config_get networkid "$cfg" networkid
|
|
[ -n "$networkid" ] || return 0
|
|
|
|
config_get subscriberid "$cfg" subscriberid
|
|
[ -n "$subscriberid" ] || return 0
|
|
|
|
append args "--dhcp-subscrid=$networkid,$subscriberid"
|
|
|
|
dhcp_option_add "$cfg" "$networkid"
|
|
}
|
|
|
|
dhcp_remoteid_add() {
|
|
local cfg="$1"
|
|
|
|
config_get networkid "$cfg" networkid
|
|
[ -n "$networkid" ] || return 0
|
|
|
|
config_get remoteid "$cfg" remoteid
|
|
[ -n "$remoteid" ] || return 0
|
|
|
|
append args "--dhcp-remoteid=$networkid,$remoteid"
|
|
|
|
dhcp_option_add "$cfg" "$networkid"
|
|
}
|
|
|
|
dhcp_circuitid_add() {
|
|
local cfg="$1"
|
|
|
|
config_get networkid "$cfg" networkid
|
|
[ -n "$networkid" ] || return 0
|
|
|
|
config_get circuitid "$cfg" circuitid
|
|
[ -n "$circuitid" ] || return 0
|
|
|
|
append args "--dhcp-circuitid=$networkid,$circuitid"
|
|
|
|
dhcp_option_add "$cfg" "$networkid"
|
|
}
|
|
|
|
dhcp_userclass_add() {
|
|
local cfg="$1"
|
|
|
|
config_get networkid "$cfg" networkid
|
|
[ -n "$networkid" ] || return 0
|
|
|
|
config_get userclass "$cfg" userclass
|
|
[ -n "$userclass" ] || return 0
|
|
|
|
append args "--dhcp-userclass=$networkid,$userclass"
|
|
|
|
dhcp_option_add "$cfg" "$networkid"
|
|
}
|
|
|
|
dhcp_vendorclass_add() {
|
|
local cfg="$1"
|
|
|
|
config_get networkid "$cfg" networkid
|
|
[ -n "$networkid" ] || return 0
|
|
|
|
config_get vendorclass "$cfg" vendorclass
|
|
[ -n "$vendorclass" ] || return 0
|
|
|
|
append args "--dhcp-vendorclass=$networkid,$vendorclass"
|
|
|
|
dhcp_option_add "$cfg" "$networkid"
|
|
}
|
|
|
|
dhcp_host_add() {
|
|
local cfg="$1"
|
|
|
|
config_get name "$cfg" name
|
|
|
|
config_get networkid "$cfg" networkid
|
|
[ -n "$networkid" ] && dhcp_option_add "$cfg" "$networkid"
|
|
|
|
config_get ip "$cfg" ip
|
|
[ -n "$ip" ] || return 0
|
|
|
|
macs=""
|
|
config_get mac "$cfg" mac
|
|
for m in $mac; do append macs "$m" ","; done
|
|
[ -n "$macs" ] || return 0
|
|
|
|
append args "--dhcp-host=$macs,${networkid:+net:$networkid,}$ip${name:+,$name}"
|
|
}
|
|
|
|
dhcp_mac_add() {
|
|
local cfg="$1"
|
|
|
|
config_get networkid "$cfg" networkid
|
|
[ -n "$networkid" ] || return 0
|
|
|
|
config_get mac "$cfg" mac
|
|
[ -n "$mac" ] || return 0
|
|
|
|
append args "--dhcp-mac=$networkid,$mac"
|
|
|
|
dhcp_option_add "$cfg" "$networkid"
|
|
}
|
|
|
|
dhcp_boot_add() {
|
|
local cfg="$1"
|
|
|
|
config_get networkid "$cfg" networkid
|
|
|
|
config_get filename "$cfg" filename
|
|
[ -n "$filename" ] || return 0
|
|
|
|
config_get servername "$cfg" servername
|
|
[ -n "$servername" ] || return 0
|
|
|
|
config_get serveraddress "$cfg" serveraddress
|
|
[ -n "$serveraddress" ] || return 0
|
|
|
|
append args "--dhcp-boot=${networkid:+net:$networkid,}$filename,$servername,$serveraddress"
|
|
|
|
dhcp_option_add "$cfg" "$networkid"
|
|
}
|
|
|
|
|
|
dhcp_add() {
|
|
local cfg="$1"
|
|
config_get net "$cfg" interface
|
|
[ -n "$net" ] || return 0
|
|
|
|
config_get networkid "$cfg" networkid
|
|
[ -n "$networkid" ] || networkid="$net"
|
|
|
|
config_get ifname "$net" ifname
|
|
[ -n "$ifname" ] || return 0
|
|
|
|
config_get dnsserver "$net" dns
|
|
[ "$cachelocal" = "0" -a -n "$dnsserver" ] && {
|
|
DNS_SERVERS="$DNS_SERVERS $dnsserver"
|
|
}
|
|
|
|
append_bool "$cfg" ignore "-2 $ifname" && return 0
|
|
|
|
config_get proto "$net" proto
|
|
[ static = "$proto" ] || return 0
|
|
|
|
config_get ipaddr "$net" ipaddr
|
|
config_get netmask "$cfg" netmask
|
|
[ -n "$netmask" ] || config_get netmask "$net" netmask
|
|
|
|
#check for an already active dhcp server on the interface, unless 'force' is set
|
|
config_get_bool force "$cfg" force 0
|
|
[ $force -gt 0 ] || {
|
|
udhcpc -n -q -s /bin/true -t 1 -i $ifname >&- && {
|
|
logger -t dnsmasq \
|
|
"found already running DHCP-server on interface '$ifname'" \
|
|
"refusing to start, use 'option force 1' to override"
|
|
return 0
|
|
}
|
|
}
|
|
|
|
config_get start "$cfg" start
|
|
config_get limit "$cfg" limit
|
|
config_get leasetime "$cfg" leasetime
|
|
config_get options "$cfg" options
|
|
config_get_bool dynamicdhcp "$cfg" dynamicdhcp 1
|
|
|
|
leasetime="${leasetime:-12h}"
|
|
start="$(dhcp_calc "${start:-100}")"
|
|
limit="${limit:-150}"
|
|
[ "$limit" -gt 0 ] && limit=$((limit-1))
|
|
eval "$(ipcalc.sh $ipaddr $netmask $start $limit)"
|
|
if [ "$dynamicdhcp" = "0" ]; then END="static"; fi
|
|
append args "--dhcp-range=$networkid,$START,$END,$NETMASK,$leasetime${options:+ $options}"
|
|
|
|
dhcp_option_add "$cfg" "$networkid"
|
|
}
|
|
|
|
dhcp_option_add() {
|
|
local cfg="$1"
|
|
local networkid="$2"
|
|
|
|
config_get dhcp_option "$cfg" dhcp_option
|
|
for o in $dhcp_option; do
|
|
append args "-O $networkid","$o"
|
|
done
|
|
|
|
}
|
|
|
|
dhcp_domain_add() {
|
|
local cfg="$1"
|
|
local ip name names
|
|
|
|
config_get names "$cfg" name
|
|
[ -n "$names" ] || return 0
|
|
|
|
config_get ip "$cfg" ip
|
|
[ -n "$ip" ] || return 0
|
|
|
|
local oIFS="$IFS"; IFS="."; set -- $ip; IFS="$oIFS"
|
|
local raddr="${4:+$4.$3.$2.$1.in-addr.arpa}"
|
|
|
|
for name in $names; do
|
|
local fqdn="$name"
|
|
|
|
[ "${fqdn%.*}" == "$fqdn" ] && \
|
|
fqdn="$fqdn${DOMAIN:+.$DOMAIN}"
|
|
|
|
append args "-A /$fqdn/$ip"
|
|
|
|
[ -n "$raddr" ] && {
|
|
append args "--ptr-record=$raddr,$fqdn"
|
|
raddr=""
|
|
}
|
|
done
|
|
}
|
|
|
|
dhcp_srv_add() {
|
|
local cfg="$1"
|
|
|
|
config_get srv "$cfg" srv
|
|
[ -n "$srv" ] || return 0
|
|
|
|
config_get target "$cfg" target
|
|
[ -n "$target" ] || return 0
|
|
|
|
config_get port "$cfg" port
|
|
|
|
local service="$srv,$target"
|
|
[ -n "$port" ] && service="$service,$port"
|
|
|
|
append args "-W $service"
|
|
}
|
|
|
|
start() {
|
|
include /lib/network
|
|
scan_interfaces
|
|
config_load dhcp
|
|
|
|
args=""
|
|
config_foreach dnsmasq dnsmasq
|
|
config_foreach dhcp_host_add host
|
|
config_foreach dhcp_boot_add boot
|
|
config_foreach dhcp_mac_add mac
|
|
config_foreach dhcp_vendorclass_add vendorclass
|
|
config_foreach dhcp_userclass_add userclass
|
|
config_foreach dhcp_circuitid_add circuitid
|
|
config_foreach dhcp_remoteid_add remoteid
|
|
config_foreach dhcp_subscrid_add subscrid
|
|
config_foreach dhcp_domain_add domain
|
|
config_foreach dhcp_srv_add srvhost
|
|
config_foreach dhcp_add dhcp
|
|
|
|
/usr/sbin/dnsmasq $args && {
|
|
rm -f /tmp/resolv.conf
|
|
[ -n "$DOMAIN" ] && echo "search $DOMAIN" >> /tmp/resolv.conf
|
|
DNS_SERVERS="$DNS_SERVERS 127.0.0.1"
|
|
for DNS_SERVER in $DNS_SERVERS ; do
|
|
echo "nameserver $DNS_SERVER" >> /tmp/resolv.conf
|
|
done
|
|
}
|
|
}
|
|
|
|
stop() {
|
|
[ -f /tmp/resolv.conf ] && {
|
|
rm -f /tmp/resolv.conf
|
|
ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
|
|
}
|
|
killall dnsmasq
|
|
return 0
|
|
}
|