From b29e9ad9792c68a9a59bd5b9be73d9d9fc5f35b0 Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Fri, 13 Oct 2017 22:25:22 +0800 Subject: [PATCH] update dnsmasq to 2.78 for CVE fix --- package/network/services/dnsmasq/Makefile | 24 +- .../services/dnsmasq/files/dhcp-script.sh | 46 ++ .../network/services/dnsmasq/files/dhcp.conf | 2 +- .../services/dnsmasq/files/dnsmasq.init | 428 ++++++++++++++---- .../services/dnsmasq/files/dnsmasq_acl.json | 4 + .../services/dnsmasq/files/dnsmasqsec.hotplug | 6 +- .../services/dnsmasq/files/rfc6761.conf | 15 + .../100-fix-dhcp-no-address-warning.patch | 47 -- .../110-ipset-remove-old-kernel-support.patch | 69 +-- ...20-dnsmasq-compile-time-option-NO_ID.patch | 149 ------ ...0-dnssec-improve-timestamp-heuristic.patch | 12 +- ...0-fix-poll-h-include-warning-on-musl.patch | 2 +- .../services/dnsmasq/patches/240-ubus.patch | 126 ++++++ 13 files changed, 574 insertions(+), 356 deletions(-) create mode 100755 package/network/services/dnsmasq/files/dhcp-script.sh create mode 100644 package/network/services/dnsmasq/files/dnsmasq_acl.json create mode 100644 package/network/services/dnsmasq/files/rfc6761.conf delete mode 100644 package/network/services/dnsmasq/patches/100-fix-dhcp-no-address-warning.patch delete mode 100644 package/network/services/dnsmasq/patches/120-dnsmasq-compile-time-option-NO_ID.patch create mode 100644 package/network/services/dnsmasq/patches/240-ubus.patch diff --git a/package/network/services/dnsmasq/Makefile b/package/network/services/dnsmasq/Makefile index 29079795c..33644e8e5 100644 --- a/package/network/services/dnsmasq/Makefile +++ b/package/network/services/dnsmasq/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dnsmasq -PKG_VERSION:=2.76 -PKG_RELEASE:=12 +PKG_VERSION:=2.78 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz -PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq -PKG_MD5SUM:=00f5ee66b4e4b7f14538bf62ae3c9461 +PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq/ +PKG_HASH:=89949f438c74b0c7543f06689c319484bd126cc4b1f8c745c742ab397681252b PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:=COPYING @@ -37,6 +37,7 @@ define Package/dnsmasq/Default CATEGORY:=Base system TITLE:=DNS and DHCP server URL:=http://www.thekelleys.org.uk/dnsmasq/ + DEPENDS:=+libubus USERID:=dnsmasq=453:dnsmasq=453 endef @@ -48,14 +49,14 @@ endef define Package/dnsmasq-dhcpv6 $(call Package/dnsmasq/Default) TITLE += (with DHCPv6 support) - DEPENDS:=@IPV6 + DEPENDS+=@IPV6 VARIANT:=dhcpv6 endef define Package/dnsmasq-full $(call Package/dnsmasq/Default) TITLE += (with DNSSEC, DHCPv6, Auth DNS, IPset, Conntrack, NO_ID enabled by default) - DEPENDS:=+PACKAGE_dnsmasq_full_dnssec:libnettle \ + DEPENDS+=+PACKAGE_dnsmasq_full_dnssec:libnettle \ +PACKAGE_dnsmasq_full_ipset:kmod-ipt-ipset \ +PACKAGE_dnsmasq_full_conntrack:libnetfilter-conntrack VARIANT:=full @@ -137,7 +138,7 @@ endif MAKE_FLAGS := \ $(TARGET_CONFIGURE_OPTS) \ - CFLAGS="$(TARGET_CFLAGS)" \ + CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS)" \ LDFLAGS="$(TARGET_LDFLAGS)" \ COPTS="$(COPTS)" \ PREFIX="/usr" @@ -150,8 +151,17 @@ define Package/dnsmasq/install $(INSTALL_DATA) ./files/dnsmasq.conf $(1)/etc/dnsmasq.conf $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/dnsmasq.init $(1)/etc/init.d/dnsmasq + $(INSTALL_DIR) $(1)/etc/hotplug.d/dhcp + $(INSTALL_DIR) $(1)/etc/hotplug.d/neigh $(INSTALL_DIR) $(1)/etc/hotplug.d/ntp + $(INSTALL_DIR) $(1)/etc/hotplug.d/tftp $(INSTALL_DATA) ./files/dnsmasqsec.hotplug $(1)/etc/hotplug.d/ntp/25-dnsmasqsec + $(INSTALL_DIR) $(1)/usr/share/dnsmasq + $(INSTALL_DATA) ./files/rfc6761.conf $(1)/usr/share/dnsmasq/ + $(INSTALL_DIR) $(1)/usr/lib/dnsmasq + $(INSTALL_BIN) ./files/dhcp-script.sh $(1)/usr/lib/dnsmasq/dhcp-script.sh + $(INSTALL_DIR) $(1)/usr/share/acl.d + $(INSTALL_DATA) ./files/dnsmasq_acl.json $(1)/usr/share/acl.d/ endef Package/dnsmasq-dhcpv6/install = $(Package/dnsmasq/install) diff --git a/package/network/services/dnsmasq/files/dhcp-script.sh b/package/network/services/dnsmasq/files/dhcp-script.sh new file mode 100755 index 000000000..86032694c --- /dev/null +++ b/package/network/services/dnsmasq/files/dhcp-script.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +[ -f "$USER_DHCPSCRIPT" ] && . "$USER_DHCPSCRIPT" "$@" + +case "$1" in + add) + export ACTION="add" + export MACADDR="$2" + export IPADDR="$3" + export HOSTNAME="$4" + exec /sbin/hotplug-call dhcp + ;; + del) + export ACTION="remove" + export MACADDR="$2" + export IPADDR="$3" + export HOSTNAME="$4" + exec /sbin/hotplug-call dhcp + ;; + old) + export ACTION="update" + export MACADDR="$2" + export IPADDR="$3" + export HOSTNAME="$4" + exec /sbin/hotplug-call dhcp + ;; + arp-add) + export ACTION="add" + export MACADDR="$2" + export IPADDR="$3" + exec /sbin/hotplug-call neigh + ;; + arp-del) + export ACTION="remove" + export MACADDR="$2" + export IPADDR="$3" + exec /sbin/hotplug-call neigh + ;; + tftp) + export ACTION="add" + export TFTP_SIZE="$2" + export TFTP_ADDR="$3" + export TFTP_PATH="$4" + exec /sbin/hotplug-call tftp + ;; +esac diff --git a/package/network/services/dnsmasq/files/dhcp.conf b/package/network/services/dnsmasq/files/dhcp.conf index 362b90a29..360c7d79e 100644 --- a/package/network/services/dnsmasq/files/dhcp.conf +++ b/package/network/services/dnsmasq/files/dhcp.conf @@ -15,7 +15,7 @@ config dnsmasq option leasefile '/tmp/dhcp.leases' option resolvfile '/tmp/resolv.conf.auto' #list server '/mycompany.local/1.2.3.4' - #option nonwildcard 1 + option nonwildcard 1 # bind to & keep track of interfaces #list interface br-lan #list notinterface lo #list bogusnxdomain '64.94.110.11' diff --git a/package/network/services/dnsmasq/files/dnsmasq.init b/package/network/services/dnsmasq/files/dnsmasq.init index b1f9e2e29..014964395 100644 --- a/package/network/services/dnsmasq/files/dnsmasq.init +++ b/package/network/services/dnsmasq/files/dnsmasq.init @@ -8,6 +8,8 @@ PROG=/usr/sbin/dnsmasq ADD_LOCAL_DOMAIN=1 ADD_LOCAL_HOSTNAME=1 +ADD_WAN_FQDN=0 +ADD_LOCAL_FQDN="" BASECONFIGFILE="/var/etc/dnsmasq.conf" BASEHOSTFILE="/tmp/hosts/dhcp" @@ -15,6 +17,10 @@ BASETIMESTAMPFILE="/etc/dnsmasq.time" TRUSTANCHORSFILE="/usr/share/dnsmasq/trust-anchors.conf" TIMEVALIDFILE="/var/state/dnsmasqsec" BASEDHCPSTAMPFILE="/var/run/dnsmasq" +RFC6761FILE="/usr/share/dnsmasq/rfc6761.conf" +DHCPSCRIPT="/usr/lib/dnsmasq/dhcp-script.sh" + +DNSMASQ_DHCP_VER=4 xappend() { local value="$1" @@ -23,22 +29,22 @@ xappend() { } hex_to_hostid() { - local var="$1" - local hex="${2#0x}" # strip optional "0x" prefix + local var="$1" + local hex="${2#0x}" # strip optional "0x" prefix - if [ -n "${hex//[0-9a-fA-F]/}" ]; then - # is invalid hex literal - return 1 - fi + if [ -n "${hex//[0-9a-fA-F]/}" ]; then + # is invalid hex literal + return 1 + fi - # convert into host id - export "$var=$( - printf "%0x:%0x" \ - $(((0x$hex >> 16) % 65536)) \ - $(( 0x$hex % 256)) - )" + # convert into host id + export "$var=$( + printf "%0x:%0x" \ + $(((0x$hex >> 16) % 65536)) \ + $(( 0x$hex % 65536)) + )" - return 0 + return 0 } dhcp_calc() { @@ -83,12 +89,24 @@ log_once() { logger -t dnsmasq "$@" } +has_handler() { + local file + + for file in /etc/hotplug.d/dhcp/* /etc/hotplug.d/tftp/* /etc/hotplug.d/neigh/*; do + [ -f "$file" ] && return 0 + done + + return 1 +} + append_bool() { local section="$1" local option="$2" local value="$3" + local default="$4" local _loctmp - config_get_bool _loctmp "$section" "$option" 0 + [ -z "$default" ] && default="0" + config_get_bool _loctmp "$section" "$option" "$default" [ $_loctmp -gt 0 ] && xappend "$value" } @@ -107,6 +125,10 @@ append_server() { xappend "--server=$1" } +append_rev_server() { + xappend "--rev-server=$1" +} + append_address() { xappend "--address=$1" } @@ -116,12 +138,12 @@ append_ipset() { } append_interface() { - network_get_device ifname "$1" || return + network_get_device ifname "$1" || ifname="$1" xappend "--interface=$ifname" } append_notinterface() { - network_get_device ifname "$1" || return + network_get_device ifname "$1" || ifname="$1" xappend "--except-interface=$ifname" } @@ -137,6 +159,10 @@ append_pxe_service() { xappend "--pxe-service=$1" } +append_interface_name() { + xappend "--interface-name=$1,$2" +} + filter_dnsmasq() { local cfg="$1" func="$2" match_cfg="$3" found_cfg @@ -180,6 +206,7 @@ dhcp_remoteid_add() { } dhcp_circuitid_add() { + # TODO: DHCPV6 does not have circuitid; catch "option6:" local cfg="$1" config_get networkid "$cfg" networkid @@ -212,6 +239,7 @@ dhcp_userclass_add() { } dhcp_vendorclass_add() { + # TODO: DHCPV6 vendor class has stricter definitions; catch? fixup? local cfg="$1" config_get networkid "$cfg" networkid @@ -245,6 +273,7 @@ dhcp_match_add() { dhcp_host_add() { local cfg="$1" + local hosttag nametime addrs duids config_get_bool force "$cfg" force 0 @@ -256,7 +285,9 @@ dhcp_host_add() { config_get name "$cfg" name config_get ip "$cfg" ip - [ -n "$ip" -o -n "$name" ] || return 0 + config_get hostid "$cfg" hostid + + [ -n "$ip" -o -n "$name" -o -n "$hostid" ] || return 0 config_get_bool dns "$cfg" dns 0 [ "$dns" = "1" -a -n "$ip" -a -n "$name" ] && { @@ -264,35 +295,105 @@ dhcp_host_add() { } config_get mac "$cfg" mac + config_get duid "$cfg" duid + config_get tag "$cfg" tag + if [ -n "$mac" ]; then # --dhcp-host=00:20:e0:3b:13:af,192.168.0.199,lap + # many MAC are possible to track a laptop ON/OFF dock macs="" for m in $mac; do append macs "$m" ","; done - else - # --dhcp-host=lap,192.168.0.199 + fi + + if [ $DNSMASQ_DHCP_VER -eq 6 -a -n "$duid" ]; then + # --dhcp-host=id:00:03:00:01:12:00:00:01:02:03,[::beef],lap + # one (virtual) machine gets one DUID per RFC3315 + duids="id:${duid// */}" + fi + + if [ -z "$macs" -a -z "$duids" ]; then + # --dhcp-host=lap,192.168.0.199,[::beef] [ -n "$name" ] || return 0 macs="$name" name="" fi - config_get tag "$cfg" tag + if [ -n "$hostid" ]; then + hex_to_hostid hostid "$hostid" + fi - if [ "$DHCPv6CAPABLE" -eq 1 ]; then - config_get hostid "$cfg" hostid - if [ -n "$hostid" ]; then - hex_to_hostid hostid "$hostid" - fi + tags="" + if [ -n "$tag" ]; then + for t in $tag; do append tags "$t" ",set:"; done fi 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${hostid:+,[::$hostid]}}${name:+,$name}${leasetime:+,$leasetime}" + [ "$broadcast" = "0" ] && broadcast= || broadcast=",set:needs-broadcast" + + hosttag="${networkid:+,set:${networkid}}${tags:+,set:${tags}}$broadcast" + nametime="${name:+,$name}${leasetime:+,$leasetime}" + + if [ $DNSMASQ_DHCP_VER -eq 6 ]; then + addrs="${ip:+,$ip}${hostid:+,[::$hostid]}" + xappend "--dhcp-host=$macs${duids:+,$duids}$hosttag$addrs$nametime" + else + xappend "--dhcp-host=$macs$hosttag${ip:+,$ip}$nametime" + fi +} + +dhcp_this_host_add() { + local net="$1" + local ifname="$2" + local mode="$3" + local routerstub routername ifdashname + local lanaddr lanaddr6 lanaddrs6 ulaprefix + + if [ "$mode" -gt 0 ] ; then + ifdashname="${ifname//./-}" + routerstub="$( md5sum /etc/os-release )" + routerstub="router-${routerstub// */}" + routername="$( uci_get system @system[0] hostname $routerstub )" + + if [ "$mode" -gt 1 ] ; then + if [ "$mode" -gt 2 ] ; then + if [ "$mode" -gt 3 ] ; then + append_interface_name "$ifdashname.$routername.$DOMAIN" "$ifname" + fi + + append_interface_name "$routername.$DOMAIN" "$ifname" + fi + + # All IP addresses discovered by dnsmasq will be labeled (except fe80::) + append_interface_name "$routername" "$ifname" + + else + # This uses a static host file entry for only limited addresses. + # Use dnsmasq option "--expandhosts" to enable FQDN on host files. + ulaprefix="$(uci_get network @globals[0] ula_prefix)" + network_get_ipaddr lanaddr "$net" + network_get_ipaddrs6 lanaddrs6 "$net" + + if [ -n "$lanaddr" ] ; then + dhcp_domain_add "" "$routername" "$lanaddr" + fi + + if [ -n "$ulaprefix" -a -n "$lanaddrs6" ] ; then + for lanaddr6 in $lanaddrs6 ; do + case "$lanaddr6" in + "${ulaprefix%%:/*}"*) + dhcp_domain_add "" "$routername" "$lanaddr6" + ;; + esac + done + fi + fi + fi } dhcp_tag_add() { + # NOTE: dnsmasq has explicit "option6:" prefix for DHCPv6 so no collisions local cfg="$1" tag="$cfg" @@ -323,6 +424,7 @@ dhcp_mac_add() { } dhcp_boot_add() { + # TODO: BOOTURL is different between DHCPv4 and DHCPv6 local cfg="$1" config_get networkid "$cfg" networkid @@ -345,24 +447,30 @@ dhcp_boot_add() { dhcp_add() { local cfg="$1" + local dhcp6range="::" + local nettag + local tags + 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" - network_get_subnet subnet "$net" || return 0 network_get_device ifname "$net" || return 0 - network_get_protocol proto "$net" || return 0 [ "$cachelocal" = "0" ] && network_get_dnsserver dnsserver "$net" && { DNS_SERVERS="$DNS_SERVERS $dnsserver" } - append_bool "$cfg" ignore "--no-dhcp-interface=$ifname" && return 0 + append_bool "$cfg" ignore "--no-dhcp-interface=$ifname" && { + # Many ISP do not have useful names for DHCP customers (your WAN). + dhcp_this_host_add "$net" "$ifname" "$ADD_WAN_FQDN" + return 0 + } + + network_get_subnet subnet "$net" || return 0 + network_get_protocol proto "$net" || return 0 # Do not support non-static interfaces for now [ static = "$proto" ] || return 0 @@ -374,35 +482,142 @@ dhcp_add() { config_get_bool force "$cfg" force 0 [ $force -gt 0 ] || dhcp_check "$ifname" || return 0 - config_get start "$cfg" start - config_get limit "$cfg" limit - config_get leasetime "$cfg" leasetime + config_get start "$cfg" start 100 + config_get limit "$cfg" limit 150 + config_get leasetime "$cfg" leasetime 12h 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 "${subnet%%/*}" $netmask $start $limit)" - if [ "$dynamicdhcp" = "0" ]; then END="static"; fi - xappend "--dhcp-range=$networkid,$START,$END,$NETMASK,$leasetime${options:+ $options}" + config_get dhcpv4 "$cfg" dhcpv4 + config_get dhcpv6 "$cfg" dhcpv6 - dhcp_option_add "$cfg" "$networkid" + config_get ra "$cfg" ra + config_get ra_management "$cfg" ra_management + config_get ra_preference "$cfg" ra_preference + config_get dns "$cfg" dns + + config_list_foreach "$cfg" "interface_name" append_interface_name "$ifname" + + # Put the router host name on this DHCP served interface address(es) + dhcp_this_host_add "$net" "$ifname" "$ADD_LOCAL_FQDN" + + start="$( dhcp_calc "$start" )" + + add_tag() { + tags="${tags}tag:$1," + } + config_list_foreach "$cfg" tag add_tag + + nettag="${networkid:+set:${networkid},}" + + if [ "$limit" -gt 0 ] ; then + limit=$((limit-1)) + fi + + eval "$(ipcalc.sh "${subnet%%/*}" $netmask $start $limit)" + + if [ "$dynamicdhcp" = "0" ] ; then + END="static" + dhcp6range="::,static" + else + dhcp6range="::1000,::ffff" + fi + + + if [ "$dhcpv4" != "disabled" ] ; then + xappend "--dhcp-range=$tags$nettag$START,$END,$NETMASK,$leasetime${options:+ $options}" + fi + + + if [ $DNSMASQ_DHCP_VER -eq 6 -a "$ra" = "server" ] ; then + # Note: dnsmasq cannot just be a DHCPv6 server (all-in-1) + # and let some other machine(s) send RA pointing to it. + + case $ra_preference in + *high*) + xappend "--ra-param=$ifname,high,0,7200" + ;; + *low*) + xappend "--ra-param=$ifname,low,0,7200" + ;; + *) + # Send UNSOLICITED RA at default interval and live for 2 hours. + # TODO: convert flexible lease time into route life time (only seconds). + xappend "--ra-param=$ifname,0,7200" + ;; + esac + + if [ "$dhcpv6" = "disabled" ] ; then + ra_management="3" + fi + + + case $ra_management in + 0) + # SLACC with DCHP for extended options + xappend "--dhcp-range=$nettag::,constructor:$ifname,ra-stateless,ra-names" + ;; + 2) + # DHCP address and RA only for management redirection + xappend "--dhcp-range=$nettag$dhcp6range,constructor:$ifname,$leasetime" + ;; + 3) + # SLAAC only but dnsmasq attempts to link HOSTNAME, DHCPv4 MAC, and SLAAC + xappend "--dhcp-range=$nettag::,constructor:$ifname,ra-only,ra-names" + ;; + *) + # SLAAC and full DHCP + xappend "--dhcp-range=$nettag$dhcp6range,constructor:$ifname,slaac,ra-names,$leasetime" + ;; + esac + + if [ -n "$dns" ]; then + dnss="" + for d in $dns; do append dnss "[$d]" ","; done + else + dnss="[::]" + fi + + dhcp_option_append "option6:dns-server,$dnss" "$networkid" + fi + + dhcp_option_add "$cfg" "$networkid" 0 + dhcp_option_add "$cfg" "$networkid" 2 } -dhcp_option_add() { - local cfg="$1" +dhcp_option_append() { + local option="$1" local networkid="$2" local force="$3" + xappend "--dhcp-option${force:+-force}=${networkid:+$networkid,}$option" +} + +dhcp_option_add() { + # NOTE: dnsmasq has explicit "option6:" prefix for DHCPv6 so no collisions + local cfg="$1" + local networkid="$2" + local force="$3" + local opt="dhcp_option" + [ "$force" = "0" ] && force= + [ "$force" = "2" ] && opt="dhcp_option_force" - config_get dhcp_option "$cfg" dhcp_option - for o in $dhcp_option; do - xappend "--dhcp-option${force:+-force}=${networkid:+$networkid,}$o" - done + local list_len + config_get list_len "$cfg" "${opt}_LENGTH" + if [ -n "$list_len" ]; then + config_list_foreach "$cfg" "$opt" dhcp_option_append "$networkid" "$force" + else + config_get dhcp_option "$cfg" "$opt" + + [ -n "$dhcp_option" ] && echo "Warning: the 'option $opt' syntax is deprecated, use 'list $opt'" >&2 + + local option + for option in $dhcp_option; do + dhcp_option_append "$option" "$networkid" "$force" + done + fi } dhcp_domain_add() { @@ -507,13 +722,14 @@ dhcp_relay_add() { if [ -z "$interface" ]; then xappend "--dhcp-relay=$local_addr,$server_addr" else - xappend "--dhcp-relay=$local_addr,$server_addr,$interface" + network_get_device ifname "$interface" || return + xappend "--dhcp-relay=$local_addr,$server_addr,$ifname" fi } dnsmasq_start() { - local cfg="$1" disabled + local cfg="$1" disabled resolvfile user_dhcpscript config_get_bool disabled "$cfg" disabled 0 [ "$disabled" -gt 0 ] && return 0 @@ -546,6 +762,41 @@ dnsmasq_start() $PROG --version | grep -osqE "^Compile time options:.* DHCPv6( |$)" && DHCPv6CAPABLE=1 || DHCPv6CAPABLE=0 + + if [ -x /usr/sbin/odhcpd -a -x /etc/init.d/odhcpd ] ; then + local odhcpd_is_main odhcpd_is_enabled + config_get odhcpd_is_main odhcpd maindhcp 0 + /etc/init.d/odhcpd enabled && odhcpd_is_enabled=1 || odhcpd_is_enabled=0 + + + if [ "$odhcpd_is_enabled" -eq 0 -a "$DHCPv6CAPABLE" -eq 1 ] ; then + # DHCP V4 and V6 in DNSMASQ + DNSMASQ_DHCP_VER=6 + elif [ "$odhcpd_is_main" -gt 0 ] ; then + # ODHCPD is doing it all + DNSMASQ_DHCP_VER=0 + else + # You have ODHCPD but use DNSMASQ for DHCPV4 + DNSMASQ_DHCP_VER=4 + fi + + elif [ "$DHCPv6CAPABLE" -eq 1 ] ; then + # DHCP V4 and V6 in DNSMASQ + DNSMASQ_DHCP_VER=6 + else + DNSMASQ_DHCP_VER=4 + fi + + # Allow DHCP/DHCPv6 to be handled by ISC DHCPD + if [ -x /usr/sbin/dhcpd ] ; then + if [ -x /etc/init.d/dhcpd ] ; then + /etc/init.d/dhcpd enabled && DNSMASQ_DHCP_VER=0 + fi + if [ -x /etc/init.d/dhcpd6 -a "$DNSMASQ_DHCP_VER" -gt 0 ] ; then + /etc/init.d/dhcpd6 enabled && DNSMASQ_DHCP_VER=4 + fi + fi + append_bool "$cfg" authoritative "--dhcp-authoritative" append_bool "$cfg" nodaemon "--no-daemon" append_bool "$cfg" domainneeded "--domain-needed" @@ -558,12 +809,11 @@ dnsmasq_start() 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" config_get tftp_root "$cfg" "tftp_root" - [ -d "$tftp_root" ] && append_bool "$cfg" enable_tftp "--enable-tftp" + [ -n "$tftp_root" ] && mkdir -p "$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" nonwildcard "--bind-dynamic" 1 append_bool "$cfg" fqdn "--dhcp-fqdn" append_bool "$cfg" proxydnssec "--proxy-dnssec" append_bool "$cfg" localservice "--local-service" @@ -573,7 +823,8 @@ dnsmasq_start() append_bool "$cfg" allservers "--all-servers" append_bool "$cfg" noping "--no-ping" - append_parm "$cfg" dhcpscript "--dhcp-script" + append_parm "$cfg" logfacility "--log-facility" + append_parm "$cfg" cachesize "--cache-size" append_parm "$cfg" dnsforwardmax "--dns-forward-max" append_parm "$cfg" port "--port" @@ -585,6 +836,7 @@ dnsmasq_start() append_parm "$cfg" "domain" "--domain" append_parm "$cfg" "local" "--server" config_list_foreach "$cfg" "server" append_server + config_list_foreach "$cfg" "rev_server" append_rev_server config_list_foreach "$cfg" "address" append_address config_list_foreach "$cfg" "ipset" append_ipset config_list_foreach "$cfg" "interface" append_interface @@ -592,7 +844,6 @@ dnsmasq_start() config_list_foreach "$cfg" "addnhosts" append_addnhosts config_list_foreach "$cfg" "bogusnxdomain" append_bogusnxdomain append_parm "$cfg" "leasefile" "--dhcp-leasefile" "/tmp/dhcp.leases" - append_parm "$cfg" "resolvfile" "--resolv-file" "/tmp/resolv.conf.auto" append_parm "$cfg" "serversfile" "--servers-file" append_parm "$cfg" "tftp_root" "--tftp-root" append_parm "$cfg" "dhcp_boot" "--dhcp-boot" @@ -603,12 +854,21 @@ dnsmasq_start() config_get_bool ADD_LOCAL_DOMAIN "$cfg" add_local_domain 1 config_get_bool ADD_LOCAL_HOSTNAME "$cfg" add_local_hostname 1 + config_get ADD_LOCAL_FQDN "$cfg" add_local_fqdn "" + config_get ADD_WAN_FQDN "$cfg" add_wan_fqdn 0 + + if [ -z "$ADD_LOCAL_FQDN" ] ; then + # maintain support for previous UCI + ADD_LOCAL_FQDN="$ADD_LOCAL_HOSTNAME" + fi config_get_bool readethers "$cfg" readethers [ "$readethers" = "1" -a \! -e "/etc/ethers" ] && touch /etc/ethers - config_get resolvfile $cfg resolvfile - config_get dhcpscript $cfg dhcpscript + config_get user_dhcpscript $cfg dhcpscript + if has_handler || [ -n "$user_dhcpscript" ]; then + xappend "--dhcp-script=$DHCPSCRIPT" + fi config_get leasefile $cfg leasefile "/tmp/dhcp.leases" [ -n "$leasefile" -a \! -e "$leasefile" ] && touch "$leasefile" @@ -621,6 +881,8 @@ dnsmasq_start() [ -n "$resolvfile" -a \! -e "$resolvfile" ] && touch "$resolvfile" fi + [ -n "$resolvfile" ] && xappend "--resolv-file=$resolvfile" + config_get hostsfile "$cfg" dhcphostsfile [ -e "$hostsfile" ] && xappend "--dhcp-hostsfile=$hostsfile" @@ -667,10 +929,11 @@ dnsmasq_start() } dhcp_option_add "$cfg" "" 0 + dhcp_option_add "$cfg" "" 2 xappend "--dhcp-broadcast=tag:needs-broadcast" - xappend "--addn-hosts=$HOSTFILE" + xappend "--addn-hosts=$(dirname $HOSTFILE)" config_get dnsmasqconfdir "$cfg" confdir "/tmp/dnsmasq.d" [ ! -d "$dnsmasqconfdir" ] && mkdir -p $dnsmasqconfdir @@ -700,37 +963,31 @@ dnsmasq_start() config_foreach filter_dnsmasq hostrecord dhcp_hostrecord_add "$cfg" config_foreach filter_dnsmasq relay dhcp_relay_add "$cfg" - # add own hostname - [ $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 Lede)" - - 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_TMP config_foreach filter_dnsmasq srvhost dhcp_srv_add "$cfg" config_foreach filter_dnsmasq mxhost dhcp_mx_add "$cfg" echo >> $CONFIGFILE_TMP - config_get odhcpd_is_active odhcpd maindhcp - if [ "$odhcpd_is_active" != "1" ]; then + config_get_bool boguspriv "$cfg" boguspriv 1 + [ "$boguspriv" -gt 0 ] && { + xappend "--bogus-priv" + [ -r "$RFC6761FILE" ] && xappend "--conf-file=$RFC6761FILE" + } + + if [ "$DNSMASQ_DHCP_VER" -gt 4 ] ; then + # Enable RA feature for when/if it is constructed, + # and RA is selected per interface pool (RA, DHCP, or both), + # but no one (should) want RA broadcast in syslog + config_foreach filter_dnsmasq dhcp dhcp_add "$cfg" + xappend "--enable-ra" + xappend "--quiet-ra" + append_bool "$cfg" quietdhcp "--quiet-dhcp6" + + elif [ "$DNSMASQ_DHCP_VER" -gt 0 ] ; then config_foreach filter_dnsmasq dhcp dhcp_add "$cfg" fi + echo >> $CONFIGFILE_TMP config_foreach filter_dnsmasq cname dhcp_cname_add "$cfg" echo >> $CONFIGFILE_TMP @@ -752,6 +1009,7 @@ dnsmasq_start() procd_open_instance $cfg procd_set_param command $PROG -C $CONFIGFILE -k -x /var/run/dnsmasq/dnsmasq."${cfg}".pid procd_set_param file $CONFIGFILE + [ -n "$user_dhcpscript" ] && procd_set_param env USER_DHCPSCRIPT="$user_dhcpscript" procd_set_param respawn local dnsmasqconffile="/etc/dnsmasq.${cfg}.conf" @@ -760,7 +1018,7 @@ dnsmasq_start() fi procd_add_jail dnsmasq ubus log - procd_add_jail_mount $CONFIGFILE $TRUSTANCHORSFILE $HOSTFILE /etc/passwd /etc/group /etc/TZ /dev/null /dev/urandom $dnsmasqconffile $dnsmasqconfdir $resolvfile $dhcpscript /etc/hosts /etc/ethers $EXTRA_MOUNT + procd_add_jail_mount $CONFIGFILE $TRUSTANCHORSFILE $HOSTFILE $RFC6761FILE /etc/passwd /etc/group /etc/TZ /dev/null /dev/urandom $dnsmasqconffile $dnsmasqconfdir $resolvfile $user_dhcpscript /etc/hosts /etc/ethers /sbin/hotplug-call $EXTRA_MOUNT $DHCPSCRIPT procd_add_jail_mount_rw /var/run/dnsmasq/ $leasefile procd_close_instance diff --git a/package/network/services/dnsmasq/files/dnsmasq_acl.json b/package/network/services/dnsmasq/files/dnsmasq_acl.json new file mode 100644 index 000000000..00ec7d0f0 --- /dev/null +++ b/package/network/services/dnsmasq/files/dnsmasq_acl.json @@ -0,0 +1,4 @@ +{ + "user": "dnsmasq", + "publish": [ "dnsmasq" ] +} diff --git a/package/network/services/dnsmasq/files/dnsmasqsec.hotplug b/package/network/services/dnsmasq/files/dnsmasqsec.hotplug index 5c69314bd..a155eb0f6 100644 --- a/package/network/services/dnsmasq/files/dnsmasqsec.hotplug +++ b/package/network/services/dnsmasq/files/dnsmasqsec.hotplug @@ -1,5 +1,7 @@ #!/bin/sh +. /lib/functions/procd.sh + TIMEVALIDFILE="/var/state/dnsmasqsec" [ "$ACTION" = stratum ] || exit 0 @@ -7,8 +9,6 @@ TIMEVALIDFILE="/var/state/dnsmasqsec" [ -f "$TIMEVALIDFILE" ] || { echo "ntpd says time is valid" >$TIMEVALIDFILE /etc/init.d/dnsmasq enabled && { - pid=$(pidof dnsmasq) - [ "$(readlink /proc/$pid/exe)" = "/usr/sbin/dnsmasq" ] && kill -SIGHUP $pid \ - || /etc/init.d/dnsmasq restart + procd_send_signal dnsmasq } } diff --git a/package/network/services/dnsmasq/files/rfc6761.conf b/package/network/services/dnsmasq/files/rfc6761.conf new file mode 100644 index 000000000..ebc1a1211 --- /dev/null +++ b/package/network/services/dnsmasq/files/rfc6761.conf @@ -0,0 +1,15 @@ +# RFC6761 included configuration file for dnsmasq +# +# includes a list of domains that should not be forwarded to Internet name servers +# to reduce burden on them, asking questions that they won't know the answer to. + +server=/bind/ +server=/example/ +server=/example.com/ +server=/example.org/ +server=/example.net/ +server=/invalid/ +server=/local/ +server=/localhost/ +server=/onion/ +server=/test/ diff --git a/package/network/services/dnsmasq/patches/100-fix-dhcp-no-address-warning.patch b/package/network/services/dnsmasq/patches/100-fix-dhcp-no-address-warning.patch deleted file mode 100644 index 5fc62ffab..000000000 --- a/package/network/services/dnsmasq/patches/100-fix-dhcp-no-address-warning.patch +++ /dev/null @@ -1,47 +0,0 @@ ---- a/src/dhcp.c -+++ b/src/dhcp.c -@@ -147,7 +147,7 @@ void dhcp_packet(time_t now, int pxe_fd) - ssize_t sz; - int iface_index = 0, unicast_dest = 0, is_inform = 0; - int rcvd_iface_index; -- struct in_addr iface_addr; -+ struct in_addr iface_addr, *addrp = NULL; - struct iface_param parm; - #ifdef HAVE_LINUX_NETWORK - struct arpreq arp_req; -@@ -277,11 +277,9 @@ void dhcp_packet(time_t now, int pxe_fd) - { - ifr.ifr_addr.sa_family = AF_INET; - if (ioctl(daemon->dhcpfd, SIOCGIFADDR, &ifr) != -1 ) -- iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; -- else - { -- my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name); -- return; -+ addrp = &iface_addr; -+ iface_addr = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr; - } - - for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next) -@@ -300,7 +298,7 @@ void dhcp_packet(time_t now, int pxe_fd) - parm.relay_local.s_addr = 0; - parm.ind = iface_index; - -- if (!iface_check(AF_INET, (struct all_addr *)&iface_addr, ifr.ifr_name, NULL)) -+ if (!iface_check(AF_INET, (struct all_addr *)addrp, ifr.ifr_name, NULL)) - { - /* If we failed to match the primary address of the interface, see if we've got a --listen-address - for a secondary */ -@@ -320,6 +318,12 @@ void dhcp_packet(time_t now, int pxe_fd) - complete_context(match.addr, iface_index, NULL, match.netmask, match.broadcast, &parm); - } - -+ if (!addrp) -+ { -+ my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name); -+ return; -+ } -+ - if (!iface_enumerate(AF_INET, &parm, complete_context)) - return; - diff --git a/package/network/services/dnsmasq/patches/110-ipset-remove-old-kernel-support.patch b/package/network/services/dnsmasq/patches/110-ipset-remove-old-kernel-support.patch index 61b09d5b2..88e334b0f 100644 --- a/package/network/services/dnsmasq/patches/110-ipset-remove-old-kernel-support.patch +++ b/package/network/services/dnsmasq/patches/110-ipset-remove-old-kernel-support.patch @@ -44,67 +44,22 @@ (buffer = safe_malloc(BUFF_SZ)) && (ipset_sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER)) != -1 && (bind(ipset_sock, (struct sockaddr *)&snl, sizeof(snl)) != -1)) -@@ -168,62 +149,16 @@ static int new_add_to_ipset(const char * - } - - --static int old_add_to_ipset(const char *setname, const struct all_addr *ipaddr, int remove) --{ -- socklen_t size; -- struct ip_set_req_adt_get { -- unsigned op; -- unsigned version; -- union { -- char name[IPSET_MAXNAMELEN]; -- uint16_t index; -- } set; -- char typename[IPSET_MAXNAMELEN]; -- } req_adt_get; -- struct ip_set_req_adt { -- unsigned op; -- uint16_t index; -- uint32_t ip; -- } req_adt; -- -- if (strlen(setname) >= sizeof(req_adt_get.set.name)) -- { -- errno = ENAMETOOLONG; -- return -1; -- } -- -- req_adt_get.op = 0x10; -- req_adt_get.version = 3; -- strcpy(req_adt_get.set.name, setname); -- size = sizeof(req_adt_get); -- if (getsockopt(ipset_sock, SOL_IP, 83, &req_adt_get, &size) < 0) -- return -1; -- req_adt.op = remove ? 0x102 : 0x101; -- req_adt.index = req_adt_get.set.index; -- req_adt.ip = ntohl(ipaddr->addr.addr4.s_addr); -- if (setsockopt(ipset_sock, SOL_IP, 83, &req_adt, sizeof(req_adt)) < 0) -- return -1; -- -- return 0; --} -- -- -- - int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags, int remove) - { - int af = AF_INET; - - #ifdef HAVE_IPV6 +@@ -217,17 +198,10 @@ int add_to_ipset(const char *setname, co if (flags & F_IPV6) -- { + { af = AF_INET6; - /* old method only supports IPv4 */ - if (old_kernel) -- return -1; -- } +- { +- errno = EAFNOSUPPORT ; +- ret = -1; +- } + } #endif -- return old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove); -+ return new_add_to_ipset(setname, ipaddr, af, remove); - } +- if (ret != -1) +- ret = old_kernel ? old_add_to_ipset(setname, ipaddr, remove) : new_add_to_ipset(setname, ipaddr, af, remove); ++ ret = new_add_to_ipset(setname, ipaddr, af, remove); - #endif + if (ret == -1) + my_syslog(LOG_ERR, _("failed to update ipset %s: %s"), setname, strerror(errno)); diff --git a/package/network/services/dnsmasq/patches/120-dnsmasq-compile-time-option-NO_ID.patch b/package/network/services/dnsmasq/patches/120-dnsmasq-compile-time-option-NO_ID.patch deleted file mode 100644 index 152d1a7fa..000000000 --- a/package/network/services/dnsmasq/patches/120-dnsmasq-compile-time-option-NO_ID.patch +++ /dev/null @@ -1,149 +0,0 @@ -From f6bea86c78ba9efbd01da3dd2fb18764ec806290 Mon Sep 17 00:00:00 2001 -From: Kevin Darbyshire-Bryant -Date: Wed, 7 Sep 2016 09:35:07 +0100 -Subject: [PATCH] dnsmasq: compile time option NO_ID - -Some consider it good practice to obscure software version numbers to -clients. Compiling with -DNO_ID removes the *.bind info structure. -This includes: version, author, copyright, cachesize, cache insertions, -evictions, misses & hits, auth & servers. - -Signed-off-by: Kevin Darbyshire-Bryant ---- - src/cache.c | 2 ++ - src/config.h | 5 +++++ - src/dnsmasq.h | 4 ++++ - src/option.c | 8 ++++++-- - src/rfc1035.c | 3 ++- - 5 files changed, 19 insertions(+), 3 deletions(-) - ---- a/src/cache.c -+++ b/src/cache.c -@@ -1290,6 +1290,7 @@ void cache_add_dhcp_entry(char *host_nam - } - #endif - -+#ifndef NO_ID - int cache_make_stat(struct txt_record *t) - { - static char *buff = NULL; -@@ -1385,6 +1386,7 @@ int cache_make_stat(struct txt_record *t - *buff = len; - return 1; - } -+#endif - - /* There can be names in the cache containing control chars, don't - mess up logging or open security holes. */ ---- a/src/config.h -+++ b/src/config.h -@@ -120,6 +120,8 @@ HAVE_LOOP - HAVE_INOTIFY - use the Linux inotify facility to efficiently re-read configuration files. - -+NO_ID -+ Don't report *.bind CHAOS info to clients. - NO_IPV6 - NO_TFTP - NO_DHCP -@@ -434,6 +436,9 @@ static char *compile_opts = - "no-" - #endif - "DNSSEC " -+#ifdef NO_ID -+"no-ID " -+#endif - #ifndef HAVE_LOOP - "no-" - #endif ---- a/src/dnsmasq.h -+++ b/src/dnsmasq.h -@@ -286,6 +286,7 @@ struct naptr { - struct naptr *next; - }; - -+#ifndef NO_ID - #define TXT_STAT_CACHESIZE 1 - #define TXT_STAT_INSERTS 2 - #define TXT_STAT_EVICTIONS 3 -@@ -293,6 +294,7 @@ struct naptr { - #define TXT_STAT_HITS 5 - #define TXT_STAT_AUTH 6 - #define TXT_STAT_SERVERS 7 -+#endif - - struct txt_record { - char *name; -@@ -1078,7 +1080,9 @@ void cache_add_dhcp_entry(char *host_nam - struct in_addr a_record_from_hosts(char *name, time_t now); - void cache_unhash_dhcp(void); - void dump_cache(time_t now); -+#ifndef NO_ID - int cache_make_stat(struct txt_record *t); -+#endif - char *cache_get_name(struct crec *crecp); - char *cache_get_cname_target(struct crec *crecp); - struct crec *cache_enumerate(int init); ---- a/src/option.c -+++ b/src/option.c -@@ -657,7 +657,8 @@ static int atoi_check8(char *a, int *res - return 1; - } - #endif -- -+ -+#ifndef NO_ID - static void add_txt(char *name, char *txt, int stat) - { - struct txt_record *r = opt_malloc(sizeof(struct txt_record)); -@@ -670,13 +671,14 @@ static void add_txt(char *name, char *tx - *(r->txt) = len; - memcpy((r->txt)+1, txt, len); - } -- -+ - r->stat = stat; - r->name = opt_string_alloc(name); - r->next = daemon->txt; - daemon->txt = r; - r->class = C_CHAOS; - } -+#endif - - static void do_usage(void) - { -@@ -4515,6 +4517,7 @@ void read_opts(int argc, char **argv, ch - daemon->soa_expiry = SOA_EXPIRY; - daemon->max_port = MAX_PORT; - -+#ifndef NO_ID - add_txt("version.bind", "dnsmasq-" VERSION, 0 ); - add_txt("authors.bind", "Simon Kelley", 0); - add_txt("copyright.bind", COPYRIGHT, 0); -@@ -4527,6 +4530,7 @@ void read_opts(int argc, char **argv, ch - add_txt("auth.bind", NULL, TXT_STAT_AUTH); - #endif - add_txt("servers.bind", NULL, TXT_STAT_SERVERS); -+#endif - - while (1) - { ---- a/src/rfc1035.c -+++ b/src/rfc1035.c -@@ -1264,6 +1264,7 @@ size_t answer_request(struct dns_header - unsigned long ttl = daemon->local_ttl; - int ok = 1; - log_query(F_CONFIG | F_RRNAME, name, NULL, ""); -+#ifndef NO_ID - /* Dynamically generate stat record */ - if (t->stat != 0) - { -@@ -1271,7 +1272,7 @@ size_t answer_request(struct dns_header - if (!cache_make_stat(t)) - ok = 0; - } -- -+#endif - if (ok && add_resource_record(header, limit, &trunc, nameoffset, &ansp, - ttl, NULL, - T_TXT, t->class, "t", t->len, t->txt)) diff --git a/package/network/services/dnsmasq/patches/210-dnssec-improve-timestamp-heuristic.patch b/package/network/services/dnsmasq/patches/210-dnssec-improve-timestamp-heuristic.patch index ca5a80669..2f854d490 100644 --- a/package/network/services/dnsmasq/patches/210-dnssec-improve-timestamp-heuristic.patch +++ b/package/network/services/dnsmasq/patches/210-dnssec-improve-timestamp-heuristic.patch @@ -35,13 +35,13 @@ Signed-off-by: Steven Barth + if (difftime(now, base) >= 0 && difftime(timestamp_time, now) <= 0) { /* time already OK, update timestamp, and do key checking from the start. */ - if (utime(daemon->timestamp_file, NULL) == -1) + if (utimes(daemon->timestamp_file, NULL) == -1) @@ -493,7 +500,7 @@ int setup_timestamp(void) close(fd); -- timestamp_time = timbuf.actime = timbuf.modtime = 1420070400; /* 1-1-2015 */ -+ timestamp_time = timbuf.actime = timbuf.modtime = base; - if (utime(daemon->timestamp_file, &timbuf) == 0) - goto check_and_exit; - } +- timestamp_time = 1420070400; /* 1-1-2015 */ ++ timestamp_time = base; /* 1-1-2015 */ + tv[0].tv_sec = tv[1].tv_sec = timestamp_time; + tv[0].tv_usec = tv[1].tv_usec = 0; + if (utimes(daemon->timestamp_file, tv) == 0) diff --git a/package/network/services/dnsmasq/patches/230-fix-poll-h-include-warning-on-musl.patch b/package/network/services/dnsmasq/patches/230-fix-poll-h-include-warning-on-musl.patch index 19300f7d6..37b11abc1 100644 --- a/package/network/services/dnsmasq/patches/230-fix-poll-h-include-warning-on-musl.patch +++ b/package/network/services/dnsmasq/patches/230-fix-poll-h-include-warning-on-musl.patch @@ -7,7 +7,7 @@ Signed-off-by: Kevin Darbyshire-Bryant --- a/src/dnsmasq.h +++ b/src/dnsmasq.h -@@ -82,7 +82,7 @@ typedef unsigned long long u64; +@@ -88,7 +88,7 @@ typedef unsigned long long u64; #if defined(HAVE_SOLARIS_NETWORK) # include #endif diff --git a/package/network/services/dnsmasq/patches/240-ubus.patch b/package/network/services/dnsmasq/patches/240-ubus.patch new file mode 100644 index 000000000..2d37b5d2f --- /dev/null +++ b/package/network/services/dnsmasq/patches/240-ubus.patch @@ -0,0 +1,126 @@ +--- a/src/dnsmasq.c ++++ b/src/dnsmasq.c +@@ -19,6 +19,8 @@ + + #include "dnsmasq.h" + ++#include ++ + struct daemon *daemon; + + static volatile pid_t pid = 0; +@@ -32,6 +34,62 @@ static void fatal_event(struct event_des + static int read_event(int fd, struct event_desc *evp, char **msg); + static void poll_resolv(int force, int do_reload, time_t now); + ++static struct ubus_context *ubus; ++static struct blob_buf b; ++ ++static struct ubus_object_type ubus_object_type = { ++ .name = "dnsmasq", ++}; ++ ++static struct ubus_object ubus_object = { ++ .name = "dnsmasq", ++ .type = &ubus_object_type, ++}; ++ ++void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name) ++{ ++ if (!ubus || !ubus_object.has_subscribers) ++ return; ++ ++ blob_buf_init(&b, 0); ++ if (mac) ++ blobmsg_add_string(&b, "mac", mac); ++ if (ip) ++ blobmsg_add_string(&b, "ip", ip); ++ if (name) ++ blobmsg_add_string(&b, "name", name); ++ ubus_notify(ubus, &ubus_object, type, b.head, -1); ++} ++ ++static void set_ubus_listeners(void) ++{ ++ if (!ubus) ++ return; ++ ++ poll_listen(ubus->sock.fd, POLLIN); ++ poll_listen(ubus->sock.fd, POLLERR); ++ poll_listen(ubus->sock.fd, POLLHUP); ++} ++ ++static void check_ubus_listeners() ++{ ++ if (!ubus) { ++ ubus = ubus_connect(NULL); ++ if (ubus) ++ ubus_add_object(ubus, &ubus_object); ++ else ++ return; ++ } ++ ++ if (poll_check(ubus->sock.fd, POLLIN)) ++ ubus_handle_event(ubus); ++ ++ if (poll_check(ubus->sock.fd, POLLHUP)) { ++ ubus_free(ubus); ++ ubus = NULL; ++ } ++} ++ + int main (int argc, char **argv) + { + int bind_fallback = 0; +@@ -911,6 +969,7 @@ int main (int argc, char **argv) + set_dbus_listeners(); + #endif + ++ set_ubus_listeners(); + #ifdef HAVE_DHCP + if (daemon->dhcp || daemon->relay4) + { +@@ -1041,6 +1100,8 @@ int main (int argc, char **argv) + check_dbus_listeners(); + #endif + ++ check_ubus_listeners(); ++ + check_dns_listeners(now); + + #ifdef HAVE_TFTP +--- a/Makefile ++++ b/Makefile +@@ -85,7 +85,7 @@ all : $(BUILDDIR) + @cd $(BUILDDIR) && $(MAKE) \ + top="$(top)" \ + build_cflags="$(version) $(dbus_cflags) $(idn2_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(nettle_cflags)" \ +- build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs)" \ ++ build_libs="$(dbus_libs) $(idn2_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(nettle_libs) $(gmp_libs) -lubox -lubus" \ + -f $(top)/Makefile dnsmasq + + mostly_clean : +--- a/src/dnsmasq.h ++++ b/src/dnsmasq.h +@@ -1397,6 +1397,8 @@ void emit_dbus_signal(int action, struct + # endif + #endif + ++void ubus_event_bcast(const char *type, const char *mac, const char *ip, const char *name); ++ + /* ipset.c */ + #ifdef HAVE_IPSET + void ipset_init(void); +--- a/src/rfc2131.c ++++ b/src/rfc2131.c +@@ -1621,6 +1621,10 @@ static void log_packet(char *type, void + daemon->namebuff, + string ? string : "", + err ? err : ""); ++ if (!strcmp(type, "DHCPACK")) ++ ubus_event_bcast("dhcp.ack", addr ? inet_ntoa(a) : NULL, daemon->namebuff, string ? string : NULL); ++ else if (!strcmp(type, "DHCPRELEASE")) ++ ubus_event_bcast("dhcp.release", addr ? inet_ntoa(a) : NULL, daemon->namebuff, string ? string : NULL); + } + + static void log_options(unsigned char *start, u32 xid)