START=60
-SERVICE_USE_PID=1
+USE_PROCD=1
+PROG=/usr/sbin/dnsmasq
DNS_SERVERS=""
DOMAIN=""
ADD_LOCAL_HOSTNAME=1
CONFIGFILE="/var/etc/dnsmasq.conf"
+HOSTFILE="/tmp/hosts/dhcp"
+TRUSTANCHORSFILE="/usr/share/dnsmasq/trust-anchors.conf"
+TIMESTAMPFILE="/etc/dnsmasq.time"
xappend() {
local value="$1"
echo "$res"
}
+dhcp_check() {
+ local ifname="$1"
+ local stamp="/var/run/dnsmasq.$ifname.dhcp"
+ local rv=0
+
+ [ -s "$stamp" ] && return $(cat "$stamp")
+
+ udhcpc -n -q -s /bin/true -t 1 -i "$ifname" >&- && rv=1 || rv=0
+
+ [ $rv -eq 1 ] && \
+ logger -t dnsmasq \
+ "found already running DHCP-server on interface '$ifname'" \
+ "refusing to start, use 'option force 1' to override"
+
+ echo $rv > "$stamp"
+ return $rv
+}
+
+log_once() {
+ pidof dnsmasq >/dev/null || \
+ logger -t dnsmasq "$@"
+}
+
append_bool() {
local section="$1"
local option="$2"
xappend "--address=$1"
}
+append_ipset() {
+ xappend "--ipset=$1"
+}
+
append_interface() {
local ifname=$(uci_get_state network "$1" ifname "$1")
xappend "--interface=$ifname"
}
append_bogusnxdomain() {
- xappend "--bogus-nxdomain=$1"
+ xappend "--bogus-nxdomain=$1"
+}
+
+append_pxe_service() {
+ xappend "--pxe-service=$1"
}
dnsmasq() {
append_bool "$cfg" nohosts "--no-hosts"
append_bool "$cfg" nonegcache "--no-negcache"
append_bool "$cfg" strictorder "--strict-order"
- append_bool "$cfg" logqueries "--log-queries"
+ append_bool "$cfg" logqueries "--log-queries=extra"
append_bool "$cfg" noresolv "--no-resolv"
append_bool "$cfg" localise_queries "--localise-queries"
append_bool "$cfg" readethers "--read-ethers"
append_bool "$cfg" dbus "--enable-dbus"
append_bool "$cfg" boguspriv "--bogus-priv"
append_bool "$cfg" expandhosts "--expand-hosts"
- append_bool "$cfg" enable_tftp "--enable-tftp"
- append_bool "$cfg" nonwildcard "--bind-interfaces"
+ config_get tftp_root "$cfg" "tftp_root"
+ [ -d "$tftp_root" ] && append_bool "$cfg" enable_tftp "--enable-tftp"
+ append_bool "$cfg" tftp_no_fail "--tftp-no-fail"
+ append_bool "$cfg" nonwildcard "--bind-dynamic"
append_bool "$cfg" fqdn "--dhcp-fqdn"
append_bool "$cfg" proxydnssec "--proxy-dnssec"
+ append_bool "$cfg" localservice "--local-service"
+ append_bool "$cfg" quietdhcp "--quiet-dhcp"
+ append_bool "$cfg" sequential_ip "--dhcp-sequential-ip"
+ append_bool "$cfg" allservers "--all-servers"
+ append_bool "$cfg" noping "--no-ping"
append_parm "$cfg" dhcpscript "--dhcp-script"
append_parm "$cfg" cachesize "--cache-size"
append_parm "$cfg" ednspacket_max "--edns-packet-max"
append_parm "$cfg" dhcpleasemax "--dhcp-lease-max"
append_parm "$cfg" "queryport" "--query-port"
+ append_parm "$cfg" "minport" "--min-port"
append_parm "$cfg" "domain" "--domain"
append_parm "$cfg" "local" "--server"
config_list_foreach "$cfg" "server" append_server
config_list_foreach "$cfg" "address" append_address
+ config_list_foreach "$cfg" "ipset" append_ipset
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" "--dhcp-leasefile"
append_parm "$cfg" "resolvfile" "--resolv-file"
+ append_parm "$cfg" "serversfile" "--servers-file"
append_parm "$cfg" "tftp_root" "--tftp-root"
append_parm "$cfg" "dhcp_boot" "--dhcp-boot"
append_parm "$cfg" "local_ttl" "--local-ttl"
-
+ append_parm "$cfg" "pxe_prompt" "--pxe-prompt"
+ config_list_foreach "$cfg" "pxe_service" append_pxe_service
config_get DOMAIN "$cfg" domain
config_get_bool ADD_LOCAL_DOMAIN "$cfg" add_local_domain 1
config_get hostsfile "$cfg" dhcphostsfile
[ -e "$hostsfile" ] && xappend "--dhcp-hostsfile=$hostsfile"
- mkdir -p /tmp/hosts
- xappend "--addn-hosts=/tmp/hosts"
-
local rebind
config_get_bool rebind "$cfg" rebind_protection 1
[ $rebind -gt 0 ] && {
- logger -t dnsmasq \
+ log_once \
"DNS rebinding protection is active," \
"will discard upstream RFC1918 responses!"
xappend "--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"
+ log_once "Allowing 127.0.0.0/8 responses"
xappend "--rebind-localhost-ok"
}
append_rebind_domain() {
- logger -t dnsmasq "Allowing RFC1918 responses for domain $1"
+ log_once "Allowing RFC1918 responses for domain $1"
xappend "--rebind-domain-ok=$1"
}
config_list_foreach "$cfg" rebind_domain append_rebind_domain
}
+ config_get_bool dnssec "$cfg" dnssec 0
+ [ "$dnssec" -gt 0 ] && {
+ xappend "--conf-file=$TRUSTANCHORSFILE"
+ xappend "--dnssec"
+ xappend "--dnssec-timestamp=$TIMESTAMPFILE"
+ append_bool "$cfg" dnsseccheckunsigned "--dnssec-check-unsigned"
+ }
+
dhcp_option_add "$cfg" "" 0
+ xappend "--dhcp-broadcast=tag:needs-broadcast"
+
+ mkdir -p /tmp/hosts /tmp/dnsmasq.d
+ xappend "--addn-hosts=/tmp/hosts"
+ xappend "--conf-dir=/tmp/dnsmasq.d"
+ xappend "--user=dnsmasq"
+ xappend "--group=dnsmasq"
+
echo >> $CONFIGFILE
+
+ config_get_bool enable_tftp "$cfg" enable_tftp 0
+ [ "$enable_tftp" -gt 0 ] && {
+ config_get tftp_root "$cfg" tftp_root
+ append EXTRA_MOUNT $tftp_root
+ }
}
dhcp_subscrid_add() {
config_get networkid "$cfg" networkid
[ -n "$networkid" ] && dhcp_option_add "$cfg" "$networkid" "$force"
+ config_get_bool enable "$cfg" enable 1
+ [ "$enable" = "0" ] && return 0
+
config_get name "$cfg" name
config_get ip "$cfg" ip
[ -n "$ip" -o -n "$name" ] || return 0
+ config_get_bool dns "$cfg" dns 0
+ [ "$dns" = "1" -a -n "$ip" -a -n "$name" ] && {
+ echo "$ip $name${DOMAIN:+.$DOMAIN}" >> $HOSTFILE
+ }
+
config_get mac "$cfg" mac
- [ -z "$mac" ] && {
+ if [ -n "$mac" ]; then
+ # --dhcp-host=00:20:e0:3b:13:af,192.168.0.199,lap
+ macs=""
+ for m in $mac; do append macs "$m" ","; done
+ else
+ # --dhcp-host=lap,192.168.0.199
[ -n "$name" ] || return 0
- mac="$name"
+ macs="$name"
name=""
- }
-
- macs=""
- for m in $mac; do append macs "$m" ","; done
+ fi
config_get tag "$cfg" tag
- xappend "--dhcp-host=$macs${networkid:+,net:$networkid}${tag:+,set:$tag}${ip:+,$ip}${name:+,$name}"
+ config_get_bool broadcast "$cfg" broadcast 0
+ [ "$broadcast" = "0" ] && broadcast=
+
+ config_get leasetime "$cfg" leasetime
+
+ xappend "--dhcp-host=$macs${networkid:+,net:$networkid}${broadcast:+,set:needs-broadcast}${tag:+,set:$tag}${ip:+,$ip}${name:+,$name}${leasetime:+,$leasetime}"
}
dhcp_tag_add() {
[ -n "$filename" ] || return 0
config_get servername "$cfg" servername
- [ -n "$servername" ] || return 0
-
config_get serveraddress "$cfg" serveraddress
- [ -n "$serveraddress" ] || return 0
- xappend "--dhcp-boot=${networkid:+net:$networkid,}$filename,$servername,$serveraddress"
+ [ -n "$serveraddress" -a ! -n "$servername" ] && return 0
+
+ xappend "--dhcp-boot=${networkid:+net:$networkid,}${filename}${servername:+,$servername}${serveraddress:+,$serveraddress}"
config_get_bool force "$cfg" force 0
config_get net "$cfg" interface
[ -n "$net" ] || return 0
+ config_get dhcpv4 "$cfg" dhcpv4
+ [ "$dhcpv4" != "disabled" ] || return 0
+
config_get networkid "$cfg" networkid
[ -n "$networkid" ] || networkid="$net"
- config_get ifname "$net" ifname
- [ -n "$ifname" ] || return 0
+ network_get_subnet subnet "$net" || return 0
+ network_get_device ifname "$net" || return 0
+ network_get_protocol proto "$net" || return 0
- config_get dnsserver "$net" dns
- [ "$cachelocal" = "0" -a -n "$dnsserver" ] && {
+ [ "$cachelocal" = "0" ] && network_get_dnsserver dnsserver "$net" && {
DNS_SERVERS="$DNS_SERVERS $dnsserver"
}
append_bool "$cfg" ignore "--no-dhcp-interface=$ifname" && return 0
- config_get proto "$net" proto
+ # Do not support non-static interfaces for now
[ static = "$proto" ] || return 0
- config_get ipaddr "$net" ipaddr
- config_get netmask "$cfg" netmask
- [ -n "$netmask" ] || config_get netmask "$net" netmask
+ # Override interface netmask with dhcp config if applicable
+ config_get netmask "$cfg" netmask "${subnet##*/}"
#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
- }
- }
+ [ $force -gt 0 ] || dhcp_check "$ifname" || return 0
config_get start "$cfg" start
config_get limit "$cfg" limit
start="$(dhcp_calc "${start:-100}")"
limit="${limit:-150}"
[ "$limit" -gt 0 ] && limit=$((limit-1))
- eval "$(ipcalc.sh $ipaddr $netmask $start $limit)"
+ eval "$(ipcalc.sh "${subnet%%/*}" $netmask $start $limit)"
if [ "$dynamicdhcp" = "0" ]; then END="static"; fi
xappend "--dhcp-range=$networkid,$START,$END,$NETMASK,$leasetime${options:+ $options}"
[ -n "$ip" ] || return 0
for name in $names; do
- record="${record:+$record/}$name"
+ record="${record:+$record }$name"
done
- xappend "--address=/$record/$ip"
+ echo "$ip $record" >> $HOSTFILE
}
dhcp_srv_add() {
xappend "--host-record=$record"
}
-start() {
- include /lib/network
- scan_interfaces
+dhcp_relay_add() {
+ local cfg="$1"
+ local local_addr server_addr interface
- local lanaddr
- config_get lanaddr "lan" ipaddr
+ config_get local_addr "$cfg" local_addr
+ [ -n "$local_addr" ] || return 0
+
+ config_get server_addr "$cfg" server_addr
+ [ -n "$server_addr" ] || return 0
+
+ config_get interface "$cfg" interface
+ if [ -z "$interface" ]; then
+ xappend "--dhcp-relay=$local_addr,$server_addr"
+ else
+ xappend "--dhcp-relay=$local_addr,$server_addr,$interface"
+ fi
+}
+
+service_triggers()
+{
+ procd_add_reload_trigger "dhcp"
+}
+
+boot() {
+ # Will be launched through hotplug
+ return 0
+}
+
+start_service() {
+ include /lib/functions
config_load dhcp
# before we can call xappend
+ mkdir -p /var/run/dnsmasq/
mkdir -p $(dirname $CONFIGFILE)
+ mkdir -p /var/lib/misc
+ touch /tmp/dhcp.leases
+
+ if [ ! -f "$TIMESTAMPFILE" ]; then
+ touch "$TIMESTAMPFILE"
+ chown dnsmasq.dnsmasq "$TIMESTAMPFILE"
+ fi
echo "# auto-generated config file from /etc/config/dhcp" > $CONFIGFILE
+ echo "# auto-generated config file from /etc/config/dhcp" > $HOSTFILE
# if we did this last, we could override auto-generated config
[ -f /etc/dnsmasq.conf ] && {
config_foreach dhcp_subscrid_add subscrid
config_foreach dhcp_domain_add domain
config_foreach dhcp_hostrecord_add hostrecord
+ config_foreach dhcp_relay_add relay
# add own hostname
- [ $ADD_LOCAL_HOSTNAME -eq 1 ] && [ -n "$lanaddr" ] && {
+ [ $ADD_LOCAL_HOSTNAME -eq 1 ] && {
+ local lanaddr lanaddr6
+ local ulaprefix="$(uci_get network @globals[0] ula_prefix)"
local hostname="$(uci_get system @system[0] hostname OpenWrt)"
- dhcp_hostrecord_add "" "$hostname${DOMAIN:+.$DOMAIN $hostname}" "$lanaddr"
+
+ network_get_ipaddr lanaddr "lan" && {
+ dhcp_domain_add "" "$hostname" "$lanaddr"
+ }
+
+ [ -n "$ulaprefix" ] && network_get_ipaddrs6 lanaddr6 "lan" && {
+ for lanaddr6 in $lanaddr6; do
+ case "$lanaddr6" in
+ "${ulaprefix%%:/*}"*)
+ dhcp_domain_add "" "$hostname" "$lanaddr6"
+ ;;
+ esac
+ done
+ }
}
echo >> $CONFIGFILE
config_foreach dhcp_srv_add srvhost
config_foreach dhcp_mx_add mxhost
echo >> $CONFIGFILE
- config_foreach dhcp_add dhcp
+
+ config_get odhcpd_is_active odhcpd maindhcp
+ if [ "$odhcpd_is_active" != "1" ]; then
+ config_foreach dhcp_add dhcp
+ fi
+
echo >> $CONFIGFILE
config_foreach dhcp_cname_add cname
echo >> $CONFIGFILE
- service_start /usr/sbin/dnsmasq -C $CONFIGFILE && {
- rm -f /tmp/resolv.conf
- [ $ADD_LOCAL_DOMAIN -eq 1 ] && [ -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
+ rm -f /tmp/resolv.conf
+ [ $ADD_LOCAL_DOMAIN -eq 1 ] && [ -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
+
+ procd_open_instance
+ procd_set_param command $PROG -C $CONFIGFILE -k -x /var/run/dnsmasq/dnsmasq.pid
+ procd_set_param file $CONFIGFILE
+ procd_set_param respawn
+
+ procd_add_jail dnsmasq ubus log
+ procd_add_jail_mount $CONFIGFILE $TRUSTANCHORSFILE $HOSTFILE /etc/passwd /etc/group /etc/TZ /dev/null /dev/urandom /etc/dnsmasq.conf /tmp/dnsmasq.d /tmp/resolv.conf.auto /etc/hosts /etc/ethers $EXTRA_MOUNT
+ procd_add_jail_mount_rw /var/run/dnsmasq/ /tmp/dhcp.leases $TIMESTAMPFILE
+
+ procd_close_instance
}
-stop() {
- service_stop /usr/sbin/dnsmasq && {
- [ -f /tmp/resolv.conf ] && {
- rm -f /tmp/resolv.conf
- ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
- }
+reload_service() {
+ rc_procd start_service "$@"
+ return 0
+}
+
+stop_service() {
+ [ -f /tmp/resolv.conf ] && {
+ rm -f /tmp/resolv.conf
+ ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
}
+ rm -f /var/run/dnsmasq.*.dhcp
}