dnsmasq.init 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. #!/bin/sh /etc/rc.common
  2. # Copyright (C) 2007-2012 OpenWrt.org
  3. START=60
  4. USE_PROCD=1
  5. PROG=/usr/sbin/dnsmasq
  6. DNS_SERVERS=""
  7. DOMAIN=""
  8. ADD_LOCAL_DOMAIN=1
  9. ADD_LOCAL_HOSTNAME=1
  10. CONFIGFILE="/var/etc/dnsmasq.conf"
  11. HOSTFILE="/tmp/hosts/dhcp"
  12. TRUSTANCHORSFILE="/usr/share/dnsmasq/trust-anchors.conf"
  13. TIMESTAMPFILE="/etc/dnsmasq.time"
  14. xappend() {
  15. local value="$1"
  16. echo "${value#--}" >> $CONFIGFILE
  17. }
  18. dhcp_calc() {
  19. local ip="$1"
  20. local res=0
  21. while [ -n "$ip" ]; do
  22. part="${ip%%.*}"
  23. res="$(($res * 256))"
  24. res="$(($res + $part))"
  25. [ "${ip%.*}" != "$ip" ] && ip="${ip#*.}" || ip=
  26. done
  27. echo "$res"
  28. }
  29. dhcp_check() {
  30. local ifname="$1"
  31. local stamp="/var/run/dnsmasq.$ifname.dhcp"
  32. local rv=0
  33. [ -s "$stamp" ] && return $(cat "$stamp")
  34. udhcpc -n -q -s /bin/true -t 1 -i "$ifname" >&- && rv=1 || rv=0
  35. [ $rv -eq 1 ] && \
  36. logger -t dnsmasq \
  37. "found already running DHCP-server on interface '$ifname'" \
  38. "refusing to start, use 'option force 1' to override"
  39. echo $rv > "$stamp"
  40. return $rv
  41. }
  42. log_once() {
  43. pidof dnsmasq >/dev/null || \
  44. logger -t dnsmasq "$@"
  45. }
  46. append_bool() {
  47. local section="$1"
  48. local option="$2"
  49. local value="$3"
  50. local _loctmp
  51. config_get_bool _loctmp "$section" "$option" 0
  52. [ $_loctmp -gt 0 ] && xappend "$value"
  53. }
  54. append_parm() {
  55. local section="$1"
  56. local option="$2"
  57. local switch="$3"
  58. local _loctmp
  59. config_get _loctmp "$section" "$option"
  60. [ -z "$_loctmp" ] && return 0
  61. xappend "$switch=$_loctmp"
  62. }
  63. append_server() {
  64. xappend "--server=$1"
  65. }
  66. append_address() {
  67. xappend "--address=$1"
  68. }
  69. append_ipset() {
  70. xappend "--ipset=$1"
  71. }
  72. append_interface() {
  73. local ifname=$(uci_get_state network "$1" ifname "$1")
  74. xappend "--interface=$ifname"
  75. }
  76. append_notinterface() {
  77. local ifname=$(uci_get_state network "$1" ifname "$1")
  78. xappend "--except-interface=$ifname"
  79. }
  80. append_addnhosts() {
  81. xappend "--addn-hosts=$1"
  82. }
  83. append_bogusnxdomain() {
  84. xappend "--bogus-nxdomain=$1"
  85. }
  86. append_pxe_service() {
  87. xappend "--pxe-service=$1"
  88. }
  89. dnsmasq() {
  90. local cfg="$1"
  91. append_bool "$cfg" authoritative "--dhcp-authoritative"
  92. append_bool "$cfg" nodaemon "--no-daemon"
  93. append_bool "$cfg" domainneeded "--domain-needed"
  94. append_bool "$cfg" filterwin2k "--filterwin2k"
  95. append_bool "$cfg" nohosts "--no-hosts"
  96. append_bool "$cfg" nonegcache "--no-negcache"
  97. append_bool "$cfg" strictorder "--strict-order"
  98. append_bool "$cfg" logqueries "--log-queries"
  99. append_bool "$cfg" noresolv "--no-resolv"
  100. append_bool "$cfg" localise_queries "--localise-queries"
  101. append_bool "$cfg" readethers "--read-ethers"
  102. append_bool "$cfg" dbus "--enable-dbus"
  103. append_bool "$cfg" boguspriv "--bogus-priv"
  104. append_bool "$cfg" expandhosts "--expand-hosts"
  105. append_bool "$cfg" enable_tftp "--enable-tftp"
  106. append_bool "$cfg" tftp_no_fail "--tftp-no-fail"
  107. append_bool "$cfg" nonwildcard "--bind-interfaces"
  108. append_bool "$cfg" fqdn "--dhcp-fqdn"
  109. append_bool "$cfg" proxydnssec "--proxy-dnssec"
  110. append_bool "$cfg" localservice "--local-service"
  111. append_bool "$cfg" quietdhcp "--quiet-dhcp"
  112. append_parm "$cfg" dhcpscript "--dhcp-script"
  113. append_parm "$cfg" cachesize "--cache-size"
  114. append_parm "$cfg" dnsforwardmax "--dns-forward-max"
  115. append_parm "$cfg" port "--port"
  116. append_parm "$cfg" ednspacket_max "--edns-packet-max"
  117. append_parm "$cfg" dhcpleasemax "--dhcp-lease-max"
  118. append_parm "$cfg" "queryport" "--query-port"
  119. append_parm "$cfg" "domain" "--domain"
  120. append_parm "$cfg" "local" "--server"
  121. config_list_foreach "$cfg" "server" append_server
  122. config_list_foreach "$cfg" "address" append_address
  123. config_list_foreach "$cfg" "ipset" append_ipset
  124. config_list_foreach "$cfg" "interface" append_interface
  125. config_list_foreach "$cfg" "notinterface" append_notinterface
  126. config_list_foreach "$cfg" "addnhosts" append_addnhosts
  127. config_list_foreach "$cfg" "bogusnxdomain" append_bogusnxdomain
  128. append_parm "$cfg" "leasefile" "--dhcp-leasefile"
  129. append_parm "$cfg" "resolvfile" "--resolv-file"
  130. append_parm "$cfg" "serversfile" "--servers-file"
  131. append_parm "$cfg" "tftp_root" "--tftp-root"
  132. append_parm "$cfg" "dhcp_boot" "--dhcp-boot"
  133. append_parm "$cfg" "local_ttl" "--local-ttl"
  134. append_parm "$cfg" "pxe_prompt" "--pxe-prompt"
  135. config_list_foreach "$cfg" "pxe_service" append_pxe_service
  136. config_get DOMAIN "$cfg" domain
  137. config_get_bool ADD_LOCAL_DOMAIN "$cfg" add_local_domain 1
  138. config_get_bool ADD_LOCAL_HOSTNAME "$cfg" add_local_hostname 1
  139. config_get_bool readethers "$cfg" readethers
  140. [ "$readethers" = "1" -a \! -e "/etc/ethers" ] && touch /etc/ethers
  141. config_get leasefile $cfg leasefile
  142. [ -n "$leasefile" -a \! -e "$leasefile" ] && touch "$leasefile"
  143. config_get_bool cachelocal "$cfg" cachelocal 1
  144. config_get hostsfile "$cfg" dhcphostsfile
  145. [ -e "$hostsfile" ] && xappend "--dhcp-hostsfile=$hostsfile"
  146. mkdir -p /tmp/hosts /tmp/dnsmasq.d
  147. xappend "--addn-hosts=/tmp/hosts"
  148. xappend "--conf-dir=/tmp/dnsmasq.d"
  149. local rebind
  150. config_get_bool rebind "$cfg" rebind_protection 1
  151. [ $rebind -gt 0 ] && {
  152. log_once \
  153. "DNS rebinding protection is active," \
  154. "will discard upstream RFC1918 responses!"
  155. xappend "--stop-dns-rebind"
  156. local rebind_localhost
  157. config_get_bool rebind_localhost "$cfg" rebind_localhost 0
  158. [ $rebind_localhost -gt 0 ] && {
  159. log_once "Allowing 127.0.0.0/8 responses"
  160. xappend "--rebind-localhost-ok"
  161. }
  162. append_rebind_domain() {
  163. log_once "Allowing RFC1918 responses for domain $1"
  164. xappend "--rebind-domain-ok=$1"
  165. }
  166. config_list_foreach "$cfg" rebind_domain append_rebind_domain
  167. }
  168. config_get_bool dnssec "$cfg" dnssec 0
  169. [ "$dnssec" -gt 0 ] && {
  170. xappend "--conf-file=$TRUSTANCHORSFILE"
  171. xappend "--dnssec"
  172. xappend "--dnssec-timestamp=$TIMESTAMPFILE"
  173. append_bool "$cfg" dnsseccheckunsigned "--dnssec-check-unsigned"
  174. }
  175. dhcp_option_add "$cfg" "" 0
  176. xappend "--dhcp-broadcast=tag:needs-broadcast"
  177. echo >> $CONFIGFILE
  178. }
  179. dhcp_subscrid_add() {
  180. local cfg="$1"
  181. config_get networkid "$cfg" networkid
  182. [ -n "$networkid" ] || return 0
  183. config_get subscriberid "$cfg" subscriberid
  184. [ -n "$subscriberid" ] || return 0
  185. xappend "--dhcp-subscrid=$networkid,$subscriberid"
  186. config_get_bool force "$cfg" force 0
  187. dhcp_option_add "$cfg" "$networkid" "$force"
  188. }
  189. dhcp_remoteid_add() {
  190. local cfg="$1"
  191. config_get networkid "$cfg" networkid
  192. [ -n "$networkid" ] || return 0
  193. config_get remoteid "$cfg" remoteid
  194. [ -n "$remoteid" ] || return 0
  195. xappend "--dhcp-remoteid=$networkid,$remoteid"
  196. config_get_bool force "$cfg" force 0
  197. dhcp_option_add "$cfg" "$networkid" "$force"
  198. }
  199. dhcp_circuitid_add() {
  200. local cfg="$1"
  201. config_get networkid "$cfg" networkid
  202. [ -n "$networkid" ] || return 0
  203. config_get circuitid "$cfg" circuitid
  204. [ -n "$circuitid" ] || return 0
  205. xappend "--dhcp-circuitid=$networkid,$circuitid"
  206. config_get_bool force "$cfg" force 0
  207. dhcp_option_add "$cfg" "$networkid" "$force"
  208. }
  209. dhcp_userclass_add() {
  210. local cfg="$1"
  211. config_get networkid "$cfg" networkid
  212. [ -n "$networkid" ] || return 0
  213. config_get userclass "$cfg" userclass
  214. [ -n "$userclass" ] || return 0
  215. xappend "--dhcp-userclass=$networkid,$userclass"
  216. config_get_bool force "$cfg" force 0
  217. dhcp_option_add "$cfg" "$networkid" "$force"
  218. }
  219. dhcp_vendorclass_add() {
  220. local cfg="$1"
  221. config_get networkid "$cfg" networkid
  222. [ -n "$networkid" ] || return 0
  223. config_get vendorclass "$cfg" vendorclass
  224. [ -n "$vendorclass" ] || return 0
  225. xappend "--dhcp-vendorclass=$networkid,$vendorclass"
  226. config_get_bool force "$cfg" force 0
  227. dhcp_option_add "$cfg" "$networkid" "$force"
  228. }
  229. dhcp_host_add() {
  230. local cfg="$1"
  231. config_get_bool force "$cfg" force 0
  232. config_get networkid "$cfg" networkid
  233. [ -n "$networkid" ] && dhcp_option_add "$cfg" "$networkid" "$force"
  234. config_get name "$cfg" name
  235. config_get ip "$cfg" ip
  236. [ -n "$ip" -o -n "$name" ] || return 0
  237. config_get_bool dns "$cfg" dns 0
  238. [ "$dns" = "1" -a -n "$ip" -a -n "$name" ] && {
  239. echo "$ip $name${DOMAIN:+.$DOMAIN}" >> $HOSTFILE
  240. }
  241. config_get mac "$cfg" mac
  242. if [ -n "$mac" ]; then
  243. # --dhcp-host=00:20:e0:3b:13:af,192.168.0.199,lap
  244. macs=""
  245. for m in $mac; do append macs "$m" ","; done
  246. else
  247. # --dhcp-host=lap,192.168.0.199
  248. [ -n "$name" ] || return 0
  249. macs="$name"
  250. name=""
  251. fi
  252. config_get tag "$cfg" tag
  253. config_get_bool broadcast "$cfg" broadcast 0
  254. [ "$broadcast" = "0" ] && broadcast=
  255. xappend "--dhcp-host=$macs${networkid:+,net:$networkid}${broadcast:+,set:needs-broadcast}${tag:+,set:$tag}${ip:+,$ip}${name:+,$name}"
  256. }
  257. dhcp_tag_add() {
  258. local cfg="$1"
  259. tag="$cfg"
  260. [ -n "$tag" ] || return 0
  261. config_get_bool force "$cfg" force 0
  262. [ "$force" = "0" ] && force=
  263. config_get option "$cfg" dhcp_option
  264. for o in $option; do
  265. xappend "--dhcp-option${force:+-force}=tag:$tag,$o"
  266. done
  267. }
  268. dhcp_mac_add() {
  269. local cfg="$1"
  270. config_get networkid "$cfg" networkid
  271. [ -n "$networkid" ] || return 0
  272. config_get mac "$cfg" mac
  273. [ -n "$mac" ] || return 0
  274. xappend "--dhcp-mac=$networkid,$mac"
  275. dhcp_option_add "$cfg" "$networkid"
  276. }
  277. dhcp_boot_add() {
  278. local cfg="$1"
  279. config_get networkid "$cfg" networkid
  280. config_get filename "$cfg" filename
  281. [ -n "$filename" ] || return 0
  282. config_get servername "$cfg" servername
  283. config_get serveraddress "$cfg" serveraddress
  284. [ -n "$serveraddress" -a ! -n "$servername" ] && return 0
  285. xappend "--dhcp-boot=${networkid:+net:$networkid,}${filename}${servername:+,$servername}${serveraddress:+,$serveraddress}"
  286. config_get_bool force "$cfg" force 0
  287. dhcp_option_add "$cfg" "$networkid" "$force"
  288. }
  289. dhcp_add() {
  290. local cfg="$1"
  291. config_get net "$cfg" interface
  292. [ -n "$net" ] || return 0
  293. config_get dhcpv4 "$cfg" dhcpv4
  294. [ "$dhcpv4" != "disabled" ] || return 0
  295. config_get networkid "$cfg" networkid
  296. [ -n "$networkid" ] || networkid="$net"
  297. network_get_subnet subnet "$net" || return 0
  298. network_get_device ifname "$net" || return 0
  299. network_get_protocol proto "$net" || return 0
  300. [ "$cachelocal" = "0" ] && network_get_dnsserver dnsserver "$net" && {
  301. DNS_SERVERS="$DNS_SERVERS $dnsserver"
  302. }
  303. append_bool "$cfg" ignore "--no-dhcp-interface=$ifname" && return 0
  304. # Do not support non-static interfaces for now
  305. [ static = "$proto" ] || return 0
  306. # Override interface netmask with dhcp config if applicable
  307. config_get netmask "$cfg" netmask "${subnet##*/}"
  308. #check for an already active dhcp server on the interface, unless 'force' is set
  309. config_get_bool force "$cfg" force 0
  310. [ $force -gt 0 ] || dhcp_check "$ifname" || return 0
  311. config_get start "$cfg" start
  312. config_get limit "$cfg" limit
  313. config_get leasetime "$cfg" leasetime
  314. config_get options "$cfg" options
  315. config_get_bool dynamicdhcp "$cfg" dynamicdhcp 1
  316. leasetime="${leasetime:-12h}"
  317. start="$(dhcp_calc "${start:-100}")"
  318. limit="${limit:-150}"
  319. [ "$limit" -gt 0 ] && limit=$((limit-1))
  320. eval "$(ipcalc.sh "${subnet%%/*}" $netmask $start $limit)"
  321. if [ "$dynamicdhcp" = "0" ]; then END="static"; fi
  322. xappend "--dhcp-range=$networkid,$START,$END,$NETMASK,$leasetime${options:+ $options}"
  323. dhcp_option_add "$cfg" "$networkid"
  324. }
  325. dhcp_option_add() {
  326. local cfg="$1"
  327. local networkid="$2"
  328. local force="$3"
  329. [ "$force" = "0" ] && force=
  330. config_get dhcp_option "$cfg" dhcp_option
  331. for o in $dhcp_option; do
  332. xappend "--dhcp-option${force:+-force}=${networkid:+$networkid,}$o"
  333. done
  334. }
  335. dhcp_domain_add() {
  336. local cfg="$1"
  337. local ip name names record
  338. config_get names "$cfg" name "$2"
  339. [ -n "$names" ] || return 0
  340. config_get ip "$cfg" ip "$3"
  341. [ -n "$ip" ] || return 0
  342. for name in $names; do
  343. record="${record:+$record }$name"
  344. done
  345. echo "$ip $record" >> $HOSTFILE
  346. }
  347. dhcp_srv_add() {
  348. local cfg="$1"
  349. config_get srv "$cfg" srv
  350. [ -n "$srv" ] || return 0
  351. config_get target "$cfg" target
  352. [ -n "$target" ] || return 0
  353. config_get port "$cfg" port
  354. [ -n "$port" ] || return 0
  355. config_get class "$cfg" class
  356. config_get weight "$cfg" weight
  357. local service="$srv,$target,$port${class:+,$class${weight:+,$weight}}"
  358. xappend "--srv-host=$service"
  359. }
  360. dhcp_mx_add() {
  361. local cfg="$1"
  362. local domain relay pref
  363. config_get domain "$cfg" domain
  364. [ -n "$domain" ] || return 0
  365. config_get relay "$cfg" relay
  366. [ -n "$relay" ] || return 0
  367. config_get pref "$cfg" pref 0
  368. local service="$domain,$relay,$pref"
  369. xappend "--mx-host=$service"
  370. }
  371. dhcp_cname_add() {
  372. local cfg="$1"
  373. local cname target
  374. config_get cname "$cfg" cname
  375. [ -n "$cname" ] || return 0
  376. config_get target "$cfg" target
  377. [ -n "$target" ] || return 0
  378. xappend "--cname=${cname},${target}"
  379. }
  380. dhcp_hostrecord_add() {
  381. local cfg="$1"
  382. local names addresses record val
  383. config_get names "$cfg" name "$2"
  384. if [ -z "$names" ]; then
  385. return 0
  386. fi
  387. config_get addresses "$cfg" ip "$3"
  388. if [ -z "$addresses" ]; then
  389. return 0
  390. fi
  391. for val in $names $addresses; do
  392. record="${record:+$record,}$val"
  393. done
  394. xappend "--host-record=$record"
  395. }
  396. service_triggers()
  397. {
  398. procd_add_reload_trigger "dhcp"
  399. }
  400. boot() {
  401. # Will be launched through hotplug
  402. return 0
  403. }
  404. start_service() {
  405. include /lib/functions
  406. config_load dhcp
  407. procd_open_instance
  408. procd_set_param command $PROG -C $CONFIGFILE -k -x /var/run/dnsmasq/dnsmasq.pid
  409. procd_set_param file $CONFIGFILE
  410. procd_set_param respawn
  411. procd_add_jail dnsmasq ubus log
  412. 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
  413. procd_add_jail_mount_rw /var/run/dnsmasq/ /tmp/dhcp.leases $TIMESTAMPFILE
  414. procd_close_instance
  415. # before we can call xappend
  416. mkdir -p /var/run/dnsmasq/
  417. mkdir -p $(dirname $CONFIGFILE)
  418. mkdir -p /var/lib/misc
  419. touch /tmp/dhcp.leases
  420. if [ ! -f "$TIMESTAMPFILE" ]; then
  421. touch "$TIMESTAMPFILE"
  422. chown nobody.nogroup "$TIMESTAMPFILE"
  423. fi
  424. echo "# auto-generated config file from /etc/config/dhcp" > $CONFIGFILE
  425. echo "# auto-generated config file from /etc/config/dhcp" > $HOSTFILE
  426. # if we did this last, we could override auto-generated config
  427. [ -f /etc/dnsmasq.conf ] && {
  428. xappend "--conf-file=/etc/dnsmasq.conf"
  429. }
  430. args=""
  431. config_foreach dnsmasq dnsmasq
  432. config_foreach dhcp_host_add host
  433. echo >> $CONFIGFILE
  434. config_foreach dhcp_boot_add boot
  435. config_foreach dhcp_mac_add mac
  436. config_foreach dhcp_tag_add tag
  437. config_foreach dhcp_vendorclass_add vendorclass
  438. config_foreach dhcp_userclass_add userclass
  439. config_foreach dhcp_circuitid_add circuitid
  440. config_foreach dhcp_remoteid_add remoteid
  441. config_foreach dhcp_subscrid_add subscrid
  442. config_foreach dhcp_domain_add domain
  443. config_foreach dhcp_hostrecord_add hostrecord
  444. # add own hostname
  445. local lanaddr
  446. [ $ADD_LOCAL_HOSTNAME -eq 1 ] && network_get_ipaddr lanaddr "lan" && {
  447. local hostname="$(uci_get system @system[0] hostname OpenWrt)"
  448. dhcp_domain_add "" "$hostname" "$lanaddr"
  449. }
  450. echo >> $CONFIGFILE
  451. config_foreach dhcp_srv_add srvhost
  452. config_foreach dhcp_mx_add mxhost
  453. echo >> $CONFIGFILE
  454. config_get odhcpd_is_active odhcpd maindhcp
  455. if [ "$odhcpd_is_active" != "1" ]; then
  456. config_foreach dhcp_add dhcp
  457. fi
  458. echo >> $CONFIGFILE
  459. config_foreach dhcp_cname_add cname
  460. echo >> $CONFIGFILE
  461. rm -f /tmp/resolv.conf
  462. [ $ADD_LOCAL_DOMAIN -eq 1 ] && [ -n "$DOMAIN" ] && {
  463. echo "search $DOMAIN" >> /tmp/resolv.conf
  464. }
  465. DNS_SERVERS="$DNS_SERVERS 127.0.0.1"
  466. for DNS_SERVER in $DNS_SERVERS ; do
  467. echo "nameserver $DNS_SERVER" >> /tmp/resolv.conf
  468. done
  469. }
  470. reload_service() {
  471. rc_procd start_service "$@"
  472. return 0
  473. }
  474. stop_service() {
  475. [ -f /tmp/resolv.conf ] && {
  476. rm -f /tmp/resolv.conf
  477. ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
  478. }
  479. rm -f /var/run/dnsmasq.*.dhcp
  480. }