dnsmasq.init 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  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=extra"
  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_bool "$cfg" sequential_ip "--dhcp-sequential-ip"
  113. append_parm "$cfg" dhcpscript "--dhcp-script"
  114. append_parm "$cfg" cachesize "--cache-size"
  115. append_parm "$cfg" dnsforwardmax "--dns-forward-max"
  116. append_parm "$cfg" port "--port"
  117. append_parm "$cfg" ednspacket_max "--edns-packet-max"
  118. append_parm "$cfg" dhcpleasemax "--dhcp-lease-max"
  119. append_parm "$cfg" "queryport" "--query-port"
  120. append_parm "$cfg" "domain" "--domain"
  121. append_parm "$cfg" "local" "--server"
  122. config_list_foreach "$cfg" "server" append_server
  123. config_list_foreach "$cfg" "address" append_address
  124. config_list_foreach "$cfg" "ipset" append_ipset
  125. config_list_foreach "$cfg" "interface" append_interface
  126. config_list_foreach "$cfg" "notinterface" append_notinterface
  127. config_list_foreach "$cfg" "addnhosts" append_addnhosts
  128. config_list_foreach "$cfg" "bogusnxdomain" append_bogusnxdomain
  129. append_parm "$cfg" "leasefile" "--dhcp-leasefile"
  130. append_parm "$cfg" "resolvfile" "--resolv-file"
  131. append_parm "$cfg" "serversfile" "--servers-file"
  132. append_parm "$cfg" "tftp_root" "--tftp-root"
  133. append_parm "$cfg" "dhcp_boot" "--dhcp-boot"
  134. append_parm "$cfg" "local_ttl" "--local-ttl"
  135. append_parm "$cfg" "pxe_prompt" "--pxe-prompt"
  136. config_list_foreach "$cfg" "pxe_service" append_pxe_service
  137. config_get DOMAIN "$cfg" domain
  138. config_get_bool ADD_LOCAL_DOMAIN "$cfg" add_local_domain 1
  139. config_get_bool ADD_LOCAL_HOSTNAME "$cfg" add_local_hostname 1
  140. config_get_bool readethers "$cfg" readethers
  141. [ "$readethers" = "1" -a \! -e "/etc/ethers" ] && touch /etc/ethers
  142. config_get leasefile $cfg leasefile
  143. [ -n "$leasefile" -a \! -e "$leasefile" ] && touch "$leasefile"
  144. config_get_bool cachelocal "$cfg" cachelocal 1
  145. config_get hostsfile "$cfg" dhcphostsfile
  146. [ -e "$hostsfile" ] && xappend "--dhcp-hostsfile=$hostsfile"
  147. mkdir -p /tmp/hosts /tmp/dnsmasq.d
  148. xappend "--addn-hosts=/tmp/hosts"
  149. xappend "--conf-dir=/tmp/dnsmasq.d"
  150. local rebind
  151. config_get_bool rebind "$cfg" rebind_protection 1
  152. [ $rebind -gt 0 ] && {
  153. log_once \
  154. "DNS rebinding protection is active," \
  155. "will discard upstream RFC1918 responses!"
  156. xappend "--stop-dns-rebind"
  157. local rebind_localhost
  158. config_get_bool rebind_localhost "$cfg" rebind_localhost 0
  159. [ $rebind_localhost -gt 0 ] && {
  160. log_once "Allowing 127.0.0.0/8 responses"
  161. xappend "--rebind-localhost-ok"
  162. }
  163. append_rebind_domain() {
  164. log_once "Allowing RFC1918 responses for domain $1"
  165. xappend "--rebind-domain-ok=$1"
  166. }
  167. config_list_foreach "$cfg" rebind_domain append_rebind_domain
  168. }
  169. config_get_bool dnssec "$cfg" dnssec 0
  170. [ "$dnssec" -gt 0 ] && {
  171. xappend "--conf-file=$TRUSTANCHORSFILE"
  172. xappend "--dnssec"
  173. xappend "--dnssec-timestamp=$TIMESTAMPFILE"
  174. append_bool "$cfg" dnsseccheckunsigned "--dnssec-check-unsigned"
  175. }
  176. dhcp_option_add "$cfg" "" 0
  177. xappend "--dhcp-broadcast=tag:needs-broadcast"
  178. echo >> $CONFIGFILE
  179. }
  180. dhcp_subscrid_add() {
  181. local cfg="$1"
  182. config_get networkid "$cfg" networkid
  183. [ -n "$networkid" ] || return 0
  184. config_get subscriberid "$cfg" subscriberid
  185. [ -n "$subscriberid" ] || return 0
  186. xappend "--dhcp-subscrid=$networkid,$subscriberid"
  187. config_get_bool force "$cfg" force 0
  188. dhcp_option_add "$cfg" "$networkid" "$force"
  189. }
  190. dhcp_remoteid_add() {
  191. local cfg="$1"
  192. config_get networkid "$cfg" networkid
  193. [ -n "$networkid" ] || return 0
  194. config_get remoteid "$cfg" remoteid
  195. [ -n "$remoteid" ] || return 0
  196. xappend "--dhcp-remoteid=$networkid,$remoteid"
  197. config_get_bool force "$cfg" force 0
  198. dhcp_option_add "$cfg" "$networkid" "$force"
  199. }
  200. dhcp_circuitid_add() {
  201. local cfg="$1"
  202. config_get networkid "$cfg" networkid
  203. [ -n "$networkid" ] || return 0
  204. config_get circuitid "$cfg" circuitid
  205. [ -n "$circuitid" ] || return 0
  206. xappend "--dhcp-circuitid=$networkid,$circuitid"
  207. config_get_bool force "$cfg" force 0
  208. dhcp_option_add "$cfg" "$networkid" "$force"
  209. }
  210. dhcp_userclass_add() {
  211. local cfg="$1"
  212. config_get networkid "$cfg" networkid
  213. [ -n "$networkid" ] || return 0
  214. config_get userclass "$cfg" userclass
  215. [ -n "$userclass" ] || return 0
  216. xappend "--dhcp-userclass=$networkid,$userclass"
  217. config_get_bool force "$cfg" force 0
  218. dhcp_option_add "$cfg" "$networkid" "$force"
  219. }
  220. dhcp_vendorclass_add() {
  221. local cfg="$1"
  222. config_get networkid "$cfg" networkid
  223. [ -n "$networkid" ] || return 0
  224. config_get vendorclass "$cfg" vendorclass
  225. [ -n "$vendorclass" ] || return 0
  226. xappend "--dhcp-vendorclass=$networkid,$vendorclass"
  227. config_get_bool force "$cfg" force 0
  228. dhcp_option_add "$cfg" "$networkid" "$force"
  229. }
  230. dhcp_host_add() {
  231. local cfg="$1"
  232. config_get_bool force "$cfg" force 0
  233. config_get networkid "$cfg" networkid
  234. [ -n "$networkid" ] && dhcp_option_add "$cfg" "$networkid" "$force"
  235. config_get name "$cfg" name
  236. config_get ip "$cfg" ip
  237. [ -n "$ip" -o -n "$name" ] || return 0
  238. config_get_bool dns "$cfg" dns 0
  239. [ "$dns" = "1" -a -n "$ip" -a -n "$name" ] && {
  240. echo "$ip $name${DOMAIN:+.$DOMAIN}" >> $HOSTFILE
  241. }
  242. config_get mac "$cfg" mac
  243. if [ -n "$mac" ]; then
  244. # --dhcp-host=00:20:e0:3b:13:af,192.168.0.199,lap
  245. macs=""
  246. for m in $mac; do append macs "$m" ","; done
  247. else
  248. # --dhcp-host=lap,192.168.0.199
  249. [ -n "$name" ] || return 0
  250. macs="$name"
  251. name=""
  252. fi
  253. config_get tag "$cfg" tag
  254. config_get_bool broadcast "$cfg" broadcast 0
  255. [ "$broadcast" = "0" ] && broadcast=
  256. xappend "--dhcp-host=$macs${networkid:+,net:$networkid}${broadcast:+,set:needs-broadcast}${tag:+,set:$tag}${ip:+,$ip}${name:+,$name}"
  257. }
  258. dhcp_tag_add() {
  259. local cfg="$1"
  260. tag="$cfg"
  261. [ -n "$tag" ] || return 0
  262. config_get_bool force "$cfg" force 0
  263. [ "$force" = "0" ] && force=
  264. config_get option "$cfg" dhcp_option
  265. for o in $option; do
  266. xappend "--dhcp-option${force:+-force}=tag:$tag,$o"
  267. done
  268. }
  269. dhcp_mac_add() {
  270. local cfg="$1"
  271. config_get networkid "$cfg" networkid
  272. [ -n "$networkid" ] || return 0
  273. config_get mac "$cfg" mac
  274. [ -n "$mac" ] || return 0
  275. xappend "--dhcp-mac=$networkid,$mac"
  276. dhcp_option_add "$cfg" "$networkid"
  277. }
  278. dhcp_boot_add() {
  279. local cfg="$1"
  280. config_get networkid "$cfg" networkid
  281. config_get filename "$cfg" filename
  282. [ -n "$filename" ] || return 0
  283. config_get servername "$cfg" servername
  284. config_get serveraddress "$cfg" serveraddress
  285. [ -n "$serveraddress" -a ! -n "$servername" ] && return 0
  286. xappend "--dhcp-boot=${networkid:+net:$networkid,}${filename}${servername:+,$servername}${serveraddress:+,$serveraddress}"
  287. config_get_bool force "$cfg" force 0
  288. dhcp_option_add "$cfg" "$networkid" "$force"
  289. }
  290. dhcp_add() {
  291. local cfg="$1"
  292. config_get net "$cfg" interface
  293. [ -n "$net" ] || return 0
  294. config_get dhcpv4 "$cfg" dhcpv4
  295. [ "$dhcpv4" != "disabled" ] || return 0
  296. config_get networkid "$cfg" networkid
  297. [ -n "$networkid" ] || networkid="$net"
  298. network_get_subnet subnet "$net" || return 0
  299. network_get_device ifname "$net" || return 0
  300. network_get_protocol proto "$net" || return 0
  301. [ "$cachelocal" = "0" ] && network_get_dnsserver dnsserver "$net" && {
  302. DNS_SERVERS="$DNS_SERVERS $dnsserver"
  303. }
  304. append_bool "$cfg" ignore "--no-dhcp-interface=$ifname" && return 0
  305. # Do not support non-static interfaces for now
  306. [ static = "$proto" ] || return 0
  307. # Override interface netmask with dhcp config if applicable
  308. config_get netmask "$cfg" netmask "${subnet##*/}"
  309. #check for an already active dhcp server on the interface, unless 'force' is set
  310. config_get_bool force "$cfg" force 0
  311. [ $force -gt 0 ] || dhcp_check "$ifname" || return 0
  312. config_get start "$cfg" start
  313. config_get limit "$cfg" limit
  314. config_get leasetime "$cfg" leasetime
  315. config_get options "$cfg" options
  316. config_get_bool dynamicdhcp "$cfg" dynamicdhcp 1
  317. leasetime="${leasetime:-12h}"
  318. start="$(dhcp_calc "${start:-100}")"
  319. limit="${limit:-150}"
  320. [ "$limit" -gt 0 ] && limit=$((limit-1))
  321. eval "$(ipcalc.sh "${subnet%%/*}" $netmask $start $limit)"
  322. if [ "$dynamicdhcp" = "0" ]; then END="static"; fi
  323. xappend "--dhcp-range=$networkid,$START,$END,$NETMASK,$leasetime${options:+ $options}"
  324. dhcp_option_add "$cfg" "$networkid"
  325. }
  326. dhcp_option_add() {
  327. local cfg="$1"
  328. local networkid="$2"
  329. local force="$3"
  330. [ "$force" = "0" ] && force=
  331. config_get dhcp_option "$cfg" dhcp_option
  332. for o in $dhcp_option; do
  333. xappend "--dhcp-option${force:+-force}=${networkid:+$networkid,}$o"
  334. done
  335. }
  336. dhcp_domain_add() {
  337. local cfg="$1"
  338. local ip name names record
  339. config_get names "$cfg" name "$2"
  340. [ -n "$names" ] || return 0
  341. config_get ip "$cfg" ip "$3"
  342. [ -n "$ip" ] || return 0
  343. for name in $names; do
  344. record="${record:+$record }$name"
  345. done
  346. echo "$ip $record" >> $HOSTFILE
  347. }
  348. dhcp_srv_add() {
  349. local cfg="$1"
  350. config_get srv "$cfg" srv
  351. [ -n "$srv" ] || return 0
  352. config_get target "$cfg" target
  353. [ -n "$target" ] || return 0
  354. config_get port "$cfg" port
  355. [ -n "$port" ] || return 0
  356. config_get class "$cfg" class
  357. config_get weight "$cfg" weight
  358. local service="$srv,$target,$port${class:+,$class${weight:+,$weight}}"
  359. xappend "--srv-host=$service"
  360. }
  361. dhcp_mx_add() {
  362. local cfg="$1"
  363. local domain relay pref
  364. config_get domain "$cfg" domain
  365. [ -n "$domain" ] || return 0
  366. config_get relay "$cfg" relay
  367. [ -n "$relay" ] || return 0
  368. config_get pref "$cfg" pref 0
  369. local service="$domain,$relay,$pref"
  370. xappend "--mx-host=$service"
  371. }
  372. dhcp_cname_add() {
  373. local cfg="$1"
  374. local cname target
  375. config_get cname "$cfg" cname
  376. [ -n "$cname" ] || return 0
  377. config_get target "$cfg" target
  378. [ -n "$target" ] || return 0
  379. xappend "--cname=${cname},${target}"
  380. }
  381. dhcp_hostrecord_add() {
  382. local cfg="$1"
  383. local names addresses record val
  384. config_get names "$cfg" name "$2"
  385. if [ -z "$names" ]; then
  386. return 0
  387. fi
  388. config_get addresses "$cfg" ip "$3"
  389. if [ -z "$addresses" ]; then
  390. return 0
  391. fi
  392. for val in $names $addresses; do
  393. record="${record:+$record,}$val"
  394. done
  395. xappend "--host-record=$record"
  396. }
  397. service_triggers()
  398. {
  399. procd_add_reload_trigger "dhcp"
  400. }
  401. boot() {
  402. # Will be launched through hotplug
  403. return 0
  404. }
  405. start_service() {
  406. include /lib/functions
  407. config_load dhcp
  408. procd_open_instance
  409. procd_set_param command $PROG -C $CONFIGFILE -k -x /var/run/dnsmasq/dnsmasq.pid
  410. procd_set_param file $CONFIGFILE
  411. procd_set_param respawn
  412. procd_add_jail dnsmasq ubus log
  413. 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
  414. procd_add_jail_mount_rw /var/run/dnsmasq/ /tmp/dhcp.leases $TIMESTAMPFILE
  415. procd_close_instance
  416. # before we can call xappend
  417. mkdir -p /var/run/dnsmasq/
  418. mkdir -p $(dirname $CONFIGFILE)
  419. mkdir -p /var/lib/misc
  420. touch /tmp/dhcp.leases
  421. if [ ! -f "$TIMESTAMPFILE" ]; then
  422. touch "$TIMESTAMPFILE"
  423. chown nobody.nogroup "$TIMESTAMPFILE"
  424. fi
  425. echo "# auto-generated config file from /etc/config/dhcp" > $CONFIGFILE
  426. echo "# auto-generated config file from /etc/config/dhcp" > $HOSTFILE
  427. # if we did this last, we could override auto-generated config
  428. [ -f /etc/dnsmasq.conf ] && {
  429. xappend "--conf-file=/etc/dnsmasq.conf"
  430. }
  431. args=""
  432. config_foreach dnsmasq dnsmasq
  433. config_foreach dhcp_host_add host
  434. echo >> $CONFIGFILE
  435. config_foreach dhcp_boot_add boot
  436. config_foreach dhcp_mac_add mac
  437. config_foreach dhcp_tag_add tag
  438. config_foreach dhcp_vendorclass_add vendorclass
  439. config_foreach dhcp_userclass_add userclass
  440. config_foreach dhcp_circuitid_add circuitid
  441. config_foreach dhcp_remoteid_add remoteid
  442. config_foreach dhcp_subscrid_add subscrid
  443. config_foreach dhcp_domain_add domain
  444. config_foreach dhcp_hostrecord_add hostrecord
  445. # add own hostname
  446. local lanaddr
  447. [ $ADD_LOCAL_HOSTNAME -eq 1 ] && network_get_ipaddr lanaddr "lan" && {
  448. local hostname="$(uci_get system @system[0] hostname libreCMC)"
  449. dhcp_domain_add "" "$hostname" "$lanaddr"
  450. }
  451. echo >> $CONFIGFILE
  452. config_foreach dhcp_srv_add srvhost
  453. config_foreach dhcp_mx_add mxhost
  454. echo >> $CONFIGFILE
  455. config_get odhcpd_is_active odhcpd maindhcp
  456. if [ "$odhcpd_is_active" != "1" ]; then
  457. config_foreach dhcp_add dhcp
  458. fi
  459. echo >> $CONFIGFILE
  460. config_foreach dhcp_cname_add cname
  461. echo >> $CONFIGFILE
  462. rm -f /tmp/resolv.conf
  463. [ $ADD_LOCAL_DOMAIN -eq 1 ] && [ -n "$DOMAIN" ] && {
  464. echo "search $DOMAIN" >> /tmp/resolv.conf
  465. }
  466. DNS_SERVERS="$DNS_SERVERS 127.0.0.1"
  467. for DNS_SERVER in $DNS_SERVERS ; do
  468. echo "nameserver $DNS_SERVER" >> /tmp/resolv.conf
  469. done
  470. }
  471. reload_service() {
  472. rc_procd start_service "$@"
  473. return 0
  474. }
  475. stop_service() {
  476. [ -f /tmp/resolv.conf ] && {
  477. rm -f /tmp/resolv.conf
  478. ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
  479. }
  480. rm -f /var/run/dnsmasq.*.dhcp
  481. }