1
1

Initial dump from Zyxel

This commit is contained in:
2026-04-17 17:00:52 +02:00
commit 81fec250f4
23116 changed files with 5231237 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
config dnsmasq_releaseno
string
prompt "specify dnsmasq release no" if PACKAGE_dnsmasq
default "2.67"
config dnsmasq_dnssec
bool
prompt "enable/disable dnsmasq dnssec" if PACKAGE_dnsmasq
default 0
+164
View File
@@ -0,0 +1,164 @@
#
# Copyright (C) 2006-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmasq
ifeq ($(CONFIG_dnsmasq_releaseno),"2.78")
PKG_VERSION:=2.78
#COPTS:=HAVE_DBUS
else
PKG_VERSION:=2.67
endif
COPTS:= -DNO_ID
PKG_BUILD_DEPENDS:=PACKAGE_zcfg:esmd
PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
#PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq
#PKG_MD5SUM:=f47e5cb8f5bac6343f24b2dbe317ab40
PKG_SOURCE_URL:=@ZyXEL_SITE/opensource/network/services
DL_DIR:=$(TOPDIR)/dl
PKG_LICENSE:=GPLv2
PKG_LICENSE_FILES:=COPYING
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
PATCH_DIR=patches_$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
ifeq ($(CONFIG_dnsmasq_dnssec),y)
COPTS += -DHAVE_DNSSEC -DNO_GMP -DNO_NETTLE_ECC
#PKG_BUILD_DEPENDS += PACKAGE_nettle:nettle
endif
define Package/dnsmasq/Default
SECTION:=net
CATEGORY:=Base system
TITLE:=A lightweight DNS and DHCP server
URL:=http://www.thekelleys.org.uk/dnsmasq/
DEPENDS:=+dnsmasq_dnssec:nettle
endef
define Package/dnsmasq
$(call Package/dnsmasq/Default)
VARIANT:=nodhcpv6
MENU:=1
endef
define Package/dnsmasq/config
select PACKAGE_libzcfg_msg if PACKAGE_zcfg
select PACKAGE_esmd if PACKAGE_zcfg
select PACKAGE_nettle if dnsmasq_dnssec
deselect PACKAGE_nettle if !dnsmasq_dnssec
deselect dnsmasq_dnssec if dnsmasq_releaseno=2.67
source "$(SOURCE)/Config.in"
endef
#Disable Dependencies Check
define CheckDependencies
endef
define Package/dnsmasq-dhcpv6
$(call Package/dnsmasq/Default)
TITLE += (with DHCPv6 support)
DEPENDS:=@IPV6 +kmod-ipv6
VARIANT:=dhcpv6
endef
define Package/dnsmasq/description
It is intended to provide coupled DNS and DHCP service to a LAN.
endef
define Package/dnsmasq-dhcpv6/description
$(call Package/dnsmasq/description)
This is a variant with DHCPv6 support
endef
define Package/dnsmasq/conffiles
/etc/config/dhcp
/etc/dnsmasq.conf
endef
Package/dnsmasq-dhcpv6/conffiles = $(Package/dnsmasq/conffiles)
TARGET_CFLAGS += \
-ffunction-sections -fdata-sections \
$(if $(CONFIG_IPV6),,-DNO_IPV6)
ifeq ($(BUILD_VARIANT),nodhcpv6)
TARGET_CFLAGS += -DNO_DHCP6
endif
ifeq ($(CONFIG_PACKAGE_zcfg),y)
TARGET_CFLAGS += -DZYXEL_PATCH
TARGET_LDFLAGS+= -lzos -lzlog -lzcfg_msg
endif
ifeq ($(CONFIG_ZYXEL_DNS_TRAFFIC_ROUTE),y)
TARGET_CFLAGS += -DDNS_TRAFFIC_ROUTE
endif
ifeq ($(CONFIG_ZyXEL_DHCP_OPTION125),y)
TARGET_CFLAGS += -DZyXEL_DHCP_OPTION125
endif
ifeq ($(CONFIG_TT_CUSTOMIZATION_TR069),y)
TARGET_CFLAGS += -DCONFIG_TT_CUSTOMIZATION_TR069
endif
ifeq ($(CONFIG_ZYXEL_DNS_TRAFFIC_ROUTE_FUZZY_COMPARE),y)
TARGET_CFLAGS += -DZYXEL_DNS_TRAFFIC_ROUTE_FUZZY_COMPARE
endif
ifeq ($(CONFIG_ZYXEL_SUPPORT_NESSUS),y)
TARGET_CFLAGS += -DZYXEL_SUPPORT_NESSUS
endif
MAKE_FLAGS := \
COPTS="$(COPTS)" \
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS) -g -Werror" \
LDFLAGS="$(TARGET_LDFLAGS) -Wl,--gc-sections" \
PREFIX="/usr"
define Package/dnsmasq/install
$(INSTALL_DIR) $(1)/usr/sbin
$(CP) $(PKG_INSTALL_DIR)/usr/sbin/dnsmasq $(1)/usr/sbin/
# $(INSTALL_DIR) $(1)/etc/config
# $(INSTALL_DATA) ./files/dhcp.conf $(1)/etc/config/dhcp
$(INSTALL_DIR) $(1)/etc
ifeq ($(strip $(CONFIG_ISKON_CUSTOMIZATION)),y)
$(INSTALL_DATA) ./files/dnsmasq.conf.ZyXEL.isKon $(1)/etc/dnsmasq.conf
else
$(INSTALL_DATA) ./files/dnsmasq.conf.ZyXEL $(1)/etc/dnsmasq.conf
endif
$(INSTALL_DATA) ./files/trust-anchors.conf $(1)/etc/trust-anchors.conf
$(INSTALL_DIR) $(1)/etc/init.d
ifeq ($(strip $(CONFIG_ISKON_CUSTOMIZATION)),y)
$(INSTALL_BIN) ./files/dnsmasq.sh.ZyXEL.isKon $(1)/etc/init.d/dnsmasq.sh
else
$(INSTALL_BIN) ./files/dnsmasq.sh.ZyXEL $(1)/etc/init.d/dnsmasq.sh
endif
$(INSTALL_DIR) $(1)/etc/rc3.d
ln -s ../init.d/dnsmasq.sh $(1)/etc/rc3.d/S48dnsmasq
# $(INSTALL_BIN) ./files/dnsmasq.init $(1)/etc/init.d/dnsmasq
endef
Package/dnsmasq-dhcpv6/install = $(Package/dnsmasq/install)
$(eval $(call BuildPackage,dnsmasq))
$(eval $(call BuildPackage,dnsmasq-dhcpv6))
+128
View File
@@ -0,0 +1,128 @@
#
# Copyright (C) 2006-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmasq
PKG_VERSION:=2.67
#PKG_VERSION:=2.75
PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
#PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq
#PKG_MD5SUM:=f47e5cb8f5bac6343f24b2dbe317ab40
PKG_SOURCE_URL:=@ZyXEL_SITE/opensource/network/services
DL_DIR:=$(TOPDIR)/dl
PKG_LICENSE:=GPLv2
PKG_LICENSE_FILES:=COPYING
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
PKG_BUILD_DEPENDS:=PACKAGE_zcfg:esmd
PATCH_DIR=patches_$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
define Package/dnsmasq/Default
SECTION:=net
CATEGORY:=Base system
TITLE:=A lightweight DNS and DHCP server
URL:=http://www.thekelleys.org.uk/dnsmasq/
endef
define Package/dnsmasq
$(call Package/dnsmasq/Default)
VARIANT:=nodhcpv6
DEPENDS:=
endef
define Package/dnsmasq/config
select PACKAGE_libzcfg_msg if PACKAGE_zcfg
select PACKAGE_esmd if PACKAGE_zcfg
endef
#Disable Dependencies Check
define CheckDependencies
endef
define Package/dnsmasq-dhcpv6
$(call Package/dnsmasq/Default)
TITLE += (with DHCPv6 support)
DEPENDS:=@IPV6 +kmod-ipv6
VARIANT:=dhcpv6
endef
define Package/dnsmasq/description
It is intended to provide coupled DNS and DHCP service to a LAN.
endef
define Package/dnsmasq-dhcpv6/description
$(call Package/dnsmasq/description)
This is a variant with DHCPv6 support
endef
define Package/dnsmasq/conffiles
/etc/config/dhcp
/etc/dnsmasq.conf
endef
Package/dnsmasq-dhcpv6/conffiles = $(Package/dnsmasq/conffiles)
TARGET_CFLAGS += \
-ffunction-sections -fdata-sections \
$(if $(CONFIG_IPV6),,-DNO_IPV6)
ifeq ($(BUILD_VARIANT),nodhcpv6)
TARGET_CFLAGS += -DNO_DHCP6
endif
TARGET_CFLAGS += -DZYXEL_PATCH
ifeq ($(CONFIG_ZYXEL_DNS_TRAFFIC_ROUTE),y)
TARGET_CFLAGS += -DDNS_TRAFFIC_ROUTE
endif
ifeq ($(CONFIG_ZyXEL_DHCP_OPTION125),y)
TARGET_CFLAGS += -DZyXEL_DHCP_OPTION125
endif
MAKE_FLAGS := \
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS) -g -Werror" \
LDFLAGS="-lzcfg_msg -Wl,--gc-sections" \
PREFIX="/usr"
define Package/dnsmasq/install
$(INSTALL_DIR) $(1)/usr/sbin
$(CP) $(PKG_INSTALL_DIR)/usr/sbin/dnsmasq $(1)/usr/sbin/
# $(INSTALL_DIR) $(1)/etc/config
# $(INSTALL_DATA) ./files/dhcp.conf $(1)/etc/config/dhcp
$(INSTALL_DIR) $(1)/etc
ifeq ($(strip $(CONFIG_ISKON_CUSTOMIZATION)),y)
$(INSTALL_DATA) ./files/dnsmasq.conf.ZyXEL.isKon $(1)/etc/dnsmasq.conf
else
$(INSTALL_DATA) ./files/dnsmasq.conf.ZyXEL $(1)/etc/dnsmasq.conf
endif
$(INSTALL_DIR) $(1)/etc/init.d
ifeq ($(strip $(CONFIG_ISKON_CUSTOMIZATION)),y)
$(INSTALL_BIN) ./files/dnsmasq.sh.ZyXEL.isKon $(1)/etc/init.d/dnsmasq.sh
else
$(INSTALL_BIN) ./files/dnsmasq.sh.ZyXEL $(1)/etc/init.d/dnsmasq.sh
endif
$(INSTALL_DIR) $(1)/etc/rc3.d
ln -s ../init.d/dnsmasq.sh $(1)/etc/rc3.d/S48dnsmasq
# $(INSTALL_BIN) ./files/dnsmasq.init $(1)/etc/init.d/dnsmasq
endef
Package/dnsmasq-dhcpv6/install = $(Package/dnsmasq/install)
$(eval $(call BuildPackage,dnsmasq))
$(eval $(call BuildPackage,dnsmasq-dhcpv6))
+129
View File
@@ -0,0 +1,129 @@
#
# Copyright (C) 2006-2012 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=dnsmasq
PKG_VERSION:=2.78
#PKG_VERSION:=2.67
#PKG_VERSION:=2.75
PKG_RELEASE:=3
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
#PKG_SOURCE_URL:=http://thekelleys.org.uk/dnsmasq
#PKG_MD5SUM:=f47e5cb8f5bac6343f24b2dbe317ab40
PKG_SOURCE_URL:=@ZyXEL_SITE/opensource/network/services
DL_DIR:=$(TOPDIR)/dl
PKG_LICENSE:=GPLv2
PKG_LICENSE_FILES:=COPYING
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(BUILD_VARIANT)/$(PKG_NAME)-$(PKG_VERSION)
PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
PKG_BUILD_DEPENDS:=PACKAGE_zcfg:esmd
COPTS:=HAVE_DBUS
PATCH_DIR=patches_$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
define Package/dnsmasq/Default
SECTION:=net
CATEGORY:=Base system
TITLE:=A lightweight DNS and DHCP server
URL:=http://www.thekelleys.org.uk/dnsmasq/
endef
define Package/dnsmasq
$(call Package/dnsmasq/Default)
VARIANT:=nodhcpv6
DEPENDS:=
endef
define Package/dnsmasq/config
select PACKAGE_libzcfg_msg if PACKAGE_zcfg
select PACKAGE_esmd if PACKAGE_zcfg
endef
#Disable Dependencies Check
define CheckDependencies
endef
define Package/dnsmasq-dhcpv6
$(call Package/dnsmasq/Default)
TITLE += (with DHCPv6 support)
DEPENDS:=@IPV6 +kmod-ipv6
VARIANT:=dhcpv6
endef
define Package/dnsmasq/description
It is intended to provide coupled DNS and DHCP service to a LAN.
endef
define Package/dnsmasq-dhcpv6/description
$(call Package/dnsmasq/description)
This is a variant with DHCPv6 support
endef
define Package/dnsmasq/conffiles
/etc/config/dhcp
/etc/dnsmasq.conf
endef
Package/dnsmasq-dhcpv6/conffiles = $(Package/dnsmasq/conffiles)
TARGET_CFLAGS += \
-ffunction-sections -fdata-sections \
$(if $(CONFIG_IPV6),,-DNO_IPV6)
ifeq ($(BUILD_VARIANT),nodhcpv6)
TARGET_CFLAGS += -DNO_DHCP6
endif
TARGET_CFLAGS += -DZYXEL_PATCH
ifeq ($(CONFIG_ZYXEL_DNS_TRAFFIC_ROUTE),y)
TARGET_CFLAGS += -DDNS_TRAFFIC_ROUTE
endif
ifeq ($(CONFIG_ZyXEL_DHCP_OPTION125),y)
TARGET_CFLAGS += -DZyXEL_DHCP_OPTION125
endif
MAKE_FLAGS := \
$(TARGET_CONFIGURE_OPTS) \
CFLAGS="$(TARGET_CFLAGS) -g -Werror" \
LDFLAGS="-lzcfg_msg -Wl,--gc-sections" \
PREFIX="/usr"
define Package/dnsmasq/install
$(INSTALL_DIR) $(1)/usr/sbin
$(CP) $(PKG_INSTALL_DIR)/usr/sbin/dnsmasq $(1)/usr/sbin/
# $(INSTALL_DIR) $(1)/etc/config
# $(INSTALL_DATA) ./files/dhcp.conf $(1)/etc/config/dhcp
$(INSTALL_DIR) $(1)/etc
ifeq ($(strip $(CONFIG_ISKON_CUSTOMIZATION)),y)
$(INSTALL_DATA) ./files/dnsmasq.conf.ZyXEL.isKon $(1)/etc/dnsmasq.conf
else
$(INSTALL_DATA) ./files/dnsmasq.conf.ZyXEL $(1)/etc/dnsmasq.conf
endif
$(INSTALL_DIR) $(1)/etc/init.d
ifeq ($(strip $(CONFIG_ISKON_CUSTOMIZATION)),y)
$(INSTALL_BIN) ./files/dnsmasq.sh.ZyXEL.isKon $(1)/etc/init.d/dnsmasq.sh
else
$(INSTALL_BIN) ./files/dnsmasq.sh.ZyXEL $(1)/etc/init.d/dnsmasq.sh
endif
$(INSTALL_DIR) $(1)/etc/rc3.d
ln -s ../init.d/dnsmasq.sh $(1)/etc/rc3.d/S48dnsmasq
# $(INSTALL_BIN) ./files/dnsmasq.init $(1)/etc/init.d/dnsmasq
endef
Package/dnsmasq-dhcpv6/install = $(Package/dnsmasq/install)
$(eval $(call BuildPackage,dnsmasq))
$(eval $(call BuildPackage,dnsmasq-dhcpv6))
@@ -0,0 +1,31 @@
config dnsmasq
option domainneeded 1
option boguspriv 1
option filterwin2k 0 # enable for dial on demand
option localise_queries 1
option rebind_protection 1 # disable if upstream must serve RFC1918 addresses
option rebind_localhost 1 # enable for RBL checking and similar services
#list rebind_domain example.lan # whitelist RFC1918 responses for domains
option local '/lan/'
option domain 'lan'
option expandhosts 1
option nonegcache 0
option authoritative 1
option readethers 1
option leasefile '/tmp/dhcp.leases'
option resolvfile '/tmp/resolv.conf.auto'
#list server '/mycompany.local/1.2.3.4'
#option nonwildcard 1
#list interface br-lan
#list notinterface lo
#list bogusnxdomain '64.94.110.11'
config dhcp lan
option interface lan
option start 100
option limit 150
option leasetime 12h
config dhcp wan
option interface wan
option ignore 1
@@ -0,0 +1,37 @@
# Change the following lines if you want dnsmasq to serve SRV
# records.
# You may add multiple srv-host lines.
# The fields are <name>,<target>,<port>,<priority>,<weight>
# A SRV record sending LDAP for the example.com domain to
# ldapserver.example.com port 289
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389
# Two SRV records for LDAP, each with different priorities
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,1
#srv-host=_ldap._tcp.example.com,ldapserver.example.com,389,2
# A SRV record indicating that there is no LDAP server for the domain
# example.com
#srv-host=_ldap._tcp.example.com
# The following line shows how to make dnsmasq serve an arbitrary PTR
# record. This is useful for DNS-SD.
# The fields are <name>,<target>
#ptr-record=_http._tcp.dns-sd-services,"New Employee Page._http._tcp.dns-sd-services"
# Change the following lines to enable dnsmasq to serve TXT records.
# These are used for things like SPF and zeroconf.
# The fields are <name>,<text>,<text>...
#Example SPF.
#txt-record=example.com,"v=spf1 a -all"
#Example zeroconf
#txt-record=_http._tcp.example.com,name=value,paper=A4
# Provide an alias for a "local" DNS name. Note that this _only_ works
# for targets which are names from DHCP or /etc/hosts. Give host
# "bert" another name, bertrand
# The fields are <cname>,<target>
#cname=bertand,bert
+48
View File
@@ -0,0 +1,48 @@
# Change this line if you want dns to get its upstream servers from
# somewhere other that /etc/resolv.conf
resolv-file=/var/fyi/sys/dns
# By default, dnsmasq will send queries to any of the upstream
# servers it knows about and tries to favour servers to are known
# to be up. Uncommenting this forces dnsmasq to try each query
# with each server strictly in the order they appear in
# /etc/resolv.conf
strict-order
# If you want dnsmasq to change uid and gid to something other
# than the default, edit the following lines.
user=root
#group=
# Never forward plain names (without a dot or domain part)
domain-needed
# If you want dnsmasq to listen for DHCP and DNS requests only on
# specified interfaces (and the loopback) give the name of the
# interface (eg eth0) here.
# Repeat the line for more than one interface.
interface=lo
# Or you can specify which interface _not_ to listen on
#except-interface=
# Or which to listen on by address (remember to include 127.0.0.1 if
# you use this.)
#listen-address=
# If you want dnsmasq to provide only DNS service on an interface,
# configure it as shown above, and then use the following line to
# disable DHCP on it.
#no-dhcp-interface=
# If you don't want dnsmasq to read /etc/hosts, uncomment the
# following line.
#no-hosts
# or if you want it to read another file, as well as /etc/hosts, use
# this.
addn-hosts=/var/dnsmasq/hosts
# Include a another lot of configuration options.
#conf-file=/etc/dnsmasq.more.conf
conf-dir=/var/dnsmasq/conf.d
# Dnsmasq picks random ports as source for outbound queries: when this option is given, the ports used will always to larger than that specified.
min-port=1024
@@ -0,0 +1,45 @@
# Change this line if you want dns to get its upstream servers from
# somewhere other that /etc/resolv.conf
resolv-file=/var/fyi/sys/dns
# By default, dnsmasq will send queries to any of the upstream
# servers it knows about and tries to favour servers to are known
# to be up. Uncommenting this forces dnsmasq to try each query
# with each server strictly in the order they appear in
# /etc/resolv.conf
strict-order
# If you want dnsmasq to change uid and gid to something other
# than the default, edit the following lines.
user=supervisor
#group=
# Never forward plain names (without a dot or domain part)
domain-needed
# If you want dnsmasq to listen for DHCP and DNS requests only on
# specified interfaces (and the loopback) give the name of the
# interface (eg eth0) here.
# Repeat the line for more than one interface.
interface=lo
# Or you can specify which interface _not_ to listen on
#except-interface=
# Or which to listen on by address (remember to include 127.0.0.1 if
# you use this.)
#listen-address=
# If you want dnsmasq to provide only DNS service on an interface,
# configure it as shown above, and then use the following line to
# disable DHCP on it.
#no-dhcp-interface=
# If you don't want dnsmasq to read /etc/hosts, uncomment the
# following line.
#no-hosts
# or if you want it to read another file, as well as /etc/hosts, use
# this.
addn-hosts=/var/dnsmasq/hosts
# Include a another lot of configuration options.
#conf-file=/etc/dnsmasq.more.conf
conf-dir=/var/dnsmasq/conf.d
@@ -0,0 +1,529 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2007-2012 OpenWrt.org
START=60
SERVICE_USE_PID=1
DNS_SERVERS=""
DOMAIN=""
ADD_LOCAL_DOMAIN=1
ADD_LOCAL_HOSTNAME=1
CONFIGFILE="/var/etc/dnsmasq.conf"
xappend() {
local value="$1"
echo "${value#--}" >> $CONFIGFILE
}
dhcp_calc() {
local ip="$1"
local res=0
while [ -n "$ip" ]; do
part="${ip%%.*}"
res="$(($res * 256))"
res="$(($res + $part))"
[ "${ip%.*}" != "$ip" ] && ip="${ip#*.}" || ip=
done
echo "$res"
}
append_bool() {
local section="$1"
local option="$2"
local value="$3"
local _loctmp
config_get_bool _loctmp "$section" "$option" 0
[ $_loctmp -gt 0 ] && xappend "$value"
}
append_parm() {
local section="$1"
local option="$2"
local switch="$3"
local _loctmp
config_get _loctmp "$section" "$option"
[ -z "$_loctmp" ] && return 0
xappend "$switch=$_loctmp"
}
append_server() {
xappend "--server=$1"
}
append_address() {
xappend "--address=$1"
}
append_interface() {
local ifname=$(uci_get_state network "$1" ifname "$1")
xappend "--interface=$ifname"
}
append_notinterface() {
local ifname=$(uci_get_state network "$1" ifname "$1")
xappend "--except-interface=$ifname"
}
append_addnhosts() {
xappend "--addn-hosts=$1"
}
append_bogusnxdomain() {
xappend "--bogus-nxdomain=$1"
}
dnsmasq() {
local cfg="$1"
append_bool "$cfg" authoritative "--dhcp-authoritative"
append_bool "$cfg" nodaemon "--no-daemon"
append_bool "$cfg" domainneeded "--domain-needed"
append_bool "$cfg" filterwin2k "--filterwin2k"
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" 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"
append_bool "$cfg" fqdn "--dhcp-fqdn"
append_parm "$cfg" dhcpscript "--dhcp-script"
append_parm "$cfg" cachesize "--cache-size"
append_parm "$cfg" dnsforwardmax "--dns-forward-max"
append_parm "$cfg" port "--port"
append_parm "$cfg" ednspacket_max "--edns-packet-max"
append_parm "$cfg" dhcpleasemax "--dhcp-lease-max"
append_parm "$cfg" "queryport" "--query-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" "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" "tftp_root" "--tftp-root"
append_parm "$cfg" "dhcp_boot" "--dhcp-boot"
append_parm "$cfg" "local_ttl" "--local-ttl"
config_get DOMAIN "$cfg" domain
config_get_bool ADD_LOCAL_DOMAIN "$cfg" add_local_domain 1
config_get_bool ADD_LOCAL_HOSTNAME "$cfg" add_local_hostname 1
config_get_bool readethers "$cfg" readethers
[ "$readethers" = "1" -a \! -e "/etc/ethers" ] && touch /etc/ethers
config_get leasefile $cfg leasefile
[ -n "$leasefile" -a \! -e "$leasefile" ] && touch "$leasefile"
config_get_bool cachelocal "$cfg" cachelocal 1
config_get hostsfile "$cfg" dhcphostsfile
[ -e "$hostsfile" ] && xappend "--dhcp-hostsfile=$hostsfile"
local rebind
config_get_bool rebind "$cfg" rebind_protection 1
[ $rebind -gt 0 ] && {
logger -t dnsmasq \
"DNS rebinding protection is active," \
"will discard upstream RFC1918 responses!"
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"
xappend "--rebind-localhost-ok"
}
append_rebind_domain() {
logger -t dnsmasq "Allowing RFC1918 responses for domain $1"
xappend "--rebind-domain-ok=$1"
}
config_list_foreach "$cfg" rebind_domain append_rebind_domain
}
dhcp_option_add "$cfg" "" 0
echo >> $CONFIGFILE
}
dhcp_subscrid_add() {
local cfg="$1"
config_get networkid "$cfg" networkid
[ -n "$networkid" ] || return 0
config_get subscriberid "$cfg" subscriberid
[ -n "$subscriberid" ] || return 0
xappend "--dhcp-subscrid=$networkid,$subscriberid"
config_get_bool force "$cfg" force 0
dhcp_option_add "$cfg" "$networkid" "$force"
}
dhcp_remoteid_add() {
local cfg="$1"
config_get networkid "$cfg" networkid
[ -n "$networkid" ] || return 0
config_get remoteid "$cfg" remoteid
[ -n "$remoteid" ] || return 0
xappend "--dhcp-remoteid=$networkid,$remoteid"
config_get_bool force "$cfg" force 0
dhcp_option_add "$cfg" "$networkid" "$force"
}
dhcp_circuitid_add() {
local cfg="$1"
config_get networkid "$cfg" networkid
[ -n "$networkid" ] || return 0
config_get circuitid "$cfg" circuitid
[ -n "$circuitid" ] || return 0
xappend "--dhcp-circuitid=$networkid,$circuitid"
config_get_bool force "$cfg" force 0
dhcp_option_add "$cfg" "$networkid" "$force"
}
dhcp_userclass_add() {
local cfg="$1"
config_get networkid "$cfg" networkid
[ -n "$networkid" ] || return 0
config_get userclass "$cfg" userclass
[ -n "$userclass" ] || return 0
xappend "--dhcp-userclass=$networkid,$userclass"
config_get_bool force "$cfg" force 0
dhcp_option_add "$cfg" "$networkid" "$force"
}
dhcp_vendorclass_add() {
local cfg="$1"
config_get networkid "$cfg" networkid
[ -n "$networkid" ] || return 0
config_get vendorclass "$cfg" vendorclass
[ -n "$vendorclass" ] || return 0
xappend "--dhcp-vendorclass=$networkid,$vendorclass"
config_get_bool force "$cfg" force 0
dhcp_option_add "$cfg" "$networkid" "$force"
}
dhcp_host_add() {
local cfg="$1"
config_get_bool force "$cfg" force 0
config_get networkid "$cfg" networkid
[ -n "$networkid" ] && dhcp_option_add "$cfg" "$networkid" "$force"
config_get name "$cfg" name
config_get ip "$cfg" ip
[ -n "$ip" -o -n "$name" ] || return 0
macs=""
config_get mac "$cfg" mac
for m in $mac; do append macs "$m" ","; done
[ -n "$macs" ] || return 0
config_get tag "$cfg" tag
xappend "--dhcp-host=$macs${networkid:+,net:$networkid}${tag:+,set:$tag}${ip:+,$ip}${name:+,$name}"
}
dhcp_tag_add() {
local cfg="$1"
tag="$cfg"
[ -n "$tag" ] || return 0
config_get_bool force "$cfg" force 0
[ "$force" = "0" ] && force=
config_get option "$cfg" dhcp_option
for o in $option; do
xappend "--dhcp-option${force:+-force}=tag:$tag,$o"
done
}
dhcp_mac_add() {
local cfg="$1"
config_get networkid "$cfg" networkid
[ -n "$networkid" ] || return 0
config_get mac "$cfg" mac
[ -n "$mac" ] || return 0
xappend "--dhcp-mac=$networkid,$mac"
dhcp_option_add "$cfg" "$networkid"
}
dhcp_boot_add() {
local cfg="$1"
config_get networkid "$cfg" networkid
config_get filename "$cfg" filename
[ -n "$filename" ] || return 0
config_get servername "$cfg" servername
[ -n "$servername" ] || return 0
config_get serveraddress "$cfg" serveraddress
[ -n "$serveraddress" ] || return 0
xappend "--dhcp-boot=${networkid:+net:$networkid,}$filename,$servername,$serveraddress"
config_get_bool force "$cfg" force 0
dhcp_option_add "$cfg" "$networkid" "$force"
}
dhcp_add() {
local cfg="$1"
config_get net "$cfg" interface
[ -n "$net" ] || return 0
config_get networkid "$cfg" networkid
[ -n "$networkid" ] || networkid="$net"
config_get ifname "$net" ifname
[ -n "$ifname" ] || return 0
config_get dnsserver "$net" dns
[ "$cachelocal" = "0" -a -n "$dnsserver" ] && {
DNS_SERVERS="$DNS_SERVERS $dnsserver"
}
append_bool "$cfg" ignore "--no-dhcp-interface=$ifname" && return 0
config_get proto "$net" proto
[ static = "$proto" ] || return 0
config_get ipaddr "$net" ipaddr
config_get netmask "$cfg" netmask
[ -n "$netmask" ] || config_get netmask "$net" netmask
#check for an already active dhcp server on the interface, unless 'force' is set
config_get_bool force "$cfg" force 0
[ $force -gt 0 ] || {
udhcpc -n -q -s /bin/true -t 1 -i $ifname >&- && {
logger -t dnsmasq \
"found already running DHCP-server on interface '$ifname'" \
"refusing to start, use 'option force 1' to override"
return 0
}
}
config_get start "$cfg" start
config_get limit "$cfg" limit
config_get leasetime "$cfg" leasetime
config_get options "$cfg" options
config_get_bool dynamicdhcp "$cfg" dynamicdhcp 1
leasetime="${leasetime:-12h}"
start="$(dhcp_calc "${start:-100}")"
limit="${limit:-150}"
[ "$limit" -gt 0 ] && limit=$((limit-1))
eval "$(ipcalc.sh $ipaddr $netmask $start $limit)"
if [ "$dynamicdhcp" = "0" ]; then END="static"; fi
xappend "--dhcp-range=$networkid,$START,$END,$NETMASK,$leasetime${options:+ $options}"
dhcp_option_add "$cfg" "$networkid"
}
dhcp_option_add() {
local cfg="$1"
local networkid="$2"
local force="$3"
[ "$force" = "0" ] && force=
config_get dhcp_option "$cfg" dhcp_option
for o in $dhcp_option; do
xappend "--dhcp-option${force:+-force}=${networkid:+$networkid,}$o"
done
}
dhcp_domain_add() {
local cfg="$1"
local ip name names
config_get names "$cfg" name "$2"
[ -n "$names" ] || return 0
config_get ip "$cfg" ip "$3"
[ -n "$ip" ] || return 0
local oIFS="$IFS"; IFS="."; set -- $ip; IFS="$oIFS"
local raddr="${4:+$4.$3.$2.$1.in-addr.arpa}"
for name in $names; do
local fqdn="$name"
[ "${fqdn%.*}" == "$fqdn" ] && \
fqdn="$fqdn${DOMAIN:+.$DOMAIN}"
xappend "--address=/$fqdn/$ip"
[ -n "$raddr" ] && {
xappend "--ptr-record=$raddr,$fqdn"
raddr=""
}
done
}
dhcp_srv_add() {
local cfg="$1"
config_get srv "$cfg" srv
[ -n "$srv" ] || return 0
config_get target "$cfg" target
[ -n "$target" ] || return 0
config_get port "$cfg" port
[ -n "$port" ] || return 0
config_get class "$cfg" class
config_get weight "$cfg" weight
local service="$srv,$target,$port${class:+,$class${weight:+,$weight}}"
xappend "--srv-host=$service"
}
dhcp_mx_add() {
local cfg="$1"
local domain relay pref
config_get domain "$cfg" domain
[ -n "$domain" ] || return 0
config_get relay "$cfg" relay
[ -n "$relay" ] || return 0
config_get pref "$cfg" pref 0
local service="$domain,$relay,$pref"
xappend "--mx-host=$service"
}
dhcp_cname_add() {
local cfg="$1"
local cname target
config_get cname "$cfg" cname
[ -n "$cname" ] || return 0
config_get target "$cfg" target
[ -n "$target" ] || return 0
xappend "--cname=${cname},${target}"
}
start() {
include /lib/network
scan_interfaces
local lanaddr
config_get lanaddr "lan" ipaddr
config_load dhcp
# before we can call xappend
mkdir -p $(dirname $CONFIGFILE)
echo "# auto-generated config file from /etc/config/dhcp" > $CONFIGFILE
# if we did this last, we could override auto-generated config
[ -f /etc/dnsmasq.conf ] && {
xappend "--conf-file=/etc/dnsmasq.conf"
}
args=""
config_foreach dnsmasq dnsmasq
config_foreach dhcp_host_add host
echo >> $CONFIGFILE
config_foreach dhcp_boot_add boot
config_foreach dhcp_mac_add mac
config_foreach dhcp_tag_add tag
config_foreach dhcp_vendorclass_add vendorclass
config_foreach dhcp_userclass_add userclass
config_foreach dhcp_circuitid_add circuitid
config_foreach dhcp_remoteid_add remoteid
config_foreach dhcp_subscrid_add subscrid
config_foreach dhcp_domain_add domain
echo >> $CONFIGFILE
config_foreach dhcp_srv_add srvhost
config_foreach dhcp_mx_add mxhost
echo >> $CONFIGFILE
config_foreach dhcp_add dhcp
echo >> $CONFIGFILE
config_foreach dhcp_cname_add cname
echo >> $CONFIGFILE
# add own hostname
[ $ADD_LOCAL_HOSTNAME -eq 1 ] && [ -n "$lanaddr" ] && {
local hostname="$(uci_get system.@system[0].hostname)"
dhcp_domain_add "" "${hostname:-OpenWrt}" "$lanaddr"
}
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
}
}
stop() {
service_stop /usr/sbin/dnsmasq && {
[ -f /tmp/resolv.conf ] && {
rm -f /tmp/resolv.conf
ln -s /tmp/resolv.conf.auto /tmp/resolv.conf
}
}
}
+136
View File
@@ -0,0 +1,136 @@
#!/bin/sh
export PATH=/home/bin:/home/scripts:/opt/bin:/bin:/sbin:/usr/bin:/usr/sbin
#export LD_LIBRARY_PATH=/lib/public:/lib/private:/usr/lib:/lib:/usr/lib/ebtables:/usr/lib/iptables
SUPPORT_LIB64=`ls / | grep lib64`
if [ "$SUPPORT_LIB64" == "lib64" ] ;then
export LD_LIBRARY_PATH=/lib/public:/lib/private:/usr/lib:/lib:/lib64/gpl:/lib64:/usr/lib/ebtables:/usr/lib/iptables
else
export LD_LIBRARY_PATH=/lib/public:/lib/private:/usr/lib:/lib:/usr/lib/ebtables:/usr/lib/iptables
fi
EXEC_NAME=dnsmasq
EXEC_PATH=/usr/sbin
EXEC_CONF=/etc/dnsmasq.conf
USER=root
DNSMASQ_LOG_CONF=/var/dnsmasq/conf.d/logquit.conf
DNSMASQ_LOG_CONF_BACK=/var/dnsmasq/conf.d/logquit.conf_back
logchk()
{
local re_start=0
if [ ! -f $DNSMASQ_LOG_CONF ]; then
echo "quiet-dhcp" > $DNSMASQ_LOG_CONF
echo "quiet-dhcp6" >> $DNSMASQ_LOG_CONF
echo "quiet-ra" >> $DNSMASQ_LOG_CONF
re_start=1
fi
cp $DNSMASQ_LOG_CONF $DNSMASQ_LOG_CONF_BACK
local str=""
for i in $@
do
if [ -z ${i##*dhcp-log*} ]; then
str='quiet-dhcp'
elif [ -z ${i##*dhcp6-log*} ]; then
str='quiet-dhcp6'
elif [ -z ${i##*ra-log*} ]; then
str='quiet-ra'
else
str=''
fi
if [ ! -z $str ]; then
local replace=$str
if [ -z ${i##enable*} ]; then
replace='#'$replace
fi
local chk=`cat $DNSMASQ_LOG_CONF | grep "^#*\s*$str\s*$"`
if [ ! -z $chk ]; then
sed -i "s/^#*[ tab]*$str[ tab]*$/$replace/g" $DNSMASQ_LOG_CONF
else
echo "$replace" >> $DNSMASQ_LOG_CONF
fi
fi
done
local orig_size=`ls -al $DNSMASQ_LOG_CONF_BACK | awk '{print $5}'`
local res_size=`ls -al $DNSMASQ_LOG_CONF | awk '{print $5}'`
if [ $orig_size -ne $res_size ]; then
re_start=1
fi
rm $DNSMASQ_LOG_CONF_BACK
echo $re_start
}
reload()
{
PID=$(pgrep dnsmasq)
if [ "$PID" == "" ] ; then
echo 'dnsmasq not running'
else
kill -HUP "$PID"
fi
}
start()
{
/bin/mkdir -p /var/dnsmasq/
/bin/mkdir -p /var/dnsmasq/conf.d
ln -sf $EXEC_CONF /var/dnsmasq/dnsmasq.conf
local re=$(logchk)
$EXEC_PATH/$EXEC_NAME -u $USER -q --conf-file=$EXEC_CONF
}
stop()
{
killall -9 $EXEC_NAME
}
case "$1" in
start)
PID=$(pgrep dnsmasq)
if [ "$PID" == "" ] ; then
start
else
echo 'dnsmasq is already running !!!'
fi
exit 0
;;
stop)
stop
exit 0
;;
restart)
stop
start
exit 0
;;
reload)
reload
exit 0
;;
log)
re=$(logchk $@)
if [ $re -eq 1 ]; then
stop
start
fi
exit 0
;;
*)
echo "$0: unrecognized option $1"
exit 1
;;
esac
@@ -0,0 +1,129 @@
#!/bin/sh
export PATH=/home/bin:/home/scripts:/opt/bin:/bin:/sbin:/usr/bin:/usr/sbin
export LD_LIBRARY_PATH=/lib/public:/lib/private:/usr/lib:/lib:/usr/lib/ebtables:/usr/lib/iptables
EXEC_NAME=dnsmasq
EXEC_PATH=/usr/sbin
EXEC_CONF=/etc/dnsmasq.conf
USER=supervisor
DNSMASQ_LOG_CONF=/var/dnsmasq/conf.d/logquit.conf
DNSMASQ_LOG_CONF_BACK=/var/dnsmasq/conf.d/logquit.conf_back
logchk()
{
local re_start=0
if [ ! -f $DNSMASQ_LOG_CONF ]; then
echo "quiet-dhcp" > $DNSMASQ_LOG_CONF
echo "quiet-dhcp6" >> $DNSMASQ_LOG_CONF
echo "quiet-ra" >> $DNSMASQ_LOG_CONF
re_start=1
fi
cp $DNSMASQ_LOG_CONF $DNSMASQ_LOG_CONF_BACK
local str=""
for i in $@
do
if [ -z ${i##*dhcp-log*} ]; then
str='quiet-dhcp'
elif [ -z ${i##*dhcp6-log*} ]; then
str='quiet-dhcp6'
elif [ -z ${i##*ra-log*} ]; then
str='quiet-ra'
else
str=''
fi
if [ ! -z $str ]; then
local replace=$str
if [ -z ${i##enable*} ]; then
replace='#'$replace
fi
local chk=`cat $DNSMASQ_LOG_CONF | grep "^#*\s*$str\s*$"`
if [ ! -z $chk ]; then
sed -i "s/^#*[ tab]*$str[ tab]*$/$replace/g" $DNSMASQ_LOG_CONF
else
echo "$replace" >> $DNSMASQ_LOG_CONF
fi
fi
done
local orig_size=`ls -al $DNSMASQ_LOG_CONF_BACK | awk '{print $5}'`
local res_size=`ls -al $DNSMASQ_LOG_CONF | awk '{print $5}'`
if [ $orig_size -ne $res_size ]; then
re_start=1
fi
rm $DNSMASQ_LOG_CONF_BACK
echo $re_start
}
reload()
{
PID=$(pgrep dnsmasq)
if [ "$PID" == "" ] ; then
echo 'dnsmasq not running'
else
kill -HUP "$PID"
fi
}
start()
{
/bin/mkdir -p /var/dnsmasq/
/bin/mkdir -p /var/dnsmasq/conf.d
ln -sf $EXEC_CONF /var/dnsmasq/dnsmasq.conf
local re=$(logchk)
$EXEC_PATH/$EXEC_NAME -u $USER -q --conf-file=$EXEC_CONF
}
stop()
{
killall -9 $EXEC_NAME
}
case "$1" in
start)
PID=$(pgrep dnsmasq)
if [ "$PID" == "" ] ; then
start
else
echo 'dnsmasq is already running !!!'
fi
exit 0
;;
stop)
stop
exit 0
;;
restart)
stop
start
exit 0
;;
reload)
reload
exit 0
;;
log)
re=$(logchk $@)
if [ $re -eq 1 ]; then
stop
start
fi
exit 0
;;
*)
echo "$0: unrecognized option $1"
exit 1
;;
esac
@@ -0,0 +1,10 @@
# The root DNSSEC trust anchor, valid as at 10/02/2017
# Note that this is a DS record (ie a hash of the root Zone Signing Key)
# If was downloaded from https://data.iana.org/root-anchors/root-anchors.xml
trust-anchor=.,19036,8,2,49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5
trust-anchor=.,20326,8,2,E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D
@@ -0,0 +1,514 @@
Index: dnsmasq-2.67/Makefile
===================================================================
--- dnsmasq-2.67.orig/Makefile 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/Makefile 2015-10-07 18:05:37.102960367 +0800
@@ -67,6 +67,8 @@
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o domain.o
+objs += extern.o
+
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
dns-protocol.h radv-protocol.h
Index: dnsmasq-2.67/src/dnsmasq.c
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dnsmasq.c 2015-10-07 18:05:37.102960367 +0800
@@ -81,6 +81,10 @@
umask(022); /* known umask, create leases and pid files as 0644 */
read_opts(argc, argv, compile_opts);
+
+#ifdef ZYXEL_PATCH /* register to zyxel zcfg, by charisse*/
+ dnsmasq_eid_register();
+#endif
if (daemon->edns_pktsz < PACKETSZ)
daemon->edns_pktsz = PACKETSZ;
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2015-10-07 20:51:18.946774230 +0800
@@ -563,6 +563,10 @@
} *slaac_address;
int vendorclass_count;
#endif
+#ifdef ZYXEL_PATCH
+ char *vendorid;
+ unsigned char *oui, *serial, *pclass;
+#endif
struct dhcp_lease *next;
};
@@ -1309,3 +1313,13 @@
time_t periodic_slaac(time_t now, struct dhcp_lease *leases);
void slaac_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface, struct dhcp_lease *leases);
#endif
+
+/* extern.c */
+#ifdef ZYXEL_PATCH
+void lease_set_vendor(struct dhcp_lease *, const char* , int );
+void lease_set_oui(struct dhcp_lease *, const char* , int );
+void lease_set_serial(struct dhcp_lease *, const char* , int );
+void lease_set_class(struct dhcp_lease *, const char* , int );
+void dnsmasq_eid_register(void);
+void sendLeaseMessageToESMD(int, struct dhcp_lease *, const char*);
+#endif
\ No newline at end of file
Index: dnsmasq-2.67/src/lease.c
===================================================================
--- dnsmasq-2.67.orig/src/lease.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/lease.c 2015-10-07 20:52:19.911389405 +0800
@@ -28,7 +28,9 @@
struct dhcp_lease *lease;
int clid_len, hw_len, hw_type;
FILE *leasestream;
-
+#ifdef ZYXEL_PATCH
+ int parse_count = 0;
+#endif
leases_left = daemon->dhcp_max;
if (option_bool(OPT_LEASE_RO))
@@ -80,11 +82,16 @@
#endif
ei = atol(daemon->dhcp_buff3);
-
+#ifdef ZYXEL_PATCH
+ parse_count = fscanf(leasestream, " %64s %255s %764s %[^\n]s\n",
+ daemon->namebuff, daemon->dhcp_buff, daemon->packet, daemon->dhcp_buff3);
+ if (parse_count != 3 && parse_count != 4)
+#else
if (fscanf(leasestream, " %64s %255s %764s",
daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
+#endif
break;
-
+
clid_len = 0;
if (strcmp(daemon->packet, "*") != 0)
clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
@@ -102,6 +109,11 @@
if (strcmp(daemon->dhcp_buff, "*") != 0)
lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain(lease->addr), NULL);
+#ifdef ZYXEL_PATCH
+ if(parse_count == 4 && strcmp(daemon->dhcp_buff3, "*") != 0){
+ lease_set_vendor(lease, daemon->dhcp_buff3, strlen(daemon->dhcp_buff3));
+ }
+#endif
}
#ifdef HAVE_DHCP6
else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6))
@@ -124,7 +136,12 @@
lease_set_iaid(lease, iaid);
if (strcmp(daemon->dhcp_buff, "*") != 0)
lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain6((struct in6_addr *)lease->hwaddr), NULL);
- }
+#ifdef ZYXEL_PATCH
+ if(parse_count == 4 && strcmp(daemon->dhcp_buff3, "*") != 0){
+ lease_set_vendor(lease, daemon->dhcp_buff3, strlen(daemon->dhcp_buff3));
+ }
+#endif
+ }
}
#endif
else
@@ -254,10 +271,22 @@
{
for (i = 0; i < lease->clid_len - 1; i++)
ourprintf(&err, "%.2x:", lease->clid[i]);
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "%.2x ", lease->clid[i]);
+#else
ourprintf(&err, "%.2x\n", lease->clid[i]);
+#endif
}
else
- ourprintf(&err, "*\n");
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "* ");
+#else
+ ourprintf(&err, "*\n");
+#endif
+
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "%s\n", (lease->vendorid) ? lease->vendorid : "*");
+#endif
}
#ifdef HAVE_DHCP6
@@ -290,10 +319,22 @@
{
for (i = 0; i < lease->clid_len - 1; i++)
ourprintf(&err, "%.2x:", lease->clid[i]);
- ourprintf(&err, "%.2x\n", lease->clid[i]);
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "%.2x ", lease->clid[i]);
+#else
+ ourprintf(&err, "%.2x\n", lease->clid[i]);
+#endif
}
else
- ourprintf(&err, "*\n");
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "* ");
+#else
+ ourprintf(&err, "*\n");
+#endif
+
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "%s\n", (lease->vendorid) ? lease->vendorid : "*");
+#endif
}
}
#endif
@@ -978,6 +1019,76 @@
lease->flags |= LEASE_CHANGED;
}
+#ifdef ZYXEL_PATCH
+void lease_set_vendor(struct dhcp_lease *lease, const char* vendor, int len)
+{
+ char *new_vendor = NULL;
+
+ if(vendor <= 0) return;
+ if(lease->vendorid){
+ if(!strcmp(lease->vendorid, vendor)) return;
+ free(lease->vendorid);
+ lease->vendorid = NULL;
+ }
+ if ((new_vendor = whine_malloc(len + 1))){
+ strncpy(new_vendor, vendor, len);
+ *(new_vendor+len) = '\0';
+ }
+
+ lease->vendorid = new_vendor;
+
+ lease->flags |= LEASE_CHANGED;
+}
+void lease_set_oui(struct dhcp_lease *lease, const char* value, int len)
+{
+ char *new_val = NULL;
+
+ if(value <= 0) return;
+ if(lease->oui){
+ free(lease->oui);
+ lease->oui = NULL;
+ }
+ if ((new_val = whine_malloc(len + 1))){
+ strncpy(new_val, value, len);
+ *(new_val+len) = '\0';
+ }
+
+ lease->oui = new_val;
+}
+void lease_set_serial(struct dhcp_lease *lease, const char* value, int len)
+{
+ char *new_val = NULL;
+
+ if(value <= 0) return;
+ if(lease->serial){
+ free(lease->serial);
+ lease->serial = NULL;
+ }
+ if ((new_val = whine_malloc(len + 1))){
+ strncpy(new_val, value, len);
+ *(new_val+len) = '\0';
+ }
+
+ lease->serial = new_val;
+}
+void lease_set_class(struct dhcp_lease *lease, const char* value, int len)
+{
+ char *new_val = NULL;
+
+ if(value <= 0) return;
+ if(lease->pclass){
+ free(lease->pclass);
+ lease->pclass = NULL;
+ }
+ if ((new_val = whine_malloc(len + 1))){
+ strncpy(new_val, value, len);
+ *(new_val+len) = '\0';
+ }
+
+ lease->pclass = new_val;
+}
+#endif
+
/* deleted leases get transferred to the old_leases list.
remove them here, after calling the lease change
script. Also run the lease change script on new/modified leases.
@@ -1020,6 +1131,9 @@
free(slaac);
}
#endif
+#ifdef ZYXEL_PATCH
+ sendLeaseMessageToESMD(ACTION_DEL, lease, NULL);
+#endif
kill_name(lease);
#ifdef HAVE_SCRIPT
queue_script(ACTION_DEL, lease, lease->old_hostname, now);
@@ -1029,6 +1143,20 @@
#endif
old_leases = lease->next;
+#ifdef ZYXEL_PATCH
+ if(lease->vendorid){
+ free(lease->vendorid);
+ }
+ if(lease->oui){
+ free(lease->oui);
+ }
+ if(lease->serial){
+ free(lease->serial);
+ }
+ if(lease->pclass){
+ free(lease->pclass);
+ }
+#endif
free(lease->old_hostname);
free(lease->clid);
free(lease->extradata);
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2015-10-07 20:51:19.006774229 +0800
@@ -93,7 +93,9 @@
struct dhcp_opt *o;
unsigned char pxe_uuid[17];
unsigned char *oui = NULL, *serial = NULL, *class = NULL;
-
+#ifdef ZYXEL_PATCH
+ char *vendor_class_ptr = NULL;
+#endif
subnet_addr.s_addr = override.s_addr = 0;
/* set tag with name == interface */
@@ -456,6 +458,9 @@
{
memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
vendor_class_len = option_len(opt);
+#ifdef ZYXEL_PATCH
+ vendor_class_ptr = option_ptr(opt, 0);
+#endif
}
match_vendor_opts(opt, daemon->dhcp_opts);
@@ -598,6 +603,16 @@
lease_set_hwaddr(lease, mess->chaddr, NULL, mess->hlen, mess->htype, 0, now, 1);
if (hostname)
lease_set_hostname(lease, hostname, 1, get_domain(lease->addr), domain);
+#ifdef ZYXEL_PATCH
+ if(vendor_class_len)
+ lease_set_vendor(lease, vendor_class_ptr, vendor_class_len);
+ if(oui)
+ lease_set_oui(lease, option_ptr(oui, 0), option_len(oui));
+ if(serial)
+ lease_set_serial(lease, option_ptr(serial, 0), option_len(serial));
+ if(class)
+ lease_set_class(lease, option_ptr(class, 0), option_len(class));
+#endif
/* infinite lease unless nailed in dhcp-host line. */
lease_set_expires(lease,
have_config(config, CONFIG_TIME) ? config->lease_time : 0xffffffff,
@@ -1346,7 +1361,16 @@
if (hostname)
lease_set_hostname(lease, hostname, hostname_auth, get_domain(lease->addr), domain);
-
+#ifdef ZYXEL_PATCH
+ if(vendor_class_len)
+ lease_set_vendor(lease, vendor_class_ptr, vendor_class_len);
+ if(oui)
+ lease_set_oui(lease, option_ptr(oui, 0), option_len(oui));
+ if(serial)
+ lease_set_serial(lease, option_ptr(serial, 0), option_len(serial));
+ if(class)
+ lease_set_class(lease, option_ptr(class, 0), option_len(class));
+#endif
lease_set_expires(lease, time, now);
lease_set_interface(lease, int_index, now);
@@ -1370,6 +1394,9 @@
}
do_options(context, mess, end, req_options, hostname, get_domain(mess->yiaddr),
netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
+#ifdef ZYXEL_PATCH
+ sendLeaseMessageToESMD(ACTION_ADD, lease, iface_name);
+#endif
}
return dhcp_packet_size(mess, agent_id, real_end);
Index: dnsmasq-2.67/src/extern.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dnsmasq-2.67/src/extern.c 2015-10-07 20:51:18.610774236 +0800
@@ -0,0 +1,134 @@
+#ifdef ZYXEL_PATCH
+#include <stdio.h>
+#include <string.h>
+#include "dnsmasq.h"
+
+/*ZyXEL zcfg*/
+#include "zcfg_common.h"
+#include "zcfg_debug.h"
+#include "zcfg_msg.h"
+
+
+void dnsmasq_eid_register( void ){
+ zcfgRet_t retzcfg;
+
+ /*Register dnsmasq eid which is defined in zcfg_eid.h*/
+ zcfgEidInit(ZCFG_EID_DNSMASQ, NULL);
+
+ /*init message server*/
+ retzcfg = zcfgMsgServerInit();
+ if(retzcfg != ZCFG_SUCCESS) {
+ zcfgLog(ZCFG_LOG_ERR, "Dnsmasq message server init fail\n");
+ return 0;
+ }
+}
+
+static zcfgRet_t dnsmasq_msg_send(int msg_type, int payloadLen, const char *payload, char **reply)
+{
+ zcfgRet_t ret = 0;
+ void *sendBuf = NULL;
+ void *recvBuf = NULL;
+ zcfgMsg_t *sendMsgHdr = NULL;
+ zcfgMsg_t *recvMsgHdr = NULL;
+ char *recv_str = NULL;
+ int buf_size = 0;
+
+ buf_size = sizeof(zcfgMsg_t)+payloadLen+1;
+ sendBuf = calloc(1,buf_size);
+ sendMsgHdr = (zcfgMsg_t*)sendBuf;
+
+ sendMsgHdr->type = msg_type;
+ sendMsgHdr->length = payloadLen+1;
+ sendMsgHdr->srcEid = ZCFG_EID_DNSMASQ;
+ sendMsgHdr->dstEid = ZCFG_EID_ESMD;
+ if(payload != NULL)
+ memcpy(sendBuf+sizeof(zcfgMsg_t), payload, payloadLen);
+
+ ret = zcfgMsgSendAndGetReply(sendMsgHdr, (zcfgMsg_t **)&recvBuf, 0);
+ if(ret == ZCFG_SUCCESS) {
+ recvMsgHdr = (zcfgMsg_t*)recvBuf;
+ if(recvMsgHdr){
+ if(recvMsgHdr->type == RESPONSE_SUCCESS) {
+ recv_str = (char *)recvBuf+sizeof(zcfgMsg_t);
+ if(recvMsgHdr->length > 0 && reply){
+ *reply = calloc(1, recvMsgHdr->length+1);
+ if(*reply) memcpy(*reply, recv_str, recvMsgHdr->length);
+ }
+ }
+ free(recvBuf);
+ }
+ }
+
+ return ret;
+}
+
+void sendLeaseMessageToESMD(int action, struct dhcp_lease *lease, const char *ifname)
+{
+ zcfgRet_t ret = 0;
+ char buf[2048] = {0}, *bufPtr, tmp[256] = {0}, *tmpPtr;
+ char *actionStr = NULL;
+ int i;
+ my_syslog(MS_DHCP | LOG_INFO, "%s ", __func__);
+
+ bufPtr = buf;
+ bufPtr += sprintf(bufPtr, "{");
+
+ switch(action){
+ case ACTION_ADD:
+ actionStr = "add";
+ break;
+ case ACTION_DEL:
+ actionStr = "del";
+ break;
+ case ACTION_OLD_HOSTNAME:
+ case ACTION_OLD:
+ actionStr = "up";
+ break;
+ }
+ if(actionStr)
+ bufPtr += sprintf(bufPtr, "\"ac\":\"%s\",", actionStr);
+
+ bufPtr += sprintf(bufPtr, "\"expire\":\"%lu\",", lease->expires);
+
+ tmpPtr = tmp;
+ for (i = 0; i < lease->hwaddr_len-1; i++)
+ tmpPtr += sprintf(tmpPtr, "%.2x:", lease->hwaddr[i]);
+ tmpPtr += sprintf(tmpPtr, "%.2x", lease->hwaddr[i]);
+ bufPtr += sprintf(bufPtr, "\"mac\":\"%s\",", tmp);
+
+#ifdef HAVE_DHCP6
+ if ((lease->flags & (LEASE_TA | LEASE_NA))){
+ bufPtr += sprintf(bufPtr, "\"ip\":\"%s\",", inet_ntop(AF_INET6, &lease->addr6, tmp, ADDRSTRLEN));
+ }
+ else
+#endif
+ bufPtr += sprintf(bufPtr, "\"ip\":\"%s\",", inet_ntop(AF_INET, &lease->addr, tmp, ADDRSTRLEN));
+
+ bufPtr += sprintf(bufPtr, "\"host\":\"%s\",", (lease->hostname) ? lease->hostname : "*");
+ //option 60
+ bufPtr += sprintf(bufPtr, "\"vendor\":\"%s\",", (lease->vendorid) ? lease->vendorid : "*");
+ //option 125
+ bufPtr += sprintf(bufPtr, "\"moui\":\"%s\",", (lease->oui) ? lease->oui : "*");
+ bufPtr += sprintf(bufPtr, "\"serial\":\"%s\",", (lease->serial) ? lease->serial : "*");
+ bufPtr += sprintf(bufPtr, "\"pclass\":\"%s\",", (lease->pclass) ? lease->pclass : "*");
+ //option 61
+ if (lease->clid && lease->clid_len != 0) {
+ tmpPtr = tmp;
+ for (i = 0; i < lease->clid_len - 1; i++)
+ tmpPtr += sprintf(tmpPtr, "%.2x:", lease->clid[i]);
+ tmpPtr += sprintf(tmpPtr, "%.2x", lease->clid[i]);
+ }
+ else sprintf(tmp, "*");
+ bufPtr += sprintf(bufPtr, "\"cid\":\"%s\",", tmp);
+
+ bufPtr += sprintf(bufPtr, "\"ifname\":\"%s\"", (ifname) ? ifname : "*");
+ bufPtr += sprintf(bufPtr, "}");
+
+ bufPtr = '\0';
+
+ my_syslog(MS_DHCP | LOG_INFO, "%s send to esmd buf = %s", __func__, buf);
+ ret = dnsmasq_msg_send(ZCFG_MSG_DHCPD_OPTION, strlen(buf), buf, NULL);
+ my_syslog(MS_DHCP | LOG_INFO, "%s esmd reply=%d", __func__, ret);
+}
+
+#endif
Index: dnsmasq-2.67/src/util.c
===================================================================
--- dnsmasq-2.67.orig/src/util.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/util.c 2015-10-07 18:05:37.110960367 +0800
@@ -302,7 +302,9 @@
return 1;
}
-
+#ifdef ZYXEL_PATCH
+#include <sys/sysinfo.h>
+#endif
time_t dnsmasq_time(void)
{
#ifdef HAVE_BROKEN_RTC
@@ -314,8 +316,14 @@
return (time_t)(times(&dummy)/tps);
#else
+#ifdef ZYXEL_PATCH
+ struct sysinfo sysinfoObject;
+ sysinfo(&sysinfoObject);
+ return sysinfoObject.uptime;
+#else
return time(NULL);
#endif
+#endif
}
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
@@ -0,0 +1,15 @@
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2015-10-06 21:49:19.991394248 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2015-10-06 21:53:25.141259510 +0800
@@ -945,8 +945,10 @@
prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"),
inet_ntoa(config->addr), daemon->dhcp_buff);
+#ifndef ZYXEL_PATCH /* when static addr is declined by host, do not disable static address lease, just let host keep on trying, ZyXEL, John */
config->flags |= CONFIG_DECLINED;
config->decline_time = now;
+#endif
}
else
/* make sure this host gets a different address next time. */
@@ -0,0 +1,242 @@
Index: dnsmasq-2.67/src/forward.c
===================================================================
--- dnsmasq-2.67.orig/src/forward.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/forward.c 2014-06-16 19:11:13.174681452 +0800
@@ -359,6 +359,12 @@
fd = start->sfd->fd;
else
{
+#ifdef ZYXEL_PATCH //reject query when special domain query has no socket
+ if(type == SERV_HAS_DOMAIN && hostname_isequal(domain, start->domain)){
+ my_syslog(LOG_WARNING, _("Reject query for %s"), start->domain);
+ break;
+ }
+#endif
#ifdef HAVE_IPV6
if (start->addr.sa.sa_family == AF_INET6)
{
Index: dnsmasq-2.67/src/network.c
===================================================================
--- dnsmasq-2.67.orig/src/network.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/network.c 2014-06-16 19:11:13.174681452 +0800
@@ -1031,8 +1031,14 @@
return 1;
}
+#ifdef ZYXEL_PATCH
+#define allocate_sfd(a, i) do_allocate_sfd(a, i, 0)
+#define allocate_sfd_mark(a, i, m) do_allocate_sfd(a, i, m)
+static struct serverfd *do_allocate_sfd(union mysockaddr *addr, char *intname, unsigned long mark)
+#else
static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
+#endif
{
struct serverfd *sfd;
int errsave;
@@ -1072,6 +1078,11 @@
free(sfd);
return NULL;
}
+#ifdef ZYXEL_PATCH
+ if(mark != 0) {
+ setsockopt(sfd->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
+ }
+#endif
if (!local_bind(sfd->fd, addr, intname, 0) || !fix_fd(sfd->fd))
{
@@ -1120,7 +1131,11 @@
for (srv = daemon->servers; srv; srv = srv->next)
if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)) &&
+#ifdef ZYXEL_PATCH
+ !allocate_sfd_mark(&srv->source_addr, srv->interface, srv->sock_mark) &&
+#else
!allocate_sfd(&srv->source_addr, srv->interface) &&
+#endif
errno != 0 &&
option_bool(OPT_NOWILD))
{
@@ -1141,6 +1156,8 @@
struct irec *iface;
struct server *new, *tmp, *ret = NULL;
int port = 0;
+#ifdef ZYXEL_PATCH
+#endif
/* interface may be new since startup */
if (!option_bool(OPT_NOWILD))
@@ -1158,8 +1175,12 @@
if (new->addr.sa.sa_family == AF_INET &&
new->addr.in.sin_addr.s_addr == 0)
{
+#ifdef ZYXEL_PATCH // don't ignoring 0.0.0.0, for special reject query
+ goto SETTOLIST;
+#else
free(new);
continue;
+#endif
}
for (iface = daemon->interfaces; iface; iface = iface->next)
@@ -1174,17 +1195,25 @@
/* Do we need a socket set? */
if (!new->sfd &&
+#ifdef ZYXEL_PATCH
+ !(new->sfd = allocate_sfd_mark(&new->source_addr, new->interface, new->sock_mark)) &&
+#else
!(new->sfd = allocate_sfd(&new->source_addr, new->interface)) &&
+#endif
errno != 0)
{
my_syslog(LOG_WARNING,
_("ignoring nameserver %s - cannot make/bind socket: %s"),
daemon->namebuff, strerror(errno));
+#ifndef ZYXEL_PATCH //don't free special domain rule. for reject query
free(new);
continue;
+#endif
}
}
-
+#ifdef ZYXEL_PATCH
+SETTOLIST:
+#endif
/* reverse order - gets it right. */
new->next = ret;
ret = new;
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2014-06-16 19:11:13.154681452 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2014-06-16 19:11:13.178681452 +0800
@@ -443,6 +443,9 @@
struct server {
union mysockaddr addr, source_addr;
+#ifdef ZYXEL_PATCH
+ unsigned long sock_mark;
+#endif
char interface[IF_NAMESIZE+1];
struct serverfd *sfd;
char *domain; /* set if this server only handles a domain. */
@@ -1053,8 +1056,13 @@
void set_option_bool(unsigned int opt);
void reset_option_bool(unsigned int opt);
struct hostsfile *expand_filelist(struct hostsfile *list);
+#ifdef ZYXEL_PATCH
+char *parse_server(char *arg, union mysockaddr *addr,
+ union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark);
+#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags);
+#endif
/* forward.c */
void reply_query(int fd, int family, time_t now);
Index: dnsmasq-2.67/src/option.c
===================================================================
--- dnsmasq-2.67.orig/src/option.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/option.c 2014-06-16 19:13:01.399686700 +0800
@@ -555,7 +555,24 @@
return ret;
}
+#ifdef ZYXEL_PATCH
+static int hextoul_check(char *a, unsigned long *res)
+{
+ char *p;
+
+ if (!a)
+ return 0;
+ unhide_metas(a);
+
+ for (p = a; *p; p++)
+ if ( !((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f')) )
+ return 0;
+
+ *res = strtoul(a, NULL, 16);
+ return 1;
+}
+#endif
static int atoi_check(char *a, int *res)
{
char *p;
@@ -656,8 +673,11 @@
}
#define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
-
+#ifdef ZYXEL_PATCH
+char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark)
+#else
char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags)
+#endif
{
int source_port = 0, serv_port = NAMESERVER_PORT;
char *portno, *source;
@@ -665,12 +685,21 @@
int scope_index = 0;
char *scope_id;
#endif
+#ifdef ZYXEL_PATCH
+ char *markPtr = NULL;
+ unsigned long sock_mark = 0;
+#endif
if ((source = split_chr(arg, '@')) && /* is there a source. */
(portno = split_chr(source, '#')) &&
!atoi_check16(portno, &source_port))
return _("bad port");
-
+#ifdef ZYXEL_PATCH
+ if (source && /* is there a source. */
+ (markPtr = split_chr(source, '$')) &&
+ !hextoul_check(markPtr, &sock_mark))
+ return _("bad mark");
+#endif
if ((portno = split_chr(arg, '#')) && /* is there a port no. */
!atoi_check16(portno, &serv_port))
return _("bad port");
@@ -691,6 +720,11 @@
if (source)
{
+#ifdef ZYXEL_PATCH
+ if(mark){
+ *mark = sock_mark;
+ }
+#endif
if (flags)
*flags |= SERV_HAS_SOURCE;
source_addr->in.sin_port = htons(source_port);
@@ -2104,7 +2138,11 @@
}
else
{
+#ifdef ZYXEL_PATCH
+ char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags, &newlist->sock_mark);
+#else
char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags);
+#endif
if (err)
ret_err(err);
}
Index: dnsmasq-2.67/src/dbus.c
===================================================================
--- dnsmasq-2.67.orig/src/dbus.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dbus.c 2014-06-16 19:11:13.178681452 +0800
@@ -416,7 +416,11 @@
memset(&interface, 0, sizeof(interface));
/* parse the IP address */
+#ifdef ZYXEL_PATCH
+ addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL, NULL);
+#else
addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL);
+#endif
if (addr_err)
{
@@ -0,0 +1,216 @@
diff -Naur dnsmasq-2.67.orig/src/cache.c dnsmasq-2.67/src/cache.c
--- dnsmasq-2.67.orig/src/cache.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/cache.c 2014-08-29 15:43:07.109749700 +0800
@@ -512,12 +512,70 @@
return new;
}
+#ifdef DNS_TRAFFIC_ROUTE
+add_dns_traffic_route(uint32_t s_addr, const char *cname, int *flush)
+{
+ char sysCmd[128] = "";
+ struct in_addr srcIP;
+ srcIP.s_addr = s_addr;
+ struct server *serv = NULL;
+
+ if(s_addr == 0){
+ return;
+ }
+
+ serv = daemon->servers;
+
+ while(serv){
+ if(serv->domain && (strcmp(cname, serv->domain) == 0)){
+ if(*flush){
+ /* deledt */
+ sprintf(sysCmd, "iptables -t mangle -D IP_ROUTE2_DNSRT -j DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ sprintf(sysCmd, "iptables -t mangle -F DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ sprintf(sysCmd, "iptables -t mangle -X DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ /* create */
+ sprintf(sysCmd, "iptables -t mangle -N DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ sprintf(sysCmd, "iptables -t mangle -A IP_ROUTE2_DNSRT -j DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ *flush = 0;
+ }
+
+ /* add */
+ sprintf(sysCmd, "iptables -t mangle -D DNSRT_RULE_%d -d %s/%d -j MARK --or-mark 0x%x 2> /dev/null",
+ serv->rule_no, inet_ntoa(srcIP), serv->subnet_mask, serv->sock_mark);
+ system(sysCmd);
+
+ sprintf(sysCmd, "iptables -t mangle -A DNSRT_RULE_%d -d %s/%d -j MARK --or-mark 0x%x",
+ serv->rule_no, inet_ntoa(srcIP), serv->subnet_mask, serv->sock_mark);
+ system(sysCmd);
+
+ break;
+ }
+ serv = serv->next;
+ }
+}
+#endif
+
/* after end of insertion, commit the new entries */
void cache_end_insert(void)
{
+#ifdef DNS_TRAFFIC_ROUTE
+ struct in_addr *target = NULL;
+ int flush = 1;
+#endif
+
if (insert_error)
return;
-
+
while (new_chain)
{
struct crec *tmp = new_chain->next;
@@ -529,6 +587,15 @@
cache_hash(new_chain);
cache_link(new_chain);
cache_inserted++;
+#ifdef DNS_TRAFFIC_ROUTE
+ if((new_chain->flags & (F_FORWARD|F_IPV4)) == (F_FORWARD|F_IPV4)){
+ target = &new_chain->addr.addr.addr.addr4;
+ }
+
+ if(target){
+ add_dns_traffic_route(target->s_addr, cache_get_name(new_chain), &flush);
+ }
+#endif
}
new_chain = tmp;
}
diff -Naur dnsmasq-2.67.orig/src/dbus.c dnsmasq-2.67/src/dbus.c
--- dnsmasq-2.67.orig/src/dbus.c 2014-08-23 02:22:30.903783200 +0800
+++ dnsmasq-2.67/src/dbus.c 2014-08-29 15:37:40.543527100 +0800
@@ -416,8 +416,12 @@
memset(&interface, 0, sizeof(interface));
/* parse the IP address */
-#ifdef ZYXEL_PATCH
+#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+ addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL, NULL, NULL, NULL);
+#else
addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL, NULL);
+#endif
#else
addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL);
#endif
diff -Naur dnsmasq-2.67.orig/src/dnsmasq.h dnsmasq-2.67/src/dnsmasq.h
--- dnsmasq-2.67.orig/src/dnsmasq.h 2014-08-23 02:22:30.903783200 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2014-08-29 15:38:13.274434400 +0800
@@ -445,6 +445,10 @@
union mysockaddr addr, source_addr;
#ifdef ZYXEL_PATCH
unsigned long sock_mark;
+#ifdef DNS_TRAFFIC_ROUTE
+ int subnet_mask;
+ int rule_no;
+#endif
#endif
char interface[IF_NAMESIZE+1];
struct serverfd *sfd;
@@ -1057,8 +1061,14 @@
void reset_option_bool(unsigned int opt);
struct hostsfile *expand_filelist(struct hostsfile *list);
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+char *parse_server(char *arg, union mysockaddr *addr,
+ union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark,
+ int *subnet_mask, int *rule_no);
+#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark);
+#endif
#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags);
diff -Naur dnsmasq-2.67.orig/src/option.c dnsmasq-2.67/src/option.c
--- dnsmasq-2.67.orig/src/option.c 2014-08-23 02:22:30.903783200 +0800
+++ dnsmasq-2.67/src/option.c 2014-08-29 15:45:11.313805300 +0800
@@ -674,7 +674,11 @@
#define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark, int *subnet_mask, int *rule_no)
+#else
char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark)
+#endif
#else
char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags)
#endif
@@ -688,6 +692,12 @@
#ifdef ZYXEL_PATCH
char *markPtr = NULL;
unsigned long sock_mark = 0;
+#ifdef DNS_TRAFFIC_ROUTE
+ char *maskPtr = NULL;
+ int mask = 32;
+ char *rulePtr = NULL;
+ int rule = 0;
+#endif
#endif
if ((source = split_chr(arg, '@')) && /* is there a source. */
@@ -695,10 +705,20 @@
!atoi_check16(portno, &source_port))
return _("bad port");
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+ if (source && /* is there a source. */
+ (rulePtr = split_chr(source, '|')) &&
+ !atoi_check(rulePtr, &rule))
+ return _("bad rule");
+ if (source && /* is there a source. */
+ (maskPtr = split_chr(source, '&')) &&
+ !atoi_check(maskPtr, &mask))
+ return _("bad mask");
+#endif
if (source && /* is there a source. */
(markPtr = split_chr(source, '$')) &&
!hextoul_check(markPtr, &sock_mark))
- return _("bad mark");
+ return _("bad mark");
#endif
if ((portno = split_chr(arg, '#')) && /* is there a port no. */
!atoi_check16(portno, &serv_port))
@@ -724,6 +744,14 @@
if(mark){
*mark = sock_mark;
}
+#ifdef DNS_TRAFFIC_ROUTE
+ if(subnet_mask){
+ *subnet_mask = mask;
+ }
+ if(rule_no){
+ *rule_no = rule;
+ }
+#endif
#endif
if (flags)
*flags |= SERV_HAS_SOURCE;
@@ -2138,8 +2166,12 @@
}
else
{
-#ifdef ZYXEL_PATCH
+#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+ char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags, &newlist->sock_mark, &newlist->subnet_mask, &newlist->rule_no);
+#else
char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags, &newlist->sock_mark);
+#endif
#else
char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags);
#endif
@@ -0,0 +1,179 @@
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2015-10-06 21:54:55.815172500 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2015-10-06 21:56:51.632448593 +0800
@@ -695,7 +695,13 @@
struct dhcp_netid netid;
struct dhcp_mac *next;
};
-
+#ifdef ZYXEL_PATCH
+struct dhcp_ifname {
+ char ifname[IF_NAMESIZE];
+ struct dhcp_netid netid;
+ struct dhcp_ifname *next;
+};
+#endif
struct dhcp_bridge {
char iface[IF_NAMESIZE];
struct dhcp_bridge *alias, *next;
@@ -932,7 +938,9 @@
/* utility string buffer, hold max sized IP address as string */
char *addrbuff;
-
+#ifdef ZYXEL_PATCH
+ struct dhcp_ifname *dhcp_ifnames;
+#endif
} *daemon;
/* cache.c */
Index: dnsmasq-2.67/src/option.c
===================================================================
--- dnsmasq-2.67.orig/src/option.c 2015-10-06 21:54:55.815172500 +0800
+++ dnsmasq-2.67/src/option.c 2015-10-06 22:03:09.119258108 +0800
@@ -138,7 +138,9 @@
#define LOPT_QUIET_DHCP 326
#define LOPT_QUIET_DHCP6 327
#define LOPT_QUIET_RA 328
-
+#ifdef ZYXEL_PATCH
+#define LOPT_TAG_IFNAME 329
+#endif
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
@@ -282,6 +284,9 @@
{ "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP },
{ "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6 },
{ "quiet-ra", 0, 0, LOPT_QUIET_RA },
+#ifdef ZYXEL_PATCH
+ { "dhcp-ifname", 1, 0, LOPT_TAG_IFNAME},
+#endif
{ NULL, 0, 0, 0 }
};
@@ -431,6 +436,9 @@
{ LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL },
{ LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL },
{ LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },
+#ifdef ZYXEL_PATCH
+ { LOPT_TAG_IFNAME, ARG_DUP, "set:<tag>,<ifname>", gettext_noop("Map interface name to option set."), NULL },
+#endif
{ 0, 0, NULL, NULL, NULL }
};
@@ -3122,7 +3130,24 @@
}
}
break;
+#ifdef ZYXEL_PATCH
+ case LOPT_TAG_IFNAME: /* --dhcp-ifname */
+ {
+ if (!(comma = split(arg)))
+ ret_err(gen_err);
+ else
+ {
+ struct dhcp_ifname *new = opt_malloc(sizeof(struct dhcp_ifname));
+ new->netid.net = opt_string_alloc(set_prefix(arg));
+ arg = comma;
+ strcpy(new->ifname, arg);
+ new->next = daemon->dhcp_ifnames;
+ daemon->dhcp_ifnames = new;
+ }
+ }
+ break;
+#endif
#ifdef OPTION6_PREFIX_CLASS
case LOPT_PREF_CLSS: /* --dhcp-prefix-class */
{
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2015-10-06 21:53:25.141259510 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2015-10-06 22:01:54.182206768 +0800
@@ -61,7 +61,9 @@
static int prune_vendor_opts(struct dhcp_netid *netid);
static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now);
struct dhcp_boot *find_boot(struct dhcp_netid *netid);
-
+#ifdef ZYXEL_PATCH
+static int find_ifname(unsigned char *subnet_mac, int len, char *ifname, char *interface);
+#endif
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
size_t sz, time_t now, int unicast_dest, int *is_inform, int pxe, struct in_addr fallback)
@@ -95,6 +97,7 @@
unsigned char *oui = NULL, *serial = NULL, *class = NULL;
#ifdef ZYXEL_PATCH
char *vendor_class_ptr = NULL;
+ struct dhcp_ifname *ifname;
#endif
subnet_addr.s_addr = override.s_addr = 0;
@@ -247,7 +250,15 @@
/* find mac to use for logging and hashing */
emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
}
-
+
+ for (ifname = daemon->dhcp_ifnames; ifname; ifname = ifname->next){
+
+ if(find_ifname(mess->chaddr, mess->hlen, ifname->ifname, iface_name)){
+ ifname->netid.next = netid;
+ netid = &ifname->netid;
+ }
+ }
+
for (mac = daemon->dhcp_macs; mac; mac = mac->next)
if (mac->hwaddr_len == mess->hlen &&
(mac->hwaddr_type == mess->htype || mac->hwaddr_type == 0) &&
@@ -256,7 +267,7 @@
mac->netid.next = netid;
netid = &mac->netid;
}
-
+
/* Determine network for this packet. Our caller will have already linked all the
contexts which match the addresses of the receiving interface but if the
machine has an address already, or came via a relay, or we have a subnet selector,
@@ -2147,7 +2158,39 @@
return boot;
}
+#ifdef ZYXEL_PATCH
+static int find_ifname(unsigned char *subnet_mac, int len, char *ifname, char *interface)
+{
+ FILE *fp;
+ char sysCmd[128] = {0};
+ char line[128] = {0};
+
+ int sub_mac_idx = 0;
+ char mac_value[32]={0};
+
+ for(sub_mac_idx = 0 ; sub_mac_idx < len ; sub_mac_idx++){
+ if(0 == sub_mac_idx){
+ sprintf(mac_value, "%02x", subnet_mac[sub_mac_idx]);
+ }else{
+ sprintf(mac_value, "%s:%02x", mac_value, subnet_mac[sub_mac_idx]);
+ }
+ }
+
+ sprintf(sysCmd, "brctl showmacs %s | grep %s", interface, mac_value);
+ fp = popen(sysCmd, "r");
+ if(fp){
+ while(fgets(line, sizeof(line), fp) != NULL){
+ if(strstr(line, ifname) != NULL){
+ pclose(fp);
+ return 1;
+ }
+ }
+ pclose(fp);
+ }
+ return 0;
+}
+#endif
static void do_options(struct dhcp_context *context,
struct dhcp_packet *mess,
unsigned char *end,
@@ -0,0 +1,365 @@
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2015-10-12 14:25:07.482715684 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2015-10-12 14:38:37.756546124 +0800
@@ -63,6 +63,54 @@
struct dhcp_boot *find_boot(struct dhcp_netid *netid);
#ifdef ZYXEL_PATCH
static int find_ifname(unsigned char *subnet_mac, int len, char *ifname, char *interface);
+static int checkIntfGrpCrit(struct dhcp_netid *netid, char *iface_name, char *client_hostname,
+ unsigned char *emac, int emac_len,
+ char *vendor_class_ptr, int vendor_class_len,
+ unsigned char *clid, int clid_len,
+ unsigned char *oui, unsigned char *serial, unsigned char *class
+ )
+{
+ struct dhcp_netid *tmpNetid = NULL;
+ struct CritDhcpInfo crit;
+ char *brNamePtr = NULL;
+
+
+ for(tmpNetid = netid; tmpNetid; tmpNetid = tmpNetid->next){
+ //my_syslog(MS_DHCP | LOG_WARNING, _("tmpNetid->net=%s, %s"), tmpNetid->net, iface_name);
+ if( !strncmp(tmpNetid->net, "Crit_br", 7)){
+ brNamePtr = strstr(tmpNetid->net, "br");
+ if(iface_name != NULL && strcmp(brNamePtr, iface_name)){
+ memset(&crit, 0, sizeof(crit));
+ crit.ifname = iface_name;
+ crit.emac = emac;
+ crit.emac_len = emac_len;
+ crit.hostname = client_hostname;
+ strcpy(crit.tag, tmpNetid->net);
+ if(oui){
+ crit.oui = option_ptr(oui, 0);
+ crit.oui_len = option_len(oui);
+ }
+ if(serial){
+ crit.serial = option_ptr(serial, 0);
+ crit.serial_len = option_len(serial);
+ }
+ if(class){
+ crit.pclass = option_ptr(class, 0);
+ crit.pclass_len = option_len(class);
+ }
+ crit.vendor = vendor_class_ptr;
+ crit.vendor_len = vendor_class_len;
+ if(clid){
+ crit.clid = clid;
+ crit.clid_len = clid_len;
+ }
+ sendCritMessageToESMD(&crit);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
#endif
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
@@ -1042,9 +1090,16 @@
else if (!address_allocate(context, &mess->yiaddr, emac, emac_len, tagif_netid, now))
message = _("no address available");
}
-
+#ifdef ZYXEL_PATCH
+ if(checkIntfGrpCrit(tagif_netid, iface_name, client_hostname, emac, emac_len, vendor_class_ptr, vendor_class_len, clid, clid_len, oui, serial, class)
+ || checkIntfGrpCrit(netid, iface_name, client_hostname, emac, emac_len, vendor_class_ptr, vendor_class_len, clid, clid_len, oui, serial, class))
+ {
+ //my_syslog(MS_DHCP | LOG_WARNING, _("Match interface grouping criteria !!! "));
+ return 0;
+ }
+#endif
log_packet("DHCPDISCOVER", opt ? option_ptr(opt, 0) : NULL, emac, emac_len, iface_name, NULL, message, mess->xid);
-
+
if (message || !(context = narrow_context(context, mess->yiaddr, tagif_netid)))
return 0;
@@ -1171,7 +1226,14 @@
fuzz = rand16();
mess->yiaddr = mess->ciaddr;
}
-
+#ifdef ZYXEL_PATCH
+ if(checkIntfGrpCrit(tagif_netid, iface_name, client_hostname, emac, emac_len, vendor_class_ptr, vendor_class_len, clid, clid_len, oui, serial, class)
+ || checkIntfGrpCrit(netid, iface_name, client_hostname, emac, emac_len, vendor_class_ptr, vendor_class_len, clid, clid_len, oui, serial, class))
+ {
+ //my_syslog(MS_DHCP | LOG_WARNING, _("Match interface grouping criteria !!! "));
+ return 0;
+ }
+#endif
log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL, NULL, mess->xid);
if (!message)
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2015-10-12 14:25:07.478715684 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2015-10-12 14:37:33.902701709 +0800
@@ -1342,10 +1342,25 @@
/* extern.c */
#ifdef ZYXEL_PATCH
+struct CritDhcpInfo{
+ char *ifname;
+ char *oui, *serial, *pclass;
+ int oui_len, serial_len, pclass_len;
+ char *emac;
+ int emac_len;
+ char *vendor;
+ int vendor_len;
+ char *hostname;
+ unsigned char *clid;
+ int clid_len;
+ char tag[20];
+};
void lease_set_vendor(struct dhcp_lease *, const char* , int );
void lease_set_oui(struct dhcp_lease *, const char* , int );
void lease_set_serial(struct dhcp_lease *, const char* , int );
void lease_set_class(struct dhcp_lease *, const char* , int );
void dnsmasq_eid_register(void);
void sendLeaseMessageToESMD(int, struct dhcp_lease *, const char*);
+void sendCritMessageToESMD(struct CritDhcpInfo *crit);
+void pruneCritReqList(void);
#endif
\ No newline at end of file
Index: dnsmasq-2.67/src/extern.c
===================================================================
--- dnsmasq-2.67.orig/src/extern.c 2015-10-12 14:25:07.426715685 +0800
+++ dnsmasq-2.67/src/extern.c 2015-10-12 14:25:07.494715684 +0800
@@ -23,6 +23,108 @@
}
}
+char *getPhyIfname(const ifname, const char *macaddr, char *reply){
+ static char phyifname[20];
+ char tmp[256] = {0};
+ FILE *fp = NULL;
+
+ phyifname[0] = 0;
+ sprintf(tmp, "brctl showmacs %s | grep %s", ifname, macaddr);
+ if((fp = popen(tmp, "r"))){
+ tmp[0] = '\0';
+ fgets(tmp, sizeof(tmp)-1, fp);
+ pclose(fp);
+ if(sscanf(tmp, "%*s %*s %*s %*s %s", phyifname) == 1){
+ strcpy(reply, phyifname);
+ if(reply) return reply;
+ return phyifname;
+ }
+ }
+
+ return "";
+}
+
+#if 1 //Prevent excessive criteria check request to ESMD.
+struct CritReqList{
+ char mac[20];
+ char phyIf[20];
+ char brIf[20];
+ unsigned long time;
+ struct CritReqList *next;
+} *critReqLists = NULL;
+
+#define CRITTIOMEOUT 15
+
+void pruneCritReqList()
+{
+ unsigned long now = time(NULL);
+ struct CritReqList *next, *prev, *tmp;
+
+ //my_syslog(MS_DHCP | LOG_DEBUG, "%s ", __func__);
+
+ if(!critReqLists) return;
+
+ for(prev = next = critReqLists; next != NULL; ){
+ tmp = next;
+ next = tmp->next;
+ //my_syslog(MS_DHCP | LOG_DEBUG, "%s : %s, %lu", __func__, tmp->mac, now - tmp->time);
+ if((now - tmp->time)>=CRITTIOMEOUT){
+ if(critReqLists == tmp){
+ critReqLists = next;
+ prev = next;
+ }
+ else prev->next = next;
+ free(tmp);
+ }
+ else prev = tmp;
+ }
+}
+
+void addCritReqtoList(const char *mac, const char *brif, const char *phyif)
+{
+ struct CritReqList *tmp, *next, *prev;
+
+ //my_syslog(MS_DHCP | LOG_DEBUG, "%s ", __func__);
+
+ tmp = calloc(1, sizeof(struct CritReqList));
+ strncpy(tmp->mac, mac, sizeof(tmp->mac)-1);
+ strncpy(tmp->brIf, brif, sizeof(tmp->brIf)-1);
+ strncpy(tmp->phyIf, phyif, sizeof(tmp->phyIf)-1);
+ tmp->time = time(NULL);
+
+ if(!critReqLists){
+ critReqLists = tmp;
+ }
+ else{
+ for(next = critReqLists; next != NULL; next = next->next){
+ prev = next;
+ }
+ prev->next = tmp;
+ }
+}
+
+int chkCritReqExist(const char *mac, const char *brif, const char *phyif)
+{
+ struct CritReqList *next;
+
+ if(!critReqLists) return 0;
+
+ for(next = critReqLists; next != NULL; next = next->next){
+#if 0 // when parse interface group criteria, ignore the request which is from same bridge port and physical port
+ if(!strcasecmp(next->mac, mac)){
+ return 1;
+ }
+#else
+ if(!strcmp(next->brIf, brif) && !strcmp(next->phyIf, phyif)){
+ return 1;
+ }
+#endif
+ }
+
+ return 0;
+}
+#endif
+
static zcfgRet_t dnsmasq_msg_send(int msg_type, int payloadLen, const char *payload, char **reply)
{
zcfgRet_t ret = 0;
@@ -68,7 +170,8 @@
char buf[2048] = {0}, *bufPtr, tmp[256] = {0}, *tmpPtr;
char *actionStr = NULL;
int i;
- my_syslog(MS_DHCP | LOG_INFO, "%s ", __func__);
+
+ if(lease <= 0) return;
bufPtr = buf;
bufPtr += sprintf(bufPtr, "{");
@@ -90,11 +193,7 @@
bufPtr += sprintf(bufPtr, "\"expire\":\"%lu\",", lease->expires);
- tmpPtr = tmp;
- for (i = 0; i < lease->hwaddr_len-1; i++)
- tmpPtr += sprintf(tmpPtr, "%.2x:", lease->hwaddr[i]);
- tmpPtr += sprintf(tmpPtr, "%.2x", lease->hwaddr[i]);
- bufPtr += sprintf(bufPtr, "\"mac\":\"%s\",", tmp);
+ bufPtr += sprintf(bufPtr, "\"mac\":\"%s\",", print_mac(tmp, lease->hwaddr, lease->hwaddr_len));
#ifdef HAVE_DHCP6
if ((lease->flags & (LEASE_TA | LEASE_NA))){
@@ -126,9 +225,86 @@
bufPtr = '\0';
- my_syslog(MS_DHCP | LOG_INFO, "%s send to esmd buf = %s", __func__, buf);
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s send to esmd buf = %s", __func__, buf);
+ ret = dnsmasq_msg_send(ZCFG_MSG_DHCPD_OPTION, strlen(buf), buf, NULL);
+ if(ret != ZCFG_SUCCESS || ret != ZCFG_SUCCESS_AND_NO_REPLY)
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s esmd ret=%d", __func__, ret);
+}
+
+void sendCritMessageToESMD(struct CritDhcpInfo *crit)
+{
+ zcfgRet_t ret = 0;
+ char buf[2048] = {0}, *bufPtr, tmp[256] = {0}, *tmpPtr;
+ char macaddr[20] = {0}, phy_ifname[20] = {0};
+ int i;
+
+ if(crit <= 0) return;
+
+ print_mac(macaddr, crit->emac, crit->emac_len);
+ getPhyIfname(crit->ifname, macaddr, phy_ifname);
+
+ if(chkCritReqExist(macaddr, crit->ifname, phy_ifname)){
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s ignore the host (%s) request", __func__, macaddr);
+ return ;
+ }
+
+ bufPtr = buf;
+ bufPtr += sprintf(bufPtr, "{");
+ bufPtr += sprintf(bufPtr, "\"ac\":\"%s\",", "crit");
+ bufPtr += sprintf(bufPtr, "\"mac\":\"%s\",", macaddr);
+
+ bufPtr += sprintf(bufPtr, "\"host\":\"%s\",", (crit->hostname) ? crit->hostname : "*");
+ //option 60
+ if(crit->vendor_len){
+ strncpy(tmp, crit->vendor, crit->vendor_len);
+ tmp[crit->vendor_len] = '\0';
+ }else sprintf(tmp, "*");
+ bufPtr += sprintf(bufPtr, "\"vendor\":\"%s\",", tmp);
+ //option 125
+ strncpy(bufPtr, "\"moui\":\"", 8); bufPtr += 8;
+ if(crit->oui){
+ strncpy(bufPtr, crit->oui, crit->oui_len);
+ bufPtr += crit->oui_len;
+ } else{ *bufPtr = '*'; bufPtr++;}
+ strncpy(bufPtr, "\",", 2); bufPtr += 2;
+
+ strncpy(bufPtr, "\"serial\":\"", 10); bufPtr += 10;
+ if(crit->serial){
+ strncpy(bufPtr, crit->serial, crit->serial_len);
+ bufPtr += crit->serial_len;
+ } else{ *bufPtr = '*'; bufPtr++;}
+ strncpy(bufPtr, "\",", 2); bufPtr += 2;
+
+ strncpy(bufPtr, "\"pclass\":\"", 10); bufPtr += 10;
+ if(crit->pclass){
+ strncpy(bufPtr, crit->pclass, crit->pclass_len);
+ bufPtr += crit->pclass_len;
+ } else{ *bufPtr = '*'; bufPtr++;}
+ strncpy(bufPtr, "\",", 2); bufPtr += 2;
+
+ //option 61
+ if (crit->clid && crit->clid_len != 0) {
+ tmpPtr = tmp;
+ for (i = 0; i < crit->clid_len - 1; i++)
+ tmpPtr += sprintf(tmpPtr, "%.2x:", crit->clid[i]);
+ tmpPtr += sprintf(tmpPtr, "%.2x", crit->clid[i]);
+ }
+ else sprintf(tmp, "*");
+ bufPtr += sprintf(bufPtr, "\"cid\":\"%s\",", tmp);
+ bufPtr += sprintf(bufPtr, "\"tag\":\"%s\",", crit->tag);
+ bufPtr += sprintf(bufPtr, "\"phyif\":\"%s\",", (phy_ifname) ? phy_ifname : "*");
+ bufPtr += sprintf(bufPtr, "\"ifname\":\"%s\"", (crit->ifname) ? crit->ifname : "*");
+ bufPtr += sprintf(bufPtr, "}");
+
+ bufPtr = '\0';
+
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s send to esmd buf = %s", __func__, buf);
ret = dnsmasq_msg_send(ZCFG_MSG_DHCPD_OPTION, strlen(buf), buf, NULL);
- my_syslog(MS_DHCP | LOG_INFO, "%s esmd reply=%d", __func__, ret);
+ // when send criteria request to esmd success, add criteria request to criteria block list
+ if(ret == ZCFG_SUCCESS || ret == ZCFG_SUCCESS_AND_NO_REPLY)
+ addCritReqtoList(macaddr, crit->ifname, phy_ifname);
+ if(ret != ZCFG_SUCCESS || ret != ZCFG_SUCCESS_AND_NO_REPLY)
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s esmd reply=%d", __func__, ret);
}
#endif
Index: dnsmasq-2.67/src/lease.c
===================================================================
--- dnsmasq-2.67.orig/src/lease.c 2015-10-12 14:25:07.422715685 +0800
+++ dnsmasq-2.67/src/lease.c 2015-10-12 14:37:33.890701709 +0800
@@ -1097,7 +1097,9 @@
int do_script_run(time_t now)
{
struct dhcp_lease *lease;
-
+#ifdef ZYXEL_PATCH
+ pruneCritReqList();
+#endif
(void)now;
#ifdef HAVE_DBUS
@@ -0,0 +1,221 @@
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2015-10-12 14:25:07.494715684 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2015-10-12 14:25:12.070715598 +0800
@@ -577,6 +577,15 @@
struct dhcp_lease *next;
};
+#if 1 //oneconnect dhcp.leases2 file
+//[WWH] add
+struct dhcp_lease_tmp {
+ char hwaddr[64];
+ char hostname[512];
+ struct dhcp_lease_tmp *next;
+};
+#endif
+
struct dhcp_netid {
char *net;
struct dhcp_netid *next;
Index: dnsmasq-2.67/src/lease.c
===================================================================
--- dnsmasq-2.67.orig/src/lease.c 2015-10-12 14:25:07.498715684 +0800
+++ dnsmasq-2.67/src/lease.c 2015-10-12 14:25:07.510715683 +0800
@@ -21,6 +21,107 @@
static struct dhcp_lease *leases = NULL, *old_leases = NULL;
static int dns_dirty, file_dirty, leases_left;
+#if 1 //oneconnect dhcp.leases2 file
+//WWH add
+static struct dhcp_lease_tmp *kill_leases = NULL;
+
+/** WWH add *********************************************************/
+static void save_killname(char *hwaddr, char *hostname)
+{
+ if ( hwaddr == NULL || hostname == NULL )
+ {
+ return;
+ }
+
+ struct dhcp_lease_tmp *lease;
+ lease = calloc(1, sizeof(struct dhcp_lease_tmp));
+ lease->next = NULL;
+
+ strcpy(lease->hwaddr , hwaddr);
+ strcpy(lease->hostname, hostname);
+
+ if ( kill_leases == NULL )
+ {
+ kill_leases = lease;
+ }
+ else
+ {
+ struct dhcp_lease_tmp *lease_tmp;
+ lease_tmp = kill_leases;
+ while(lease_tmp->next)
+ {
+ lease_tmp = lease_tmp->next;
+ }
+ lease_tmp->next = lease;
+ }
+}
+
+void get_kill_leases_hostname(char *hwaddr, char *hostname)
+{
+ if ( hwaddr == NULL || kill_leases == NULL )
+ {
+ return;
+ }
+
+ struct dhcp_lease_tmp *lease;
+ lease = kill_leases;
+ while(lease)
+ {
+ if ( strncmp(hwaddr, lease->hwaddr, 17) == 0 ) //find same mac
+ {
+ strcpy(hostname, lease->hostname);
+ return;
+ }
+ lease = lease->next;
+ }
+ strncpy(hostname, "*", 1);
+}
+
+void Removeoutputfile(void)
+{
+ char buf[1024];
+ FILE *fp = fopen("/tmp/dhcp.leases2", "r");
+ if (fp)
+ {
+ while (fgets(buf, sizeof(buf), fp))
+ {
+ char hwaddr[64] = "";
+ char ip[64] = "";
+ char hostname[512] = "";
+ sscanf( buf , "%s %s %s", hwaddr, ip, hostname);
+ save_killname(hwaddr, hostname);
+ }
+ fclose(fp);
+ }
+
+ remove("/tmp/dhcp.leases2");
+ system("touch /tmp/dhcp.leases2");
+}
+
+void outputData(char *outputdata)
+{
+ char output[1024];
+ sprintf(output, "echo \"%s\" >> %s", outputdata, "/tmp/dhcp.leases2");
+ system(output);
+}
+
+
+void free_kill_leases()
+{
+ struct dhcp_lease_tmp *lease_f;
+ struct dhcp_lease_tmp *lease_tmp;
+ lease_f = kill_leases;
+ while (lease_f)
+ {
+ lease_tmp = lease_f->next;
+ free(lease_f);
+ lease_f = lease_tmp;
+ }
+ kill_leases = NULL;
+}
+/** WWH *************************************************************/
+#endif
+
void lease_init(time_t now)
{
unsigned long ei;
@@ -194,6 +295,12 @@
file_dirty = 0;
lease_prune(NULL, now);
dns_dirty = 1;
+
+#if 1 //oneconnect dhcp.leases2 file
+ //[WWH] add
+ system("touch /tmp/dhcp.leases2");
+#endif
+
}
void lease_update_from_configs(void)
@@ -238,7 +345,12 @@
rewind(daemon->lease_stream);
if (errno != 0 || ftruncate(fileno(daemon->lease_stream), 0) != 0)
err = errno;
-
+
+#if 1 //oneconnect dhcp.leases2 file
+ //WWH add
+ Removeoutputfile();
+#endif
+
for (lease = leases; lease; lease = lease->next)
{
@@ -267,6 +379,35 @@
ourprintf(&err, " %s ", daemon->addrbuff);
ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
+#if 1 //oneconnect dhcp.leases2 file
+ //[WWH] output file
+ int macCount = 0;
+ char outputdata[1024] = "";
+ char output_hwaddr[64] = "";
+ char output_hostname[512] = "";
+ for (macCount = 0; macCount < lease->hwaddr_len; macCount++)
+ {
+ sprintf(output_hwaddr+(macCount*3), "%.2x", lease->hwaddr[macCount]);
+ if (macCount != lease->hwaddr_len - 1)
+ {
+ sprintf(output_hwaddr+((macCount*3)+2), ":");
+ }
+ }
+
+ if ( !lease->hostname ) //lease->hostname is NULL, find kill_leases
+ {
+ //get hostname in kill_leases
+ get_kill_leases_hostname(output_hwaddr, output_hostname);
+ }
+ else
+ {
+ strcpy(output_hostname, lease->hostname);
+ }
+ sprintf(outputdata, "%s %s %s\0", output_hwaddr, daemon->addrbuff, output_hostname);
+ //output file
+ outputData(outputdata);
+#endif
+
if (lease->clid && lease->clid_len != 0)
{
for (i = 0; i < lease->clid_len - 1; i++)
@@ -386,6 +527,11 @@
}
send_alarm(next_event, now);
+
+#if 1 //oneconnect dhcp.leases2 file
+ //clear kill_leases
+ free_kill_leases();
+#endif
}
@@ -883,6 +1029,13 @@
static void kill_name(struct dhcp_lease *lease)
{
+#if 1 //oneconnect dhcp.leases2 file
+ //save kill name
+ char hwaddr_tmp[64] = "";
+ sprintf(hwaddr_tmp, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", lease->hwaddr[0],lease->hwaddr[1],lease->hwaddr[2],lease->hwaddr[3],lease->hwaddr[4],lease->hwaddr[5]);
+ save_killname(hwaddr_tmp, lease->hostname);
+#endif
+
/* run script to say we lost our old name */
/* this shouldn't happen unless updates are very quick and the
@@ -0,0 +1,383 @@
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2015-10-12 19:51:32.362349003 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2015-10-12 19:51:32.374349003 +0800
@@ -666,6 +666,9 @@
#define DHOPT_RFC3925 2048
#define DHOPT_TAGOK 4096
#define DHOPT_ADDR6 8192
+#ifdef ZYXEL_PATCH //for option 125
+#define DHOPT_RFC3925_OPT 16384
+#endif
struct dhcp_boot {
char *file, *sname, *tftp_sname;
@@ -687,6 +690,9 @@
#define MATCH_CIRCUIT 3
#define MATCH_REMOTE 4
#define MATCH_SUBSCRIBER 5
+#ifdef ZYXEL_PATCH
+#define MATCH_VENDOR_EXACT 6
+#endif
/* vendorclass, userclass, remote-id or cicuit-id */
struct dhcp_vendor {
Index: dnsmasq-2.67/src/option.c
===================================================================
--- dnsmasq-2.67.orig/src/option.c 2015-10-12 19:51:32.334349003 +0800
+++ dnsmasq-2.67/src/option.c 2015-10-13 18:51:26.348975906 +0800
@@ -140,6 +140,7 @@
#define LOPT_QUIET_RA 328
#ifdef ZYXEL_PATCH
#define LOPT_TAG_IFNAME 329
+#define LOPT_VENDOREXACT 330
#endif
#ifdef HAVE_GETOPT_LONG
@@ -196,6 +197,9 @@
{ "read-ethers", 0, 0, 'Z' },
{ "alias", 1, 0, 'V' },
{ "dhcp-vendorclass", 1, 0, 'U' },
+#ifdef ZYXEL_PATCH
+ { "dhcp-vendorclass-exact", 1, 0, LOPT_VENDOREXACT },
+#endif
{ "dhcp-userclass", 1, 0, 'j' },
{ "dhcp-ignore", 1, 0, 'J' },
{ "edns-packet-max", 1, 0, 'P' },
@@ -356,6 +360,9 @@
{ LOPT_MAXTTL, ARG_ONE, "<integer>", gettext_noop("Specify time-to-live in seconds for maximum TTL to send to clients."), NULL },
{ 'u', ARG_ONE, "<username>", gettext_noop("Change to this user after startup. (defaults to %s)."), CHUSER },
{ 'U', ARG_DUP, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag."), NULL },
+#ifdef ZYXEL_PATCH
+ { LOPT_VENDOREXACT, ARG_DUP, "set:<tag>,<class>", gettext_noop("Map DHCP vendor class to tag. (Exact match)"), NULL },
+#endif
{ 'v', 0, NULL, gettext_noop("Display dnsmasq version and copyright information."), NULL },
{ 'V', ARG_DUP, "<ipaddr>,<ipaddr>,<netmask>", gettext_noop("Translate IPv4 addresses from upstream servers."), NULL },
{ 'W', ARG_DUP, "<name>,<target>,...", gettext_noop("Specify a SRV record."), NULL },
@@ -924,6 +931,18 @@
break;
}
}
+#ifdef ZYXEL_PATCH //for option 125
+ else if (strstr(arg, "vi-encap-opt:") == arg)
+ {
+ new->u.encap = atoi(arg+13);
+ new->flags |= DHOPT_RFC3925_OPT;
+ if (flags == DHOPT_MATCH)
+ {
+ option_ok = 1;
+ break;
+ }
+ }
+#endif
else
{
new->netid = opt_malloc(sizeof (struct dhcp_netid));
@@ -935,7 +954,7 @@
new->netid->next = np;
np = new->netid;
}
-
+
arg = comma;
}
@@ -952,13 +971,80 @@
else
#endif
if (opt_len == 0 &&
- !(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925)))
+#ifdef ZYXEL_PATCH //for option 125
+ !(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925 | DHOPT_RFC3925_OPT))
+#else
+ !(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925))
+#endif
+ )
opt_len = lookup_dhcp_len(AF_INET, new->opt);
/* option may be missing with rfc3925 match */
if (!option_ok)
ret_err(_("bad dhcp-option"));
-
+#ifdef ZYXEL_PATCH //for option 125
+ // config format {id}={str}%%{id}=hex#{hex_str}%%....
+ // convert to format {id}{len}{val}{id}{len}{val}....
+ if(comma && (new->flags & DHOPT_RFC3925_OPT)){
+ char *tmp_val,*match_str, *next_str, *tmpPtr, *tmpPtr2, tmpBuf[10];
+ char *new_val;
+ int tmp_len, i, match_len, j, k, match_id, v;
+
+ if((tmp_len = strlen(comma)) <= 0 || !(new_val = calloc(1, tmp_len+3)) || !(tmp_val = (char *)opt_string_alloc(comma))){
+ ret_err(_("bad dhcp-option-125 1"));
+ }
+
+ i=j=0;
+ for(match_str = tmp_val; match_str ; ){
+ next_str = strstr(match_str,"%%");
+ if(next_str) { match_len = next_str - match_str; next_str+=2;}
+ else { match_len = strlen(match_str); }
+
+ if(match_len){
+ //parse suboption, format: {id}={value}
+ tmpPtr = strchr(match_str, '=');
+ if(tmpPtr && (i = tmpPtr-match_str)<=3){
+ strncpy(tmpBuf, match_str, i); tmpBuf[i] = '\0';
+ match_id = atoi(tmpBuf);
+
+ if(match_id > 0 && match_id <= 255 && (match_len -= (i+1)) > 0 && match_len <= 255){
+ new_val[j++] = (char) match_id;
+ match_str += (i+1);
+ if(!strncmp(match_str,"hex#", 4)){
+ match_str+=4;
+ match_len-=4;
+ tmpBuf[2] = 0;
+ for(k=j+1,tmpPtr=match_str;(tmpPtr+2) <= (match_str+match_len);tmpPtr+=2)
+ {
+ tmpBuf[0] = *tmpPtr;
+ tmpBuf[1] = *(tmpPtr+1);
+ v = (int)strtol(tmpBuf, &tmpPtr2, 16);
+ if(*tmpPtr2 != '\0')
+ ret_err(_("bad dhcp-option-125 2"));
+ new_val[k++] = (char) ( v & 0xFF);
+ }
+ new_val[j] = (char)((k-j-1)& 0xFF); //hex length
+ j=k;
+ }
+ else {
+ new_val[j++] = (char) (match_len & 0xFF); //string length
+ memcpy((new_val+j), match_str, match_len);
+ j+=match_len;
+ }
+ }
+ else ret_err(_("bad dhcp-option-125 3"));
+ }
+ }
+ match_str = next_str;
+ }
+ if(j <= 0) ret_err(_("bad dhcp-option-125 4"));
+
+ new->len = j;
+ new->val = (unsigned char *)new_val;
+ free(tmp_val);
+ }
+ else
+#endif
if (comma)
{
/* characterise the value */
@@ -967,6 +1053,7 @@
is_addr = is_addr6 = is_hex = is_dec = is_string = 1;
addrs = digs = 1;
dots = 0;
+
for (cp = comma; (c = *cp); cp++)
if (c == ',')
{
@@ -1015,7 +1102,7 @@
}
else
found_dig = 1;
-
+
if (!found_dig)
is_dec = is_addr = 0;
@@ -1173,6 +1260,7 @@
else if (is_string)
{
/* text arg */
+
if ((new->opt == OPTION_DOMAIN_SEARCH || new->opt == OPTION_SIP_SERVER) &&
!is6 && !(new->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR | DHOPT_RFC3925)))
{
@@ -1312,11 +1400,12 @@
}
#endif
else
- {
+ {
new->len = strlen(comma);
/* keep terminating zero on string */
new->val = (unsigned char *)opt_string_alloc(comma);
new->flags |= DHOPT_STRING;
+
}
}
}
@@ -1324,7 +1413,11 @@
if (!is6 &&
((new->len > 255) ||
(new->len > 253 && (new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE))) ||
- (new->len > 250 && (new->flags & DHOPT_RFC3925))))
+ (new->len > 250 && (new->flags & DHOPT_RFC3925))
+#ifdef ZYXEL_PATCH //for option 125
+ || (new->len > 250 && (new->flags & DHOPT_RFC3925_OPT))
+#endif
+ ))
ret_err(_("dhcp-option too long"));
if (flags == DHOPT_MATCH)
@@ -3164,8 +3257,9 @@
break;
}
#endif
-
-
+#ifdef ZYXEL_PATCH
+ case LOPT_VENDOREXACT: /*--dhcp-vendorclass-exact*/
+#endif
case 'U': /* --dhcp-vendorclass */
case 'j': /* --dhcp-userclass */
case LOPT_CIRCUIT: /* --dhcp-circuitid */
@@ -3186,7 +3280,11 @@
arg = comma;
if ((comma = split(arg)))
{
+#ifdef ZYXEL_PATCH
+ if ((option != LOPT_VENDOREXACT && option != 'U') || strstr(arg, "enterprise:") != arg)
+#else
if (option != 'U' || strstr(arg, "enterprise:") != arg)
+#endif
ret_err(gen_err);
else
new->enterprise = atoi(arg+11);
@@ -3200,7 +3298,11 @@
else if (*p != ':')
break;
unhide_metas(comma);
+#ifdef ZYXEL_PATCH
+ if ((option == LOPT_VENDOREXACT && option == 'U') || option == 'j' || *p || !dig)
+#else
if (option == 'U' || option == 'j' || *p || !dig)
+#endif
{
new->len = strlen(comma);
new->data = opt_malloc(new->len);
@@ -3220,7 +3322,12 @@
break;
case 'U':
new->match_type = MATCH_VENDOR;
- break;
+ break;
+#ifdef ZYXEL_PATCH
+ case LOPT_VENDOREXACT:
+ new->match_type = MATCH_VENDOR_EXACT;
+ break;
+#endif
case LOPT_CIRCUIT:
new->match_type = MATCH_CIRCUIT;
break;
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2015-10-12 19:51:32.346349003 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2015-10-13 18:49:15.752301031 +0800
@@ -76,7 +76,7 @@
for(tmpNetid = netid; tmpNetid; tmpNetid = tmpNetid->next){
- //my_syslog(MS_DHCP | LOG_WARNING, _("tmpNetid->net=%s, %s"), tmpNetid->net, iface_name);
+ //my_syslog(MS_DHCP | LOG_DEBUG, _("tmpNetid->net=%s, %s"), tmpNetid->net, iface_name);
if( !strncmp(tmpNetid->net, "Crit_br", 7)){
brNamePtr = strstr(tmpNetid->net, "br");
if(iface_name != NULL && strcmp(brNamePtr, iface_name)){
@@ -448,7 +448,61 @@
break;
}
}
- else
+#ifdef ZYXEL_PATCH //for option 125
+ else if (o->flags & DHOPT_RFC3925_OPT)
+ {
+ char *match_str, *next_str, *tmpPtr, *matchPtr, tmpBuf[255], hexBuf[3];
+ unsigned char *x, *y, *opt_value;
+ int match_len, match_id, i, j, match2, v;
+ unsigned char isStr=0;
+
+ if (!(opt = option_find(mess, sz, OPTION_VENDOR_IDENT_OPT, 5)))
+ continue;
+
+ for (offset = 0; offset < (option_len(opt) - 5u); offset += len + 5)
+ {
+ len = option_uint(opt, offset + 4 , 1);
+ if ((offset + len + 5 <= (option_len(opt))) &&
+ option_uint(opt, offset, 4) == (unsigned int)o->u.encap)
+ {
+ len = option_uint(opt, 4 , 1);
+ x = option_ptr(opt, offset + 5);
+ y = option_ptr(opt, offset + len + 5);
+
+ match = 1;
+ for(match_str = o->val; match_str < (o->val + o->len) ; ){
+ match_id = (int)match_str[0];
+ match_len = (int)match_str[1];
+ next_str = match_str+match_len+2;
+ if(match_len && (opt_value = option_find1(x, y, match_id, 1))){
+ match_str += 2;
+ if(option_len(opt_value) < match_len){
+ match = 0;
+ break;
+ }
+ else{
+ //wildcard match
+ match2 = 0;
+ for(i = 0;(i+match_len)<=option_len(opt_value);i++){
+ if(!memcmp(option_ptr(opt_value, i), match_str, match_len)){
+ match2 = 1;
+ break;
+ }
+ }
+ if(match2 == 0) {
+ match = 0;
+ break;
+ }
+ }
+ }
+ match_str = next_str;
+ }
+ break;
+ }
+ }
+ }
+#endif
+ else
{
if (!(opt = option_find(mess, sz, o->opt, 1)))
continue;
@@ -490,8 +544,11 @@
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next)
{
int mopt;
-
+#ifdef ZYXEL_PATCH
+ if (vendor->match_type == MATCH_VENDOR || vendor->match_type == MATCH_VENDOR_EXACT)
+#else
if (vendor->match_type == MATCH_VENDOR)
+#endif
mopt = OPTION_VENDOR_ID;
else if (vendor->match_type == MATCH_USER)
mopt = OPTION_USER_CLASS;
@@ -501,13 +558,23 @@
if ((opt = option_find(mess, sz, mopt, 1)))
{
int i;
+#ifdef ZYXEL_PATCH
+ if(vendor->match_type == MATCH_VENDOR_EXACT){
+ if((vendor->len == option_len(opt) && memcmp(vendor->data, option_ptr(opt, 0), vendor->len) == 0)){
+ vendor->netid.next = netid;
+ netid = &vendor->netid;
+ break;
+ }
+ }
+ else
+#endif
for (i = 0; i <= (option_len(opt) - vendor->len); i++)
if (memcmp(vendor->data, option_ptr(opt, i), vendor->len) == 0)
{
vendor->netid.next = netid;
netid = &vendor->netid;
break;
- }
+ }
}
}
@@ -0,0 +1,222 @@
Index: dnsmasq-2.67/src/dnsmasq.c
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.c 2015-10-28 22:55:50.356457337 +0800
+++ dnsmasq-2.67/src/dnsmasq.c 2015-10-28 22:56:44.478460913 +0800
@@ -846,6 +846,9 @@
{
/* otherwise undefined after error */
FD_ZERO(&rset); FD_ZERO(&wset); FD_ZERO(&eset);
+#ifdef ZYXEL_PATCH
+ checkListenerSock();
+#endif
}
now = dnsmasq_time();
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2015-10-28 22:55:50.452457336 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2015-11-05 13:55:28.914663975 +0800
@@ -1378,4 +1378,9 @@
void sendLeaseMessageToESMD(int, struct dhcp_lease *, const char*);
void sendCritMessageToESMD(struct CritDhcpInfo *crit);
void pruneCritReqList(void);
+int checkListenerSock();
+#if 0
+int chkClose(int fd, const char *func, const int line);
+#define close(fd) chkClose(fd, __FUNCTION__, __LINE__)
+#endif
#endif
\ No newline at end of file
Index: dnsmasq-2.67/src/extern.c
===================================================================
--- dnsmasq-2.67.orig/src/extern.c 2015-10-28 22:55:50.428457336 +0800
+++ dnsmasq-2.67/src/extern.c 2015-11-05 13:55:36.253867552 +0800
@@ -1,6 +1,23 @@
#ifdef ZYXEL_PATCH
#include <stdio.h>
#include <string.h>
+#include <time.h>
+#if 0
+int __test_sock_fd = -1;
+
+int chkClose(int fd, const char *func, const int line){
+ if(fd == __test_sock_fd){
+ time_t curtime;
+ FILE *fp = fopen("/tmp/dnsmasq_error", "a+");
+ if(fp) {
+ time(&curtime);
+ fprintf(fp, "%s:%d: close general socket(%d) >>> %s", func, line, fd, ctime(&curtime));
+ fclose(fp);
+ }
+ }
+ return close(fd);
+}
+#endif
#include "dnsmasq.h"
/*ZyXEL zcfg*/
@@ -8,6 +25,103 @@
#include "zcfg_debug.h"
#include "zcfg_msg.h"
+int checkSocketAlive(int sock)
+{
+ int error_code = -1, retval;
+ int error_code_size = sizeof(error_code);
+ //WPRINT(W_DEBUG,"Enter.\n");
+
+ retval = getsockopt(sock, SOL_SOCKET, SO_ERROR, &error_code, &error_code_size);
+
+ //WPRINT(W_DEBUG,"error_code = %d.\n", error_code);
+
+ if(retval != 0 || error_code != 0) {
+ return -1;
+ }
+ else return 0;
+}
+
+extern struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow);
+int checkListenerSock(){
+ int err;
+ struct listener *listener, *l = NULL;
+ union mysockaddr addr;
+ FILE *fp = fopen("/dev/console", "w");
+
+ for (listener = daemon->listeners; listener; listener = listener->next)
+ {
+ err = 0;
+ if(listener->fd != -1){
+ if(checkSocketAlive(listener->fd) < 0){
+ if(fp) fprintf(fp, "%s: listener->fd(%d) is fail.....\n", __FUNCTION__, listener->fd);
+ err = 1;
+ listener->fd = -1;
+ }
+ }
+
+ if(err == 0 && listener->tcpfd != -1){
+ if(checkSocketAlive(listener->tcpfd) < 0){
+ if(fp) fprintf(fp, "%s: listener->tcpfd (%d) is fail.....\n", __FUNCTION__, listener->tcpfd);
+ err = 1;
+ listener->tcpfd = -1;
+ }
+ }
+
+ if(err){
+#if 0
+ __test_sock_fd = -1;
+#endif
+ if(listener->fd != -1){ close(listener->fd);}
+ if(listener->tcpfd != -1){ close(listener->tcpfd);}
+ if(listener->tftpfd != -1){ close(listener->tftpfd);}
+
+ listener->fd = -1; listener->tcpfd = -1; listener->tftpfd = -1;
+
+ if(listener->iface){
+ memcpy(&addr, &(listener->iface->addr), sizeof(addr));
+ }
+ else{
+ memset(&addr, 0, sizeof(addr));
+ if(listener->family == AF_INET){
+#ifdef HAVE_SOCKADDR_SA_LEN
+ addr.in.sin_len = sizeof(addr.in);
+#endif
+ addr.in.sin_family = AF_INET;
+ addr.in.sin_addr.s_addr = INADDR_ANY;
+ addr.in.sin_port = htons(daemon->port);
+ }
+#ifdef HAVE_IPV6
+ else{
+#ifdef HAVE_SOCKADDR_SA_LEN
+ addr.in6.sin6_len = sizeof(addr.in6);
+#endif
+ addr.in6.sin6_family = AF_INET6;
+ addr.in6.sin6_addr = in6addr_any;
+ addr.in6.sin6_port = htons(daemon->port);
+ }
+#else
+ else continue;
+#endif
+ }
+
+ l = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
+ if(l){
+ listener->fd = l->fd;
+ listener->tcpfd = l->tcpfd;
+ listener->tftpfd = l->tftpfd;
+ free(l); l=NULL;
+
+ if(fp) fprintf(fp, "%s: reopen socket(%d).....\n", __FUNCTION__, listener->fd);
+#if 0
+ __test_sock_fd = listener->fd;
+#endif
+ }
+ }
+ }
+
+ if(fp) fclose(fp);
+ return 0;
+}
void dnsmasq_eid_register( void ){
zcfgRet_t retzcfg;
@@ -19,11 +133,10 @@
retzcfg = zcfgMsgServerInit();
if(retzcfg != ZCFG_SUCCESS) {
zcfgLog(ZCFG_LOG_ERR, "Dnsmasq message server init fail\n");
- return 0;
}
}
-char *getPhyIfname(const ifname, const char *macaddr, char *reply){
+char *getPhyIfname(const char *ifname, const char *macaddr, char *reply){
static char phyifname[20];
char tmp[256] = {0};
FILE *fp = NULL;
Index: dnsmasq-2.67/src/network.c
===================================================================
--- dnsmasq-2.67.orig/src/network.c 2015-10-28 22:55:50.384457337 +0800
+++ dnsmasq-2.67/src/network.c 2015-11-05 13:56:43.303813326 +0800
@@ -707,8 +707,11 @@
return if_index;
}
-
+#ifdef ZYXEL_PATCH
+struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow)
+#else
static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow)
+#endif
{
struct listener *l = NULL;
int fd = -1, tcpfd = -1, tftpfd = -1;
@@ -752,11 +755,16 @@
l->fd = fd;
l->tcpfd = tcpfd;
l->tftpfd = tftpfd;
+#ifdef ZYXEL_PATCH
+ l->iface = NULL;
+#endif
}
return l;
}
-
+#if 0 //def ZYXEL_PATCH
+extern int __test_sock_fd;
+#endif
void create_wildcard_listeners(void)
{
union mysockaddr addr;
@@ -771,7 +779,11 @@
addr.in.sin_port = htons(daemon->port);
l = create_listeners(&addr, !!option_bool(OPT_TFTP), 1);
-
+#if 0 //def ZYXEL_PATCH
+ if(l){
+ __test_sock_fd = l->fd;
+ }
+#endif
#ifdef HAVE_IPV6
memset(&addr, 0, sizeof(addr));
# ifdef HAVE_SOCKADDR_SA_LEN
@@ -0,0 +1,34 @@
Index: dnsmasq-2.67/src/forward.c
===================================================================
--- dnsmasq-2.67.orig/src/forward.c 2016-02-01 10:52:19.436523279 +0800
+++ dnsmasq-2.67/src/forward.c 2016-02-01 11:02:28.153602000 +0800
@@ -243,6 +243,9 @@
unsigned int flags = 0;
unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL);
struct server *start = NULL;
+#ifdef ZYXEL_PATCH
+ char if_name[IFNAMSIZ]={0};
+#endif
/* RFC 4035: sect 4.6 para 2 */
header->hb4 &= ~HB4_AD;
@@ -421,6 +424,19 @@
start->queries++;
forwarded = 1;
forward->sentto = start;
+
+#ifdef ZYXEL_PATCH
+ /*if the query-interface is "lo", forward to all servers*/
+ /*Because "lo" interface always send-query with different port and header->id,
+ *the query is always forwarded to the first dns server.
+ *Hence, we force the query to all dns servers as the interface is "lo".*/
+ if (indextoname(udpfd, dst_iface, if_name))
+ {
+ if(!strncmp(if_name,"lo",2))
+ forward->forwardall = 1;
+ }
+#endif
+
if (!forward->forwardall)
break;
forward->forwardall++;
@@ -0,0 +1,323 @@
Index: dnsmasq-2.67/src/dnsmasq.c
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.c 2017-10-05 14:04:09.815226781 +0800
+++ dnsmasq-2.67/src/dnsmasq.c 2017-10-05 14:28:13.472533410 +0800
@@ -88,8 +88,12 @@
if (daemon->edns_pktsz < PACKETSZ)
daemon->edns_pktsz = PACKETSZ;
- daemon->packet_buff_sz = daemon->edns_pktsz > DNSMASQ_PACKETSZ ?
- daemon->edns_pktsz : DNSMASQ_PACKETSZ;
+ /* CVE-2017-14491
+ Min buffer size: we check after adding each record, so there must be
+ memory for the largest packet, and the largest record so the
+ min for DNS is PACKETSZ+MAXDNAME+RRFIXEDSZ which is < 1000.
+ This might be increased is EDNS packet size if greater than the minimum. */
+ daemon->packet_buff_sz = daemon->edns_pktsz + MAXDNAME + RRFIXEDSZ;
daemon->packet = safe_malloc(daemon->packet_buff_sz);
daemon->addrbuff = safe_malloc(ADDRSTRLEN);
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2017-10-05 14:04:09.815226781 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2017-10-05 14:09:53.176549137 +0800
@@ -1036,7 +1036,7 @@
unsigned short rand16(void);
int legal_hostname(char *c);
char *canonicalise(char *s, int *nomem);
-unsigned char *do_rfc1035_name(unsigned char *p, char *sval);
+unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit);
void *safe_malloc(size_t size);
void safe_pipe(int *fd, int read_noblock);
void *whine_malloc(size_t size);
@@ -1383,4 +1383,4 @@
int chkClose(int fd, const char *func, const int line);
#define close(fd) chkClose(fd, __FUNCTION__, __LINE__)
#endif
-#endif
\ No newline at end of file
+#endif
Index: dnsmasq-2.67/src/forward.c
===================================================================
--- dnsmasq-2.67.orig/src/forward.c 2017-10-05 14:04:09.831226656 +0800
+++ dnsmasq-2.67/src/forward.c 2017-10-05 14:37:50.880468988 +0800
@@ -753,7 +753,10 @@
(msg.msg_flags & MSG_TRUNC) ||
(header->hb3 & HB3_QR))
return;
-
+
+ /* CVE-2017-13704: Clear buffer beyond request to avoid risk of information disclosure. */
+ memset(daemon->packet + n, 0, daemon->edns_pktsz - n);
+
source_addr.sa.sa_family = listen->family;
#ifdef HAVE_IPV6
if (listen->family == AF_INET6)
@@ -968,7 +971,10 @@
if (size < (int)sizeof(struct dns_header))
continue;
-
+
+ /* CVE-2017-13704: Clear buffer beyond request to avoid risk of information disclosure. */
+ memset(payload + size, 0, 65536 - size);
+
check_subnet = 0;
/* save state of "cd" flag in query */
Index: dnsmasq-2.67/src/option.c
===================================================================
--- dnsmasq-2.67.orig/src/option.c 2017-10-05 14:04:09.791226970 +0800
+++ dnsmasq-2.67/src/option.c 2017-10-05 14:45:32.557216632 +0800
@@ -1386,7 +1386,7 @@
}
p = newp;
- end = do_rfc1035_name(p + len, dom);
+ end = do_rfc1035_name(p + len, dom, NULL);
*end++ = 0;
len = end - p;
free(dom);
Index: dnsmasq-2.67/src/radv.c
===================================================================
--- dnsmasq-2.67.orig/src/radv.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/radv.c 2017-10-05 14:46:26.972833155 +0800
@@ -185,6 +185,9 @@
/* look for link-layer address option for logging */
if (sz >= 16 && packet[8] == ICMP6_OPT_SOURCE_MAC && (packet[9] * 8) + 8 <= sz)
{
+ if ((packet[9] * 8 - 2) * 3 - 1 >= MAXDNAME) {
+ return;
+ }
print_mac(daemon->namebuff, &packet[10], (packet[9] * 8) - 2);
mac = daemon->namebuff;
}
Index: dnsmasq-2.67/src/rfc1035.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc1035.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/rfc1035.c 2017-10-05 14:58:07.159997574 +0800
@@ -44,7 +44,7 @@
/* end marker */
{
/* check that there are the correct no of bytes after the name */
- if (!CHECK_LEN(header, p, plen, extrabytes))
+ if (!CHECK_LEN(header, p1 ? p1 : p, plen, extrabytes))
return 0;
if (isExtract)
@@ -794,6 +794,8 @@
{
unsigned int i, len = *p1;
unsigned char *p2 = p1;
+ if ((p1 + len - p) >= rdlen)
+ return 0; /* bad packet */
/* make counted string zero-term and sanitise */
for (i = 0; i < len; i++)
{
@@ -1307,10 +1309,21 @@
long lval;
char *sval;
+#define CHECK_LIMIT(size) \
+ if (limit && p + (size) > (unsigned char*)limit) \
+ { \
+ va_end(ap); \
+ goto truncated; \
+ }
+
if (truncp && *truncp)
return 0;
va_start(ap, format); /* make ap point to 1st unamed argument */
+
+ /* nameoffset (1 or 2) + type (2) + class (2) + ttl (4) + 0 (2) */
+ CHECK_LIMIT(12);
+
if (nameoffset > 0)
{
@@ -1320,7 +1333,12 @@
{
char *name = va_arg(ap, char *);
if (name)
- p = do_rfc1035_name(p, name);
+ p = do_rfc1035_name(p, name, limit);
+ if (!p)
+ {
+ va_end(ap);
+ goto truncated;
+ }
if (nameoffset < 0)
{
PUTSHORT(-nameoffset | 0xc000, p);
@@ -1341,6 +1359,7 @@
{
#ifdef HAVE_IPV6
case '6':
+ CHECK_LIMIT(IN6ADDRSZ);
sval = va_arg(ap, char *);
memcpy(p, sval, IN6ADDRSZ);
p += IN6ADDRSZ;
@@ -1348,30 +1367,40 @@
#endif
case '4':
+ CHECK_LIMIT(INADDRSZ);
sval = va_arg(ap, char *);
memcpy(p, sval, INADDRSZ);
p += INADDRSZ;
break;
case 's':
+ CHECK_LIMIT(2);
usval = va_arg(ap, int);
PUTSHORT(usval, p);
break;
case 'l':
+ CHECK_LIMIT(4);
lval = va_arg(ap, long);
PUTLONG(lval, p);
break;
case 'd':
- /* get domain-name answer arg and store it in RDATA field */
- if (offset)
- *offset = p - (unsigned char *)header;
- p = do_rfc1035_name(p, va_arg(ap, char *));
- *p++ = 0;
+ /* get domain-name answer arg and store it in RDATA field */
+ if (offset)
+ *offset = p - (unsigned char *)header;
+ p = do_rfc1035_name(p, va_arg(ap, char *), limit);
+ if (!p)
+ {
+ va_end(ap);
+ goto truncated;
+ }
+ CHECK_LIMIT(1);
+ *p++ = 0;
break;
case 't':
+ CHECK_LIMIT(usval);
usval = va_arg(ap, int);
sval = va_arg(ap, char *);
if (usval != 0)
@@ -1384,20 +1413,24 @@
usval = sval ? strlen(sval) : 0;
if (usval > 255)
usval = 255;
+ CHECK_LIMIT(usval + 1);
*p++ = (unsigned char)usval;
memcpy(p, sval, usval);
p += usval;
break;
}
+#undef CHECK_LIMIT
va_end(ap); /* clean up variable argument pointer */
j = p - sav - 2;
+ /* this has already been checked against limit before */
PUTSHORT(j, sav); /* Now, store real RDLength */
/* check for overflow of buffer */
if (limit && ((unsigned char *)limit - p) < 0)
{
+truncated:
if (truncp)
*truncp = 1;
return 0;
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2017-10-05 14:04:09.791226970 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2017-10-05 15:00:05.219197609 +0800
@@ -203,7 +203,7 @@
for (offset = 0; offset < (len - 5); offset += elen + 5)
{
elen = option_uint(opt, offset + 4 , 1);
- if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA)
+ if (option_uint(opt, offset, 4) == BRDBAND_FORUM_IANA && offset + elen + 5 <= len)
{
unsigned char *x = option_ptr(opt, offset + 5);
unsigned char *y = option_ptr(opt, offset + elen + 5);
@@ -2515,10 +2515,10 @@
if (fqdn_flags & 0x04)
{
- p = do_rfc1035_name(p, hostname);
+ p = do_rfc1035_name(p, hostname, NULL);
if (domain)
{
- p = do_rfc1035_name(p, domain);
+ p = do_rfc1035_name(p, domain, NULL);
*p++ = 0;
}
}
Index: dnsmasq-2.67/src/rfc3315.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc3315.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/rfc3315.c 2017-10-05 15:14:20.361449268 +0800
@@ -203,6 +203,9 @@
/* RFC-6939 */
if ((opt = opt6_find(opts, end, OPTION6_CLIENT_MAC, 3)))
{
+ if (opt6_len(opt) - 2 > DHCP_CHADDR_MAX) {
+ return 0;
+ }
state->mac_type = opt6_uint(opt, 0, 2);
state->mac_len = opt6_len(opt) - 2;
memcpy(&state->mac[0], opt6_ptr(opt, 2), state->mac_len);
@@ -210,6 +213,9 @@
for (opt = opts; opt; opt = opt6_next(opt, end))
{
+ if (opt6_ptr(opt, 0) + opt6_len(opt) >= end) {
+ return 0;
+ }
int o = new_opt6(opt6_type(opt));
if (opt6_type(opt) == OPTION6_RELAY_MSG)
{
@@ -1399,10 +1405,10 @@
if ((p = expand(len + 2)))
{
*(p++) = state->fqdn_flags;
- p = do_rfc1035_name(p, state->hostname);
+ p = do_rfc1035_name(p, state->hostname, NULL);
if (state->send_domain)
{
- p = do_rfc1035_name(p, state->send_domain);
+ p = do_rfc1035_name(p, state->send_domain, NULL);
*p = 0;
}
}
Index: dnsmasq-2.67/src/util.c
===================================================================
--- dnsmasq-2.67.orig/src/util.c 2017-10-05 14:04:09.599228472 +0800
+++ dnsmasq-2.67/src/util.c 2017-10-05 15:16:31.828582260 +0800
@@ -205,15 +205,21 @@
return ret;
}
-unsigned char *do_rfc1035_name(unsigned char *p, char *sval)
+unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit)
{
int j;
while (sval && *sval)
{
+ if (limit && p + 1 > (unsigned char*)limit)
+ return p;
+
unsigned char *cp = p++;
- for (j = 0; *sval && (*sval != '.'); sval++, j++)
- *p++ = *sval;
+ for (j = 0; *sval && (*sval != '.'); sval++, j++) {
+ if (limit && p + 1 > (unsigned char*)limit)
+ return p;
+ *p++ = *sval;
+ }
*cp = j;
if (*sval)
sval++;
@@ -0,0 +1,72 @@
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2017-10-20 16:41:13.286484495 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2017-10-20 16:43:14.426156466 +0800
@@ -79,34 +79,39 @@
//my_syslog(MS_DHCP | LOG_DEBUG, _("tmpNetid->net=%s, %s"), tmpNetid->net, iface_name);
if( !strncmp(tmpNetid->net, "Crit_br", 7)){
brNamePtr = strstr(tmpNetid->net, "br");
- if(iface_name != NULL && strcmp(brNamePtr, iface_name)){
- memset(&crit, 0, sizeof(crit));
- crit.ifname = iface_name;
- crit.emac = emac;
- crit.emac_len = emac_len;
- crit.hostname = client_hostname;
- strcpy(crit.tag, tmpNetid->net);
- if(oui){
- crit.oui = option_ptr(oui, 0);
- crit.oui_len = option_len(oui);
- }
- if(serial){
- crit.serial = option_ptr(serial, 0);
- crit.serial_len = option_len(serial);
- }
- if(class){
- crit.pclass = option_ptr(class, 0);
- crit.pclass_len = option_len(class);
- }
- crit.vendor = vendor_class_ptr;
- crit.vendor_len = vendor_class_len;
- if(clid){
- crit.clid = clid;
- crit.clid_len = clid_len;
- }
- sendCritMessageToESMD(&crit);
- return 1;
- }
+ if(iface_name != NULL){
+ if(strcmp(brNamePtr, iface_name)){
+ memset(&crit, 0, sizeof(crit));
+ crit.ifname = iface_name;
+ crit.emac = emac;
+ crit.emac_len = emac_len;
+ crit.hostname = client_hostname;
+ strcpy(crit.tag, tmpNetid->net);
+ if(oui){
+ crit.oui = option_ptr(oui, 0);
+ crit.oui_len = option_len(oui);
+ }
+ if(serial){
+ crit.serial = option_ptr(serial, 0);
+ crit.serial_len = option_len(serial);
+ }
+ if(class){
+ crit.pclass = option_ptr(class, 0);
+ crit.pclass_len = option_len(class);
+ }
+ crit.vendor = vendor_class_ptr;
+ crit.vendor_len = vendor_class_len;
+ if(clid){
+ crit.clid = clid;
+ crit.clid_len = clid_len;
+ }
+ sendCritMessageToESMD(&crit);
+ return 1;
+ }else{
+ my_syslog(MS_DHCP | LOG_DEBUG, _("Port no change, no need re-bind!!"));
+ return 0;
+ }
+ }
}
}
return 0;
@@ -0,0 +1,85 @@
Index: dnsmasq-2.67/src/cache.c
===================================================================
--- dnsmasq-2.67.orig/src/cache.c 2018-03-13 14:40:54.122500703 +0800
+++ dnsmasq-2.67/src/cache.c 2018-03-13 14:42:24.100643317 +0800
@@ -513,7 +513,7 @@
}
#ifdef DNS_TRAFFIC_ROUTE
-add_dns_traffic_route(uint32_t s_addr, const char *cname, int *flush)
+void add_dns_traffic_route(uint32_t s_addr, const char *cname, int *flush)
{
char sysCmd[128] = "";
struct in_addr srcIP;
Index: dnsmasq-2.67/src/extern.c
===================================================================
--- dnsmasq-2.67.orig/src/extern.c 2018-03-13 14:40:54.306592708 +0800
+++ dnsmasq-2.67/src/extern.c 2018-03-13 14:42:06.171599126 +0800
@@ -315,14 +315,31 @@
else
#endif
bufPtr += sprintf(bufPtr, "\"ip\":\"%s\",", inet_ntop(AF_INET, &lease->addr, tmp, ADDRSTRLEN));
-
- bufPtr += sprintf(bufPtr, "\"host\":\"%s\",", (lease->hostname) ? lease->hostname : "*");
+
+ if (lease->hostname != NULL)
+ bufPtr += sprintf(bufPtr, "\"host\":\"%s\",", lease->hostname);
+ else
+ bufPtr += sprintf(bufPtr, "\"host\":\"*\",");
//option 60
- bufPtr += sprintf(bufPtr, "\"vendor\":\"%s\",", (lease->vendorid) ? lease->vendorid : "*");
+ if (lease->vendorid != NULL)
+ bufPtr += sprintf(bufPtr, "\"vendor\":\"%s\",", lease->vendorid);
+ else
+ bufPtr += sprintf(bufPtr, "\"vendor\":\"*\",");
//option 125
- bufPtr += sprintf(bufPtr, "\"moui\":\"%s\",", (lease->oui) ? lease->oui : "*");
- bufPtr += sprintf(bufPtr, "\"serial\":\"%s\",", (lease->serial) ? lease->serial : "*");
- bufPtr += sprintf(bufPtr, "\"pclass\":\"%s\",", (lease->pclass) ? lease->pclass : "*");
+ if (lease->oui != NULL)
+ bufPtr += sprintf(bufPtr, "\"moui\":\"%s\",", lease->oui);
+ else
+ bufPtr += sprintf(bufPtr, "\"moui\":\"*\",");
+
+ if (lease->serial != NULL)
+ bufPtr += sprintf(bufPtr, "\"serial\":\"%s\",", lease->serial);
+ else
+ bufPtr += sprintf(bufPtr, "\"serial\":\"*\",");
+
+ if (lease->pclass != NULL)
+ bufPtr += sprintf(bufPtr, "\"pclass\":\"%s\",", lease->pclass);
+ else
+ bufPtr += sprintf(bufPtr, "\"pclass\":\"*\",");
//option 61
if (lease->clid && lease->clid_len != 0) {
tmpPtr = tmp;
@@ -332,9 +349,13 @@
}
else sprintf(tmp, "*");
bufPtr += sprintf(bufPtr, "\"cid\":\"%s\",", tmp);
-
- bufPtr += sprintf(bufPtr, "\"ifname\":\"%s\"", (ifname) ? ifname : "*");
- bufPtr += sprintf(bufPtr, "}");
+
+ if (ifname != NULL)
+ bufPtr += sprintf(bufPtr, "\"ifname\":\"%s\"", ifname);
+ else
+ bufPtr += sprintf(bufPtr, "\"ifname\":\"*\"");
+
+ bufPtr += sprintf(bufPtr, "}");
bufPtr = '\0';
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2018-03-13 14:40:54.394636712 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2018-03-13 14:42:15.393967416 +0800
@@ -475,7 +475,7 @@
y = option_ptr(opt, offset + len + 5);
match = 1;
- for(match_str = o->val; match_str < (o->val + o->len) ; ){
+ for(match_str = o->val; (unsigned char*)match_str < (o->val + o->len) ; ){
match_id = (int)match_str[0];
match_len = (int)match_str[1];
next_str = match_str+match_len+2;
@@ -0,0 +1,33 @@
Index: dnsmasq-2.67/src/dhcp-common.c
===================================================================
--- dnsmasq-2.67.orig/src/dhcp-common.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dhcp-common.c 2018-08-07 20:31:58.899621002 +0800
@@ -567,10 +567,11 @@
{ "subnet-select", 118, OT_INTERNAL },
{ "domain-search", 119, OT_RFC1035_NAME },
{ "sip-server", 120, 0 },
- { "classless-static-route", 121, 0 },
+ { "classless-static-route", 121, 0 }, //
{ "vendor-id-encap", 125, 0 },
- { "server-ip-address", 255, OT_ADDR_LIST }, /* special, internal only, sets siaddr */
- { NULL, 0, 0 }
+ { "captive-portal", 160, OT_NAME },
+ { "server-ip-address", 255, OT_ADDR_LIST }, /* special, internal only, sets siaddr */
+ { NULL, 0, 0 }
};
#ifdef HAVE_DHCP6
Index: dnsmasq-2.67/src/dhcp-protocol.h
===================================================================
--- dnsmasq-2.67.orig/src/dhcp-protocol.h 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dhcp-protocol.h 2018-08-07 20:32:42.913495200 +0800
@@ -58,7 +58,8 @@
#define OPTION_DOMAIN_SEARCH 119
#define OPTION_SIP_SERVER 120
#define OPTION_VENDOR_IDENT 124
-#define OPTION_VENDOR_IDENT_OPT 125
+#define OPTION_VENDOR_IDENT_OPT 125
+#define OPTION_CAPTIVE_PORTAL 160
#define OPTION_END 255
#define SUBOPT_CIRCUIT_ID 1
@@ -0,0 +1,22 @@
Index: dnsmasq-2.67/src/dhcp.c
===================================================================
--- dnsmasq-2.67.orig/src/dhcp.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dhcp.c 2018-09-06 15:05:51.718844574 +0800
@@ -984,8 +984,16 @@
to.sa.sa_family = AF_INET;
to.in.sin_addr = relay->server.addr.addr4;
to.in.sin_port = htons(daemon->dhcp_server_port);
-
+
+#if 1
+ /*+++ Kide@zyxel:
+ * I am not sure the origial design of it. But the src address of all dhcp relayed pkts should
+ * be changed to the one of the interface uplinked to dhcp server?!
+ */
+ send_from(daemon->dhcpfd, 1, (char *)mess, sz, &to, &from, 0);
+#else
send_from(daemon->dhcpfd, 0, (char *)mess, sz, &to, &from, 0);
+#endif
if (option_bool(OPT_LOG_OPTS))
{
@@ -0,0 +1,33 @@
Index: dnsmasq-2.67/src/extern.c
===================================================================
--- dnsmasq-2.67.orig/src/extern.c 2019-04-08 16:41:27.969142172 +0800
+++ dnsmasq-2.67/src/extern.c 2019-04-08 16:46:08.060267974 +0800
@@ -142,17 +142,26 @@
FILE *fp = NULL;
phyifname[0] = 0;
- sprintf(tmp, "brctl showmacs %s | grep %s", ifname, macaddr);
+ //sprintf(tmp, "brctl showmacs %s | grep %s", ifname, macaddr);
+ sprintf(tmp, "brctl showmacs %s | grep %s | awk '{print$NF}'", ifname, macaddr);
+
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s command = %s", __func__, tmp);
+
if((fp = popen(tmp, "r"))){
tmp[0] = '\0';
fgets(tmp, sizeof(tmp)-1, fp);
pclose(fp);
- if(sscanf(tmp, "%*s %*s %*s %*s %s", phyifname) == 1){
+ //if(sscanf(tmp, "%*s %*s %*s %*s %s", phyifname) == 1){
+ if(sscanf(tmp, "%s", phyifname) == 1){
strcpy(reply, phyifname);
if(reply) return reply;
return phyifname;
}
}
+ else
+ {
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s Cannot get Phy Ifname = %s", __func__);
+ }
return "";
}
@@ -0,0 +1,20 @@
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2019-07-22 00:11:45.985995664 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2019-07-22 00:15:55.627833291 +0800
@@ -304,6 +304,7 @@
emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
}
+#ifdef ZYXEL_PATCH
for (ifname = daemon->dhcp_ifnames; ifname; ifname = ifname->next){
if(find_ifname(mess->chaddr, mess->hlen, ifname->ifname, iface_name)){
@@ -311,6 +312,7 @@
netid = &ifname->netid;
}
}
+#endif
for (mac = daemon->dhcp_macs; mac; mac = mac->next)
if (mac->hwaddr_len == mess->hlen &&
@@ -0,0 +1,52 @@
Index: dnsmasq-2.67/src/forward.c
===================================================================
--- dnsmasq-2.67.orig/src/forward.c 2020-10-19 10:58:03.878810953 +0800
+++ dnsmasq-2.67/src/forward.c 2020-10-19 11:06:41.942814734 +0800
@@ -717,7 +717,11 @@
CMSG_SPACE(sizeof(struct sockaddr_dl))];
#endif
} control_u;
-
+
+#ifdef ZYXEL_SUPPORT_NESSUS
+ struct irec *iface;
+ int iFound = 0;
+#endif
/* packet buffer overwritten */
daemon->srv_save = NULL;
@@ -843,8 +847,9 @@
if (listen->family == AF_INET && option_bool(OPT_LOCALISE))
{
+#ifndef ZYXEL_SUPPORT_NESSUS
struct irec *iface;
-
+#endif
/* get the netmask of the interface whch has the address we were sent to.
This is no neccessarily the interface we arrived on. */
@@ -869,7 +874,22 @@
dst_addr_4.s_addr = 0;
}
}
-
+
+#ifdef ZYXEL_SUPPORT_NESSUS
+ for (iface = daemon->interfaces; iface; iface = iface->next)
+ {
+ if (dst_addr_4.s_addr && iface->addr.sa.sa_family == AF_INET &&
+ iface->addr.in.sin_addr.s_addr == dst_addr_4.s_addr)
+ {
+ iFound = 1;
+ break;
+ }
+ }
+
+ if (!iFound)
+ return;
+#endif
+
if (extract_request(header, (size_t)n, daemon->namebuff, &type))
{
char types[20];
@@ -0,0 +1,16 @@
Index: dnsmasq-2.67/src/forward.c
===================================================================
--- dnsmasq-2.67.orig/src/forward.c 2020-10-21 18:02:16.956257876 +0800
+++ dnsmasq-2.67/src/forward.c 2020-10-21 18:05:23.516259238 +0800
@@ -757,6 +757,11 @@
(msg.msg_flags & MSG_TRUNC) ||
(header->hb3 & HB3_QR))
return;
+
+#ifdef ZYXEL_SUPPORT_NESSUS
+ if (!(header->hb3 & HB3_RD))
+ return;
+#endif
/* CVE-2017-13704: Clear buffer beyond request to avoid risk of information disclosure. */
memset(daemon->packet + n, 0, daemon->edns_pktsz - n);
@@ -0,0 +1,532 @@
Index: dnsmasq-2.78/src/dnsmasq.c
===================================================================
--- dnsmasq-2.78.orig/src/dnsmasq.c 2018-10-29 18:12:09.617732825 +0800
+++ dnsmasq-2.78/src/dnsmasq.c 2018-10-29 18:12:09.793732832 +0800
@@ -90,6 +90,10 @@
read_opts(argc, argv, compile_opts);
+#ifdef ZYXEL_PATCH /* register to zyxel zcfg, by charisse */
+ dnsmasq_eid_register();
+#endif
+
if (daemon->edns_pktsz < PACKETSZ)
daemon->edns_pktsz = PACKETSZ;
Index: dnsmasq-2.78/src/dnsmasq.h
===================================================================
--- dnsmasq-2.78.orig/src/dnsmasq.h 2018-10-29 18:12:09.661732827 +0800
+++ dnsmasq-2.78/src/dnsmasq.h 2018-10-29 18:12:09.797732832 +0800
@@ -694,6 +694,10 @@
} *slaac_address;
int vendorclass_count;
#endif
+#ifdef ZYXEL_PATCH
+ char *vendorid;
+ unsigned char *oui, *serial, *pclass;
+#endif
struct dhcp_lease *next;
};
@@ -1562,6 +1566,16 @@
char *interface, struct dhcp_lease *leases);
#endif
+/* extern.c */
+#ifdef ZYXEL_PATCH
+void lease_set_vendor(struct dhcp_lease *, const char* , int );
+void lease_set_oui(struct dhcp_lease *, const char* , int );
+void lease_set_serial(struct dhcp_lease *, const char* , int );
+void lease_set_class(struct dhcp_lease *, const char* , int );
+void dnsmasq_eid_register(void);
+void sendLeaseMessageToESMD(int, struct dhcp_lease *, const char*);
+#endif
+
/* loop.c */
#ifdef HAVE_LOOP
void loop_send_probes(void);
Index: dnsmasq-2.78/src/lease.c
===================================================================
--- dnsmasq-2.78.orig/src/lease.c 2018-10-29 18:12:09.693732828 +0800
+++ dnsmasq-2.78/src/lease.c 2018-10-29 18:12:09.797732832 +0800
@@ -29,6 +29,9 @@
int clid_len, hw_len, hw_type;
int items;
char *domain = NULL;
+#ifdef ZYXEL_PATCH
+ int parse_count = 0;
+#endif
*daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0';
@@ -60,8 +63,15 @@
}
#endif
+#ifdef ZYXEL_PATCH
+ parse_count = fscanf(leasestream, " %64s %255s %764s %[^\n]s\n",
+ daemon->namebuff, daemon->dhcp_buff,
+ daemon->packet, daemon->dhcp_buff3);
+ if (parse_count != 3 && parse_count != 4)
+#else
if (fscanf(leasestream, " %64s %255s %764s",
daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
+#endif
return 0;
if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4)) {
@@ -74,6 +84,13 @@
/* For backwards compatibility, no explicit MAC address type means ether. */
if (hw_type == 0 && hw_len != 0)
hw_type = ARPHRD_ETHER;
+
+#ifdef ZYXEL_PATCH
+ if (parse_count == 4 && strcmp(daemon->dhcp_buff3, "*") != 0) {
+ lease_set_vendor(lease, daemon->dhcp_buff3,
+ strlen(daemon->dhcp_buff3));
+ }
+#endif
}
#ifdef HAVE_DHCP6
else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6)) {
@@ -88,6 +105,12 @@
if ((lease = lease6_allocate(&addr.addr.addr6, lease_type))) {
lease_set_iaid(lease, strtoul(s, NULL, 10));
domain = get_domain6((struct in6_addr *) lease->hwaddr);
+#ifdef ZYXEL_PATCH
+ if (parse_count == 4 && strcmp(daemon->dhcp_buff3, "*") != 0) {
+ lease_set_vendor(lease, daemon->dhcp_buff3,
+ strlen(daemon->dhcp_buff3));
+ }
+#endif
}
}
#endif
@@ -283,9 +306,21 @@
if (lease->clid && lease->clid_len != 0) {
for (i = 0; i < lease->clid_len - 1; i++)
ourprintf(&err, "%.2x:", lease->clid[i]);
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "%.2x ", lease->clid[i]);
+#else
ourprintf(&err, "%.2x\n", lease->clid[i]);
+#endif
} else
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "* ");
+#else
ourprintf(&err, "*\n");
+#endif
+
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "%s\n", (lease->vendorid) ? lease->vendorid : "*");
+#endif
}
#ifdef HAVE_DHCP6
@@ -315,9 +350,21 @@
if (lease->clid && lease->clid_len != 0) {
for (i = 0; i < lease->clid_len - 1; i++)
ourprintf(&err, "%.2x:", lease->clid[i]);
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "%.2x ", lease->clid[i]);
+#else
ourprintf(&err, "%.2x\n", lease->clid[i]);
+#endif
} else
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "* ");
+#else
ourprintf(&err, "*\n");
+#endif
+
+#ifdef ZYXEL_PATCH
+ ourprintf(&err, "%s\n", (lease->vendorid) ? lease->vendorid : "*");
+#endif
}
}
#endif
@@ -1016,6 +1063,84 @@
lease->flags |= LEASE_CHANGED;
}
+#ifdef ZYXEL_PATCH
+void lease_set_vendor(struct dhcp_lease *lease, const char *vendor, int len)
+{
+ char *new_vendor = NULL;
+
+ if (vendor <= 0)
+ return;
+ if (lease->vendorid) {
+ if (!strcmp(lease->vendorid, vendor))
+ return;
+ free(lease->vendorid);
+ lease->vendorid = NULL;
+ }
+ if ((new_vendor = whine_malloc(len + 1))) {
+ strncpy(new_vendor, vendor, len);
+ *(new_vendor + len) = '\0';
+ }
+
+ lease->vendorid = new_vendor;
+
+ lease->flags |= LEASE_CHANGED;
+}
+
+void lease_set_oui(struct dhcp_lease *lease, const char *value, int len)
+{
+ char *new_val = NULL;
+
+ if (value <= 0)
+ return;
+ if (lease->oui) {
+ free(lease->oui);
+ lease->oui = NULL;
+ }
+ if ((new_val = whine_malloc(len + 1))) {
+ strncpy(new_val, value, len);
+ *(new_val + len) = '\0';
+ }
+
+ lease->oui = new_val;
+}
+
+void lease_set_serial(struct dhcp_lease *lease, const char *value, int len)
+{
+ char *new_val = NULL;
+
+ if (value <= 0)
+ return;
+ if (lease->serial) {
+ free(lease->serial);
+ lease->serial = NULL;
+ }
+ if ((new_val = whine_malloc(len + 1))) {
+ strncpy(new_val, value, len);
+ *(new_val + len) = '\0';
+ }
+
+ lease->serial = new_val;
+}
+
+void lease_set_class(struct dhcp_lease *lease, const char *value, int len)
+{
+ char *new_val = NULL;
+
+ if (value <= 0)
+ return;
+ if (lease->pclass) {
+ free(lease->pclass);
+ lease->pclass = NULL;
+ }
+ if ((new_val = whine_malloc(len + 1))) {
+ strncpy(new_val, value, len);
+ *(new_val + len) = '\0';
+ }
+
+ lease->pclass = new_val;
+}
+#endif
+
/* deleted leases get transferred to the old_leases list.
remove them here, after calling the lease change
script. Also run the lease change script on new/modified leases.
@@ -1053,6 +1178,9 @@
free(slaac);
}
#endif
+#ifdef ZYXEL_PATCH
+ sendLeaseMessageToESMD(ACTION_DEL, lease, NULL);
+#endif
kill_name(lease);
#ifdef HAVE_SCRIPT
queue_script(ACTION_DEL, lease, lease->old_hostname, now);
@@ -1062,6 +1190,20 @@
#endif
old_leases = lease->next;
+#ifdef ZYXEL_PATCH
+ if (lease->vendorid) {
+ free(lease->vendorid);
+ }
+ if (lease->oui) {
+ free(lease->oui);
+ }
+ if (lease->serial) {
+ free(lease->serial);
+ }
+ if (lease->pclass) {
+ free(lease->pclass);
+ }
+#endif
free(lease->old_hostname);
free(lease->clid);
free(lease->extradata);
Index: dnsmasq-2.78/src/extern.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ dnsmasq-2.78/src/extern.c 2018-10-29 18:15:39.754640600 +0800
@@ -0,0 +1,151 @@
+#ifdef ZYXEL_PATCH
+#include "dnsmasq.h"
+
+
+/*ZyXEL zcfg*/
+#include "zcfg_common.h"
+#include "zcfg_debug.h"
+#include "zcfg_msg.h"
+
+
+
+void dnsmasq_eid_register(void)
+{
+ zcfgRet_t retzcfg;
+
+ /*Register dnsmasq eid which is defined in zcfg_eid.h */
+ zcfgEidInit(ZCFG_EID_DNSMASQ, NULL);
+
+ /*init message server */
+ retzcfg = zcfgMsgServerInit();
+ if (retzcfg != ZCFG_SUCCESS) {
+ zcfgLog(ZCFG_LOG_ERR, "Dnsmasq message server init fail\n");
+
+ }
+}
+
+static zcfgRet_t dnsmasq_msg_send(int msg_type, int payloadLen,
+ const char *payload, char **reply)
+{
+ zcfgRet_t ret = 0;
+ void *sendBuf = NULL;
+ void *recvBuf = NULL;
+ zcfgMsg_t *sendMsgHdr = NULL;
+ zcfgMsg_t *recvMsgHdr = NULL;
+ char *recv_str = NULL;
+ int buf_size = 0;
+
+ buf_size = sizeof(zcfgMsg_t) + payloadLen + 1;
+ sendBuf = calloc(1, buf_size);
+ sendMsgHdr = (zcfgMsg_t *) sendBuf;
+
+ sendMsgHdr->type = msg_type;
+ sendMsgHdr->length = payloadLen + 1;
+ sendMsgHdr->srcEid = ZCFG_EID_DNSMASQ;
+ sendMsgHdr->dstEid = ZCFG_EID_ESMD;
+ if (payload != NULL)
+ memcpy(sendBuf + sizeof(zcfgMsg_t), payload, payloadLen);
+
+ ret = zcfgMsgSendAndGetReply(sendMsgHdr, (zcfgMsg_t **) & recvBuf, 0);
+ if (ret == ZCFG_SUCCESS) {
+ recvMsgHdr = (zcfgMsg_t *) recvBuf;
+ if (recvMsgHdr) {
+ if (recvMsgHdr->type == RESPONSE_SUCCESS) {
+ recv_str = (char *) recvBuf + sizeof(zcfgMsg_t);
+ if (recvMsgHdr->length > 0 && reply) {
+ *reply = calloc(1, recvMsgHdr->length + 1);
+ if (*reply)
+ memcpy(*reply, recv_str, recvMsgHdr->length);
+ }
+ }
+ free(recvBuf);
+ }
+ }
+
+ return ret;
+}
+
+void sendLeaseMessageToESMD(int action, struct dhcp_lease *lease,
+ const char *ifname)
+{
+ zcfgRet_t ret = 0;
+ char buf[2048] = { 0 }, *bufPtr, tmp[256] = {
+ 0}, *tmpPtr;
+ char *actionStr = NULL;
+ int i;
+ my_syslog(MS_DHCP | LOG_INFO, "%s ", __func__);
+
+ bufPtr = buf;
+ bufPtr += sprintf(bufPtr, "{");
+
+ switch (action) {
+ case ACTION_ADD:
+ actionStr = "add";
+ break;
+ case ACTION_DEL:
+ actionStr = "del";
+ break;
+ case ACTION_OLD_HOSTNAME:
+ case ACTION_OLD:
+ actionStr = "up";
+ break;
+ }
+ if (actionStr)
+ bufPtr += sprintf(bufPtr, "\"ac\":\"%s\",", actionStr);
+
+ bufPtr += sprintf(bufPtr, "\"expire\":\"%lu\",", lease->expires);
+
+ tmpPtr = tmp;
+ for (i = 0; i < lease->hwaddr_len - 1; i++)
+ tmpPtr += sprintf(tmpPtr, "%.2x:", lease->hwaddr[i]);
+ tmpPtr += sprintf(tmpPtr, "%.2x", lease->hwaddr[i]);
+ bufPtr += sprintf(bufPtr, "\"mac\":\"%s\",", tmp);
+
+#ifdef HAVE_DHCP6
+ if ((lease->flags & (LEASE_TA | LEASE_NA))) {
+ bufPtr +=
+ sprintf(bufPtr, "\"ip\":\"%s\",",
+ inet_ntop(AF_INET6, &lease->addr6, tmp, ADDRSTRLEN));
+ } else
+#endif
+ bufPtr +=
+ sprintf(bufPtr, "\"ip\":\"%s\",",
+ inet_ntop(AF_INET, &lease->addr, tmp, ADDRSTRLEN));
+
+ bufPtr +=
+ sprintf(bufPtr, "\"host\":\"%s\",",
+ (lease->hostname) ? lease->hostname : "*");
+ //option 60
+ bufPtr +=
+ sprintf(bufPtr, "\"vendor\":\"%s\",",
+ (lease->vendorid) ? lease->vendorid : "*");
+ //option 125
+ bufPtr +=
+ sprintf(bufPtr, "\"moui\":\"%s\",", (lease->oui) ? (char *)lease->oui : "*");
+ bufPtr +=
+ sprintf(bufPtr, "\"serial\":\"%s\",",
+ (lease->serial) ? (char *)lease->serial : "*");
+ bufPtr +=
+ sprintf(bufPtr, "\"pclass\":\"%s\",",
+ (lease->pclass) ? (char *)lease->pclass : "*");
+ //option 61
+ if (lease->clid && lease->clid_len != 0) {
+ tmpPtr = tmp;
+ for (i = 0; i < lease->clid_len - 1; i++)
+ tmpPtr += sprintf(tmpPtr, "%.2x:", lease->clid[i]);
+ tmpPtr += sprintf(tmpPtr, "%.2x", lease->clid[i]);
+ } else
+ sprintf(tmp, "*");
+ bufPtr += sprintf(bufPtr, "\"cid\":\"%s\",", tmp);
+
+ bufPtr += sprintf(bufPtr, "\"ifname\":\"%s\"", (ifname) ? ifname : "*");
+ bufPtr += sprintf(bufPtr, "}");
+
+ bufPtr = '\0';
+
+ my_syslog(MS_DHCP | LOG_INFO, "%s send to esmd buf = %s", __func__, buf);
+ ret = dnsmasq_msg_send(ZCFG_MSG_DHCPD_OPTION, strlen(buf), buf, NULL);
+ my_syslog(MS_DHCP | LOG_INFO, "%s esmd reply=%d", __func__, ret);
+}
+
+#endif
Index: dnsmasq-2.78/src/rfc2131.c
===================================================================
--- dnsmasq-2.78.orig/src/rfc2131.c 2018-10-29 18:12:09.757732831 +0800
+++ dnsmasq-2.78/src/rfc2131.c 2018-10-29 18:12:09.797732832 +0800
@@ -117,6 +117,10 @@
#ifdef HAVE_SCRIPT
unsigned char *class = NULL;
#endif
+#ifdef ZYXEL_PATCH
+ char *vendor_class_ptr = NULL;
+
+#endif
subnet_addr.s_addr = override.s_addr = 0;
@@ -471,6 +475,9 @@
if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 1))) {
memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
vendor_class_len = option_len(opt);
+#ifdef ZYXEL_PATCH
+ vendor_class_ptr = option_ptr(opt, 0);
+#endif
}
match_vendor_opts(opt, daemon->dhcp_opts);
@@ -608,6 +615,16 @@
if (hostname)
lease_set_hostname(lease, hostname, 1, get_domain(lease->addr),
domain);
+#ifdef ZYXEL_PATCH
+ if (vendor_class_len)
+ lease_set_vendor(lease, vendor_class_ptr, vendor_class_len);
+ if (oui)
+ lease_set_oui(lease, option_ptr(oui, 0), option_len(oui));
+ if (serial)
+ lease_set_serial(lease, option_ptr(serial, 0), option_len(serial));
+ if (class)
+ lease_set_class(lease, option_ptr(class, 0), option_len(class));
+#endif
/* infinite lease unless nailed in dhcp-host line. */
lease_set_expires(lease,
have_config(config,
@@ -1386,7 +1403,16 @@
if (hostname)
lease_set_hostname(lease, hostname, hostname_auth,
get_domain(lease->addr), domain);
-
+#ifdef ZYXEL_PATCH
+ if (vendor_class_len)
+ lease_set_vendor(lease, vendor_class_ptr, vendor_class_len);
+ if (oui)
+ lease_set_oui(lease, option_ptr(oui, 0), option_len(oui));
+ if (serial)
+ lease_set_serial(lease, option_ptr(serial, 0), option_len(serial));
+ if (class)
+ lease_set_class(lease, option_ptr(class, 0), option_len(class));
+#endif
lease_set_expires(lease, time, now);
lease_set_interface(lease, int_index, now);
@@ -1406,6 +1432,9 @@
do_options(context, mess, end, req_options, hostname,
get_domain(mess->yiaddr), netid, subnet_addr, fqdn_flags,
borken_opt, pxearch, uuid, vendor_class_len, now, time, fuzz);
+#ifdef ZYXEL_PATCH
+ sendLeaseMessageToESMD(ACTION_ADD, lease, iface_name);
+#endif
}
return dhcp_packet_size(mess, agent_id, real_end);
Index: dnsmasq-2.78/src/util.c
===================================================================
--- dnsmasq-2.78.orig/src/util.c 2018-10-29 18:12:09.777732832 +0800
+++ dnsmasq-2.78/src/util.c 2018-10-29 18:12:09.797732832 +0800
@@ -354,6 +354,9 @@
return 1;
}
+#ifdef ZYXEL_PATCH
+#include <sys/sysinfo.h>
+#endif
time_t dnsmasq_time(void)
{
#ifdef HAVE_BROKEN_RTC
@@ -365,8 +368,14 @@
return (time_t) (times(&dummy) / tps);
#else
+#ifdef ZYXEL_PATCH
+ struct sysinfo sysinfoObject;
+ sysinfo(&sysinfoObject);
+ return sysinfoObject.uptime;
+#else
return time(NULL);
#endif
+#endif
}
int netmask_length(struct in_addr mask)
Index: dnsmasq-2.78/Makefile
===================================================================
--- dnsmasq-2.78.orig/Makefile 2017-10-02 21:13:51.000000000 +0800
+++ dnsmasq-2.78/Makefile 2018-10-29 18:12:09.797732832 +0800
@@ -78,6 +78,8 @@
domain.o dnssec.o blockdata.o tables.o loop.o inotify.o \
poll.o rrfilter.o edns0.o arp.o
+objs += extern.o
+
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
dns-protocol.h radv-protocol.h ip6addr.h
@@ -0,0 +1,22 @@
Index: dnsmasq-2.78/src/rfc2131.c
===================================================================
--- dnsmasq-2.78.orig/src/rfc2131.c 2018-10-30 17:23:23.959084000 +0800
+++ dnsmasq-2.78/src/rfc2131.c 2018-10-30 17:25:27.296016100 +0800
@@ -964,14 +964,15 @@
if (lease && lease->addr.s_addr == option_addr(opt).s_addr)
lease_prune(lease, now);
- if (have_config(config, CONFIG_ADDR) &&
- config->addr.s_addr == option_addr(opt).s_addr) {
+ if (have_config(config, CONFIG_ADDR) && config->addr.s_addr == option_addr(opt).s_addr) {
prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
my_syslog(MS_DHCP | LOG_WARNING,
_("disabling DHCP static address %s for %s"),
inet_ntoa(config->addr), daemon->dhcp_buff);
+#ifndef ZYXEL_PATCH /* when static addr is declined by host, do not disable static address lease, just let host keep on trying, ZyXEL, John */
config->flags |= CONFIG_DECLINED;
config->decline_time = now;
+#endif
} else
/* make sure this host gets a different address next time. */
for (; context; context = context->current)
@@ -0,0 +1,274 @@
Index: dnsmasq-2.78/src/forward.c
===================================================================
--- dnsmasq-2.78.orig/src/forward.c 2018-10-30 21:27:08.244884357 +0800
+++ dnsmasq-2.78/src/forward.c 2018-10-30 21:27:08.392810356 +0800
@@ -433,6 +433,13 @@
if (start->sfd)
fd = start->sfd->fd;
else {
+#ifdef ZYXEL_PATCH //reject query when special domain query has no socket
+ if (type == SERV_HAS_DOMAIN
+ && hostname_isequal(domain, start->domain)) {
+ my_syslog(LOG_WARNING, _("Reject query for %s"), start->domain);
+ break;
+ }
+#endif
#ifdef HAVE_IPV6
if (start->addr.sa.sa_family == AF_INET6) {
if (!forward->rfd6 && !(forward->rfd6 = allocate_rfd(AF_INET6)))
Index: dnsmasq-2.78/src/dnsmasq.h
===================================================================
--- dnsmasq-2.78.orig/src/dnsmasq.h 2018-10-30 21:27:08.356828356 +0800
+++ dnsmasq-2.78/src/dnsmasq.h 2018-10-30 21:27:08.392810356 +0800
@@ -510,6 +510,9 @@
struct server {
union mysockaddr addr, source_addr;
+#ifdef ZYXEL_PATCH
+ unsigned long sock_mark;
+#endif
char interface[IF_NAMESIZE + 1];
struct serverfd *sfd;
char *domain; /* set if this server only handles a domain. */
@@ -1254,8 +1257,14 @@
void set_option_bool(unsigned int opt);
void reset_option_bool(unsigned int opt);
struct hostsfile *expand_filelist(struct hostsfile *list);
+#ifdef ZYXEL_PATCH
+char *parse_server(char *arg, union mysockaddr *addr,
+ union mysockaddr *source_addr, char *interface,
+ int *flags, unsigned long *mark);
+#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags);
+#endif
int option_read_dynfile(char *file, int flags);
/* forward.c */
Index: dnsmasq-2.78/src/network.c
===================================================================
--- dnsmasq-2.78.orig/src/network.c 2018-10-30 21:27:08.264874357 +0800
+++ dnsmasq-2.78/src/network.c 2018-10-30 21:27:08.396808356 +0800
@@ -1157,7 +1157,15 @@
return 1;
}
+#ifdef ZYXEL_PATCH
+#define allocate_sfd(a, i) do_allocate_sfd(a, i, 0)
+#define allocate_sfd_mark(a, i, m) do_allocate_sfd(a, i, m)
+
+static struct serverfd *do_allocate_sfd(union mysockaddr *addr,
+ char *intname, unsigned long mark)
+#else
static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
+#endif
{
struct serverfd *sfd;
unsigned int ifindex = 0;
@@ -1198,6 +1206,11 @@
free(sfd);
return NULL;
}
+#ifdef ZYXEL_PATCH
+ if (mark != 0) {
+ setsockopt(sfd->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
+ }
+#endif
if (!local_bind(sfd->fd, addr, intname, 0) || !fix_fd(sfd->fd)) {
errsave = errno; /* save error from bind. */
@@ -1248,9 +1261,13 @@
if (!
(srv->
flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV |
- SERV_NO_REBIND))
- && !allocate_sfd(&srv->source_addr, srv->interface) && errno != 0
- && option_bool(OPT_NOWILD)) {
+ SERV_NO_REBIND)) &&
+#ifdef ZYXEL_PATCH
+ !allocate_sfd_mark(&srv->source_addr, srv->interface, srv->sock_mark) &&
+#else
+ !allocate_sfd(&srv->source_addr, srv->interface) &&
+#endif
+ errno != 0 && option_bool(OPT_NOWILD)) {
prettyprint_addr(&srv->source_addr, daemon->namebuff);
if (srv->interface[0] != 0) {
strcat(daemon->namebuff, " ");
@@ -1423,8 +1440,12 @@
/* 0.0.0.0 is nothing, the stack treats it like 127.0.0.1 */
if (serv->addr.sa.sa_family == AF_INET &&
serv->addr.in.sin_addr.s_addr == 0) {
+#ifdef ZYXEL_PATCH // don't ignoring 0.0.0.0, for special reject query
+ goto SETTOLIST;
+#else
serv->flags |= SERV_MARK;
continue;
+#endif
}
for (iface = daemon->interfaces; iface; iface = iface->next)
@@ -1439,19 +1460,29 @@
/* Do we need a socket set? */
if (!serv->sfd &&
+#ifdef ZYXEL_PATCH
+ !(serv->sfd = allocate_sfd_mark(&serv->source_addr, serv->interface, serv->sock_mark)) &&
+#else
!(serv->sfd = allocate_sfd(&serv->source_addr, serv->interface)) &&
+#endif
errno != 0) {
my_syslog(LOG_WARNING,
_("ignoring nameserver %s - cannot make/bind socket: %s"),
daemon->namebuff, strerror(errno));
+#ifndef ZYXEL_PATCH //don't free special domain rule. for reject query
serv->flags |= SERV_MARK;
continue;
+#endif
}
if (serv->sfd)
serv->sfd->used = 1;
}
+#ifdef ZYXEL_PATCH
+ SETTOLIST:
+#endif
+
if (!(serv->flags & SERV_NO_REBIND)
&& !(serv->flags & SERV_LITERAL_ADDRESS)) {
if (++count > SERVERS_LOGGED)
Index: dnsmasq-2.78/src/option.c
===================================================================
--- dnsmasq-2.78.orig/src/option.c 2018-10-30 21:27:08.292860357 +0800
+++ dnsmasq-2.78/src/option.c 2018-10-30 21:27:56.147708600 +0800
@@ -871,6 +871,24 @@
return ret;
}
+#ifdef ZYXEL_PATCH
+static int hextoul_check(char *a, unsigned long *res)
+{
+ char *p;
+
+ if (!a)
+ return 0;
+
+ unhide_metas(a);
+
+ for (p = a; *p; p++)
+ if (!((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f')))
+ return 0;
+
+ *res = strtoul(a, NULL, 16);
+ return 1;
+}
+#endif
static int atoi_check(char *a, int *res)
{
char *p;
@@ -998,9 +1016,14 @@
return NULL;
}
-
+#ifdef ZYXEL_PATCH
+char *parse_server(char *arg, union mysockaddr *addr,
+ union mysockaddr *source_addr, char *interface,
+ int *flags, unsigned long *mark)
+#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags)
+#endif
{
int source_port = 0, serv_port = NAMESERVER_PORT;
char *portno, *source;
@@ -1009,7 +1032,10 @@
int scope_index = 0;
char *scope_id;
#endif
-
+#ifdef ZYXEL_PATCH
+ char *markPtr = NULL;
+ unsigned long sock_mark = 0;
+#endif
if (!arg || strlen(arg) == 0) {
*flags |= SERV_NO_ADDR;
*interface = 0;
@@ -1019,7 +1045,11 @@
if ((source = split_chr(arg, '@')) && /* is there a source. */
(portno = split_chr(source, '#')) && !atoi_check16(portno, &source_port))
return _("bad port");
-
+#ifdef ZYXEL_PATCH
+ if (source && /* is there a source. */
+ (markPtr = split_chr(source, '$')) && !hextoul_check(markPtr, &sock_mark))
+ return _("bad mark");
+#endif
if ((portno = split_chr(arg, '#')) && /* is there a port no. */
!atoi_check16(portno, &serv_port))
return _("bad port");
@@ -1050,6 +1080,11 @@
source_addr->in.sin_port = htons(daemon->query_port);
if (source) {
+#ifdef ZYXEL_PATCH
+ if (mark) {
+ *mark = sock_mark;
+ }
+#endif
if (flags)
*flags |= SERV_HAS_SOURCE;
source_addr->in.sin_port = htons(source_port);
@@ -2498,9 +2533,15 @@
if (newlist->flags & SERV_LITERAL_ADDRESS)
ret_err(gen_err);
} else {
+#ifdef ZYXEL_PATCH
+ char *err =
+ parse_server(arg, &newlist->addr, &newlist->source_addr,
+ newlist->interface, &newlist->flags, &newlist->sock_mark);
+#else
char *err =
parse_server(arg, &newlist->addr, &newlist->source_addr,
newlist->interface, &newlist->flags);
+#endif
if (err)
ret_err(err);
}
@@ -2545,10 +2586,15 @@
else
ret_err(gen_err);
+#ifdef ZYXEL_PATCH
+ string =
+ parse_server(comma, &serv->addr, &serv->source_addr, serv->interface,
+ &serv->flags, &serv->sock_mark);
+#else
string =
parse_server(comma, &serv->addr, &serv->source_addr, serv->interface,
&serv->flags);
-
+#endif
if (string)
ret_err(string);
Index: dnsmasq-2.78/src/dbus.c
===================================================================
--- dnsmasq-2.78.orig/src/dbus.c 2018-10-30 21:27:08.200906358 +0800
+++ dnsmasq-2.78/src/dbus.c 2018-10-30 21:27:08.400806356 +0800
@@ -345,9 +345,15 @@
memset(&interface, 0, sizeof(interface));
/* parse the IP address */
+#ifdef ZYXEL_PATCH
+ if ((addr_err =
+ parse_server(str_addr, &addr, &source_addr, (char *) &interface,
+ &flags, NULL))) {
+#else
if ((addr_err =
parse_server(str_addr, &addr, &source_addr, (char *) &interface,
&flags))) {
+#endif
error =
dbus_message_new_error_printf(message, DBUS_ERROR_INVALID_ARGS,
"Invalid IP address '%s': %s", str,
@@ -0,0 +1,250 @@
Index: dnsmasq-2.78/src/cache.c
===================================================================
--- dnsmasq-2.78.orig/src/cache.c 2018-10-31 11:59:54.897051182 +0800
+++ dnsmasq-2.78/src/cache.c 2018-10-31 11:59:55.149051188 +0800
@@ -555,11 +555,80 @@
new_chain = new;
return new;
+
}
+#ifdef DNS_TRAFFIC_ROUTE
+void add_dns_traffic_route(uint32_t s_addr, const char *cname, int *flush)
+{
+ char sysCmd[128] = "";
+ struct in_addr srcIP;
+ srcIP.s_addr = s_addr;
+ struct server *serv = NULL;
+
+ if (s_addr == 0) {
+
+ return;
+ }
+
+ serv = daemon->servers;
+
+ while (serv) {
+ if (serv->domain && (strcmp(cname, serv->domain) == 0)) {
+ if (*flush) {
+ /* deledt */
+ sprintf(sysCmd,
+ "iptables -t mangle -D IP_ROUTE2_DNSRT -j DNSRT_RULE_%d",
+ serv->rule_no);
+ system(sysCmd);
+
+ sprintf(sysCmd, "iptables -t mangle -F DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ sprintf(sysCmd, "iptables -t mangle -X DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ /* create */
+ sprintf(sysCmd, "iptables -t mangle -N DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ sprintf(sysCmd,
+ "iptables -t mangle -A IP_ROUTE2_DNSRT -j DNSRT_RULE_%d",
+ serv->rule_no);
+ system(sysCmd);
+
+ *flush = 0;
+ }
+
+ /* add */
+ sprintf(sysCmd,
+ "iptables -t mangle -D DNSRT_RULE_%d -d %s/%d -j MARK --or-mark 0x%x 2> /dev/null",
+ serv->rule_no, inet_ntoa(srcIP), serv->subnet_mask,
+ serv->sock_mark);
+ system(sysCmd);
+
+ sprintf(sysCmd,
+ "iptables -t mangle -A DNSRT_RULE_%d -d %s/%d -j MARK --or-mark 0x%x",
+ serv->rule_no, inet_ntoa(srcIP), serv->subnet_mask,
+ serv->sock_mark);
+ system(sysCmd);
+
+ break;
+ }
+ serv = serv->next;
+ }
+
+}
+#endif
+
/* after end of insertion, commit the new entries */
void cache_end_insert(void)
{
+#ifdef DNS_TRAFFIC_ROUTE
+ struct in_addr *target = NULL;
+ int flush = 1;
+#endif
+
if (insert_error)
return;
@@ -572,6 +641,16 @@
cache_hash(new_chain);
cache_link(new_chain);
cache_inserted++;
+#ifdef DNS_TRAFFIC_ROUTE
+ if ((new_chain->flags & (F_FORWARD | F_IPV4)) == (F_FORWARD | F_IPV4)) {
+ target = &new_chain->addr.addr.addr.addr4;
+ }
+
+ if (target) {
+ add_dns_traffic_route(target->s_addr, cache_get_name(new_chain),
+ &flush);
+ }
+#endif
}
new_chain = tmp;
}
Index: dnsmasq-2.78/src/dbus.c
===================================================================
--- dnsmasq-2.78.orig/src/dbus.c 2018-10-31 11:59:55.133051188 +0800
+++ dnsmasq-2.78/src/dbus.c 2018-10-31 11:59:55.149051188 +0800
@@ -346,9 +346,15 @@
/* parse the IP address */
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+ if ((addr_err =
+ parse_server(str_addr, &addr, &source_addr, (char *) &interface,
+ &flags, NULL, NULL, NULL))) {
+#else
if ((addr_err =
parse_server(str_addr, &addr, &source_addr, (char *) &interface,
&flags, NULL))) {
+#endif
#else
if ((addr_err =
parse_server(str_addr, &addr, &source_addr, (char *) &interface,
Index: dnsmasq-2.78/src/dnsmasq.h
===================================================================
--- dnsmasq-2.78.orig/src/dnsmasq.h 2018-10-31 11:59:55.129051188 +0800
+++ dnsmasq-2.78/src/dnsmasq.h 2018-10-31 11:59:55.149051188 +0800
@@ -512,6 +512,10 @@
union mysockaddr addr, source_addr;
#ifdef ZYXEL_PATCH
unsigned long sock_mark;
+#ifdef DNS_TRAFFIC_ROUTE
+ int subnet_mask;
+ int rule_no;
+#endif
#endif
char interface[IF_NAMESIZE + 1];
struct serverfd *sfd;
@@ -1258,9 +1262,16 @@
void reset_option_bool(unsigned int opt);
struct hostsfile *expand_filelist(struct hostsfile *list);
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+char *parse_server(char *arg, union mysockaddr *addr,
+ union mysockaddr *source_addr, char *interface,
+ int *flags, unsigned long *mark, int *subnet_mask,
+ int *rule_no);
+#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface,
int *flags, unsigned long *mark);
+#endif
#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags);
Index: dnsmasq-2.78/src/option.c
===================================================================
--- dnsmasq-2.78.orig/src/option.c 2018-10-31 11:59:55.133051188 +0800
+++ dnsmasq-2.78/src/option.c 2018-10-31 12:01:01.000485000 +0800
@@ -1017,9 +1017,16 @@
return NULL;
}
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+char *parse_server(char *arg, union mysockaddr *addr,
+ union mysockaddr *source_addr, char *interface,
+ int *flags, unsigned long *mark, int *subnet_mask,
+ int *rule_no)
+#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface,
int *flags, unsigned long *mark)
+#endif
#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags)
@@ -1035,6 +1042,12 @@
#ifdef ZYXEL_PATCH
char *markPtr = NULL;
unsigned long sock_mark = 0;
+#ifdef DNS_TRAFFIC_ROUTE
+ char *maskPtr = NULL;
+ int mask = 32;
+ char *rulePtr = NULL;
+ int rule = 0;
+#endif
#endif
if (!arg || strlen(arg) == 0) {
*flags |= SERV_NO_ADDR;
@@ -1046,6 +1059,14 @@
(portno = split_chr(source, '#')) && !atoi_check16(portno, &source_port))
return _("bad port");
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+ if (source && /* is there a source. */
+ (rulePtr = split_chr(source, '|')) && !atoi_check(rulePtr, &rule))
+ return _("bad rule");
+ if (source && /* is there a source. */
+ (maskPtr = split_chr(source, '&')) && !atoi_check(maskPtr, &mask))
+ return _("bad mask");
+#endif
if (source && /* is there a source. */
(markPtr = split_chr(source, '$')) && !hextoul_check(markPtr, &sock_mark))
return _("bad mark");
@@ -1084,6 +1105,14 @@
if (mark) {
*mark = sock_mark;
}
+#ifdef DNS_TRAFFIC_ROUTE
+ if (subnet_mask) {
+ *subnet_mask = mask;
+ }
+ if (rule_no) {
+ *rule_no = rule;
+ }
+#endif
#endif
if (flags)
*flags |= SERV_HAS_SOURCE;
@@ -2534,9 +2563,15 @@
ret_err(gen_err);
} else {
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+ char *err =
+ parse_server(arg, &newlist->addr, &newlist->source_addr,
+ newlist->interface, &newlist->flags, &newlist->sock_mark, &newlist->subnet_mask, &newlist->rule_no);
+#else
char *err =
parse_server(arg, &newlist->addr, &newlist->source_addr,
newlist->interface, &newlist->flags, &newlist->sock_mark);
+#endif
#else
char *err =
parse_server(arg, &newlist->addr, &newlist->source_addr,
@@ -2587,9 +2622,15 @@
ret_err(gen_err);
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+ string =
+ parse_server(comma, &serv->addr, &serv->source_addr, serv->interface,
+ &serv->flags, &serv->sock_mark, &serv->subnet_mask, &serv->rule_no);
+#else
string =
parse_server(comma, &serv->addr, &serv->source_addr, serv->interface,
&serv->flags, &serv->sock_mark);
+#endif
#else
string =
parse_server(comma, &serv->addr, &serv->source_addr, serv->interface,
@@ -0,0 +1,177 @@
Index: dnsmasq-2.78/src/dnsmasq.h
===================================================================
--- dnsmasq-2.78.orig/src/dnsmasq.h 2018-10-31 15:45:27.946913771 +0800
+++ dnsmasq-2.78/src/dnsmasq.h 2018-10-31 15:45:27.962913771 +0800
@@ -832,7 +832,13 @@
struct dhcp_netid netid;
struct dhcp_mac *next;
};
-
+#ifdef ZYXEL_PATCH
+struct dhcp_ifname {
+ char ifname[IF_NAMESIZE];
+ struct dhcp_netid netid;
+ struct dhcp_ifname *next;
+};
+#endif
struct dhcp_bridge {
char iface[IF_NAMESIZE];
struct dhcp_bridge *alias, *next;
@@ -1092,6 +1098,9 @@
/* utility string buffer, hold max sized IP address as string */
char *addrbuff;
char *addrbuff2; /* only allocated when OPT_EXTRALOG */
+#ifdef ZYXEL_PATCH
+ struct dhcp_ifname *dhcp_ifnames;
+#endif
} *daemon;
Index: dnsmasq-2.78/src/option.c
===================================================================
--- dnsmasq-2.78.orig/src/option.c 2018-10-31 15:45:27.946913771 +0800
+++ dnsmasq-2.78/src/option.c 2018-10-31 15:45:27.966913771 +0800
@@ -162,6 +162,10 @@
#define LOPT_TFTP_MTU 349
#define LOPT_REPLY_DELAY 350
+#ifdef ZYXEL_PATCH
+#define LOPT_TAG_IFNAME 329
+#endif
+
#ifdef HAVE_GETOPT_LONG
static const struct option opts[] =
#else
@@ -326,6 +330,9 @@
{"script-arp", 0, 0, LOPT_SCRIPT_ARP},
{"dhcp-ttl", 1, 0, LOPT_DHCPTTL},
{"dhcp-reply-delay", 1, 0, LOPT_REPLY_DELAY},
+#ifdef ZYXEL_PATCH
+ {"dhcp-ifname", 1, 0, LOPT_TAG_IFNAME},
+#endif
{NULL, 0, 0, 0}
};
@@ -749,8 +756,13 @@
NULL}, {
LOPT_REPLY_DELAY, ARG_ONE, "<integer>",
gettext_noop("Delay DHCP replies for at least number of seconds."),
- NULL}, {
- 0, 0, NULL, NULL, NULL}
+ NULL},
+#ifdef ZYXEL_PATCH
+ {
+ LOPT_TAG_IFNAME, ARG_DUP, "set:<tag>,<ifname>",
+ gettext_noop("Map interface name to option set."), NULL},
+#endif
+ {0, 0, NULL, NULL, NULL}
};
/* We hide metacharacters in quoted strings by mapping them into the ASCII control
@@ -3568,7 +3580,23 @@
}
}
break;
+#ifdef ZYXEL_PATCH
+ case LOPT_TAG_IFNAME: /* --dhcp-ifname */
+ {
+ if (!(comma = split(arg)))
+ ret_err(gen_err);
+ else {
+ struct dhcp_ifname *new = opt_malloc(sizeof(struct dhcp_ifname));
+ new->netid.net = opt_string_alloc(set_prefix(arg));
+ arg = comma;
+ strcpy(new->ifname, arg);
+ new->next = daemon->dhcp_ifnames;
+ daemon->dhcp_ifnames = new;
+ }
+ }
+ break;
+#endif
#ifdef OPTION6_PREFIX_CLASS
case LOPT_PREF_CLSS: /* --dhcp-prefix-class */
{
Index: dnsmasq-2.78/src/rfc2131.c
===================================================================
--- dnsmasq-2.78.orig/src/rfc2131.c 2018-10-31 15:45:27.906913770 +0800
+++ dnsmasq-2.78/src/rfc2131.c 2018-10-31 15:46:01.715691600 +0800
@@ -75,6 +75,10 @@
static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid,
struct in_addr local, time_t now);
struct dhcp_boot *find_boot(struct dhcp_netid *netid);
+#ifdef ZYXEL_PATCH
+static int find_ifname(unsigned char *subnet_mac, int len, char *ifname,
+ char *interface);
+#endif
static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid,
struct dhcp_packet *mess, struct in_addr local,
time_t now, int pxe);
@@ -119,7 +123,7 @@
#endif
#ifdef ZYXEL_PATCH
char *vendor_class_ptr = NULL;
-
+ struct dhcp_ifname *ifname;
#endif
subnet_addr.s_addr = override.s_addr = 0;
@@ -277,6 +281,16 @@
&emac_len);
}
+#ifdef ZYXEL_PATCH
+ for (ifname = daemon->dhcp_ifnames; ifname; ifname = ifname->next) {
+
+ if (find_ifname(mess->chaddr, mess->hlen, ifname->ifname, iface_name)) {
+ ifname->netid.next = netid;
+ netid = &ifname->netid;
+ }
+ }
+#endif
+
for (mac = daemon->dhcp_macs; mac; mac = mac->next)
if (mac->hwaddr_len == mess->hlen &&
(mac->hwaddr_type == mess->htype || mac->hwaddr_type == 0) &&
@@ -2218,6 +2232,41 @@
return boot;
}
+#ifdef ZYXEL_PATCH
+static int
+find_ifname(unsigned char *subnet_mac, int len, char *ifname, char *interface)
+{
+ FILE *fp;
+ char sysCmd[128] = { 0 };
+ char line[128] = { 0 };
+
+ int sub_mac_idx = 0;
+ char mac_value[32] = { 0 };
+
+ for (sub_mac_idx = 0; sub_mac_idx < len; sub_mac_idx++) {
+ if (0 == sub_mac_idx) {
+ sprintf(mac_value, "%02x", subnet_mac[sub_mac_idx]);
+ } else {
+ sprintf(mac_value, "%s:%02x", mac_value, subnet_mac[sub_mac_idx]);
+ }
+ }
+
+ sprintf(sysCmd, "brctl showmacs %s | grep %s", interface, mac_value);
+ fp = popen(sysCmd, "r");
+
+ if (fp) {
+ while (fgets(line, sizeof(line), fp) != NULL) {
+ if (strstr(line, ifname) != NULL) {
+ pclose(fp);
+ return 1;
+ }
+ }
+ pclose(fp);
+ }
+ return 0;
+}
+#endif
+
static void do_options(struct dhcp_context *context,
struct dhcp_packet *mess,
unsigned char *end,
@@ -0,0 +1,406 @@
Index: dnsmasq-2.78/src/dnsmasq.h
===================================================================
--- dnsmasq-2.78.orig/src/dnsmasq.h 2018-11-01 10:07:19.527354088 +0800
+++ dnsmasq-2.78/src/dnsmasq.h 2018-11-01 11:08:47.906341300 +0800
@@ -1595,14 +1595,30 @@
char *interface, struct dhcp_lease *leases);
#endif
+
/* extern.c */
#ifdef ZYXEL_PATCH
+struct CritDhcpInfo {
+ char *ifname;
+ char *oui, *serial, *pclass;
+ int oui_len, serial_len, pclass_len;
+ char *emac;
+ int emac_len;
+ char *vendor;
+ int vendor_len;
+ char *hostname;
+ unsigned char *clid;
+ int clid_len;
+ char tag[20];
+};
void lease_set_vendor(struct dhcp_lease *, const char* , int );
void lease_set_oui(struct dhcp_lease *, const char* , int );
void lease_set_serial(struct dhcp_lease *, const char* , int );
void lease_set_class(struct dhcp_lease *, const char* , int );
void dnsmasq_eid_register(void);
void sendLeaseMessageToESMD(int, struct dhcp_lease *, const char*);
+void sendCritMessageToESMD(struct CritDhcpInfo *crit);
+void pruneCritReqList(void);
#endif
/* loop.c */
Index: dnsmasq-2.78/src/rfc2131.c
===================================================================
--- dnsmasq-2.78.orig/src/rfc2131.c 2018-11-01 10:07:19.531354088 +0800
+++ dnsmasq-2.78/src/rfc2131.c 2018-11-01 10:23:02.698103900 +0800
@@ -78,6 +78,54 @@
#ifdef ZYXEL_PATCH
static int find_ifname(unsigned char *subnet_mac, int len, char *ifname,
char *interface);
+static int
+checkIntfGrpCrit(struct dhcp_netid *netid, char *iface_name,
+ char *client_hostname, unsigned char *emac, int emac_len,
+ char *vendor_class_ptr, int vendor_class_len,
+ unsigned char *clid, int clid_len, unsigned char *oui,
+ unsigned char *serial, unsigned char *class)
+{
+ struct dhcp_netid *tmpNetid = NULL;
+ struct CritDhcpInfo crit;
+ char *brNamePtr = NULL;
+
+
+ for (tmpNetid = netid; tmpNetid; tmpNetid = tmpNetid->next) {
+ //my_syslog(MS_DHCP | LOG_DEBUG, _("tmpNetid->net=%s, %s"), tmpNetid->net, iface_name);
+ if (!strncmp(tmpNetid->net, "Crit_br", 7)) {
+ brNamePtr = strstr(tmpNetid->net, "br");
+ if(iface_name != NULL && strcmp(brNamePtr, iface_name)){
+ memset(&crit, 0, sizeof(crit));
+ crit.ifname = iface_name;
+ crit.emac = emac;
+ crit.emac_len = emac_len;
+ crit.hostname = client_hostname;
+ strcpy(crit.tag, tmpNetid->net);
+ if(oui){
+ crit.oui = option_ptr(oui, 0);
+ crit.oui_len = option_len(oui);
+ }
+ if(serial){
+ crit.serial = option_ptr(serial, 0);
+ crit.serial_len = option_len(serial);
+ }
+ if(class){
+ crit.pclass = option_ptr(class, 0);
+ crit.pclass_len = option_len(class);
+ }
+ crit.vendor = vendor_class_ptr;
+ crit.vendor_len = vendor_class_len;
+ if(clid){
+ crit.clid = clid;
+ crit.clid_len = clid_len;
+ }
+ sendCritMessageToESMD(&crit);
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
#endif
static int pxe_uefi_workaround(int pxe_arch, struct dhcp_netid *netid,
struct dhcp_packet *mess, struct in_addr local,
@@ -1081,9 +1129,22 @@
message = _("no address available");
}
+#ifdef ZYXEL_PATCH
+ if (checkIntfGrpCrit
+ (tagif_netid, iface_name, client_hostname, emac, emac_len,
+ vendor_class_ptr, vendor_class_len, clid, clid_len, oui, serial, class)
+ || checkIntfGrpCrit(netid, iface_name, client_hostname, emac,
+ emac_len, vendor_class_ptr, vendor_class_len,
+ clid, clid_len, oui, serial, class)) {
+ //my_syslog(MS_DHCP | LOG_WARNING, _("Match interface grouping criteria !!! "));
+ return 0;
+ }
+#endif
+
log_packet("DHCPDISCOVER", opt ? option_ptr(opt, 0) : NULL, emac, emac_len,
iface_name, NULL, message, mess->xid);
+
if (message
|| !(context = narrow_context(context, mess->yiaddr, tagif_netid)))
return 0;
@@ -1196,7 +1257,17 @@
fuzz = rand16();
mess->yiaddr = mess->ciaddr;
}
-
+#ifdef ZYXEL_PATCH
+ if (checkIntfGrpCrit
+ (tagif_netid, iface_name, client_hostname, emac, emac_len,
+ vendor_class_ptr, vendor_class_len, clid, clid_len, oui, serial, class)
+ || checkIntfGrpCrit(netid, iface_name, client_hostname, emac,
+ emac_len, vendor_class_ptr, vendor_class_len,
+ clid, clid_len, oui, serial, class)) {
+ //my_syslog(MS_DHCP | LOG_WARNING, _("Match interface grouping criteria !!! "));
+ return 0;
+ }
+#endif
log_packet("DHCPREQUEST", &mess->yiaddr, emac, emac_len, iface_name, NULL,
NULL, mess->xid);
Index: dnsmasq-2.78/src/extern.c
===================================================================
--- dnsmasq-2.78.orig/src/extern.c 2018-11-01 10:07:19.359354084 +0800
+++ dnsmasq-2.78/src/extern.c 2018-11-01 11:04:48.072740900 +0800
@@ -24,6 +24,112 @@
}
}
+
+char *getPhyIfname(const char *ifname, const char *macaddr, char *reply)
+{
+ static char phyifname[20];
+ char tmp[256] = { 0 };
+ FILE *fp = NULL;
+
+ phyifname[0] = 0;
+ sprintf(tmp, "brctl showmacs %s | grep %s", ifname, macaddr);
+ if ((fp = popen(tmp, "r"))) {
+ tmp[0] = '\0';
+ fgets(tmp, sizeof(tmp) - 1, fp);
+ pclose(fp);
+ if (sscanf(tmp, "%*s %*s %*s %*s %s", phyifname) == 1) {
+ strcpy(reply, phyifname);
+ if (reply)
+ return reply;
+ return phyifname;
+ }
+ }
+
+ return "";
+}
+
+#if 1 //Prevent excessive criteria check request to ESMD.
+struct CritReqList {
+ char mac[20];
+ char phyIf[20];
+ char brIf[20];
+ unsigned long time;
+ struct CritReqList *next;
+} *critReqLists = NULL;
+
+#define CRITTIOMEOUT 15
+
+void pruneCritReqList()
+{
+ unsigned long now = time(NULL);
+ struct CritReqList *next, *prev, *tmp;
+
+ //my_syslog(MS_DHCP | LOG_DEBUG, "%s ", __func__);
+
+ if (!critReqLists)
+ return;
+
+ for (prev = next = critReqLists; next != NULL;) {
+ tmp = next;
+ next = tmp->next;
+ //my_syslog(MS_DHCP | LOG_DEBUG, "%s : %s, %lu", __func__, tmp->mac, now - tmp->time);
+ if ((now - tmp->time) >= CRITTIOMEOUT) {
+ if (critReqLists == tmp) {
+ critReqLists = next;
+ prev = next;
+ } else
+ prev->next = next;
+ free(tmp);
+ } else
+ prev = tmp;
+ }
+}
+
+void addCritReqtoList(const char *mac, const char *brif, const char *phyif)
+{
+ struct CritReqList *tmp, *next, *prev;
+
+ //my_syslog(MS_DHCP | LOG_DEBUG, "%s ", __func__);
+
+ tmp = calloc(1, sizeof(struct CritReqList));
+ strncpy(tmp->mac, mac, sizeof(tmp->mac) - 1);
+ strncpy(tmp->brIf, brif, sizeof(tmp->brIf) - 1);
+ strncpy(tmp->phyIf, phyif, sizeof(tmp->phyIf) - 1);
+ tmp->time = time(NULL);
+
+ if (!critReqLists) {
+ critReqLists = tmp;
+ } else {
+ for (next = critReqLists; next != NULL; next = next->next) {
+ prev = next;
+ }
+ prev->next = tmp;
+ }
+}
+
+int chkCritReqExist(const char *mac, const char *brif, const char *phyif)
+{
+ struct CritReqList *next;
+
+ if (!critReqLists)
+ return 0;
+
+ for (next = critReqLists; next != NULL; next = next->next) {
+#if 0 // when parse interface group criteria, ignore the request which is from same bridge port and physical port
+ if (!strcasecmp(next->mac, mac)) {
+ return 1;
+ }
+#else
+ if (!strcmp(next->brIf, brif) && !strcmp(next->phyIf, phyif)) {
+ return 1;
+ }
+#endif
+ }
+
+ return 0;
+}
+#endif
+
static zcfgRet_t dnsmasq_msg_send(int msg_type, int payloadLen,
const char *payload, char **reply)
{
@@ -75,6 +181,9 @@
int i;
my_syslog(MS_DHCP | LOG_INFO, "%s ", __func__);
+ if (lease <= 0)
+ return;
+
bufPtr = buf;
bufPtr += sprintf(bufPtr, "{");
@@ -95,11 +204,9 @@
bufPtr += sprintf(bufPtr, "\"expire\":\"%lu\",", lease->expires);
- tmpPtr = tmp;
- for (i = 0; i < lease->hwaddr_len - 1; i++)
- tmpPtr += sprintf(tmpPtr, "%.2x:", lease->hwaddr[i]);
- tmpPtr += sprintf(tmpPtr, "%.2x", lease->hwaddr[i]);
- bufPtr += sprintf(bufPtr, "\"mac\":\"%s\",", tmp);
+ bufPtr +=
+ sprintf(bufPtr, "\"mac\":\"%s\",",
+ print_mac(tmp, lease->hwaddr, lease->hwaddr_len));
#ifdef HAVE_DHCP6
if ((lease->flags & (LEASE_TA | LEASE_NA))) {
@@ -143,9 +250,110 @@
bufPtr = '\0';
- my_syslog(MS_DHCP | LOG_INFO, "%s send to esmd buf = %s", __func__, buf);
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s send to esmd buf = %s", __func__, buf);
+ ret = dnsmasq_msg_send(ZCFG_MSG_DHCPD_OPTION, strlen(buf), buf, NULL);
+ if (ret != ZCFG_SUCCESS || ret != ZCFG_SUCCESS_AND_NO_REPLY)
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s esmd ret=%d", __func__, ret);
+}
+
+void sendCritMessageToESMD(struct CritDhcpInfo *crit)
+{
+ zcfgRet_t ret = 0;
+ char buf[2048] = { 0 }, *bufPtr, tmp[256] = {
+ 0}, *tmpPtr;
+ char macaddr[20] = { 0 }, phy_ifname[20] = {
+ 0};
+ int i;
+
+ if (crit <= 0)
+ return;
+
+ print_mac(macaddr, crit->emac, crit->emac_len);
+ getPhyIfname(crit->ifname, macaddr, phy_ifname);
+
+ if (chkCritReqExist(macaddr, crit->ifname, phy_ifname)) {
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s ignore the host (%s) request",
+ __func__, macaddr);
+ return;
+ }
+
+ bufPtr = buf;
+ bufPtr += sprintf(bufPtr, "{");
+ bufPtr += sprintf(bufPtr, "\"ac\":\"%s\",", "crit");
+ bufPtr += sprintf(bufPtr, "\"mac\":\"%s\",", macaddr);
+
+ bufPtr +=
+ sprintf(bufPtr, "\"host\":\"%s\",",
+ (crit->hostname) ? crit->hostname : "*");
+ //option 60
+ if (crit->vendor_len) {
+ strncpy(tmp, crit->vendor, crit->vendor_len);
+ tmp[crit->vendor_len] = '\0';
+ } else
+ sprintf(tmp, "*");
+ bufPtr += sprintf(bufPtr, "\"vendor\":\"%s\",", tmp);
+ //option 125
+ strncpy(bufPtr, "\"moui\":\"", 8);
+ bufPtr += 8;
+ if (crit->oui) {
+ strncpy(bufPtr, crit->oui, crit->oui_len);
+ bufPtr += crit->oui_len;
+ } else {
+ *bufPtr = '*';
+ bufPtr++;
+ }
+ strncpy(bufPtr, "\",", 2);
+ bufPtr += 2;
+
+ strncpy(bufPtr, "\"serial\":\"", 10);
+ bufPtr += 10;
+ if (crit->serial) {
+ strncpy(bufPtr, crit->serial, crit->serial_len);
+ bufPtr += crit->serial_len;
+ } else {
+ *bufPtr = '*';
+ bufPtr++;
+ }
+ strncpy(bufPtr, "\",", 2);
+ bufPtr += 2;
+
+ strncpy(bufPtr, "\"pclass\":\"", 10);
+ bufPtr += 10;
+ if (crit->pclass) {
+ strncpy(bufPtr, crit->pclass, crit->pclass_len);
+ bufPtr += crit->pclass_len;
+ } else {
+ *bufPtr = '*';
+ bufPtr++;
+ }
+ strncpy(bufPtr, "\",", 2);
+ bufPtr += 2;
+
+ //option 61
+ if (crit->clid && crit->clid_len != 0) {
+ tmpPtr = tmp;
+ for (i = 0; i < crit->clid_len - 1; i++)
+ tmpPtr += sprintf(tmpPtr, "%.2x:", crit->clid[i]);
+ tmpPtr += sprintf(tmpPtr, "%.2x", crit->clid[i]);
+ } else
+ sprintf(tmp, "*");
+ bufPtr += sprintf(bufPtr, "\"cid\":\"%s\",", tmp);
+ bufPtr += sprintf(bufPtr, "\"tag\":\"%s\",", crit->tag);
+ bufPtr +=
+ sprintf(bufPtr, "\"phyif\":\"%s\",", (phy_ifname) ? phy_ifname : "*");
+ bufPtr +=
+ sprintf(bufPtr, "\"ifname\":\"%s\"", (crit->ifname) ? crit->ifname : "*");
+ bufPtr += sprintf(bufPtr, "}");
+
+ bufPtr = '\0';
+
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s send to esmd buf = %s", __func__, buf);
ret = dnsmasq_msg_send(ZCFG_MSG_DHCPD_OPTION, strlen(buf), buf, NULL);
- my_syslog(MS_DHCP | LOG_INFO, "%s esmd reply=%d", __func__, ret);
+ // when send criteria request to esmd success, add criteria request to criteria block list
+ if (ret == ZCFG_SUCCESS || ret == ZCFG_SUCCESS_AND_NO_REPLY)
+ addCritReqtoList(macaddr, crit->ifname, phy_ifname);
+ if (ret != ZCFG_SUCCESS || ret != ZCFG_SUCCESS_AND_NO_REPLY)
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s esmd reply=%d", __func__, ret);
}
#endif
Index: dnsmasq-2.78/src/lease.c
===================================================================
--- dnsmasq-2.78.orig/src/lease.c 2018-11-01 10:07:19.355354084 +0800
+++ dnsmasq-2.78/src/lease.c 2018-11-01 11:05:33.297831100 +0800
@@ -1149,7 +1149,9 @@
int do_script_run(time_t now)
{
struct dhcp_lease *lease;
-
+#ifdef ZYXEL_PATCH
+ pruneCritReqList();
+#endif
(void) now;
#ifdef HAVE_DBUS
@@ -0,0 +1,210 @@
Index: dnsmasq-2.78/src/dnsmasq.h
===================================================================
--- dnsmasq-2.78.orig/src/dnsmasq.h 2018-11-02 13:29:27.803054642 +0800
+++ dnsmasq-2.78/src/dnsmasq.h 2018-11-02 13:33:49.881217800 +0800
@@ -708,6 +708,15 @@
struct dhcp_lease *next;
};
+#if 1 //oneconnect dhcp.leases2 file
+//[WWH] add
+struct dhcp_lease_tmp {
+ char hwaddr[64];
+ char hostname[512];
+ struct dhcp_lease_tmp *next;
+};
+#endif
+
struct dhcp_netid {
char *net;
struct dhcp_netid *next;
Index: dnsmasq-2.78/src/lease.c
===================================================================
--- dnsmasq-2.78.orig/src/lease.c 2018-11-02 13:29:27.807054642 +0800
+++ dnsmasq-2.78/src/lease.c 2018-11-02 13:47:48.143135600 +0800
@@ -21,6 +21,98 @@
static struct dhcp_lease *leases = NULL, *old_leases = NULL;
static int dns_dirty, file_dirty, leases_left;
+#if 1 //oneconnect dhcp.leases2 file
+//WWH add
+static struct dhcp_lease_tmp *kill_leases = NULL;
+
+/** WWH add *********************************************************/
+static void save_killname(char *hwaddr, char *hostname)
+{
+ if (hwaddr == NULL || hostname == NULL) {
+ return;
+ }
+
+ struct dhcp_lease_tmp *lease;
+ lease = calloc(1, sizeof(struct dhcp_lease_tmp));
+ lease->next = NULL;
+
+ strcpy(lease->hwaddr, hwaddr);
+ strcpy(lease->hostname, hostname);
+
+ if (kill_leases == NULL) {
+ kill_leases = lease;
+ } else {
+ struct dhcp_lease_tmp *lease_tmp;
+ lease_tmp = kill_leases;
+ while (lease_tmp->next) {
+ lease_tmp = lease_tmp->next;
+ }
+ lease_tmp->next = lease;
+ }
+}
+
+void get_kill_leases_hostname(char *hwaddr, char *hostname)
+{
+ if (hwaddr == NULL || kill_leases == NULL) {
+ return;
+ }
+
+ struct dhcp_lease_tmp *lease;
+ lease = kill_leases;
+ while (lease) {
+ if (strncmp(hwaddr, lease->hwaddr, 17) == 0) //find same mac
+ {
+ strcpy(hostname, lease->hostname);
+ return;
+ }
+ lease = lease->next;
+ }
+ strncpy(hostname, "*", 1);
+}
+
+void Removeoutputfile(void)
+{
+ char buf[1024];
+ FILE *fp = fopen("/tmp/dhcp.leases2", "r");
+ if (fp) {
+ while (fgets(buf, sizeof(buf), fp)) {
+ char hwaddr[64] = "";
+ char ip[64] = "";
+ char hostname[512] = "";
+ sscanf(buf, "%s %s %s", hwaddr, ip, hostname);
+ save_killname(hwaddr, hostname);
+ }
+ fclose(fp);
+ }
+
+ remove("/tmp/dhcp.leases2");
+ system("touch /tmp/dhcp.leases2");
+}
+
+void outputData(char *outputdata)
+{
+ char output[1024];
+ sprintf(output, "echo \"%s\" >> %s", outputdata, "/tmp/dhcp.leases2");
+ system(output);
+}
+
+
+void free_kill_leases()
+{
+ struct dhcp_lease_tmp *lease_f;
+ struct dhcp_lease_tmp *lease_tmp;
+ lease_f = kill_leases;
+ while (lease_f) {
+ lease_tmp = lease_f->next;
+ free(lease_f);
+ lease_f = lease_tmp;
+ }
+ kill_leases = NULL;
+}
+
+/** WWH *************************************************************/
+#endif
+
static int read_leases(time_t now, FILE * leasestream)
{
unsigned long ei;
@@ -230,6 +322,12 @@
file_dirty = 0;
lease_prune(NULL, now);
dns_dirty = 1;
+
+#if 1 //oneconnect dhcp.leases2 file
+ //[WWH] add
+ system("touch /tmp/dhcp.leases2");
+#endif
+
}
void lease_update_from_configs(void)
@@ -277,6 +375,11 @@
if (errno != 0 || ftruncate(fileno(daemon->lease_stream), 0) != 0)
err = errno;
+#if 1 //oneconnect dhcp.leases2 file
+ //WWH add
+ Removeoutputfile();
+#endif
+
for (lease = leases; lease; lease = lease->next) {
#ifdef HAVE_DHCP6
@@ -303,6 +406,33 @@
ourprintf(&err, " %s ", daemon->addrbuff);
ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
+#if 1 //oneconnect dhcp.leases2 file
+ //[WWH] output file
+ int macCount = 0;
+ char outputdata[1024] = "";
+ char output_hwaddr[64] = "";
+ char output_hostname[512] = "";
+ for (macCount = 0; macCount < lease->hwaddr_len; macCount++) {
+ sprintf(output_hwaddr + (macCount * 3), "%.2x",
+ lease->hwaddr[macCount]);
+ if (macCount != lease->hwaddr_len - 1) {
+ sprintf(output_hwaddr + ((macCount * 3) + 2), ":");
+ }
+ }
+
+ if (!lease->hostname) //lease->hostname is NULL, find kill_leases
+ {
+ //get hostname in kill_leases
+ get_kill_leases_hostname(output_hwaddr, output_hostname);
+ } else {
+ strcpy(output_hostname, lease->hostname);
+ }
+ sprintf(outputdata, "%s %s %s\0", output_hwaddr, daemon->addrbuff,
+ output_hostname);
+ //output file
+ outputData(outputdata);
+#endif
+
if (lease->clid && lease->clid_len != 0) {
for (i = 0; i < lease->clid_len - 1; i++)
ourprintf(&err, "%.2x:", lease->clid[i]);
@@ -412,6 +542,11 @@
}
send_alarm(next_event, now);
+
+#if 1 //oneconnect dhcp.leases2 file
+ //clear kill_leases
+ free_kill_leases();
+#endif
}
@@ -934,6 +1069,15 @@
static void kill_name(struct dhcp_lease *lease)
{
+#if 1 //oneconnect dhcp.leases2 file
+ //save kill name
+ char hwaddr_tmp[64] = "";
+ sprintf(hwaddr_tmp, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", lease->hwaddr[0],
+ lease->hwaddr[1], lease->hwaddr[2], lease->hwaddr[3],
+ lease->hwaddr[4], lease->hwaddr[5]);
+ save_killname(hwaddr_tmp, lease->hostname);
+#endif
+
/* run script to say we lost our old name */
/* this shouldn't happen unless updates are very quick and the
@@ -0,0 +1,327 @@
Index: dnsmasq-2.78/src/dnsmasq.h
===================================================================
--- dnsmasq-2.78.orig/src/dnsmasq.h 2018-11-02 13:56:09.219040825 +0800
+++ dnsmasq-2.78/src/dnsmasq.h 2018-11-02 14:00:24.424869300 +0800
@@ -803,6 +803,10 @@
#define DHOPT_RFC3925 2048
#define DHOPT_TAGOK 4096
#define DHOPT_ADDR6 8192
+#ifdef ZYXEL_PATCH //for option 125
+#define DHOPT_RFC3925_OPT 16384
+#endif
+
struct dhcp_boot {
char *file, *sname, *tftp_sname;
@@ -824,6 +828,9 @@
#define MATCH_CIRCUIT 3
#define MATCH_REMOTE 4
#define MATCH_SUBSCRIBER 5
+#ifdef ZYXEL_PATCH
+#define MATCH_VENDOR_EXACT 6
+#endif
/* vendorclass, userclass, remote-id or circuit-id */
struct dhcp_vendor {
Index: dnsmasq-2.78/src/option.c
===================================================================
--- dnsmasq-2.78.orig/src/option.c 2018-11-02 13:56:09.183040825 +0800
+++ dnsmasq-2.78/src/option.c 2018-11-02 14:23:02.286525400 +0800
@@ -164,6 +164,7 @@
#ifdef ZYXEL_PATCH
#define LOPT_TAG_IFNAME 329
+#define LOPT_VENDOREXACT 330
#endif
#ifdef HAVE_GETOPT_LONG
@@ -225,6 +226,9 @@
{"read-ethers", 0, 0, 'Z'},
{"alias", 1, 0, 'V'},
{"dhcp-vendorclass", 1, 0, 'U'},
+#ifdef ZYXEL_PATCH
+ {"dhcp-vendorclass-exact", 1, 0, LOPT_VENDOREXACT},
+#endif
{"dhcp-userclass", 1, 0, 'j'},
{"dhcp-ignore", 1, 0, 'J'},
{"edns-packet-max", 1, 0, 'P'},
@@ -503,7 +507,13 @@
gettext_noop("Change to this user after startup. (defaults to %s)."),
CHUSER}, {
'U', ARG_DUP, "set:<tag>,<class>",
- gettext_noop("Map DHCP vendor class to tag."), NULL}, {
+ gettext_noop("Map DHCP vendor class to tag."), NULL},
+#ifdef ZYXEL_PATCH
+ {
+ LOPT_VENDOREXACT, ARG_DUP, "set:<tag>,<class>",
+ gettext_noop("Map DHCP vendor class to tag. (Exact match)"), NULL},
+#endif
+ {
'v', 0, NULL,
gettext_noop("Display dnsmasq version and copyright information."),
NULL}, {
@@ -1333,7 +1343,18 @@
option_ok = 1;
break;
}
- } else {
+ }
+#ifdef ZYXEL_PATCH //for option 125
+ else if (strstr(arg, "vi-encap-opt:") == arg) {
+ new->u.encap = atoi(arg + 13);
+ new->flags |= DHOPT_RFC3925_OPT;
+ if (flags == DHOPT_MATCH) {
+ option_ok = 1;
+ break;
+ }
+ }
+#endif
+ else {
new->netid = opt_malloc(sizeof(struct dhcp_netid));
/* allow optional "net:" or "tag:" for consistency */
if (is_tag_prefix(arg))
@@ -1357,13 +1378,86 @@
} else
#endif
if (opt_len == 0 &&
- !(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925)))
+#ifdef ZYXEL_PATCH //for option 125
+ !(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925 | DHOPT_RFC3925_OPT))
+#else
+ !(new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE | DHOPT_RFC3925))
+#endif
+ )
opt_len = lookup_dhcp_len(AF_INET, new->opt);
/* option may be missing with rfc3925 match */
if (!option_ok)
ret_err(_("bad dhcp-option"));
+#ifdef ZYXEL_PATCH //for option 125
+ // config format {id}={str}%%{id}=hex#{hex_str}%%....
+ // convert to format {id}{len}{val}{id}{len}{val}....
+ if (comma && (new->flags & DHOPT_RFC3925_OPT)) {
+ char *tmp_val, *match_str, *next_str, *tmpPtr, *tmpPtr2, tmpBuf[10];
+ char *new_val;
+ int tmp_len, i, match_len, j, k, match_id, v;
+
+ if ((tmp_len = strlen(comma)) <= 0 || !(new_val = calloc(1, tmp_len + 3))
+ || !(tmp_val = (char *) opt_string_alloc(comma))) {
+ ret_err(_("bad dhcp-option-125 1"));
+ }
+
+ i = j = 0;
+ for (match_str = tmp_val; match_str;) {
+ next_str = strstr(match_str, "%%");
+ if (next_str) {
+ match_len = next_str - match_str;
+ next_str += 2;
+ } else {
+ match_len = strlen(match_str);
+ }
+ if (match_len) {
+ //parse suboption, format: {id}={value}
+ tmpPtr = strchr(match_str, '=');
+ if (tmpPtr && (i = tmpPtr - match_str) <= 3) {
+ strncpy(tmpBuf, match_str, i);
+ tmpBuf[i] = '\0';
+ match_id = atoi(tmpBuf);
+
+ if (match_id > 0 && match_id <= 255 && (match_len -= (i + 1)) > 0
+ && match_len <= 255) {
+ new_val[j++] = (char) match_id;
+ match_str += (i + 1);
+ if (!strncmp(match_str, "hex#", 4)) {
+ match_str += 4;
+ match_len -= 4;
+ tmpBuf[2] = 0;
+ for (k = j + 1, tmpPtr = match_str;
+ (tmpPtr + 2) <= (match_str + match_len); tmpPtr += 2) {
+ tmpBuf[0] = *tmpPtr;
+ tmpBuf[1] = *(tmpPtr + 1);
+ v = (int) strtol(tmpBuf, &tmpPtr2, 16);
+ if (*tmpPtr2 != '\0')
+ ret_err(_("bad dhcp-option-125 2"));
+ new_val[k++] = (char) (v & 0xFF);
+ }
+ new_val[j] = (char) ((k - j - 1) & 0xFF); //hex length
+ j = k;
+ } else {
+ new_val[j++] = (char) (match_len & 0xFF); //string length
+ memcpy((new_val + j), match_str, match_len);
+ j += match_len;
+ }
+ } else
+ ret_err(_("bad dhcp-option-125 3"));
+ }
+ }
+ match_str = next_str;
+ }
+ if (j <= 0)
+ ret_err(_("bad dhcp-option-125 4"));
+
+ new->len = j;
+ new->val = (unsigned char *) new_val;
+ free(tmp_val);
+ } else
+#endif
if (comma) {
/* characterise the value */
char c;
@@ -1684,7 +1778,11 @@
if (!is6 &&
((new->len > 255) ||
(new->len > 253 && (new->flags & (DHOPT_VENDOR | DHOPT_ENCAPSULATE))) ||
- (new->len > 250 && (new->flags & DHOPT_RFC3925))))
+ (new->len > 250 && (new->flags & DHOPT_RFC3925))
+#ifdef ZYXEL_PATCH //for option 125
+ || (new->len > 250 && (new->flags & DHOPT_RFC3925_OPT))
+#endif
+ ))
ret_err(_("dhcp-option too long"));
if (flags == DHOPT_MATCH) {
@@ -3612,8 +3710,9 @@
break;
}
#endif
-
-
+#ifdef ZYXEL_PATCH
+ case LOPT_VENDOREXACT: /* --dhcp-vendorclass-exact*/
+#endif
case 'U': /* --dhcp-vendorclass */
case 'j': /* --dhcp-userclass */
case LOPT_CIRCUIT: /* --dhcp-circuitid */
@@ -3633,7 +3732,11 @@
arg = comma;
if ((comma = split(arg))) {
+#ifdef ZYXEL_PATCH
+ if ((option != LOPT_VENDOREXACT && option != 'U') || strstr(arg, "enterprise:") != arg)
+#else
if (option != 'U' || strstr(arg, "enterprise:") != arg)
+#endif
ret_err(gen_err);
else
new->enterprise = atoi(arg + 11);
@@ -3646,7 +3749,12 @@
else if (*p != ':')
break;
unhide_metas(comma);
- if (option == 'U' || option == 'j' || *p || !dig) {
+#ifdef ZYXEL_PATCH
+ if ((option == LOPT_VENDOREXACT && option == 'U') || option == 'j' || *p || !dig)
+#else
+ if (option == 'U' || option == 'j' || *p || !dig)
+#endif
+ {
new->len = strlen(comma);
new->data = opt_malloc(new->len);
memcpy(new->data, comma, new->len);
@@ -3665,6 +3773,11 @@
case 'U':
new->match_type = MATCH_VENDOR;
break;
+#ifdef ZYXEL_PATCH
+ case LOPT_VENDOREXACT:
+ new->match_type = MATCH_VENDOR_EXACT;
+ break;
+#endif
case LOPT_CIRCUIT:
new->match_type = MATCH_CIRCUIT;
break;
Index: dnsmasq-2.78/src/rfc2131.c
===================================================================
--- dnsmasq-2.78.orig/src/rfc2131.c 2018-11-02 13:56:09.203040825 +0800
+++ dnsmasq-2.78/src/rfc2131.c 2018-11-02 14:44:40.031529300 +0800
@@ -476,7 +476,58 @@
if (match)
break;
}
- } else {
+ }
+#ifdef ZYXEL_PATCH //for option 125
+ else if (o->flags & DHOPT_RFC3925_OPT) {
+ char *match_str, *next_str, *tmpPtr, *matchPtr, tmpBuf[255], hexBuf[3];
+ unsigned char *x, *y, *opt_value;
+ int match_len, match_id, i, j, match2, v;
+ unsigned char isStr = 0;
+
+ if (!(opt = option_find(mess, sz, OPTION_VENDOR_IDENT_OPT, 5)))
+ continue;
+
+ for (offset = 0; offset < (option_len(opt) - 5u); offset += len + 5) {
+ len = option_uint(opt, offset + 4, 1);
+ if ((offset + len + 5 <= (option_len(opt))) &&
+ option_uint(opt, offset, 4) == (unsigned int) o->u.encap) {
+ len = option_uint(opt, 4, 1);
+ x = option_ptr(opt, offset + 5);
+ y = option_ptr(opt, offset + len + 5);
+
+ match = 1;
+ for (match_str = o->val; match_str < (o->val + o->len);) {
+ match_id = (int) match_str[0];
+ match_len = (int) match_str[1];
+ next_str = match_str + match_len + 2;
+ if (match_len && (opt_value = option_find1(x, y, match_id, 1))) {
+ match_str += 2;
+ if (option_len(opt_value) < match_len) {
+ match = 0;
+ break;
+ } else {
+ //wildcard match
+ match2 = 0;
+ for (i = 0; (i + match_len) <= option_len(opt_value); i++) {
+ if (!memcmp(option_ptr(opt_value, i), match_str, match_len)) {
+ match2 = 1;
+ break;
+ }
+ }
+ if (match2 == 0) {
+ match = 0;
+ break;
+ }
+ }
+ }
+ match_str = next_str;
+ }
+ break;
+ }
+ }
+ }
+#endif
+ else {
if (!(opt = option_find(mess, sz, o->opt, 1)))
continue;
@@ -513,8 +564,11 @@
for (vendor = daemon->dhcp_vendors; vendor; vendor = vendor->next) {
int mopt;
-
+#ifdef ZYXEL_PATCH
+ if (vendor->match_type == MATCH_VENDOR || vendor->match_type == MATCH_VENDOR_EXACT)
+#else
if (vendor->match_type == MATCH_VENDOR)
+#endif
mopt = OPTION_VENDOR_ID;
else if (vendor->match_type == MATCH_USER)
mopt = OPTION_USER_CLASS;
@@ -523,6 +577,16 @@
if ((opt = option_find(mess, sz, mopt, 1))) {
int i;
+#ifdef ZYXEL_PATCH
+ if (vendor->match_type == MATCH_VENDOR_EXACT) {
+ if ((vendor->len == option_len(opt)
+ && memcmp(vendor->data, option_ptr(opt, 0), vendor->len) == 0)) {
+ vendor->netid.next = netid;
+ netid = &vendor->netid;
+ break;
+ }
+ } else
+#endif
for (i = 0; i <= (option_len(opt) - vendor->len); i++)
if (memcmp(vendor->data, option_ptr(opt, i), vendor->len) == 0) {
vendor->netid.next = netid;
@@ -0,0 +1,232 @@
Index: dnsmasq-2.78/src/dnsmasq.c
===================================================================
--- dnsmasq-2.78.orig/src/dnsmasq.c 2018-11-05 13:26:09.032072779 +0800
+++ dnsmasq-2.78/src/dnsmasq.c 2018-11-05 14:30:12.518047600 +0800
@@ -953,8 +953,12 @@
more calls to my_syslog() can occur */
set_log_writer();
- if (do_poll(timeout) < 0)
+ if (do_poll(timeout) < 0){
+#ifdef ZYXEL_PATCH
+ checkListenerSock();
+#endif
continue;
+ }
now = dnsmasq_time();
Index: dnsmasq-2.78/src/dnsmasq.h
===================================================================
--- dnsmasq-2.78.orig/src/dnsmasq.h 2018-11-05 13:26:09.340072792 +0800
+++ dnsmasq-2.78/src/dnsmasq.h 2018-11-05 14:28:26.433507100 +0800
@@ -1635,6 +1635,11 @@
void sendLeaseMessageToESMD(int, struct dhcp_lease *, const char*);
void sendCritMessageToESMD(struct CritDhcpInfo *crit);
void pruneCritReqList(void);
+int checkListenerSock();
+#if 0
+int chkClose(int fd, const char *func, const int line);
+#define close(fd) chkClose(fd, __FUNCTION__, __LINE__)
+#endif
#endif
/* loop.c */
Index: dnsmasq-2.78/src/extern.c
===================================================================
--- dnsmasq-2.78.orig/src/extern.c 2018-11-05 13:26:09.264072789 +0800
+++ dnsmasq-2.78/src/extern.c 2018-11-05 14:43:00.509198900 +0800
@@ -1,4 +1,22 @@
#ifdef ZYXEL_PATCH
+#if 0
+int __test_sock_fd = -1;
+
+int chkClose(int fd, const char *func, const int line)
+{
+ if (fd == __test_sock_fd) {
+ time_t curtime;
+ FILE *fp = fopen("/tmp/dnsmasq_error", "a+");
+ if (fp) {
+ time(&curtime);
+ fprintf(fp, "%s:%d: close general socket(%d) >>> %s", func, line, fd,
+ ctime(&curtime));
+ fclose(fp);
+ }
+ }
+ return close(fd);
+}
+#endif
#include "dnsmasq.h"
@@ -7,7 +25,121 @@
#include "zcfg_debug.h"
#include "zcfg_msg.h"
+int checkSocketAlive(int sock)
+{
+ int error_code = -1, retval;
+ int error_code_size = sizeof(error_code);
+ //WPRINT(W_DEBUG,"Enter.\n");
+
+ retval =
+ getsockopt(sock, SOL_SOCKET, SO_ERROR, &error_code, &error_code_size);
+
+ //WPRINT(W_DEBUG,"error_code = %d.\n", error_code);
+
+ if (retval != 0 || error_code != 0) {
+ return -1;
+ } else
+ return 0;
+}
+
+extern struct listener *create_listeners(union mysockaddr *addr,
+ int do_tftp, int dienow);
+int checkListenerSock()
+{
+ int err;
+ struct listener *listener, *l = NULL;
+ union mysockaddr addr;
+ FILE *fp = fopen("/dev/console", "w");
+
+ for (listener = daemon->listeners; listener; listener = listener->next) {
+ err = 0;
+ if (listener->fd != -1) {
+ if (checkSocketAlive(listener->fd) < 0) {
+ if (fp)
+ fprintf(fp, "%s: listener->fd(%d) is fail.....\n", __FUNCTION__,
+ listener->fd);
+ err = 1;
+ listener->fd = -1;
+ }
+ }
+
+ if (err == 0 && listener->tcpfd != -1) {
+ if (checkSocketAlive(listener->tcpfd) < 0) {
+ if (fp)
+ fprintf(fp, "%s: listener->tcpfd (%d) is fail.....\n",
+ __FUNCTION__, listener->tcpfd);
+ err = 1;
+ listener->tcpfd = -1;
+ }
+ }
+
+ if (err) {
+#if 0
+ __test_sock_fd = -1;
+#endif
+ if (listener->fd != -1) {
+ close(listener->fd);
+ }
+ if (listener->tcpfd != -1) {
+ close(listener->tcpfd);
+ }
+ if (listener->tftpfd != -1) {
+ close(listener->tftpfd);
+ }
+
+ listener->fd = -1;
+ listener->tcpfd = -1;
+ listener->tftpfd = -1;
+
+ if (listener->iface) {
+ memcpy(&addr, &(listener->iface->addr), sizeof(addr));
+ } else {
+ memset(&addr, 0, sizeof(addr));
+ if (listener->family == AF_INET) {
+#ifdef HAVE_SOCKADDR_SA_LEN
+ addr.in.sin_len = sizeof(addr.in);
+#endif
+ addr.in.sin_family = AF_INET;
+ addr.in.sin_addr.s_addr = INADDR_ANY;
+ addr.in.sin_port = htons(daemon->port);
+ }
+#ifdef HAVE_IPV6
+ else {
+#ifdef HAVE_SOCKADDR_SA_LEN
+ addr.in6.sin6_len = sizeof(addr.in6);
+#endif
+ addr.in6.sin6_family = AF_INET6;
+ addr.in6.sin6_addr = in6addr_any;
+ addr.in6.sin6_port = htons(daemon->port);
+ }
+#else
+ else
+ continue;
+#endif
+ }
+
+ l = create_listeners(&addr, ! !option_bool(OPT_TFTP), 1);
+ if (l) {
+ listener->fd = l->fd;
+ listener->tcpfd = l->tcpfd;
+ listener->tftpfd = l->tftpfd;
+ free(l);
+ l = NULL;
+
+ if (fp)
+ fprintf(fp, "%s: reopen socket(%d).....\n", __FUNCTION__,
+ listener->fd);
+#if 0
+ __test_sock_fd = listener->fd;
+#endif
+ }
+ }
+ }
+ if (fp)
+ fclose(fp);
+ return 0;
+}
void dnsmasq_eid_register(void)
{
Index: dnsmasq-2.78/src/network.c
===================================================================
--- dnsmasq-2.78.orig/src/network.c 2018-11-05 13:26:09.132072783 +0800
+++ dnsmasq-2.78/src/network.c 2018-11-05 14:54:11.386369600 +0800
@@ -825,8 +825,11 @@
return if_index;
}
-static struct listener *create_listeners(union mysockaddr *addr, int do_tftp,
- int dienow)
+#ifdef ZYXEL_PATCH
+struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow)
+#else
+static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, int dienow)
+#endif
{
struct listener *l = NULL;
int fd = -1, tcpfd = -1, tftpfd = -1;
@@ -864,12 +867,17 @@
l->fd = fd;
l->tcpfd = tcpfd;
l->tftpfd = tftpfd;
+#ifdef ZYXEL_PATCH
l->iface = NULL;
+#endif
}
return l;
}
+#if 0 //def ZYXEL_PATCH
+extern int __test_sock_fd;
+#endif
void create_wildcard_listeners(void)
{
union mysockaddr addr;
@@ -884,7 +892,11 @@
addr.in.sin_port = htons(daemon->port);
l = create_listeners(&addr, ! !option_bool(OPT_TFTP), 1);
-
+#if 0 //def ZYXEL_PATCH
+ if (l) {
+ __test_sock_fd = l->fd;
+ }
+#endif
#ifdef HAVE_IPV6
memset(&addr, 0, sizeof(addr));
#ifdef HAVE_SOCKADDR_SA_LEN
@@ -0,0 +1,33 @@
Index: dnsmasq-2.78/src/forward.c
===================================================================
--- dnsmasq-2.78.orig/src/forward.c 2018-11-05 15:14:10.392354110 +0800
+++ dnsmasq-2.78/src/forward.c 2018-11-05 15:17:49.865397200 +0800
@@ -222,6 +222,9 @@
struct all_addr *addrp = NULL;
unsigned int flags = 0;
struct server *start = NULL;
+#ifdef ZYXEL_PATCH
+ char if_name[IFNAMSIZ] = { 0 };
+#endif
#ifdef HAVE_DNSSEC
void *hash = hash_questions(header, plen, daemon->namebuff);
int do_dnssec = 0;
@@ -504,6 +507,18 @@
start->queries++;
forwarded = 1;
forward->sentto = start;
+
+#ifdef ZYXEL_PATCH
+ /*if the query-interface is "lo", forward to all servers */
+ /*Because "lo" interface always send-query with different port and header->id,
+ *the query is always forwarded to the first dns server.
+ *Hence, we force the query to all dns servers as the interface is "lo".*/
+ if (indextoname(udpfd, dst_iface, if_name)) {
+ if (!strncmp(if_name, "lo", 2))
+ forward->forwardall = 1;
+ }
+#endif
+
if (!forward->forwardall)
break;
forward->forwardall++;
@@ -0,0 +1,70 @@
Index: dnsmasq-2.78/src/rfc2131.c
===================================================================
--- dnsmasq-2.78.orig/src/rfc2131.c 2018-11-05 18:20:29.837161824 +0800
+++ dnsmasq-2.78/src/rfc2131.c 2018-11-05 18:24:50.830902900 +0800
@@ -94,33 +94,39 @@
//my_syslog(MS_DHCP | LOG_DEBUG, _("tmpNetid->net=%s, %s"), tmpNetid->net, iface_name);
if (!strncmp(tmpNetid->net, "Crit_br", 7)) {
brNamePtr = strstr(tmpNetid->net, "br");
- if(iface_name != NULL && strcmp(brNamePtr, iface_name)){
- memset(&crit, 0, sizeof(crit));
- crit.ifname = iface_name;
- crit.emac = emac;
- crit.emac_len = emac_len;
- crit.hostname = client_hostname;
- strcpy(crit.tag, tmpNetid->net);
- if(oui){
- crit.oui = option_ptr(oui, 0);
- crit.oui_len = option_len(oui);
+ if (iface_name != NULL) {
+ if (strcmp(brNamePtr, iface_name)) {
+ memset(&crit, 0, sizeof(crit));
+ crit.ifname = iface_name;
+ crit.emac = emac;
+ crit.emac_len = emac_len;
+ crit.hostname = client_hostname;
+ strcpy(crit.tag, tmpNetid->net);
+ if (oui) {
+ crit.oui = option_ptr(oui, 0);
+ crit.oui_len = option_len(oui);
+ }
+ if (serial) {
+ crit.serial = option_ptr(serial, 0);
+ crit.serial_len = option_len(serial);
+ }
+ if (class) {
+ crit.pclass = option_ptr(class, 0);
+ crit.pclass_len = option_len(class);
+ }
+ crit.vendor = vendor_class_ptr;
+ crit.vendor_len = vendor_class_len;
+ if (clid) {
+ crit.clid = clid;
+ crit.clid_len = clid_len;
+ }
+ sendCritMessageToESMD(&crit);
+ return 1;
+ } else {
+ my_syslog(MS_DHCP | LOG_DEBUG,
+ _("Port no change, no need re-bind!!"));
+ return 0;
}
- if(serial){
- crit.serial = option_ptr(serial, 0);
- crit.serial_len = option_len(serial);
- }
- if(class){
- crit.pclass = option_ptr(class, 0);
- crit.pclass_len = option_len(class);
- }
- crit.vendor = vendor_class_ptr;
- crit.vendor_len = vendor_class_len;
- if(clid){
- crit.clid = clid;
- crit.clid_len = clid_len;
- }
- sendCritMessageToESMD(&crit);
- return 1;
}
}
}
@@ -0,0 +1,75 @@
Index: dnsmasq-2.78/src/extern.c
===================================================================
--- dnsmasq-2.78.orig/src/extern.c 2018-11-05 18:43:25.732825516 +0800
+++ dnsmasq-2.78/src/extern.c 2018-11-05 18:47:50.977961300 +0800
@@ -351,22 +351,30 @@
sprintf(bufPtr, "\"ip\":\"%s\",",
inet_ntop(AF_INET, &lease->addr, tmp, ADDRSTRLEN));
- bufPtr +=
- sprintf(bufPtr, "\"host\":\"%s\",",
- (lease->hostname) ? lease->hostname : "*");
+ if (lease->hostname != NULL)
+ bufPtr += sprintf(bufPtr, "\"host\":\"%s\",", lease->hostname);
+ else
+ bufPtr += sprintf(bufPtr, "\"host\":\"*\",");
//option 60
- bufPtr +=
- sprintf(bufPtr, "\"vendor\":\"%s\",",
- (lease->vendorid) ? lease->vendorid : "*");
+ if (lease->vendorid != NULL)
+ bufPtr += sprintf(bufPtr, "\"vendor\":\"%s\",", lease->vendorid);
+ else
+ bufPtr += sprintf(bufPtr, "\"vendor\":\"*\",");
//option 125
- bufPtr +=
- sprintf(bufPtr, "\"moui\":\"%s\",", (lease->oui) ? (char *)lease->oui : "*");
- bufPtr +=
- sprintf(bufPtr, "\"serial\":\"%s\",",
- (lease->serial) ? (char *)lease->serial : "*");
- bufPtr +=
- sprintf(bufPtr, "\"pclass\":\"%s\",",
- (lease->pclass) ? (char *)lease->pclass : "*");
+ if (lease->oui != NULL)
+ bufPtr += sprintf(bufPtr, "\"moui\":\"%s\",", lease->oui);
+ else
+ bufPtr += sprintf(bufPtr, "\"moui\":\"*\",");
+
+ if (lease->serial != NULL)
+ bufPtr += sprintf(bufPtr, "\"serial\":\"%s\",", lease->serial);
+ else
+ bufPtr += sprintf(bufPtr, "\"serial\":\"*\",");
+
+ if (lease->pclass != NULL)
+ bufPtr += sprintf(bufPtr, "\"pclass\":\"%s\",", lease->pclass);
+ else
+ bufPtr += sprintf(bufPtr, "\"pclass\":\"*\",");
//option 61
if (lease->clid && lease->clid_len != 0) {
tmpPtr = tmp;
@@ -377,7 +385,11 @@
sprintf(tmp, "*");
bufPtr += sprintf(bufPtr, "\"cid\":\"%s\",", tmp);
- bufPtr += sprintf(bufPtr, "\"ifname\":\"%s\"", (ifname) ? ifname : "*");
+ if (ifname != NULL)
+ bufPtr += sprintf(bufPtr, "\"ifname\":\"%s\"", ifname);
+ else
+ bufPtr += sprintf(bufPtr, "\"ifname\":\"*\"");
+
bufPtr += sprintf(bufPtr, "}");
bufPtr = '\0';
Index: dnsmasq-2.78/src/rfc2131.c
===================================================================
--- dnsmasq-2.78.orig/src/rfc2131.c 2018-11-05 18:43:25.776847518 +0800
+++ dnsmasq-2.78/src/rfc2131.c 2018-11-05 18:48:19.191861600 +0800
@@ -502,7 +502,7 @@
y = option_ptr(opt, offset + len + 5);
match = 1;
- for (match_str = o->val; match_str < (o->val + o->len);) {
+ for (match_str = o->val; (unsigned char *) match_str < (o->val + o->len);) {
match_id = (int) match_str[0];
match_len = (int) match_str[1];
next_str = match_str + match_len + 2;
@@ -0,0 +1,24 @@
Index: dnsmasq-2.78/src/dhcp-common.c
===================================================================
--- dnsmasq-2.78.orig/src/dhcp-common.c 2018-11-05 18:54:36.891541355 +0800
+++ dnsmasq-2.78/src/dhcp-common.c 2018-11-05 18:58:28.759081600 +0800
@@ -562,6 +562,7 @@
"sip-server", 120, 0}, {
"classless-static-route", 121, 0}, {
"vendor-id-encap", 125, 0}, {
+ "captive-portal", 160, OT_NAME}, {
"server-ip-address", 255, OT_ADDR_LIST}, /* special, internal only, sets siaddr */
{
NULL, 0, 0}
Index: dnsmasq-2.78/src/dhcp-protocol.h
===================================================================
--- dnsmasq-2.78.orig/src/dhcp-protocol.h 2018-11-05 18:54:36.891541355 +0800
+++ dnsmasq-2.78/src/dhcp-protocol.h 2018-11-05 19:02:53.343839800 +0800
@@ -63,6 +63,7 @@
#define OPTION_SIP_SERVER 120
#define OPTION_VENDOR_IDENT 124
#define OPTION_VENDOR_IDENT_OPT 125
+#define OPTION_CAPTIVE_PORTAL 160
#define OPTION_END 255
#define SUBOPT_CIRCUIT_ID 1
@@ -0,0 +1,20 @@
Index: dnsmasq-2.78/src/dhcp.c
===================================================================
--- dnsmasq-2.78.orig/src/dhcp.c 2018-11-05 19:08:14.763576856 +0800
+++ dnsmasq-2.78/src/dhcp.c 2018-11-05 19:09:16.208166900 +0800
@@ -995,7 +995,15 @@
to.in.sin_addr = relay->server.addr.addr4;
to.in.sin_port = htons(daemon->dhcp_server_port);
+#if 1
+ /*+++ Kide@zyxel:
+ * I am not sure the origial design of it. But the src address of all dhcp relayed pkts should
+ * be changed to the one of the interface uplinked to dhcp server?!
+ */
+ send_from(daemon->dhcpfd, 1, (char *) mess, sz, &to, &from, 0);
+#else
send_from(daemon->dhcpfd, 0, (char *) mess, sz, &to, &from, 0);
+#endif
if (option_bool(OPT_LOG_OPTS)) {
inet_ntop(AF_INET, &relay->local, daemon->addrbuff, ADDRSTRLEN);
@@ -0,0 +1,31 @@
Index: dnsmasq-2.78/src/option.c
===================================================================
--- dnsmasq-2.78.orig/src/option.c 2018-11-20 18:50:55.881131015 +0800
+++ dnsmasq-2.78/src/option.c 2018-11-20 18:50:55.933131015 +0800
@@ -4471,8 +4471,12 @@
_(" at line %d of %s"), lineno, file);
if (hard_opt != 0)
my_syslog(LOG_ERR, "%s", daemon->namebuff);
- else
- die("%s", daemon->namebuff, EC_BADCONF);
+ else{
+ //die("%s", daemon->namebuff, EC_BADCONF);
+ my_syslog(MS_DHCP | LOG_ERR, _("%s\n"), daemon->namebuff);
+
+ continue;
+ }
}
}
Index: dnsmasq-2.78/src/log.c
===================================================================
--- dnsmasq-2.78.orig/src/log.c 2018-11-20 18:50:55.809131015 +0800
+++ dnsmasq-2.78/src/log.c 2018-11-20 18:50:55.933131015 +0800
@@ -323,6 +323,7 @@
}
va_start(ap, format);
vsyslog(priority, format, ap);
+ vprintf(format, ap);
va_end(ap);
#endif
@@ -0,0 +1,15 @@
Index: dnsmasq-2.78/src/option.c
===================================================================
--- dnsmasq-2.78.orig/src/option.c 2018-12-20 16:03:57.765113663 +0800
+++ dnsmasq-2.78/src/option.c 2018-12-20 16:23:15.701257400 +0800
@@ -163,8 +163,8 @@
#define LOPT_REPLY_DELAY 350
#ifdef ZYXEL_PATCH
-#define LOPT_TAG_IFNAME 329
-#define LOPT_VENDOREXACT 330
+#define LOPT_TAG_IFNAME 351
+#define LOPT_VENDOREXACT 352
#endif
#ifdef HAVE_GETOPT_LONG
@@ -0,0 +1,29 @@
Index: dnsmasq-2.78/Makefile
===================================================================
--- dnsmasq-2.78.orig/Makefile 2019-01-11 21:41:31.707022755 +0800
+++ dnsmasq-2.78/Makefile 2019-01-11 21:46:56.715013379 +0800
@@ -62,7 +62,8 @@
lua_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --cflags lua5.2`
lua_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_LUASCRIPT $(PKG_CONFIG) --libs lua5.2`
nettle_cflags = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --cflags nettle hogweed`
-nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --libs nettle hogweed`
+#nettle_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC $(PKG_CONFIG) --libs nettle hogweed`
+nettle_libs = `if echo $(COPTS) | grep HAVE_DNSSEC >/dev/null 2>&1; then echo -lnettle -lhogweed; fi`
gmp_libs = `echo $(COPTS) | $(top)/bld/pkg-wrapper HAVE_DNSSEC NO_GMP --copy -lgmp`
sunos_libs = `if uname | grep SunOS >/dev/null 2>&1; then echo -lsocket -lnsl -lposix4; fi`
version = -DVERSION='\"`$(top)/bld/get-version $(top)`\"'
Index: dnsmasq-2.78/src/dnssec.c
===================================================================
--- dnsmasq-2.78.orig/src/dnssec.c 2019-01-11 21:41:31.679022756 +0800
+++ dnsmasq-2.78/src/dnssec.c 2019-01-11 21:41:31.815022752 +0800
@@ -19,6 +19,10 @@
#ifdef HAVE_DNSSEC
+#ifdef NO_GMP
+#include <nettle/mini-gmp.h>
+#endif
+
#include <nettle/rsa.h>
#include <nettle/dsa.h>
#ifndef NO_NETTLE_ECC
@@ -0,0 +1,34 @@
Index: dnsmasq-2.78/src/extern.c
===================================================================
--- dnsmasq-2.78.orig/src/extern.c 2019-04-08 16:58:40.000000000 +0800
+++ dnsmasq-2.78/src/extern.c 2019-04-08 17:02:36.280891251 +0800
@@ -164,18 +164,27 @@
FILE *fp = NULL;
phyifname[0] = 0;
- sprintf(tmp, "brctl showmacs %s | grep %s", ifname, macaddr);
+ //sprintf(tmp, "brctl showmacs %s | grep %s", ifname, macaddr);
+ sprintf(tmp, "brctl showmacs %s | grep %s | awk '{print$NF}'", ifname, macaddr);
+
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s command = %s", __func__, tmp);
+
if ((fp = popen(tmp, "r"))) {
tmp[0] = '\0';
fgets(tmp, sizeof(tmp) - 1, fp);
pclose(fp);
- if (sscanf(tmp, "%*s %*s %*s %*s %s", phyifname) == 1) {
+ //if (sscanf(tmp, "%*s %*s %*s %*s %s", phyifname) == 1) {
+ if(sscanf(tmp, "%s", phyifname) == 1){
strcpy(reply, phyifname);
if (reply)
return reply;
return phyifname;
}
}
+ else
+ {
+ my_syslog(MS_DHCP | LOG_DEBUG, "%s Cannot get Phy Ifname = %s", __func__);
+ }
return "";
}
@@ -0,0 +1,19 @@
Index: dnsmasq-2.78/src/dhcp.c
===================================================================
--- dnsmasq-2.78.orig/src/dhcp.c 2019-11-18 14:19:57.147260155 +0800
+++ dnsmasq-2.78/src/dhcp.c 2019-11-18 14:25:24.459009740 +0800
@@ -102,8 +102,12 @@
saddr.sin_len = sizeof(struct sockaddr_in);
#endif
- if (bind(fd, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in)))
- die(_("failed to bind DHCP server socket: %s"), NULL, EC_BADNET);
+ if (bind(fd, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in))){
+ my_syslog(LOG_ERR, "!!! %s failed to bind DHCP server socket !!!\n", __FUNCTION__);
+ sleep(1);
+ if (bind(fd, (struct sockaddr *) &saddr, sizeof(struct sockaddr_in)))
+ die(_("failed to bind DHCP server socket: %s"), NULL, EC_BADNET);
+ }
return fd;
}
@@ -0,0 +1,170 @@
Index: dnsmasq-2.78/src/dnsmasq.h
===================================================================
--- dnsmasq-2.78.orig/src/dnsmasq.h 2020-09-03 11:33:23.106421301 +0800
+++ dnsmasq-2.78/src/dnsmasq.h 2020-09-03 16:25:11.147418143 +0800
@@ -253,6 +253,16 @@
#define MS_DHCP LOG_DAEMON
#define MS_SCRIPT LOG_MAIL
+#ifdef CONFIG_TT_CUSTOMIZATION_TR069
+struct query_domain {
+ char domainname[MAXDNAME];
+ int queryCount;
+ time_t timer;
+ unsigned int QType;
+ struct query_domain *next;
+};
+#endif
+
struct all_addr {
union {
struct in_addr addr4;
@@ -1075,6 +1085,9 @@
struct randfd *rfd_save; /* " " */
pid_t tcp_pids[MAX_PROCS];
struct randfd randomsocks[RANDOM_SOCKS];
+#ifdef CONFIG_TT_CUSTOMIZATION_TR069
+ struct query_domain *domainQuery;
+#endif
int v6pktinfo;
struct addrlist *interface_addrs; /* list of all addresses/prefix lengths associated with all local interfaces */
int log_id, log_display_id; /* ids of transactions for logging */
Index: dnsmasq-2.78/src/forward.c
===================================================================
--- dnsmasq-2.78.orig/src/forward.c 2020-09-03 11:33:23.110421301 +0800
+++ dnsmasq-2.78/src/forward.c 2020-09-03 16:25:42.077393473 +0800
@@ -212,6 +212,23 @@
return flags;
}
+#ifdef CONFIG_TT_CUSTOMIZATION_TR069
+static struct query_domain *create_domain_rec(char *namebuff,unsigned int QType)
+{
+ struct query_domain *n ;
+ if(n= (struct query_domain *)whine_malloc(sizeof(struct query_domain))){
+ n->next = daemon->domainQuery;
+ n->queryCount = 0;
+ strncpy(n->domainname,namebuff,MAXDNAME);
+ n->timer = dnsmasq_time();
+ n->QType = QType;//richard
+ daemon->domainQuery = n;
+ }
+ return n;
+
+}
+#endif
+
static int forward_query(int udpfd, union mysockaddr *udpaddr,
struct all_addr *dst_addr, unsigned int dst_iface,
struct dns_header *header, size_t plen, time_t now,
@@ -233,6 +250,15 @@
void *hash = &crc;
#endif
unsigned int gotname = extract_request(header, plen, daemon->namebuff, NULL);
+#ifdef CONFIG_TT_CUSTOMIZATION_TR069
+ int i =0;
+ int forwardFlag = 0;//richard
+ time_t now_time;
+ char diff_buf[8];
+ int diff=0;
+ char tmpStr[256] = {0};
+ int bytes;
+#endif
(void) do_bit;
@@ -385,6 +411,71 @@
int subnet, forwarded = 0;
size_t edns0_len;
+#ifdef CONFIG_TT_CUSTOMIZATION_TR069
+ struct query_domain *n = NULL;
+ int found = 0;
+
+ FILE *fp = fopen("/tmp/tr69url", "r");
+ if (fp){
+ bytes = fread(tmpStr, sizeof(char), 256,fp);
+ if(bytes<256)
+ tmpStr[bytes]='\0';
+
+ fclose(fp);
+ }
+
+ for(n = daemon->domainQuery; n!=NULL ; n=n->next)
+ {
+ if(daemon->namebuff!=NULL && !strncmp(n->domainname,daemon->namebuff,MAXDNAME) && n->QType == gotname)//richard
+ {
+ found = 1;
+ break;
+ }
+ }
+ if (found){
+ now_time = dnsmasq_time();
+ sprintf(diff_buf, "%f", difftime(now_time, n->timer) );
+ diff = atoi(diff_buf);
+ if(diff >= 30 || diff <= -30 )
+ {
+ n->timer = now_time;
+ n->queryCount = 0;
+ }
+ }else{
+ n = create_domain_rec(daemon->namebuff,(unsigned short)gotname);//richard
+
+ if(n == NULL)
+ return 0;
+
+ }
+ if(n!=NULL && n->domainname!=NULL && strncmp(n->domainname, tmpStr, strlen(tmpStr)) == 0 && n->queryCount ==2)
+ return 1;
+
+ if(!forwardFlag){//richard
+ firstsentto = start = daemon->servers;
+
+ if(n != NULL){
+ i=(n->queryCount)%2;
+ }
+ if( i == 0 ){
+ start = firstsentto;
+ }else if ( i ==1 ){
+#if 1//RichardFeng
+ for(start != NULL;start != NULL && start->domain!= NULL ; start = start->next){
+ if( domain && hostname_isequal(domain, start->domain))
+ break;
+ }
+ if(start != NULL)
+#endif
+ start = start->next;
+
+ if(start == NULL){
+ start = firstsentto;
+ }
+ }
+ }//richard
+#endif
+
/* If a query is retried, use the log_id for the retry when logging the answer. */
forward->log_id = daemon->log_id;
@@ -505,6 +596,11 @@
(struct all_addr *) &start->addr.in6.sin6_addr, NULL);
#endif
start->queries++;
+#ifdef CONFIG_TT_CUSTOMIZATION_TR069
+ if(n != NULL){
+ n->queryCount++;
+ }
+#endif
forwarded = 1;
forward->sentto = start;
@@ -518,8 +614,9 @@
forward->forwardall = 1;
}
#endif
-
+#ifndef CONFIG_TT_CUSTOMIZATION_TR069
if (!forward->forwardall)
+#endif
break;
forward->forwardall++;
}
@@ -0,0 +1,64 @@
Index: dnsmasq-2.78/src/cache.c
===================================================================
--- dnsmasq-2.78.orig/src/cache.c 2020-10-12 18:13:51.876978526 +0800
+++ dnsmasq-2.78/src/cache.c 2020-10-12 18:14:13.868979384 +0800
@@ -559,6 +559,9 @@
}
#ifdef DNS_TRAFFIC_ROUTE
+#if defined(ZYXEL_DNS_TRAFFIC_ROUTE_FUZZY_COMPARE)
+#define DNS_ROUTE_FUZZY_MATCH_HEADER "*."
+#endif
void add_dns_traffic_route(uint32_t s_addr, const char *cname, int *flush)
{
char sysCmd[128] = "";
@@ -566,6 +569,13 @@
srcIP.s_addr = s_addr;
struct server *serv = NULL;
+#if defined(ZYXEL_DNS_TRAFFIC_ROUTE_FUZZY_COMPARE)
+ char *pFuzzyName = NULL, *pRemoveHeaderCName = NULL, cTmpCName[MAXDNAME];
+ uint8_t i, uCNameLength, uMatch = 0, uFuzzyLengh = strlen (DNS_ROUTE_FUZZY_MATCH_HEADER);
+#else
+ uint8_t uMatch = 0;
+#endif //#if defined(ZYXEL_DNS_TRAFFIC_ROUTE_FUZZY_COMPARE)
+
if (s_addr == 0) {
return;
@@ -574,7 +584,35 @@
serv = daemon->servers;
while (serv) {
+#if defined(ZYXEL_DNS_TRAFFIC_ROUTE_FUZZY_COMPARE)
+ if (serv->domain) {
+ if (strncmp (serv->domain, DNS_ROUTE_FUZZY_MATCH_HEADER, uFuzzyLengh) == 0) {
+ pFuzzyName = serv->domain + uFuzzyLengh;
+
+ pRemoveHeaderCName = NULL;
+ strncpy (cTmpCName, cname, MAXDNAME);
+ uCNameLength = strlen (cTmpCName);
+
+ for (i = 0 ; i < uCNameLength ; i++) {
+ if (cTmpCName [i] == '.') {
+ pRemoveHeaderCName = (cTmpCName + (i + 1));
+ break;
+ }
+ }
+
+ if (pRemoveHeaderCName != NULL && strcmp (pFuzzyName, pRemoveHeaderCName) == 0) {
+ uMatch = 1;
+ }
+ } else if (strcmp(cname, serv->domain) == 0) {
+ uMatch = 1;
+ }
+ }
+#else
if (serv->domain && (strcmp(cname, serv->domain) == 0)) {
+ uMatch = 1;
+ }
+#endif //#if defined(ZYXEL_DNS_TRAFFIC_ROUTE_FUZZY_COMPARE)
+ if (uMatch == 1) {
if (*flush) {
/* deledt */
sprintf(sysCmd,
@@ -0,0 +1,204 @@
Index: dnsmasq-2.78/src/dnssec.c
===================================================================
--- dnsmasq-2.78.orig/src/dnssec.c 2021-01-06 16:29:34.825763729 +0800
+++ dnsmasq-2.78/src/dnssec.c 2021-01-06 16:29:34.865763729 +0800
@@ -447,15 +447,17 @@
static int count_labels(char *name)
{
int i;
+ char *p;
if (*name == 0)
return 0;
- for (i = 0; *name; name++)
- if (*name == '.')
+ for (p = name, i = 0; *p; p++)
+ if (*p == '.')
i++;
- return i + 1;
+ /* Don't count empty first label. */
+ return *name == '.' ? i : i+1;
}
/* Implement RFC1982 wrapped compare for 32-bit numbers */
@@ -1399,10 +1401,8 @@
}
}
-static int prove_non_existence_nsec(struct dns_header *header, size_t plen,
- unsigned char **nsecs, int nsec_count,
- char *workspace1, char *workspace2,
- char *name, int type, int *nons)
+static int prove_non_existence_nsec(struct dns_header *header, size_t plen, unsigned char **nsecs, unsigned char **labels, int nsec_count,
+ char *workspace1_in, char *workspace2, char *name, int type, int *nons)
{
int i, rc, rdlen;
unsigned char *p, *psave;
@@ -1414,6 +1414,9 @@
/* Find NSEC record that proves name doesn't exist */
for (i = 0; i < nsec_count; i++) {
+ char *workspace1 = workspace1_in;
+ int sig_labels, name_labels;
+
p = nsecs[i];
if (!extract_name(header, plen, &p, workspace1, 1, 10))
return 0;
@@ -1423,6 +1426,26 @@
if (!extract_name(header, plen, &p, workspace2, 1, 10))
return 0;
+ /* If NSEC comes from wildcard expansion, use original wildcard
+ as name for computation. */
+ sig_labels = *labels[i];
+ name_labels = count_labels(workspace1);
+
+ if (sig_labels < name_labels)
+ {
+ int k;
+ for (k = name_labels - sig_labels; k != 0; k--)
+ {
+ while (*workspace1 != '.' && *workspace1 != 0)
+ workspace1++;
+ if (k != 1 && *workspace1 == '.')
+ workspace1++;
+ }
+
+ workspace1--;
+ *workspace1 = '*';
+ }
+
rc = hostname_cmp(workspace1, name);
if (rc == 0) {
@@ -1818,21 +1841,23 @@
char *keyname, char *name, int qtype, int qclass,
char *wildname, int *nons)
{
- static unsigned char **nsecset = NULL;
- static int nsecset_sz = 0;
+ static unsigned char **nsecset = NULL, **rrsig_labels = NULL;
+ static int nsecset_sz = 0, rrsig_labels_sz = 0;
int type_found = 0;
- unsigned char *p = skip_questions(header, plen);
+ unsigned char *auth_start, *p = skip_questions(header, plen);
int type, class, rdlen, i, nsecs_found;
/* Move to NS section */
if (!p || !(p = skip_section(p, ntohs(header->ancount), header, plen)))
return 0;
+ auth_start = p;
+
for (nsecs_found = 0, i = ntohs(header->nscount); i != 0; i--) {
unsigned char *pstart = p;
- if (!(p = skip_name(p, header, plen, 10)))
+ if (!extract_name(header, plen, &p, daemon->workspacename, 1, 10))
return 0;
GETSHORT(type, p);
@@ -1850,6 +1875,68 @@
if (!expand_workspace(&nsecset, &nsecset_sz, nsecs_found))
return 0;
+ if (type == T_NSEC)
+ {
+ /* If we're looking for NSECs, find the corresponding SIGs, to
+ extract the labels value, which we need in case the NSECs
+ are the result of wildcard expansion.
+ Note that the NSEC may not have been validated yet
+ so if there are multiple SIGs, make sure the label value
+ is the same in all, to avoid be duped by a rogue one.
+ If there are no SIGs, that's an error */
+ unsigned char *p1 = auth_start;
+ int res, j, rdlen1, type1, class1;
+
+ if (!expand_workspace(&rrsig_labels, &rrsig_labels_sz, nsecs_found))
+ return 0;
+
+ rrsig_labels[nsecs_found] = NULL;
+
+ for (j = ntohs(header->nscount); j != 0; j--)
+ {
+ if (!(res = extract_name(header, plen, &p1, daemon->workspacename, 0, 10)))
+ return 0;
+
+ GETSHORT(type1, p1);
+ GETSHORT(class1, p1);
+ p1 += 4; /* TTL */
+ GETSHORT(rdlen1, p1);
+
+ if (!CHECK_LEN(header, p1, plen, rdlen1))
+ return 0;
+
+ if (res == 1 && class1 == qclass && type1 == T_RRSIG)
+ {
+ int type_covered;
+ unsigned char *psav = p1;
+
+ if (rdlen < 18)
+ return 0; /* bad packet */
+
+ GETSHORT(type_covered, p1);
+
+ if (type_covered == T_NSEC)
+ {
+ p1++; /* algo */
+
+ /* labels field must be the same in every SIG we find. */
+ if (!rrsig_labels[nsecs_found])
+ rrsig_labels[nsecs_found] = p1;
+ else if (*rrsig_labels[nsecs_found] != *p1) /* algo */
+ return 0;
+ }
+ p1 = psav;
+ }
+
+ if (!ADD_RDLEN(header, p1, plen, rdlen1))
+ return 0;
+ }
+
+ /* Must have found at least one sig. */
+ if (!rrsig_labels[nsecs_found])
+ return 0;
+ }
+
nsecset[nsecs_found++] = pstart;
}
@@ -1858,9 +1945,9 @@
}
if (type_found == T_NSEC)
- return prove_non_existence_nsec(header, plen, nsecset, nsecs_found,
- daemon->workspacename, keyname, name, qtype,
- nons);
+ return prove_non_existence_nsec(header, plen, nsecset, rrsig_labels,
+ nsecs_found, daemon->workspacename,
+ keyname, name, qtype, nons);
else if (type_found == T_NSEC3)
return prove_non_existence_nsec3(header, plen, nsecset, nsecs_found,
daemon->workspacename, keyname, name,
Index: dnsmasq-2.78/CHANGELOG
===================================================================
--- dnsmasq-2.78.orig/CHANGELOG 2021-01-06 16:32:14.383579750 +0800
+++ dnsmasq-2.78/CHANGELOG 2021-01-06 16:32:41.257015910 +0800
@@ -1,3 +1,14 @@
+
+ Fix for DNSSEC with wildcard-derived NSEC records.
+ It's OK for NSEC records to be expanded from wildcards,
+ but in that case, the proof of non-existence is only valid
+ starting at the wildcard name, *.<domain> NOT the name expanded
+ from the wildcard. Without this check it's possible for an
+ attacker to craft an NSEC which wrongly proves non-existence.
+ Thanks to Ralph Dolmans for finding this, and co-ordinating
+ the vulnerability tracking and fix release.
+ CVE-2017-15107 applies.
+
version 2.78
Fix logic of appending ".<layer>" to PXE basename. Thanks to Chris
Novakovic for the patch.
@@ -0,0 +1,31 @@
Index: dnsmasq-2.78/src/helper.c
===================================================================
--- dnsmasq-2.78.orig/src/helper.c 2021-01-06 16:29:34.000000000 +0800
+++ dnsmasq-2.78/src/helper.c 2021-01-06 16:43:41.710656279 +0800
@@ -83,6 +83,7 @@
pid_t pid;
int i, pipefd[2];
struct sigaction sigact;
+ unsigned char *alloc_buff = NULL;
/* create the pipe through which the main program sends us commands,
then fork our process. */
@@ -176,11 +177,16 @@
struct script_data data;
char *p, *action_str, *hostname = NULL, *domain = NULL;
unsigned char *buf = (unsigned char *) daemon->namebuff;
- unsigned char *end, *extradata, *alloc_buff = NULL;
+ unsigned char *end, *extradata;
int is6, err = 0;
int pipeout[2];
- free(alloc_buff);
+ /* Free rarely-allocated memory from previous iteration. */
+ if (alloc_buff)
+ {
+ free(alloc_buff);
+ alloc_buff = NULL;
+ }
/* we read zero bytes when pipe closed: this is our signal to exit */
if (!read_write(pipefd[0], (unsigned char *) &data, sizeof(data), 1)) {
@@ -0,0 +1,455 @@
diff -Naur dnsmasq-2.67-orig/.gitignore dnsmasq-2.67/.gitignore
--- dnsmasq-2.67-orig/.gitignore 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/.gitignore 1970-01-01 08:00:00.000000000 +0800
@@ -1,14 +0,0 @@
-src/*.o
-src/*.mo
-src/dnsmasq.pot
-src/dnsmasq
-src/dnsmasq_baseline
-src/.configured
-contrib/wrt/dhcp_lease_time
-contrib/wrt/dhcp_release
-debian/base/
-debian/daemon/
-debian/files
-debian/substvars
-debian/utils-substvars
-debian/utils/
diff -Naur dnsmasq-2.67-orig/Makefile dnsmasq-2.67/Makefile
--- dnsmasq-2.67-orig/Makefile 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/Makefile 2014-01-09 14:42:06.621110009 +0800
@@ -44,6 +44,15 @@
PO = po
MAN = man
+#USERSPACE_ZCFG_DIR = $(BUILD_DIR)/userspace/zyxel/private/apps/zcfg
+#USERSPACE_ZCFG_INCLUDE = $(USERSPACE_ZCFG_DIR)/include
+#USERSPACE_ZCMD_INCLUDE = $(BUILD_DIR)/userspace/zyxel/private/apps/esmd
+ZYXEL_CFLAGS += -DZYXEL_DHCP
+ZYXEL_OBJS += extern.o
+#ZYXEL_INCDIR += -I$(USERSPACE_ZCMD_INCLUDE) -I$(USERSPACE_ZCFG_INCLUDE)
+ZYXEL_LIBS = -lzcfg_msg
+#ZYXEL_LIBDIR += -L$(INSTALL_DIR)/lib/public
+
#################################################################
# pmake way. (NB no spaces to keep gmake 3.82 happy)
@@ -65,7 +74,7 @@
objs = cache.o rfc1035.o util.o option.o forward.o network.o \
dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
- dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o domain.o
+ dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o domain.o $(ZYXEL_OBJS)
hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
dns-protocol.h radv-protocol.h
@@ -73,8 +82,8 @@
all : $(BUILDDIR)
@cd $(BUILDDIR) && $(MAKE) \
top="$(top)" \
- build_cflags="$(version) $(dbus_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags)" \
- build_libs="$(dbus_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs)" \
+ build_cflags="$(version) $(dbus_cflags) $(idn_cflags) $(ct_cflags) $(lua_cflags) $(ZYXEL_CFLAGS)" \
+ build_libs="$(dbus_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs) $(ZYXEL_LIBS)" \
-f $(top)/Makefile dnsmasq
mostly_clean :
@@ -92,6 +101,7 @@
$(INSTALL) -d $(DESTDIR)$(BINDIR) -d $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 644 $(MAN)/dnsmasq.8 $(DESTDIR)$(MANDIR)/man8
$(INSTALL) -m 755 $(BUILDDIR)/dnsmasq $(DESTDIR)$(BINDIR)
+# $(INSTALL) -m 755 $(SRC)/dnsmasq $(INSTALL_DIR)/bin
all-i18n : $(BUILDDIR)
@cd $(BUILDDIR) && $(MAKE) \
@@ -143,10 +153,10 @@
ln -s $(top)/$(SRC)/$@ .
.c.o:
- $(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(RPM_OPT_FLAGS) -c $<
+ $(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(BUILD_CFLAGS) $(RPM_OPT_FLAGS) -c $<
dnsmasq : .configured $(hdrs) $(objs)
- $(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS)
+ $(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(BUILD_CFLAGS) $(LIBS)
dnsmasq.pot : $(objs:.o=.c) $(hdrs)
$(XGETTEXT) -d dnsmasq --foreign-user --omit-header --keyword=_ -o $@ -i $(objs:.o=.c)
diff -Naur dnsmasq-2.67-orig/.new dnsmasq-2.67/.new
--- dnsmasq-2.67-orig/.new 1970-01-01 08:00:00.000000000 +0800
+++ dnsmasq-2.67/.new 2014-01-09 14:10:39.529029357 +0800
@@ -0,0 +1 @@
+shlibs:Depends=libc6 (>= 2.1)
diff -Naur dnsmasq-2.67-orig/src/dhcp.c dnsmasq-2.67/src/dhcp.c
--- dnsmasq-2.67-orig/src/dhcp.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dhcp.c 2014-01-09 14:10:39.281029363 +0800
@@ -331,6 +331,11 @@
iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz,
now, unicast_dest, &is_inform, pxe_fd, iface_addr);
lease_update_file(now);
+
+#ifdef ZYXEL_DHCP
+ handle_STB_Vendor_ID_request();
+#endif
+
lease_update_dns(0);
if (iov.iov_len == 0)
diff -Naur dnsmasq-2.67-orig/src/dnsmasq.c dnsmasq-2.67/src/dnsmasq.c
--- dnsmasq-2.67-orig/src/dnsmasq.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dnsmasq.c 2014-01-09 14:10:39.277029368 +0800
@@ -64,6 +64,10 @@
textdomain("dnsmasq");
#endif
+#ifdef ZYXEL_DHCP /* register to zyxel zcfg, by charisse*/
+ dnsmasq_eid_register();
+#endif
+
sigact.sa_handler = sig_handler;
sigact.sa_flags = 0;
sigemptyset(&sigact.sa_mask);
diff -Naur dnsmasq-2.67-orig/src/dnsmasq.h dnsmasq-2.67/src/dnsmasq.h
--- dnsmasq-2.67-orig/src/dnsmasq.h 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2014-01-09 14:10:39.285029353 +0800
@@ -232,6 +232,12 @@
#define MS_TFTP LOG_USER
#define MS_DHCP LOG_DAEMON
+#ifdef ZYXEL_DHCP
+ #define DHCP_CLIENT_NUM 34
+ #define VENDORID_LENGTH 100
+ #define MAC_LENGTH 18
+#endif
+
struct all_addr {
union {
struct in_addr addr4;
@@ -1309,3 +1315,12 @@
time_t periodic_slaac(time_t now, struct dhcp_lease *leases);
void slaac_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface, struct dhcp_lease *leases);
#endif
+
+/* extern.c */
+#ifdef ZYXEL_DHCP
+extern void dnsmasq_eid_register(void);
+extern void handle_op125_request(unsigned char *oui,unsigned char *serial,unsigned char *pclass);
+extern void send_dhcp_option_request(char *ifName, char *vendorID, unsigned char *chaddr, char reply[]);
+extern void handle_STB_Vendor_ID_request();
+#endif
+
diff -Naur dnsmasq-2.67-orig/src/extern.c dnsmasq-2.67/src/extern.c
--- dnsmasq-2.67-orig/src/extern.c 1970-01-01 08:00:00.000000000 +0800
+++ dnsmasq-2.67/src/extern.c 2014-01-09 14:10:39.285029353 +0800
@@ -0,0 +1,133 @@
+#ifdef ZYXEL_DHCP
+#include <stdio.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "dnsmasq.h"
+
+/*ZyXEL zcfg*/
+#include "zcfg_common.h"
+#include "zcfg_fe_rdm_access.h"
+#include "zcfg_debug.h"
+#include "zcfg_msg.h"
+#include <json/json.h>
+
+/*ZyXEL esmd*/
+#include "esmd_mgabdev.h"
+#include "esmd_connection.h"
+
+void dnsmasq_eid_register( void ){
+ zcfgRet_t retzcfg;
+
+ /*Register dnsmasq eid which is defined in zcfg_eid.h*/
+ zcfgEidInit(ZCFG_EID_DNSMASQ, NULL);
+
+ /*init message server*/
+ retzcfg = zcfgMsgServerInit();
+ if(retzcfg != ZCFG_SUCCESS) {
+ zcfgLog(ZCFG_LOG_ERR, "Dnsmasq message server init fail\n");
+ return 0;
+ }
+}
+
+zcfgRet_t dnsmasq_msg_send(int msg_type, int payloadLen, const char *payload, char reply[])
+{
+ zcfgRet_t ret = 0;
+ void *sendBuf = NULL;
+ void *recvBuf = NULL;
+ zcfgMsg_t *sendMsgHdr = NULL;
+ zcfgMsg_t *recvMsgHdr = NULL;
+ char *recv_str = NULL;
+ int buf_size = 0;
+
+ buf_size = sizeof(zcfgMsg_t)+payloadLen;
+ sendBuf = malloc(buf_size);
+ sendMsgHdr = (zcfgMsg_t*)sendBuf;
+
+ sendMsgHdr->type = msg_type;
+ sendMsgHdr->length = payloadLen;
+ sendMsgHdr->srcEid = ZCFG_EID_DNSMASQ;
+ sendMsgHdr->dstEid = ZCFG_EID_ESMD;
+ if(payload != NULL)
+ memcpy(sendBuf+sizeof(zcfgMsg_t), payload, payloadLen);
+
+ ret = zcfgMsgSendAndGetReply(sendMsgHdr, (zcfgMsg_t **)&recvBuf, 0);
+ if(ret == ZCFG_SUCCESS) {
+ recvMsgHdr = (zcfgMsg_t*)recvBuf;
+ if(recvMsgHdr){
+ if(recvMsgHdr->type == RESPONSE_SUCCESS) {
+ recv_str = (char *)recvBuf+sizeof(zcfgMsg_t);
+ strcpy(reply, recv_str);
+ }
+ free(recvBuf);
+ }
+ }
+
+ return ret;
+}
+
+void handle_op125_request(unsigned char *oui , unsigned char *serial, unsigned char *pclass)
+{
+ zcfgRet_t ret;
+ mgabDev_t mgabdev;
+ my_syslog(MS_DHCP | LOG_INFO, "%s ", __func__);
+
+ memset(&mgabdev, '\0', sizeof(mgabdev));
+
+ if(oui){
+ strncpy(mgabdev.ManufacturerOUI, (char *)(&oui[2]), oui[1]);
+ }
+ if(serial){
+ strncpy(mgabdev.SerialNumber, (char *)(&serial[2]), serial[1]);
+ }
+ if(pclass){
+ strncpy(mgabdev.ProductClass, (char *)(&pclass[2]), pclass[1]);
+ }
+
+ /* send ZCFG_MSG_MGABDEV_DETECT to ESMD for notification */
+ ret = dnsmasq_msg_send(ZCFG_MSG_MGABDEV_DETECT, sizeof(mgabDev_t), (const char*)&mgabdev, NULL);
+ if(ret != ZCFG_SUCCESS && ret != ZCFG_SUCCESS_AND_NO_REPLY)
+ my_syslog(MS_DHCP | LOG_ERR, "%s dnsmasq_msg_send fail,ret=%d", __func__, ret);
+
+}
+
+void send_dhcp_option_request(char *ifName, char *vendorID, unsigned char *chaddr, char reply[])
+{
+ zcfgRet_t ret = 0;
+ dnsmasqOption_t dnsmasqInfo;
+
+ my_syslog(MS_DHCP | LOG_INFO, "%s ", __func__);
+
+ memset(&dnsmasqInfo, '\0', sizeof(dnsmasqInfo));
+
+ if(ifName)
+ strncpy(dnsmasqInfo.ifName, (char *)ifName, sizeof(dnsmasqInfo.ifName));
+
+ if(chaddr)
+ memcpy(dnsmasqInfo.chaddr, (char *)chaddr, 32);
+
+ if(vendorID)
+ strncpy(dnsmasqInfo.op60, (char *)vendorID, sizeof(dnsmasqInfo.op60));
+
+ /* send ZCFG_MSG_DHCPD_OPTION to ESMD for DHCP option */
+ ret = dnsmasq_msg_send(ZCFG_MSG_DHCPD_OPTION, sizeof(dnsmasqOption_t), (const char *)&dnsmasqInfo, reply);
+ my_syslog(MS_DHCP | LOG_INFO, "%s esmd reply=%s", __func__, reply);
+
+ if(ret != ZCFG_SUCCESS && ret != ZCFG_SUCCESS_AND_NO_REPLY){
+ my_syslog(MS_DHCP | LOG_ERR, "%s dnsmasq_msg_send fail,ret=%d", __func__, ret);
+ strcpy(reply, "accept");//default pass any port any service
+ }
+}
+
+void handle_STB_Vendor_ID_request()
+{
+ zcfgRet_t ret;
+ my_syslog(MS_DHCP | LOG_INFO, "%s ", __func__);
+
+ /* send ZCFG_MSG_MGABDEV_DETECT to ESMD for notification */
+ ret = dnsmasq_msg_send(ZCFG_MSG_STB_VENDOR_ID_FIND, 0, NULL, NULL);
+ if(ret != ZCFG_SUCCESS && ret != ZCFG_SUCCESS_AND_NO_REPLY)
+ my_syslog(MS_DHCP | LOG_ERR, "%s ZCFG_MSG_STB_VENDOR_ID_FIND fail,ret=%d", __func__, ret);
+
+}
+#endif
diff -Naur dnsmasq-2.67-orig/src/lease.c dnsmasq-2.67/src/lease.c
--- dnsmasq-2.67-orig/src/lease.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/lease.c 2014-01-09 14:10:39.277029368 +0800
@@ -18,6 +18,11 @@
#ifdef HAVE_DHCP
+#ifdef ZYXEL_DHCP
+extern char vendorid[DHCP_CLIENT_NUM][VENDORID_LENGTH];
+extern int dhcpclientnum;
+#endif
+
static struct dhcp_lease *leases = NULL, *old_leases = NULL;
static int dns_dirty, file_dirty, leases_left;
@@ -214,6 +219,9 @@
struct dhcp_lease *lease;
time_t next_event;
int i, err = 0;
+#ifdef ZYXEL_DHCP
+ int j = 0;
+#endif
if (file_dirty != 0 && daemon->lease_stream)
{
@@ -254,10 +262,17 @@
{
for (i = 0; i < lease->clid_len - 1; i++)
ourprintf(&err, "%.2x:", lease->clid[i]);
- ourprintf(&err, "%.2x\n", lease->clid[i]);
+ ourprintf(&err, "%.2x ", lease->clid[i]);
}
else
- ourprintf(&err, "*\n");
+ ourprintf(&err, "* ");
+
+#ifdef ZYXEL_DHCP
+ my_syslog(LOG_INFO, _("dhcpclientnum = %d"), dhcpclientnum);
+ my_syslog(LOG_INFO, _("j = %d , Vendor-ID = %s"), j, vendorid[dhcpclientnum - j - 1]);
+ ourprintf(&err, "%s\n", vendorid[dhcpclientnum - j - 1]);
+ j++;
+#endif
}
#ifdef HAVE_DHCP6
diff -Naur dnsmasq-2.67-orig/src/rfc2131.c dnsmasq-2.67/src/rfc2131.c
--- dnsmasq-2.67-orig/src/rfc2131.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2014-01-09 14:10:39.281029363 +0800
@@ -18,6 +18,12 @@
#ifdef HAVE_DHCP
+#ifdef ZYXEL_DHCP
+char vendorid[DHCP_CLIENT_NUM][VENDORID_LENGTH] = {};
+char clientmac[DHCP_CLIENT_NUM][MAC_LENGTH] = {};
+int dhcpclientnum = 0;
+#endif
+
#define option_len(opt) ((int)(((unsigned char *)(opt))[1]))
#define option_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[2u+(unsigned int)(i)]))
@@ -93,7 +99,12 @@
struct dhcp_opt *o;
unsigned char pxe_uuid[17];
unsigned char *oui = NULL, *serial = NULL, *class = NULL;
-
+#ifdef ZYXEL_DHCP
+ char *s_ret = NULL, *macEmpty = NULL;
+ int j;
+ char vendorId[256] = "";
+ char intfGrpOptionCheck[16] = "";
+#endif
subnet_addr.s_addr = override.s_addr = 0;
/* set tag with name == interface */
@@ -117,6 +128,63 @@
return 0;
mess_type = option_uint(opt, 0, 1);
+
+#ifdef ZYXEL_DHCP
+ if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 2))){ //get dhcp option 60
+ emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
+ vendor_class_len = option_len(opt);
+ memset(daemon->dhcp_buff3, '\0', strlen(daemon->dhcp_buff3));
+ memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
+ strncpy(vendorId, option_ptr(opt, 0), option_len(opt));
+ for(j=0; j<dhcpclientnum; j++){
+ my_syslog(LOG_INFO, _("print_mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
+ my_syslog(LOG_INFO, _("clientmac[%d] = %s"), j, clientmac[j]);
+ s_ret = strstr(clientmac[j], print_mac(daemon->namebuff, emac, emac_len)); //get client MAC Address
+ if(s_ret != NULL) //client MAC already exist in mac table
+ break;
+ }
+ my_syslog(LOG_INFO, _("s_ret = %s"), s_ret);
+
+ my_syslog(LOG_INFO, _("daemon->dhcp_buff3 = %s"), vendorId);
+ my_syslog(LOG_INFO, _("mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
+
+ my_syslog(MS_DHCP | LOG_WARNING, _("iface_name=%s"), iface_name);
+ my_syslog(MS_DHCP | LOG_WARNING, _("inet_ntoa(mess->giaddr)=%s"),inet_ntoa(mess->giaddr));
+
+ macEmpty = strstr(print_mac(daemon->namebuff, emac, emac_len), "<null>");
+ if(s_ret == NULL && macEmpty == NULL){ //client MAC doesn't exist in mac table, means this client is newer
+ strcpy(clientmac[dhcpclientnum], print_mac(daemon->namebuff, emac, emac_len));
+ if(strcmp(daemon->dhcp_buff3, ""))
+ strcpy(vendorid[dhcpclientnum], daemon->dhcp_buff3);
+ else
+ strcpy(vendorid[dhcpclientnum], "*");
+ my_syslog(LOG_INFO, _("dhcp client number ++"));
+ dhcpclientnum++; //means total number that connect to DHCP server
+ }
+ my_syslog(LOG_INFO, _("New Coming MAC Address = %s"), print_mac(daemon->namebuff, emac, emac_len));
+ my_syslog(LOG_INFO, _("current dhcpclientnum = %d"), dhcpclientnum);
+ }
+ else{ //DHCP packet don't have option 60
+ for(j=0; j<dhcpclientnum; j++){
+ my_syslog(LOG_INFO, _("print_mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
+ my_syslog(LOG_INFO, _("clientmac[%d] = %s"), j, clientmac[j]);
+ s_ret = strstr(clientmac[j], print_mac(daemon->namebuff, emac, emac_len));
+ if(s_ret != NULL)
+ break;
+ }
+ my_syslog(LOG_INFO, _("s_ret = %s"), s_ret);
+ macEmpty = strstr(print_mac(daemon->namebuff, emac, emac_len), "<null>");
+ if(s_ret == NULL && macEmpty == NULL){
+ strcpy(clientmac[dhcpclientnum], print_mac(daemon->namebuff, emac, emac_len));
+ strcpy(vendorid[dhcpclientnum], "*");
+ my_syslog(LOG_INFO, _("dhcp client number ++"));
+ dhcpclientnum++;
+ }
+ my_syslog(LOG_INFO, _("New Coming MAC Address = %s"), print_mac(daemon->namebuff, emac, emac_len));
+ my_syslog(LOG_INFO, _("current dhcpclientnum = %d"), dhcpclientnum);
+ my_syslog(LOG_INFO, _("option 60 doesn't exist"));
+ }
+#endif
/* two things to note here: expand_buf may move the packet,
so reassign mess from daemon->packet. Also, the size
@@ -157,6 +225,10 @@
oui = option_find1(x, y, 1, 1);
serial = option_find1(x, y, 2, 1);
class = option_find1(x, y, 3, 1);
+
+#ifdef ZYXEL_DHCP /*save the DHCP option to Gateway , by charisse*/
+ handle_op125_request( oui, serial, class);
+#endif
/* If TR069-id is present set the tag "cpewan-id" to facilitate echoing
the gateway id back. Note that the device class is optional */
@@ -905,7 +977,25 @@
memcpy(req_options, option_ptr(opt, 0), option_len(opt));
req_options[option_len(opt)] = OPTION_END;
}
-
+
+#ifdef ZYXEL_DHCP
+ my_syslog(LOG_INFO, _("mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
+
+ my_syslog(MS_DHCP | LOG_WARNING, _("iface_name=%s"), iface_name);
+ my_syslog(MS_DHCP | LOG_WARNING, _("vendorId=%s"), vendorId);
+ /*send option 60 information for any port any service*/
+if(strcmp(vendorId, "")){
+ send_dhcp_option_request(iface_name, vendorId, emac, intfGrpOptionCheck);
+my_syslog(MS_DHCP | LOG_WARNING, _("intfGrpOptionCheck=%s"), intfGrpOptionCheck);
+ /*check interface grouping creteria*/
+ if((intfGrpOptionCheck != NULL) && (strcmp(intfGrpOptionCheck, ""))){
+ if(!strcmp(intfGrpOptionCheck, "decline") || !strcmp(intfGrpOptionCheck, "redirect"))
+ return 0;
+ }
+}
+
+#endif
+
switch (mess_type)
{
case DHCPDECLINE:
@@ -0,0 +1,15 @@
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2014-03-10 10:55:45.532600970 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2014-03-10 11:00:48.935129792 +0800
@@ -1020,8 +1020,10 @@
prettyprint_time(daemon->dhcp_buff, DECLINE_BACKOFF);
my_syslog(MS_DHCP | LOG_WARNING, _("disabling DHCP static address %s for %s"),
inet_ntoa(config->addr), daemon->dhcp_buff);
+#if 0 /* when static addr is declined by host, do not disable static address lease, just let host keep on trying, ZyXEL, John */
config->flags |= CONFIG_DECLINED;
config->decline_time = now;
+#endif
}
else
/* make sure this host gets a different address next time. */
@@ -0,0 +1,145 @@
Index: dnsmasq-2.67/src/lease.c
===================================================================
--- dnsmasq-2.67.orig/src/lease.c 2014-06-05 23:20:17.169582839 +0800
+++ dnsmasq-2.67/src/lease.c 2014-06-05 23:24:41.444989207 +0800
@@ -267,11 +267,16 @@
else
ourprintf(&err, "* ");
-#ifdef ZYXEL_DHCP
- my_syslog(LOG_INFO, _("dhcpclientnum = %d"), dhcpclientnum);
- my_syslog(LOG_INFO, _("j = %d , Vendor-ID = %s"), j, vendorid[dhcpclientnum - j - 1]);
- ourprintf(&err, "%s\n", vendorid[dhcpclientnum - j - 1]);
- j++;
+#ifdef ZYXEL_DHCP
+ if(dhcpclientnum > 0 && dhcpclientnum <= DHCP_CLIENT_NUM && (dhcpclientnum - j - 1) >= 0){//work around, need to modify method of get vendor id
+ my_syslog(LOG_INFO, _("dhcpclientnum = %d"), dhcpclientnum);
+ my_syslog(LOG_INFO, _("j = %d , Vendor-ID = %s"), j, vendorid[dhcpclientnum - j - 1]);
+ ourprintf(&err, "%s\n", vendorid[dhcpclientnum - j - 1]);
+ j++;
+ }
+ else{
+ ourprintf(&err, "%s\n", "* ");
+ }
#endif
}
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2014-06-05 23:20:17.177582839 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2014-06-05 23:25:11.156762705 +0800
@@ -130,60 +130,62 @@
mess_type = option_uint(opt, 0, 1);
#ifdef ZYXEL_DHCP
- if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 2))){ //get dhcp option 60
- emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
- vendor_class_len = option_len(opt);
- memset(daemon->dhcp_buff3, '\0', strlen(daemon->dhcp_buff3));
- memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
- strncpy(vendorId, option_ptr(opt, 0), option_len(opt));
- for(j=0; j<dhcpclientnum; j++){
- my_syslog(LOG_INFO, _("print_mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
- my_syslog(LOG_INFO, _("clientmac[%d] = %s"), j, clientmac[j]);
- s_ret = strstr(clientmac[j], print_mac(daemon->namebuff, emac, emac_len)); //get client MAC Address
- if(s_ret != NULL) //client MAC already exist in mac table
- break;
- }
- my_syslog(LOG_INFO, _("s_ret = %s"), s_ret);
+ if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 2))){ //get dhcp option 60
+ if(dhcpclientnum <= DHCP_CLIENT_NUM && 0<= dhcpclientnum){
+ emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
+ vendor_class_len = option_len(opt);
+ memset(daemon->dhcp_buff3, '\0', strlen(daemon->dhcp_buff3));
+ memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
+ strncpy(vendorId, option_ptr(opt, 0), option_len(opt));
+ for(j=0; j<dhcpclientnum; j++){
+ my_syslog(LOG_INFO, _("print_mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
+ my_syslog(LOG_INFO, _("clientmac[%d] = %s"), j, clientmac[j]);
+ s_ret = strstr(clientmac[j], print_mac(daemon->namebuff, emac, emac_len)); //get client MAC Address
+ if(s_ret != NULL) //client MAC already exist in mac table
+ break;
+ }
+ my_syslog(LOG_INFO, _("s_ret = %s"), s_ret);
+ my_syslog(LOG_INFO, _("daemon->dhcp_buff3 = %s"), vendorId);
+ my_syslog(LOG_INFO, _("mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
+ my_syslog(MS_DHCP | LOG_WARNING, _("iface_name=%s"), iface_name);
+ my_syslog(MS_DHCP | LOG_WARNING, _("inet_ntoa(mess->giaddr)=%s"),inet_ntoa(mess->giaddr));
- my_syslog(LOG_INFO, _("daemon->dhcp_buff3 = %s"), vendorId);
- my_syslog(LOG_INFO, _("mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
-
- my_syslog(MS_DHCP | LOG_WARNING, _("iface_name=%s"), iface_name);
- my_syslog(MS_DHCP | LOG_WARNING, _("inet_ntoa(mess->giaddr)=%s"),inet_ntoa(mess->giaddr));
-
- macEmpty = strstr(print_mac(daemon->namebuff, emac, emac_len), "<null>");
- if(s_ret == NULL && macEmpty == NULL){ //client MAC doesn't exist in mac table, means this client is newer
- strcpy(clientmac[dhcpclientnum], print_mac(daemon->namebuff, emac, emac_len));
- if(strcmp(daemon->dhcp_buff3, ""))
- strcpy(vendorid[dhcpclientnum], daemon->dhcp_buff3);
- else
- strcpy(vendorid[dhcpclientnum], "*");
- my_syslog(LOG_INFO, _("dhcp client number ++"));
- dhcpclientnum++; //means total number that connect to DHCP server
+ macEmpty = strstr(print_mac(daemon->namebuff, emac, emac_len), "<null>");
+ if(s_ret == NULL && macEmpty == NULL){ //client MAC doesn't exist in mac table, means this client is newer
+ strcpy(clientmac[dhcpclientnum], print_mac(daemon->namebuff, emac, emac_len));
+ if(strcmp(daemon->dhcp_buff3, ""))
+ strcpy(vendorid[dhcpclientnum], daemon->dhcp_buff3);
+ else
+ strcpy(vendorid[dhcpclientnum], "*");
+ my_syslog(LOG_INFO, _("dhcp client number ++"));
+ dhcpclientnum++; //means total number that connect to DHCP server
+ }
+ my_syslog(LOG_INFO, _("New Coming MAC Address = %s"), print_mac(daemon->namebuff, emac, emac_len));
+ my_syslog(LOG_INFO, _("current dhcpclientnum = %d"), dhcpclientnum);
+ }
+ }
+ else{ //DHCP packet don't have option 60
+ if(dhcpclientnum <= DHCP_CLIENT_NUM && 0<= dhcpclientnum){
+ for(j=0; j<dhcpclientnum; j++){
+ my_syslog(LOG_INFO, _("print_mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
+ my_syslog(LOG_INFO, _("clientmac[%d] = %s"), j, clientmac[j]);
+ s_ret = strstr(clientmac[j], print_mac(daemon->namebuff, emac, emac_len));
+ if(s_ret != NULL)
+ break;
+ }
+ my_syslog(LOG_INFO, _("s_ret = %s"), s_ret);
+ macEmpty = strstr(print_mac(daemon->namebuff, emac, emac_len), "<null>");
+ if(s_ret == NULL && macEmpty == NULL){
+ strcpy(clientmac[dhcpclientnum], print_mac(daemon->namebuff, emac, emac_len));
+ strcpy(vendorid[dhcpclientnum], "*");
+ my_syslog(LOG_INFO, _("dhcp client number ++"));
+ dhcpclientnum++;
+ }
+ my_syslog(LOG_INFO, _("New Coming MAC Address = %s"), print_mac(daemon->namebuff, emac, emac_len));
+ my_syslog(LOG_INFO, _("current dhcpclientnum = %d"), dhcpclientnum);
+ my_syslog(LOG_INFO, _("option 60 doesn't exist"));
+ }
}
- my_syslog(LOG_INFO, _("New Coming MAC Address = %s"), print_mac(daemon->namebuff, emac, emac_len));
- my_syslog(LOG_INFO, _("current dhcpclientnum = %d"), dhcpclientnum);
- }
- else{ //DHCP packet don't have option 60
- for(j=0; j<dhcpclientnum; j++){
- my_syslog(LOG_INFO, _("print_mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
- my_syslog(LOG_INFO, _("clientmac[%d] = %s"), j, clientmac[j]);
- s_ret = strstr(clientmac[j], print_mac(daemon->namebuff, emac, emac_len));
- if(s_ret != NULL)
- break;
- }
- my_syslog(LOG_INFO, _("s_ret = %s"), s_ret);
- macEmpty = strstr(print_mac(daemon->namebuff, emac, emac_len), "<null>");
- if(s_ret == NULL && macEmpty == NULL){
- strcpy(clientmac[dhcpclientnum], print_mac(daemon->namebuff, emac, emac_len));
- strcpy(vendorid[dhcpclientnum], "*");
- my_syslog(LOG_INFO, _("dhcp client number ++"));
- dhcpclientnum++;
- }
- my_syslog(LOG_INFO, _("New Coming MAC Address = %s"), print_mac(daemon->namebuff, emac, emac_len));
- my_syslog(LOG_INFO, _("current dhcpclientnum = %d"), dhcpclientnum);
- my_syslog(LOG_INFO, _("option 60 doesn't exist"));
- }
#endif
/* two things to note here: expand_buf may move the packet,
@@ -0,0 +1,242 @@
Index: dnsmasq-2.67/src/forward.c
===================================================================
--- dnsmasq-2.67.orig/src/forward.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/forward.c 2014-06-16 19:11:13.174681452 +0800
@@ -359,6 +359,12 @@
fd = start->sfd->fd;
else
{
+#ifdef ZYXEL_PATCH //reject query when special domain query has no socket
+ if(type == SERV_HAS_DOMAIN && hostname_isequal(domain, start->domain)){
+ my_syslog(LOG_WARNING, _("Reject query for %s"), start->domain);
+ break;
+ }
+#endif
#ifdef HAVE_IPV6
if (start->addr.sa.sa_family == AF_INET6)
{
Index: dnsmasq-2.67/src/network.c
===================================================================
--- dnsmasq-2.67.orig/src/network.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/network.c 2014-06-16 19:11:13.174681452 +0800
@@ -1031,8 +1031,14 @@
return 1;
}
+#ifdef ZYXEL_PATCH
+#define allocate_sfd(a, i) do_allocate_sfd(a, i, 0)
+#define allocate_sfd_mark(a, i, m) do_allocate_sfd(a, i, m)
+static struct serverfd *do_allocate_sfd(union mysockaddr *addr, char *intname, unsigned long mark)
+#else
static struct serverfd *allocate_sfd(union mysockaddr *addr, char *intname)
+#endif
{
struct serverfd *sfd;
int errsave;
@@ -1072,6 +1078,11 @@
free(sfd);
return NULL;
}
+#ifdef ZYXEL_PATCH
+ if(mark != 0) {
+ setsockopt(sfd->fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark));
+ }
+#endif
if (!local_bind(sfd->fd, addr, intname, 0) || !fix_fd(sfd->fd))
{
@@ -1120,7 +1131,11 @@
for (srv = daemon->servers; srv; srv = srv->next)
if (!(srv->flags & (SERV_LITERAL_ADDRESS | SERV_NO_ADDR | SERV_USE_RESOLV | SERV_NO_REBIND)) &&
+#ifdef ZYXEL_PATCH
+ !allocate_sfd_mark(&srv->source_addr, srv->interface, srv->sock_mark) &&
+#else
!allocate_sfd(&srv->source_addr, srv->interface) &&
+#endif
errno != 0 &&
option_bool(OPT_NOWILD))
{
@@ -1141,6 +1156,8 @@
struct irec *iface;
struct server *new, *tmp, *ret = NULL;
int port = 0;
+#ifdef ZYXEL_PATCH
+#endif
/* interface may be new since startup */
if (!option_bool(OPT_NOWILD))
@@ -1158,8 +1175,12 @@
if (new->addr.sa.sa_family == AF_INET &&
new->addr.in.sin_addr.s_addr == 0)
{
+#ifdef ZYXEL_PATCH // don't ignoring 0.0.0.0, for special reject query
+ goto SETTOLIST;
+#else
free(new);
continue;
+#endif
}
for (iface = daemon->interfaces; iface; iface = iface->next)
@@ -1174,17 +1195,25 @@
/* Do we need a socket set? */
if (!new->sfd &&
+#ifdef ZYXEL_PATCH
+ !(new->sfd = allocate_sfd_mark(&new->source_addr, new->interface, new->sock_mark)) &&
+#else
!(new->sfd = allocate_sfd(&new->source_addr, new->interface)) &&
+#endif
errno != 0)
{
my_syslog(LOG_WARNING,
_("ignoring nameserver %s - cannot make/bind socket: %s"),
daemon->namebuff, strerror(errno));
+#ifndef ZYXEL_PATCH //don't free special domain rule. for reject query
free(new);
continue;
+#endif
}
}
-
+#ifdef ZYXEL_PATCH
+SETTOLIST:
+#endif
/* reverse order - gets it right. */
new->next = ret;
ret = new;
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2014-06-16 19:11:13.154681452 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2014-06-16 19:11:13.178681452 +0800
@@ -443,6 +443,9 @@
struct server {
union mysockaddr addr, source_addr;
+#ifdef ZYXEL_PATCH
+ unsigned long sock_mark;
+#endif
char interface[IF_NAMESIZE+1];
struct serverfd *sfd;
char *domain; /* set if this server only handles a domain. */
@@ -1053,8 +1056,13 @@
void set_option_bool(unsigned int opt);
void reset_option_bool(unsigned int opt);
struct hostsfile *expand_filelist(struct hostsfile *list);
+#ifdef ZYXEL_PATCH
+char *parse_server(char *arg, union mysockaddr *addr,
+ union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark);
+#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags);
+#endif
/* forward.c */
void reply_query(int fd, int family, time_t now);
Index: dnsmasq-2.67/src/option.c
===================================================================
--- dnsmasq-2.67.orig/src/option.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/option.c 2014-06-16 19:13:01.399686700 +0800
@@ -555,7 +555,24 @@
return ret;
}
+#ifdef ZYXEL_PATCH
+static int hextoul_check(char *a, unsigned long *res)
+{
+ char *p;
+
+ if (!a)
+ return 0;
+ unhide_metas(a);
+
+ for (p = a; *p; p++)
+ if ( !((*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f')) )
+ return 0;
+
+ *res = strtoul(a, NULL, 16);
+ return 1;
+}
+#endif
static int atoi_check(char *a, int *res)
{
char *p;
@@ -656,8 +673,11 @@
}
#define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
-
+#ifdef ZYXEL_PATCH
+char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark)
+#else
char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags)
+#endif
{
int source_port = 0, serv_port = NAMESERVER_PORT;
char *portno, *source;
@@ -665,12 +685,21 @@
int scope_index = 0;
char *scope_id;
#endif
+#ifdef ZYXEL_PATCH
+ char *markPtr = NULL;
+ unsigned long sock_mark = 0;
+#endif
if ((source = split_chr(arg, '@')) && /* is there a source. */
(portno = split_chr(source, '#')) &&
!atoi_check16(portno, &source_port))
return _("bad port");
-
+#ifdef ZYXEL_PATCH
+ if (source && /* is there a source. */
+ (markPtr = split_chr(source, '$')) &&
+ !hextoul_check(markPtr, &sock_mark))
+ return _("bad mark");
+#endif
if ((portno = split_chr(arg, '#')) && /* is there a port no. */
!atoi_check16(portno, &serv_port))
return _("bad port");
@@ -691,6 +720,11 @@
if (source)
{
+#ifdef ZYXEL_PATCH
+ if(mark){
+ *mark = sock_mark;
+ }
+#endif
if (flags)
*flags |= SERV_HAS_SOURCE;
source_addr->in.sin_port = htons(source_port);
@@ -2104,7 +2138,11 @@
}
else
{
+#ifdef ZYXEL_PATCH
+ char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags, &newlist->sock_mark);
+#else
char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags);
+#endif
if (err)
ret_err(err);
}
Index: dnsmasq-2.67/src/dbus.c
===================================================================
--- dnsmasq-2.67.orig/src/dbus.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dbus.c 2014-06-16 19:11:13.178681452 +0800
@@ -416,7 +416,11 @@
memset(&interface, 0, sizeof(interface));
/* parse the IP address */
+#ifdef ZYXEL_PATCH
+ addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL, NULL);
+#else
addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL);
+#endif
if (addr_err)
{
@@ -0,0 +1,274 @@
Index: dnsmasq-2.67/src/dhcp-protocol.h
===================================================================
--- dnsmasq-2.67.orig/src/dhcp-protocol.h 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dhcp-protocol.h 2014-08-22 08:04:24.210432561 +0800
@@ -94,3 +94,19 @@
u8 chaddr[DHCP_CHADDR_MAX], sname[64], file[128];
u8 options[312];
};
+
+#ifdef ZYXEL_DHCP
+enum dhcp_option {
+ FLAG_OPTION_VENDOR_ID = 2, // OPTION 60
+ FLAG_OPTION_CLIENT_ID, // OPTION 61
+ FLAG_OPTION_VENDOR_IDENT_OPT // OPTION 125
+};
+
+#define SET_FLAG_OPTION_60(x) ((x) |= (1 << FLAG_OPTION_VENDOR_ID))
+#define SET_FLAG_OPTION_61(x) ((x) |= (1 << FLAG_OPTION_CLIENT_ID))
+#define SET_FLAG_OPTION_125(x) ((x) |= (1 << FLAG_OPTION_VENDOR_IDENT_OPT))
+
+#define CLIENT_HAVE_OPTION_60(x) ((x) & (1 << FLAG_OPTION_VENDOR_ID))
+#define CLIENT_HAVE_OPTION_61(x) ((x) & (1 << FLAG_OPTION_CLIENT_ID))
+#define CLIENT_HAVE_OPTION_125(x) ((x) & (1 << FLAG_OPTION_VENDOR_IDENT_OPT))
+#endif /* ZYXEL_DHCP */
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2014-08-22 07:51:27.746462288 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2014-08-22 08:04:36.506432090 +0800
@@ -1328,7 +1328,7 @@
#ifdef ZYXEL_DHCP
extern void dnsmasq_eid_register(void);
extern void handle_op125_request(unsigned char *oui,unsigned char *serial,unsigned char *pclass);
-extern void send_dhcp_option_request(char *ifName, char *vendorID, unsigned char *chaddr, char reply[]);
+extern void send_dhcp_option_request(char *ifName, char *vendorID, unsigned char *chaddr, unsigned char *oui, unsigned char *serial, unsigned char *pclass, char *opt61Val, char reply[]);
extern void handle_STB_Vendor_ID_request();
#endif
Index: dnsmasq-2.67/src/extern.c
===================================================================
--- dnsmasq-2.67.orig/src/extern.c 2014-08-22 07:51:27.690462290 +0800
+++ dnsmasq-2.67/src/extern.c 2014-08-22 08:05:11.258430759 +0800
@@ -91,31 +91,53 @@
}
-void send_dhcp_option_request(char *ifName, char *vendorID, unsigned char *chaddr, char reply[])
+void
+send_dhcp_option_request(
+ char *ifName,
+ char *vendorID,
+ unsigned char *chaddr,
+ unsigned char *oui,
+ unsigned char *serial,
+ unsigned char *pclass,
+ char *opt61Val,
+ char reply[]
+)
{
zcfgRet_t ret = 0;
dnsmasqOption_t dnsmasqInfo;
-
+
my_syslog(MS_DHCP | LOG_INFO, "%s ", __func__);
memset(&dnsmasqInfo, '\0', sizeof(dnsmasqInfo));
-
+
+ if(oui)
+ strncpy(dnsmasqInfo.ManufacturerOUI, (char *)(&oui[2]), oui[1]);
+
+ if(serial)
+ strncpy(dnsmasqInfo.SerialNumber, (char *)(&serial[2]), serial[1]);
+
+ if(pclass)
+ strncpy(dnsmasqInfo.ProductClass, (char *)(&pclass[2]), pclass[1]);
+
if(ifName)
strncpy(dnsmasqInfo.ifName, (char *)ifName, sizeof(dnsmasqInfo.ifName));
-
+
if(chaddr)
memcpy(dnsmasqInfo.chaddr, (char *)chaddr, 32);
-
+
if(vendorID)
strncpy(dnsmasqInfo.op60, (char *)vendorID, sizeof(dnsmasqInfo.op60));
+ if(opt61Val)
+ strncpy(dnsmasqInfo.op61, (char *)opt61Val, sizeof(dnsmasqInfo.op61));
+
/* send ZCFG_MSG_DHCPD_OPTION to ESMD for DHCP option */
ret = dnsmasq_msg_send(ZCFG_MSG_DHCPD_OPTION, sizeof(dnsmasqOption_t), (const char *)&dnsmasqInfo, reply);
my_syslog(MS_DHCP | LOG_INFO, "%s esmd reply=%s", __func__, reply);
-
+
if(ret != ZCFG_SUCCESS && ret != ZCFG_SUCCESS_AND_NO_REPLY){
my_syslog(MS_DHCP | LOG_ERR, "%s dnsmasq_msg_send fail,ret=%d", __func__, ret);
- strcpy(reply, "accept");//default pass any port any service
+ strcpy(reply, "accept");//default pass any port any service
}
}
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2014-08-22 07:51:27.734462289 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2014-08-22 08:08:27.534423245 +0800
@@ -100,10 +100,14 @@
unsigned char pxe_uuid[17];
unsigned char *oui = NULL, *serial = NULL, *class = NULL;
#ifdef ZYXEL_DHCP
+ unsigned int option_flag = 1; // always check MAC address
char *s_ret = NULL, *macEmpty = NULL;
+ int i;
int j;
char vendorId[256] = "";
char intfGrpOptionCheck[16] = "";
+ char opt61Val[256] = "\0";
+ char *p = NULL;
#endif
subnet_addr.s_addr = override.s_addr = 0;
@@ -130,61 +134,43 @@
mess_type = option_uint(opt, 0, 1);
#ifdef ZYXEL_DHCP
- if ((opt = option_find(mess, sz, OPTION_VENDOR_ID, 2))){ //get dhcp option 60
- if(dhcpclientnum <= DHCP_CLIENT_NUM && 0<= dhcpclientnum){
+ opt = option_find(mess, sz, OPTION_VENDOR_ID, 2);
+ if ( opt ) {
+ SET_FLAG_OPTION_60(option_flag);
+ }
+
+ if(dhcpclientnum <= DHCP_CLIENT_NUM && 0<= dhcpclientnum){
+ if ( CLIENT_HAVE_OPTION_60(option_flag) ) {
emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
vendor_class_len = option_len(opt);
memset(daemon->dhcp_buff3, '\0', strlen(daemon->dhcp_buff3));
memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
strncpy(vendorId, option_ptr(opt, 0), option_len(opt));
- for(j=0; j<dhcpclientnum; j++){
- my_syslog(LOG_INFO, _("print_mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
- my_syslog(LOG_INFO, _("clientmac[%d] = %s"), j, clientmac[j]);
- s_ret = strstr(clientmac[j], print_mac(daemon->namebuff, emac, emac_len)); //get client MAC Address
- if(s_ret != NULL) //client MAC already exist in mac table
- break;
- }
- my_syslog(LOG_INFO, _("s_ret = %s"), s_ret);
- my_syslog(LOG_INFO, _("daemon->dhcp_buff3 = %s"), vendorId);
- my_syslog(LOG_INFO, _("mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
- my_syslog(MS_DHCP | LOG_WARNING, _("iface_name=%s"), iface_name);
- my_syslog(MS_DHCP | LOG_WARNING, _("inet_ntoa(mess->giaddr)=%s"),inet_ntoa(mess->giaddr));
-
- macEmpty = strstr(print_mac(daemon->namebuff, emac, emac_len), "<null>");
- if(s_ret == NULL && macEmpty == NULL){ //client MAC doesn't exist in mac table, means this client is newer
- strcpy(clientmac[dhcpclientnum], print_mac(daemon->namebuff, emac, emac_len));
- if(strcmp(daemon->dhcp_buff3, ""))
- strcpy(vendorid[dhcpclientnum], daemon->dhcp_buff3);
- else
- strcpy(vendorid[dhcpclientnum], "*");
- my_syslog(LOG_INFO, _("dhcp client number ++"));
- dhcpclientnum++; //means total number that connect to DHCP server
- }
- my_syslog(LOG_INFO, _("New Coming MAC Address = %s"), print_mac(daemon->namebuff, emac, emac_len));
- my_syslog(LOG_INFO, _("current dhcpclientnum = %d"), dhcpclientnum);
}
- }
- else{ //DHCP packet don't have option 60
- if(dhcpclientnum <= DHCP_CLIENT_NUM && 0<= dhcpclientnum){
- for(j=0; j<dhcpclientnum; j++){
- my_syslog(LOG_INFO, _("print_mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
- my_syslog(LOG_INFO, _("clientmac[%d] = %s"), j, clientmac[j]);
- s_ret = strstr(clientmac[j], print_mac(daemon->namebuff, emac, emac_len));
- if(s_ret != NULL)
- break;
- }
- my_syslog(LOG_INFO, _("s_ret = %s"), s_ret);
- macEmpty = strstr(print_mac(daemon->namebuff, emac, emac_len), "<null>");
- if(s_ret == NULL && macEmpty == NULL){
- strcpy(clientmac[dhcpclientnum], print_mac(daemon->namebuff, emac, emac_len));
+
+ for(j=0; j<dhcpclientnum; j++){
+ my_syslog(LOG_INFO, _("print_mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
+ my_syslog(LOG_INFO, _("print_mac = %s len = %d"), print_mac(daemon->namebuff, emac, emac_len), emac_len);
+ my_syslog(LOG_INFO, _("clientmac[%d] = %s"), j, clientmac[j]);
+ s_ret = strstr(clientmac[j], print_mac(daemon->namebuff, emac, emac_len)); //get client MAC Address
+ if(s_ret != NULL) //client MAC already exist in mac table
+ break;
+ }
+
+ macEmpty = strstr(print_mac(daemon->namebuff, emac, emac_len), "<null>");
+ if(s_ret == NULL && macEmpty == NULL){
+ strcpy(clientmac[dhcpclientnum], print_mac(daemon->namebuff, emac, emac_len));
+ if ( CLIENT_HAVE_OPTION_60(option_flag) ) {
+ if(strcmp(daemon->dhcp_buff3, "")) strcpy(vendorid[dhcpclientnum], daemon->dhcp_buff3);
+ else strcpy(vendorid[dhcpclientnum], "*");
+ } else {
strcpy(vendorid[dhcpclientnum], "*");
- my_syslog(LOG_INFO, _("dhcp client number ++"));
- dhcpclientnum++;
}
- my_syslog(LOG_INFO, _("New Coming MAC Address = %s"), print_mac(daemon->namebuff, emac, emac_len));
- my_syslog(LOG_INFO, _("current dhcpclientnum = %d"), dhcpclientnum);
- my_syslog(LOG_INFO, _("option 60 doesn't exist"));
+ my_syslog(LOG_INFO, _("dhcp client number ++"));
+ dhcpclientnum++;
}
+ my_syslog(LOG_INFO, _("New Coming MAC Address = %s"), print_mac(daemon->namebuff, emac, emac_len));
+ my_syslog(LOG_INFO, _("current dhcpclientnum = %d"), dhcpclientnum);
}
#endif
@@ -229,7 +215,8 @@
class = option_find1(x, y, 3, 1);
#ifdef ZYXEL_DHCP /*save the DHCP option to Gateway , by charisse*/
- handle_op125_request( oui, serial, class);
+ SET_FLAG_OPTION_125(option_flag);
+ handle_op125_request(oui, serial, class);
#endif
/* If TR069-id is present set the tag "cpewan-id" to facilitate echoing
@@ -303,6 +290,17 @@
{
clid_len = option_len(opt);
clid = option_ptr(opt, 0);
+
+#ifdef ZYXEL_DHCP // for Interface Grouping Criteria
+ /* only for type2 "ff $IAID 0002 $DUID" */
+ if ( clid_len < 255 ) {
+ SET_FLAG_OPTION_61(option_flag);
+ p = opt61Val;
+ for ( i = 0 ; i < clid_len ; i++ ) {
+ p += sprintf(p, "%X", *(clid+i));
+ }
+ }
+#endif
}
/* do we have a lease in store? */
@@ -982,20 +980,23 @@
#ifdef ZYXEL_DHCP
my_syslog(LOG_INFO, _("mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
-
+
my_syslog(MS_DHCP | LOG_WARNING, _("iface_name=%s"), iface_name);
my_syslog(MS_DHCP | LOG_WARNING, _("vendorId=%s"), vendorId);
- /*send option 60 information for any port any service*/
-if(strcmp(vendorId, "")){
- send_dhcp_option_request(iface_name, vendorId, emac, intfGrpOptionCheck);
-my_syslog(MS_DHCP | LOG_WARNING, _("intfGrpOptionCheck=%s"), intfGrpOptionCheck);
- /*check interface grouping creteria*/
- if((intfGrpOptionCheck != NULL) && (strcmp(intfGrpOptionCheck, ""))){
- if(!strcmp(intfGrpOptionCheck, "decline") || !strcmp(intfGrpOptionCheck, "redirect"))
- return 0;
- }
-}
+ /*send DHCP option information for any port any service*/
+ if ( option_flag ) {
+ //unsigned char *oui = NULL, *serial = NULL, *class = NULL;
+ send_dhcp_option_request(iface_name, vendorId, emac, oui, serial, class, opt61Val, intfGrpOptionCheck);
+ my_syslog(MS_DHCP | LOG_WARNING, _("intfGrpOptionCheck=%s"), intfGrpOptionCheck);
+
+ /*check interface grouping creteria*/
+ if((intfGrpOptionCheck != NULL) && (strcmp(intfGrpOptionCheck, ""))){
+ if(!strcmp(intfGrpOptionCheck, "decline") || !strcmp(intfGrpOptionCheck, "redirect")) {
+ return 0;
+ }
+ }
+ }
#endif
switch (mess_type)
@@ -0,0 +1,216 @@
diff -Naur dnsmasq-2.67.orig/src/cache.c dnsmasq-2.67/src/cache.c
--- dnsmasq-2.67.orig/src/cache.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/cache.c 2014-08-29 15:43:07.109749700 +0800
@@ -512,12 +512,70 @@
return new;
}
+#ifdef DNS_TRAFFIC_ROUTE
+add_dns_traffic_route(uint32_t s_addr, const char *cname, int *flush)
+{
+ char sysCmd[128] = "";
+ struct in_addr srcIP;
+ srcIP.s_addr = s_addr;
+ struct server *serv = NULL;
+
+ if(s_addr == 0){
+ return;
+ }
+
+ serv = daemon->servers;
+
+ while(serv){
+ if(serv->domain && (strcmp(cname, serv->domain) == 0)){
+ if(*flush){
+ /* deledt */
+ sprintf(sysCmd, "iptables -t mangle -D IP_ROUTE2_DNSRT -j DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ sprintf(sysCmd, "iptables -t mangle -F DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ sprintf(sysCmd, "iptables -t mangle -X DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ /* create */
+ sprintf(sysCmd, "iptables -t mangle -N DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ sprintf(sysCmd, "iptables -t mangle -A IP_ROUTE2_DNSRT -j DNSRT_RULE_%d", serv->rule_no);
+ system(sysCmd);
+
+ *flush = 0;
+ }
+
+ /* add */
+ sprintf(sysCmd, "iptables -t mangle -D DNSRT_RULE_%d -d %s/%d -j MARK --or-mark 0x%x 2> /dev/null",
+ serv->rule_no, inet_ntoa(srcIP), serv->subnet_mask, serv->sock_mark);
+ system(sysCmd);
+
+ sprintf(sysCmd, "iptables -t mangle -A DNSRT_RULE_%d -d %s/%d -j MARK --or-mark 0x%x",
+ serv->rule_no, inet_ntoa(srcIP), serv->subnet_mask, serv->sock_mark);
+ system(sysCmd);
+
+ break;
+ }
+ serv = serv->next;
+ }
+}
+#endif
+
/* after end of insertion, commit the new entries */
void cache_end_insert(void)
{
+#ifdef DNS_TRAFFIC_ROUTE
+ struct in_addr *target = NULL;
+ int flush = 1;
+#endif
+
if (insert_error)
return;
-
+
while (new_chain)
{
struct crec *tmp = new_chain->next;
@@ -529,6 +587,15 @@
cache_hash(new_chain);
cache_link(new_chain);
cache_inserted++;
+#ifdef DNS_TRAFFIC_ROUTE
+ if((new_chain->flags & (F_FORWARD|F_IPV4)) == (F_FORWARD|F_IPV4)){
+ target = &new_chain->addr.addr.addr.addr4;
+ }
+
+ if(target){
+ add_dns_traffic_route(target->s_addr, cache_get_name(new_chain), &flush);
+ }
+#endif
}
new_chain = tmp;
}
diff -Naur dnsmasq-2.67.orig/src/dbus.c dnsmasq-2.67/src/dbus.c
--- dnsmasq-2.67.orig/src/dbus.c 2014-08-23 02:22:30.903783200 +0800
+++ dnsmasq-2.67/src/dbus.c 2014-08-29 15:37:40.543527100 +0800
@@ -416,8 +416,12 @@
memset(&interface, 0, sizeof(interface));
/* parse the IP address */
-#ifdef ZYXEL_PATCH
+#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+ addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL, NULL, NULL, NULL);
+#else
addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL, NULL);
+#endif
#else
addr_err = parse_server(str_addr, &addr, &source_addr, (char *) &interface, NULL);
#endif
diff -Naur dnsmasq-2.67.orig/src/dnsmasq.h dnsmasq-2.67/src/dnsmasq.h
--- dnsmasq-2.67.orig/src/dnsmasq.h 2014-08-23 02:22:30.903783200 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2014-08-29 15:38:13.274434400 +0800
@@ -445,6 +445,10 @@
union mysockaddr addr, source_addr;
#ifdef ZYXEL_PATCH
unsigned long sock_mark;
+#ifdef DNS_TRAFFIC_ROUTE
+ int subnet_mask;
+ int rule_no;
+#endif
#endif
char interface[IF_NAMESIZE+1];
struct serverfd *sfd;
@@ -1057,8 +1061,14 @@
void reset_option_bool(unsigned int opt);
struct hostsfile *expand_filelist(struct hostsfile *list);
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+char *parse_server(char *arg, union mysockaddr *addr,
+ union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark,
+ int *subnet_mask, int *rule_no);
+#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark);
+#endif
#else
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags);
diff -Naur dnsmasq-2.67.orig/src/option.c dnsmasq-2.67/src/option.c
--- dnsmasq-2.67.orig/src/option.c 2014-08-23 02:22:30.903783200 +0800
+++ dnsmasq-2.67/src/option.c 2014-08-29 15:45:11.313805300 +0800
@@ -674,7 +674,11 @@
#define ret_err(x) do { strcpy(errstr, (x)); return 0; } while (0)
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark, int *subnet_mask, int *rule_no)
+#else
char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags, unsigned long *mark)
+#endif
#else
char *parse_server(char *arg, union mysockaddr *addr, union mysockaddr *source_addr, char *interface, int *flags)
#endif
@@ -688,6 +692,12 @@
#ifdef ZYXEL_PATCH
char *markPtr = NULL;
unsigned long sock_mark = 0;
+#ifdef DNS_TRAFFIC_ROUTE
+ char *maskPtr = NULL;
+ int mask = 32;
+ char *rulePtr = NULL;
+ int rule = 0;
+#endif
#endif
if ((source = split_chr(arg, '@')) && /* is there a source. */
@@ -695,10 +705,20 @@
!atoi_check16(portno, &source_port))
return _("bad port");
#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+ if (source && /* is there a source. */
+ (rulePtr = split_chr(source, '|')) &&
+ !atoi_check(rulePtr, &rule))
+ return _("bad rule");
+ if (source && /* is there a source. */
+ (maskPtr = split_chr(source, '&')) &&
+ !atoi_check(maskPtr, &mask))
+ return _("bad mask");
+#endif
if (source && /* is there a source. */
(markPtr = split_chr(source, '$')) &&
!hextoul_check(markPtr, &sock_mark))
- return _("bad mark");
+ return _("bad mark");
#endif
if ((portno = split_chr(arg, '#')) && /* is there a port no. */
!atoi_check16(portno, &serv_port))
@@ -724,6 +744,14 @@
if(mark){
*mark = sock_mark;
}
+#ifdef DNS_TRAFFIC_ROUTE
+ if(subnet_mask){
+ *subnet_mask = mask;
+ }
+ if(rule_no){
+ *rule_no = rule;
+ }
+#endif
#endif
if (flags)
*flags |= SERV_HAS_SOURCE;
@@ -2138,8 +2166,12 @@
}
else
{
-#ifdef ZYXEL_PATCH
+#ifdef ZYXEL_PATCH
+#ifdef DNS_TRAFFIC_ROUTE
+ char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags, &newlist->sock_mark, &newlist->subnet_mask, &newlist->rule_no);
+#else
char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags, &newlist->sock_mark);
+#endif
#else
char *err = parse_server(arg, &newlist->addr, &newlist->source_addr, newlist->interface, &newlist->flags);
#endif
@@ -0,0 +1,285 @@
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2014-09-19 15:33:29.030222780 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2014-09-19 15:37:49.262876588 +0800
@@ -234,7 +234,7 @@
#ifdef ZYXEL_DHCP
#define DHCP_CLIENT_NUM 34
- #define VENDORID_LENGTH 100
+ #define VENDORID_LENGTH 256
#define MAC_LENGTH 18
#endif
@@ -565,6 +565,7 @@
unsigned char *extradata;
unsigned int extradata_len, extradata_size;
int last_interface;
+ char vendorid[VENDORID_LENGTH];
#ifdef HAVE_DHCP6
struct in6_addr addr6;
int iaid;
@@ -1023,6 +1024,11 @@
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2);
int hostname_isequal(const char *a, const char *b);
time_t dnsmasq_time(void);
+#ifdef ZYXEL_DHCP
+#include <sys/sysinfo.h>
+struct sysinfo sysinfoObject;
+unsigned long getUptime();
+#endif
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask);
#ifdef HAVE_IPV6
int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen);
@@ -1150,6 +1156,9 @@
void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth, char *domain, char *config_domain);
void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now);
void lease_set_interface(struct dhcp_lease *lease, int interface, time_t now);
+#ifdef ZYXEL_DHCP
+void lease_set_vendorid(struct dhcp_lease *lease, char *vendorid);
+#endif
struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int hw_type,
unsigned char *clid, int clid_len);
struct dhcp_lease *lease_find_by_addr(struct in_addr addr);
Index: dnsmasq-2.67/src/lease.c
===================================================================
--- dnsmasq-2.67.orig/src/lease.c 2014-09-19 15:33:28.962222780 +0800
+++ dnsmasq-2.67/src/lease.c 2014-09-19 15:41:15.055235889 +0800
@@ -18,11 +18,6 @@
#ifdef HAVE_DHCP
-#ifdef ZYXEL_DHCP
-extern char vendorid[DHCP_CLIENT_NUM][VENDORID_LENGTH];
-extern int dhcpclientnum;
-#endif
-
static struct dhcp_lease *leases = NULL, *old_leases = NULL;
static int dns_dirty, file_dirty, leases_left;
@@ -219,10 +214,8 @@
struct dhcp_lease *lease;
time_t next_event;
int i, err = 0;
-#ifdef ZYXEL_DHCP
- int j = 0;
-#endif
+ my_syslog(LOG_INFO, _("%s(): file_dirty = %d"), __FUNCTION__, file_dirty);
if (file_dirty != 0 && daemon->lease_stream)
{
errno = 0;
@@ -268,15 +261,8 @@
ourprintf(&err, "* ");
#ifdef ZYXEL_DHCP
- if(dhcpclientnum > 0 && dhcpclientnum <= DHCP_CLIENT_NUM && (dhcpclientnum - j - 1) >= 0){//work around, need to modify method of get vendor id
- my_syslog(LOG_INFO, _("dhcpclientnum = %d"), dhcpclientnum);
- my_syslog(LOG_INFO, _("j = %d , Vendor-ID = %s"), j, vendorid[dhcpclientnum - j - 1]);
- ourprintf(&err, "%s\n", vendorid[dhcpclientnum - j - 1]);
- j++;
- }
- else{
- ourprintf(&err, "%s\n", "* ");
- }
+ ourprintf(&err, "%s\n", lease->vendorid);
+ my_syslog(LOG_INFO, _("lease->vendorid = %s"), lease->vendorid);
#endif
}
@@ -528,8 +514,9 @@
leases_left++;
}
- else
- up = &lease->next;
+ else{
+ up = &lease->next;
+ }
}
}
@@ -990,6 +977,15 @@
#endif
}
+#ifdef ZYXEL_DHCP
+void lease_set_vendorid(struct dhcp_lease *lease, char *vendorid)
+{
+ my_syslog(LOG_INFO, _("%s(): vendorid = %s"), __FUNCTION__, vendorid);
+ strcpy(lease->vendorid, vendorid);
+ file_dirty = 1;
+}
+#endif
+
void rerun_scripts(void)
{
struct dhcp_lease *lease;
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2014-09-19 15:33:29.018222780 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2014-09-19 15:43:48.248164653 +0800
@@ -18,12 +18,6 @@
#ifdef HAVE_DHCP
-#ifdef ZYXEL_DHCP
-char vendorid[DHCP_CLIENT_NUM][VENDORID_LENGTH] = {};
-char clientmac[DHCP_CLIENT_NUM][MAC_LENGTH] = {};
-int dhcpclientnum = 0;
-#endif
-
#define option_len(opt) ((int)(((unsigned char *)(opt))[1]))
#define option_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[2u+(unsigned int)(i)]))
@@ -101,13 +95,11 @@
unsigned char *oui = NULL, *serial = NULL, *class = NULL;
#ifdef ZYXEL_DHCP
unsigned int option_flag = 1; // always check MAC address
- char *s_ret = NULL, *macEmpty = NULL;
- int i;
- int j;
char vendorId[256] = "";
char intfGrpOptionCheck[16] = "";
char opt61Val[256] = "\0";
char *p = NULL;
+ int i=0;
#endif
subnet_addr.s_addr = override.s_addr = 0;
@@ -135,42 +127,16 @@
#ifdef ZYXEL_DHCP
opt = option_find(mess, sz, OPTION_VENDOR_ID, 2);
- if ( opt ) {
+ if(opt){
SET_FLAG_OPTION_60(option_flag);
}
- if(dhcpclientnum <= DHCP_CLIENT_NUM && 0<= dhcpclientnum){
- if ( CLIENT_HAVE_OPTION_60(option_flag) ) {
- emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
- vendor_class_len = option_len(opt);
- memset(daemon->dhcp_buff3, '\0', strlen(daemon->dhcp_buff3));
- memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
- strncpy(vendorId, option_ptr(opt, 0), option_len(opt));
- }
-
- for(j=0; j<dhcpclientnum; j++){
- my_syslog(LOG_INFO, _("print_mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
- my_syslog(LOG_INFO, _("print_mac = %s len = %d"), print_mac(daemon->namebuff, emac, emac_len), emac_len);
- my_syslog(LOG_INFO, _("clientmac[%d] = %s"), j, clientmac[j]);
- s_ret = strstr(clientmac[j], print_mac(daemon->namebuff, emac, emac_len)); //get client MAC Address
- if(s_ret != NULL) //client MAC already exist in mac table
- break;
- }
-
- macEmpty = strstr(print_mac(daemon->namebuff, emac, emac_len), "<null>");
- if(s_ret == NULL && macEmpty == NULL){
- strcpy(clientmac[dhcpclientnum], print_mac(daemon->namebuff, emac, emac_len));
- if ( CLIENT_HAVE_OPTION_60(option_flag) ) {
- if(strcmp(daemon->dhcp_buff3, "")) strcpy(vendorid[dhcpclientnum], daemon->dhcp_buff3);
- else strcpy(vendorid[dhcpclientnum], "*");
- } else {
- strcpy(vendorid[dhcpclientnum], "*");
- }
- my_syslog(LOG_INFO, _("dhcp client number ++"));
- dhcpclientnum++;
- }
- my_syslog(LOG_INFO, _("New Coming MAC Address = %s"), print_mac(daemon->namebuff, emac, emac_len));
- my_syslog(LOG_INFO, _("current dhcpclientnum = %d"), dhcpclientnum);
+ if(CLIENT_HAVE_OPTION_60(option_flag)){
+ emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
+ vendor_class_len = option_len(opt);
+ memset(daemon->dhcp_buff3, '\0', strlen(daemon->dhcp_buff3));
+ memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
+ strncpy(vendorId, option_ptr(opt, 0), option_len(opt));
}
#endif
@@ -675,7 +641,12 @@
have_config(config, CONFIG_TIME) ? config->lease_time : 0xffffffff,
now);
lease_set_interface(lease, int_index, now);
-
+#ifdef ZYXEL_DHCP
+ if(strcmp(daemon->dhcp_buff3, ""))
+ lease_set_vendorid(lease, daemon->dhcp_buff3);
+ else
+ lease_set_vendorid(lease, "*");
+#endif
clear_packet(mess, end);
do_options(context, mess, end, NULL, hostname, get_domain(mess->yiaddr),
netid, subnet_addr, 0, 0, -1, NULL, vendor_class_len, now);
@@ -980,9 +951,7 @@
#ifdef ZYXEL_DHCP
my_syslog(LOG_INFO, _("mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
-
my_syslog(MS_DHCP | LOG_WARNING, _("iface_name=%s"), iface_name);
- my_syslog(MS_DHCP | LOG_WARNING, _("vendorId=%s"), vendorId);
/*send DHCP option information for any port any service*/
if ( option_flag ) {
@@ -1441,10 +1410,15 @@
if (hostname)
lease_set_hostname(lease, hostname, hostname_auth, get_domain(lease->addr), domain);
-
+
lease_set_expires(lease, time, now);
lease_set_interface(lease, int_index, now);
-
+#ifdef ZYXEL_DHCP
+ if(strcmp(daemon->dhcp_buff3, ""))
+ lease_set_vendorid(lease, daemon->dhcp_buff3);
+ else
+ lease_set_vendorid(lease, "*");
+#endif
if (override.s_addr != 0)
lease->override = override;
else
@@ -1576,7 +1550,7 @@
static unsigned int calc_time(struct dhcp_context *context, struct dhcp_config *config, unsigned char *opt)
{
unsigned int time = have_config(config, CONFIG_TIME) ? config->lease_time : context->lease_time;
-
+
if (opt)
{
unsigned int req_time = option_uint(opt, 0, 4);
Index: dnsmasq-2.67/src/util.c
===================================================================
--- dnsmasq-2.67.orig/src/util.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/util.c 2014-09-19 15:37:54.297381304 +0800
@@ -302,7 +302,14 @@
return 1;
}
-
+#ifdef ZYXEL_DHCP
+unsigned long getUptime()
+{
+ sysinfo(&sysinfoObject);
+ return sysinfoObject.uptime;
+}
+#endif
+
time_t dnsmasq_time(void)
{
#ifdef HAVE_BROKEN_RTC
@@ -314,7 +321,13 @@
return (time_t)(times(&dummy)/tps);
#else
- return time(NULL);
+
+#ifdef ZYXEL_DHCP
+ return (time_t)getUptime();
+#else
+ return time(NULL);
+#endif
+
#endif
}
@@ -0,0 +1,162 @@
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2014-12-19 13:35:24.156204774 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2014-12-19 13:37:10.280636391 +0800
@@ -699,6 +699,12 @@
struct dhcp_mac *next;
};
+struct dhcp_ifname {
+ char ifname[IF_NAMESIZE];
+ struct dhcp_netid netid;
+ struct dhcp_ifname *next;
+};
+
struct dhcp_bridge {
char iface[IF_NAMESIZE];
struct dhcp_bridge *alias, *next;
@@ -935,6 +941,7 @@
/* utility string buffer, hold max sized IP address as string */
char *addrbuff;
+ struct dhcp_ifname *dhcp_ifnames;
} *daemon;
Index: dnsmasq-2.67/src/option.c
===================================================================
--- dnsmasq-2.67.orig/src/option.c 2014-12-19 13:35:24.148204774 +0800
+++ dnsmasq-2.67/src/option.c 2014-12-19 13:37:55.579230477 +0800
@@ -138,6 +138,7 @@
#define LOPT_QUIET_DHCP 326
#define LOPT_QUIET_DHCP6 327
#define LOPT_QUIET_RA 328
+#define LOPT_SUBNET 329
#ifdef HAVE_GETOPT_LONG
@@ -282,6 +283,7 @@
{ "quiet-dhcp", 0, 0, LOPT_QUIET_DHCP },
{ "quiet-dhcp6", 0, 0, LOPT_QUIET_DHCP6 },
{ "quiet-ra", 0, 0, LOPT_QUIET_RA },
+ { "dhcp-ifname", 1, 0, LOPT_SUBNET},
{ NULL, 0, 0, 0 }
};
@@ -431,6 +433,7 @@
{ LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL },
{ LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL },
{ LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL },
+ { LOPT_SUBNET, ARG_DUP, "set:<tag>,<ifname>", gettext_noop("Map interface name to option set."), NULL },
{ 0, 0, NULL, NULL, NULL }
};
@@ -3122,6 +3125,23 @@
}
}
break;
+
+ case LOPT_SUBNET: /* --dhcp-ifname */
+ {
+ if (!(comma = split(arg)))
+ ret_err(gen_err);
+ else
+ {
+ struct dhcp_ifname *new = opt_malloc(sizeof(struct dhcp_ifname));
+ new->netid.net = opt_string_alloc(set_prefix(arg));
+ arg = comma;
+ strcpy(new->ifname, arg);
+
+ new->next = daemon->dhcp_ifnames;
+ daemon->dhcp_ifnames = new;
+ }
+ }
+ break;
#ifdef OPTION6_PREFIX_CLASS
case LOPT_PREF_CLSS: /* --dhcp-prefix-class */
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2014-12-19 13:35:24.156204774 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2014-12-19 13:38:27.267217191 +0800
@@ -61,6 +61,7 @@
static int prune_vendor_opts(struct dhcp_netid *netid);
static struct dhcp_opt *pxe_opts(int pxe_arch, struct dhcp_netid *netid, struct in_addr local, time_t now);
struct dhcp_boot *find_boot(struct dhcp_netid *netid);
+static int find_ifname(unsigned char *subnet_mac, int len, char *ifname, char *interface);
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
@@ -70,6 +71,7 @@
struct dhcp_lease *ltmp, *lease = NULL;
struct dhcp_vendor *vendor;
struct dhcp_mac *mac;
+ struct dhcp_ifname *ifname;
struct dhcp_netid_list *id_list;
int clid_len = 0, ignore = 0, do_classes = 0, selecting = 0, pxearch = -1;
struct dhcp_packet *mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
@@ -283,7 +285,15 @@
/* find mac to use for logging and hashing */
emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
}
-
+
+ for (ifname = daemon->dhcp_ifnames; ifname; ifname = ifname->next){
+
+ if(find_ifname(mess->chaddr, mess->hlen, ifname->ifname, iface_name)){
+ ifname->netid.next = netid;
+ netid = &ifname->netid;
+ }
+ }
+
for (mac = daemon->dhcp_macs; mac; mac = mac->next)
if (mac->hwaddr_len == mess->hlen &&
(mac->hwaddr_type == mess->htype || mac->hwaddr_type == 0) &&
@@ -292,7 +302,7 @@
mac->netid.next = netid;
netid = &mac->netid;
}
-
+
/* Determine network for this packet. Our caller will have already linked all the
contexts which match the addresses of the receiving interface but if the
machine has an address already, or came via a relay, or we have a subnet selector,
@@ -2188,6 +2198,38 @@
return boot;
}
+static int find_ifname(unsigned char *subnet_mac, int len, char *ifname, char *interface)
+{
+ FILE *fp;
+ char sysCmd[128] = {0};
+ char line[128] = {0};
+
+ int sub_mac_idx = 0;
+ char mac_value[32]={0};
+
+ for(sub_mac_idx = 0 ; sub_mac_idx < len ; sub_mac_idx++){
+ if(0 == sub_mac_idx){
+ sprintf(mac_value, "%02x", subnet_mac[sub_mac_idx]);
+ }else{
+ sprintf(mac_value, "%s:%02x", mac_value, subnet_mac[sub_mac_idx]);
+ }
+ }
+
+ sprintf(sysCmd, "brctl showmacs %s | grep %s", interface, mac_value);
+ fp = popen(sysCmd, "r");
+
+ if(fp){
+ while(fgets(line, sizeof(line), fp) != NULL){
+ if(strstr(line, ifname) != NULL){
+ pclose(fp);
+ return 1;
+ }
+ }
+ pclose(fp);
+ }
+ return 0;
+}
+
static void do_options(struct dhcp_context *context,
struct dhcp_packet *mess,
unsigned char *end,
@@ -0,0 +1,101 @@
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2015-01-26 10:34:56.552910177 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2015-01-26 10:34:56.560910177 +0800
@@ -1349,5 +1349,7 @@
extern void handle_op125_request(unsigned char *oui,unsigned char *serial,unsigned char *pclass);
extern void send_dhcp_option_request(char *ifName, char *vendorID, unsigned char *chaddr, unsigned char *oui, unsigned char *serial, unsigned char *pclass, char *opt61Val, char reply[]);
extern void handle_STB_Vendor_ID_request();
+//__ZYXEL__, Chi-Hsiang Auto reserve IP for the same host.
+int handle_Auto_Reserve_IP_request(int payloadLen, const char *payload);
#endif
Index: dnsmasq-2.67/src/extern.c
===================================================================
--- dnsmasq-2.67.orig/src/extern.c 2015-01-26 10:34:56.492910178 +0800
+++ dnsmasq-2.67/src/extern.c 2015-01-26 10:34:56.560910177 +0800
@@ -152,4 +152,16 @@
my_syslog(MS_DHCP | LOG_ERR, "%s ZCFG_MSG_STB_VENDOR_ID_FIND fail,ret=%d", __func__, ret);
}
+
+#if 1//__ZYXEL__, Chi-Hsiang Auto reserve IP for the same host.
+int handle_Auto_Reserve_IP_request(int payloadLen, const char *payload)
+{
+ zcfgRet_t ret;
+ ret = dnsmasq_msg_send(ZCFG_MSG_AUTO_RSV_IP, payloadLen, (const char*)payload, NULL);
+
+ if(ret != ZCFG_SUCCESS && ret != ZCFG_SUCCESS_AND_NO_REPLY)
+ my_syslog(MS_DHCP | LOG_ERR, "%s ZCFG_MSG_AUTO_RSV_IP fail,ret=%d", __func__, ret);
+
+}
+#endif
#endif
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2015-01-26 10:34:56.552910177 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2015-01-26 11:12:31.253814935 +0800
@@ -1441,6 +1441,63 @@
netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
}
+#if 1//__ZYXEL__, Chi-Hsiang Auto reserve IP for the same host.
+ char payload[128] = {};
+ int payloadLen = 0;
+ char str[INET_ADDRSTRLEN]={};
+ char buf[]={};
+/*parse to json format
+/{"ifName":"br0","chAddr":"00:1a:92:e4:a1:81","yiAddr":"192.168.1.123","OPT61":"","OPT12":"hostname","OPT60":""}
+/ dnsmasq_info already contain opt60/opt61, skip here.
+*/
+ inet_ntop( AF_INET, &mess->yiaddr, str, INET_ADDRSTRLEN);
+ sprintf( buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+ mess->chaddr[0], mess->chaddr[1], mess->chaddr[2], mess->chaddr[3], mess->chaddr[4], mess->chaddr[5]);
+ /*
+ char *optCI = option_find(mess, sz, OPTION_CLIENT_ID, 2);
+ char *optVCI = option_find(mess, sz, OPTION_VENDOR_IDENT, 1);
+ char tmpCI[]={};
+ char tmpVCI[]={};
+ */
+ strcat(payload, "{\"ifName\":\"");
+ strcat(payload, iface_name);
+ strcat(payload, "\",");
+ strcat(payload, "\"chAddr\":\"");
+ strcat(payload, buf);
+ strcat(payload, "\",");
+ strcat(payload, "\"yiAddr\":\"");
+ strcat(payload, str);
+ //strcat(payload, "\",");
+ /*
+ strcat(payload, "\"OPT61\":\"");
+
+ while(optCI){
+ sprintf(tmpCI[i], "%c", *optCI);
+ optCI++;
+ }
+ strcat(payload, tmpCI);
+ strcat(payload, "\",");
+
+
+ strcat(payload, "\"OPT12\":\"");
+ strcat(payload, hostname);
+
+
+ strcat(payload, "\",");
+ strcat(payload, "\"OPT60\":\"");
+
+ while(optVCI){
+ sprintf(tmpVCI[i], "%c", *optVCI);
+ optVCI++;
+ }
+ strcat(payload, tmpVCI);
+ */
+ strcat(payload, "\"}");
+
+ payloadLen=strlen(payload)+1;
+ handle_Auto_Reserve_IP_request(payloadLen, payload);
+#endif
+
return dhcp_packet_size(mess, agent_id, real_end);
case DHCPINFORM:
@@ -0,0 +1,124 @@
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2015-05-08 11:03:05.350805773 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2015-05-08 11:04:40.308376221 +0800
@@ -1435,6 +1435,48 @@
override = lease->override;
log_packet("DHCPACK", &mess->yiaddr, emac, emac_len, iface_name, hostname, NULL, mess->xid);
+#if 1 //__ZYXEL__, Chi-Hsiang send message to esmd
+ char buf[1024] = {0};
+ int payloadLen = 0, i;
+ char *payload = buf;
+ char str[INET_ADDRSTRLEN+1]={};
+ unsigned char *optTmp = NULL;
+
+/*parse to json format
+/{"ifName":"br0","chAddr":"00:1a:92:e4:a1:81","yiAddr":"192.168.1.123","OPT61":"","OPT12":"hostname","OPT60":""}
+/ dnsmasq_info already contain opt60/opt61, skip here.
+*/
+ payload += sprintf(payload, "{\"ifName\":\"%s\"" ,iface_name);
+ payload += sprintf(payload, ",\"chAddr\":\"%02X:%02X:%02X:%02X:%02X:%02X\"",
+ mess->chaddr[0], mess->chaddr[1], mess->chaddr[2], mess->chaddr[3], mess->chaddr[4], mess->chaddr[5]);
+ inet_ntop( AF_INET, &mess->yiaddr, str, INET_ADDRSTRLEN);
+ payload += sprintf(payload, ",\"yiAddr\":\"%s\"", str);
+
+ if((optTmp = option_find(mess, sz, OPTION_CLIENT_ID, 2))){
+ payload += sprintf(payload, ",\"OPT61\":\"");
+ payload += sprintf(payload, "%.2x", *((unsigned char*)option_ptr(optTmp, 0)));
+ for(i=1;i<option_len(optTmp);i++){
+ payload += sprintf(payload, ":%.2x", *((unsigned char*)option_ptr(optTmp, i)));
+ }
+ payload += sprintf(payload, "\"");
+ }
+
+ if((optTmp = option_find(mess, sz, OPTION_VENDOR_ID, 1))){
+ payload += sprintf(payload, ",\"OPT60\":\"");
+ memcpy(payload, option_ptr(optTmp, 0), option_len(optTmp));
+ payload += option_len(optTmp);
+ payload += sprintf(payload, "\"");
+ }
+
+ if(hostname){
+ payload += sprintf(payload, ",\"OPT12\":\"%s\"", hostname);
+ }
+ payload += sprintf(payload, "}");
+
+ payloadLen=payload - buf +1;
+ handle_Auto_Reserve_IP_request(payloadLen, buf);
+#endif
+
clear_packet(mess, end);
option_put(mess, end, OPTION_MESSAGE_TYPE, 1, DHCPACK);
@@ -1451,63 +1493,6 @@
netid, subnet_addr, fqdn_flags, borken_opt, pxearch, uuid, vendor_class_len, now);
}
-#if 1//__ZYXEL__, Chi-Hsiang Auto reserve IP for the same host.
- char payload[128] = {};
- int payloadLen = 0;
- char str[INET_ADDRSTRLEN]={};
- char buf[]={};
-/*parse to json format
-/{"ifName":"br0","chAddr":"00:1a:92:e4:a1:81","yiAddr":"192.168.1.123","OPT61":"","OPT12":"hostname","OPT60":""}
-/ dnsmasq_info already contain opt60/opt61, skip here.
-*/
- inet_ntop( AF_INET, &mess->yiaddr, str, INET_ADDRSTRLEN);
- sprintf( buf, "%02X:%02X:%02X:%02X:%02X:%02X",
- mess->chaddr[0], mess->chaddr[1], mess->chaddr[2], mess->chaddr[3], mess->chaddr[4], mess->chaddr[5]);
- /*
- char *optCI = option_find(mess, sz, OPTION_CLIENT_ID, 2);
- char *optVCI = option_find(mess, sz, OPTION_VENDOR_IDENT, 1);
- char tmpCI[]={};
- char tmpVCI[]={};
- */
- strcat(payload, "{\"ifName\":\"");
- strcat(payload, iface_name);
- strcat(payload, "\",");
- strcat(payload, "\"chAddr\":\"");
- strcat(payload, buf);
- strcat(payload, "\",");
- strcat(payload, "\"yiAddr\":\"");
- strcat(payload, str);
- //strcat(payload, "\",");
- /*
- strcat(payload, "\"OPT61\":\"");
-
- while(optCI){
- sprintf(tmpCI[i], "%c", *optCI);
- optCI++;
- }
- strcat(payload, tmpCI);
- strcat(payload, "\",");
-
-
- strcat(payload, "\"OPT12\":\"");
- strcat(payload, hostname);
-
-
- strcat(payload, "\",");
- strcat(payload, "\"OPT60\":\"");
-
- while(optVCI){
- sprintf(tmpVCI[i], "%c", *optVCI);
- optVCI++;
- }
- strcat(payload, tmpVCI);
- */
- strcat(payload, "\"}");
-
- payloadLen=strlen(payload)+1;
- handle_Auto_Reserve_IP_request(payloadLen, payload);
-#endif
-
return dhcp_packet_size(mess, agent_id, real_end);
case DHCPINFORM:
@@ -2663,4 +2648,4 @@
-
+
\ No newline at end of file
@@ -0,0 +1,93 @@
Index: dnsmasq-2.67/src/dnsmasq.h
===================================================================
--- dnsmasq-2.67.orig/src/dnsmasq.h 2015-06-22 16:52:48.254338852 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2015-06-22 16:55:07.022157183 +0800
@@ -1359,4 +1359,6 @@
//__ZYXEL__, Chi-Hsiang Auto reserve IP for the same host.
int handle_Auto_Reserve_IP_request(int payloadLen, const char *payload);
#endif
-
+#ifdef ZyXEL_DHCP_OPTION125 /* __ZyXEL__, Albert, 20150622, Support DHCP option125 */
+extern void send_dhcp_op125_check(unsigned char *oui , unsigned char *serial, unsigned char *pclass, char reply[]);
+#endif
\ No newline at end of file
Index: dnsmasq-2.67/src/extern.c
===================================================================
--- dnsmasq-2.67.orig/src/extern.c 2015-06-22 16:52:48.254338852 +0800
+++ dnsmasq-2.67/src/extern.c 2015-06-22 16:55:33.152867960 +0800
@@ -91,6 +91,36 @@
}
+#ifdef ZyXEL_DHCP_OPTION125 /* __ZyXEL__, Albert, 20150622, Support DHCP option125 */
+void send_dhcp_op125_check(unsigned char *oui , unsigned char *serial, unsigned char *pclass, char reply[])
+{
+ zcfgRet_t ret;
+ mgabDev_t mgabdev;
+ my_syslog(MS_DHCP | LOG_INFO, "%s ", __func__);
+
+ memset(&mgabdev, '\0', sizeof(mgabdev));
+
+ if(oui){
+ strncpy(mgabdev.ManufacturerOUI, (char *)(&oui[2]), oui[1]);
+ }
+ if(serial){
+ strncpy(mgabdev.SerialNumber, (char *)(&serial[2]), serial[1]);
+ }
+ if(pclass){
+ strncpy(mgabdev.ProductClass, (char *)(&pclass[2]), pclass[1]);
+ }
+
+ /* send ZCFG_MSG_MGABDEV_DETECT to ESMD for notification */
+ ret = dnsmasq_msg_send(ZCFG_MSG_DHCP_OPTIONI125_CHK, sizeof(mgabDev_t), (const char*)&mgabdev, reply);
+ my_syslog(MS_DHCP | LOG_INFO, "%s esmd reply=%s", __func__, reply);
+
+ if(ret != ZCFG_SUCCESS && ret != ZCFG_SUCCESS_AND_NO_REPLY){
+ my_syslog(MS_DHCP | LOG_ERR, "%s dnsmasq_msg_send fail,ret=%d", __func__, ret);
+ strcpy(reply, "accept");//default pass any port any service
+ }
+}
+#endif
+
void
send_dhcp_option_request(
char *ifName,
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2015-06-22 16:52:48.262338852 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2015-06-22 16:56:05.324042381 +0800
@@ -170,6 +170,7 @@
if ((opt = option_find(mess, sz, OPTION_VENDOR_IDENT_OPT, 5)))
{
unsigned int elen, offset, len = option_len(opt);
+ int isaccept = 0;
for (offset = 0; offset < (len - 5); offset += elen + 5)
{
@@ -187,6 +188,15 @@
handle_op125_request(oui, serial, class);
#endif
+#ifdef ZyXEL_DHCP_OPTION125 /* __ZyXEL__, Albert, 20150622, Support DHCP option125 */
+ char Option125Check[16] = "";
+ send_dhcp_op125_check(oui, serial, class, Option125Check);
+ if (strcmp(Option125Check, "none")==0 )
+ continue;
+ else
+ isaccept = 1;
+#endif
+
/* If TR069-id is present set the tag "cpewan-id" to facilitate echoing
the gateway id back. Note that the device class is optional */
if (oui && serial)
@@ -198,6 +208,10 @@
break;
}
}
+#ifdef ZyXEL_DHCP_OPTION125 /* __ZyXEL__, Albert, 20150622, Support DHCP option125 */
+ if(isaccept == 0)
+ return 0;
+#endif
}
if ((opt = option_find(mess, sz, OPTION_AGENT_ID, 1)))
@@ -0,0 +1,28 @@
Index: dnsmasq-2.67/src/dhcp-common.c
===================================================================
--- dnsmasq-2.67.orig/src/dhcp-common.c 2013-10-25 17:37:30.000000000 +0800
+++ dnsmasq-2.67/src/dhcp-common.c 2015-08-06 10:49:20.817815765 +0800
@@ -25,7 +25,9 @@
daemon->dhcp_buff = safe_malloc(256);
daemon->dhcp_buff2 = safe_malloc(256);
daemon->dhcp_buff3 = safe_malloc(256);
-
+ memset(daemon->dhcp_buff, '\0', 256);
+ memset(daemon->dhcp_buff2, '\0', 256);
+ memset(daemon->dhcp_buff3, '\0', 256);
/* dhcp_packet is used by v4 and v6, outpacket only by v6
sizeof(struct dhcp_packet) is as good an initial size as any,
even for v6 */
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2015-08-06 10:49:20.809815765 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2015-08-06 10:50:02.295295600 +0800
@@ -136,7 +136,7 @@
if(CLIENT_HAVE_OPTION_60(option_flag)){
emac = extended_hwaddr(mess->htype, mess->hlen, mess->chaddr, clid_len, clid, &emac_len);
vendor_class_len = option_len(opt);
- memset(daemon->dhcp_buff3, '\0', strlen(daemon->dhcp_buff3));
+ memset(daemon->dhcp_buff3, '\0', 256);
memcpy(daemon->dhcp_buff3, option_ptr(opt, 0), option_len(opt));
strncpy(vendorId, option_ptr(opt, 0), option_len(opt));
}
@@ -0,0 +1,36 @@
Index: dnsmasq-2.67/src/rfc2131.c
===================================================================
--- dnsmasq-2.67.orig/src/rfc2131.c 2015-08-14 18:15:11.487482302 +0800
+++ dnsmasq-2.67/src/rfc2131.c 2015-08-14 18:17:14.556266700 +0800
@@ -977,6 +977,23 @@
my_syslog(LOG_INFO, _("mac = %s"), print_mac(daemon->namebuff, emac, emac_len));
my_syslog(MS_DHCP | LOG_WARNING, _("iface_name=%s"), iface_name);
+ struct dhcp_netid *tmpNetid = NULL;
+ char *brNamePtr = NULL;
+ for(tmpNetid = netid; tmpNetid; tmpNetid = tmpNetid->next){
+ my_syslog(MS_DHCP | LOG_WARNING, _("tmpNetid->net=%s"), tmpNetid->net);
+ if( !strncmp(tmpNetid->net, "Crit_br", 7)){
+ brNamePtr = strstr(tmpNetid->net, "br");
+ if(iface_name != NULL && strcmp(brNamePtr, iface_name)){
+ if ( option_flag ) {
+ send_dhcp_option_request(iface_name, vendorId, emac, oui, serial, class, opt61Val, intfGrpOptionCheck);
+ return 0;
+ }
+ }
+
+ }
+ }
+
+#if 0
/*send DHCP option information for any port any service*/
if ( option_flag ) {
//unsigned char *oui = NULL, *serial = NULL, *class = NULL;
@@ -991,6 +1008,7 @@
}
}
#endif
+#endif
switch (mess_type)
{
@@ -0,0 +1,219 @@
diff -Naur dnsmasq-2.67.orig/src/dnsmasq.h dnsmasq-2.67/src/dnsmasq.h
--- dnsmasq-2.67.orig/src/dnsmasq.h 2015-09-03 13:38:17.781306600 +0800
+++ dnsmasq-2.67/src/dnsmasq.h 2015-09-03 13:48:33.246098010 +0800
@@ -580,6 +580,15 @@
struct dhcp_lease *next;
};
+#if 1 //oneconnect dhcp.leases2 file
+//[WWH] add
+struct dhcp_lease_tmp {
+ char hwaddr[64];
+ char hostname[512];
+ struct dhcp_lease_tmp *next;
+};
+#endif
+
struct dhcp_netid {
char *net;
struct dhcp_netid *next;
diff -Naur dnsmasq-2.67.orig/src/lease.c dnsmasq-2.67/src/lease.c
--- dnsmasq-2.67.orig/src/lease.c 2015-09-03 13:38:17.725306600 +0800
+++ dnsmasq-2.67/src/lease.c 2015-09-03 13:50:57.706266768 +0800
@@ -21,6 +21,107 @@
static struct dhcp_lease *leases = NULL, *old_leases = NULL;
static int dns_dirty, file_dirty, leases_left;
+#if 1 //oneconnect dhcp.leases2 file
+//WWH add
+static struct dhcp_lease_tmp *kill_leases = NULL;
+
+/** WWH add *********************************************************/
+static void save_killname(char *hwaddr, char *hostname)
+{
+ if ( hwaddr == NULL || hostname == NULL )
+ {
+ return;
+ }
+
+ struct dhcp_lease_tmp *lease;
+ lease = calloc(1, sizeof(struct dhcp_lease_tmp));
+ lease->next = NULL;
+
+ strcpy(lease->hwaddr , hwaddr);
+ strcpy(lease->hostname, hostname);
+
+ if ( kill_leases == NULL )
+ {
+ kill_leases = lease;
+ }
+ else
+ {
+ struct dhcp_lease_tmp *lease_tmp;
+ lease_tmp = kill_leases;
+ while(lease_tmp->next)
+ {
+ lease_tmp = lease_tmp->next;
+ }
+ lease_tmp->next = lease;
+ }
+}
+
+void get_kill_leases_hostname(char *hwaddr, char *hostname)
+{
+ if ( hwaddr == NULL || kill_leases == NULL )
+ {
+ return;
+ }
+
+ struct dhcp_lease_tmp *lease;
+ lease = kill_leases;
+ while(lease)
+ {
+ if ( strncmp(hwaddr, lease->hwaddr, 17) == 0 ) //find same mac
+ {
+ strcpy(hostname, lease->hostname);
+ return;
+ }
+ lease = lease->next;
+ }
+ strncpy(hostname, "*", 1);
+}
+
+void Removeoutputfile(void)
+{
+ char buf[1024];
+ FILE *fp = fopen("/tmp/dhcp.leases2", "r");
+ if (fp)
+ {
+ while (fgets(buf, sizeof(buf), fp))
+ {
+ char hwaddr[64] = "";
+ char ip[64] = "";
+ char hostname[512] = "";
+ sscanf( buf , "%s %s %s", hwaddr, ip, hostname);
+ save_killname(hwaddr, hostname);
+ }
+ fclose(fp);
+ }
+
+ remove("/tmp/dhcp.leases2");
+ system("touch /tmp/dhcp.leases2");
+}
+
+void outputData(char *outputdata)
+{
+ char output[1024];
+ sprintf(output, "echo \"%s\" >> %s", outputdata, "/tmp/dhcp.leases2");
+ system(output);
+}
+
+
+void free_kill_leases()
+{
+ struct dhcp_lease_tmp *lease_f;
+ struct dhcp_lease_tmp *lease_tmp;
+ lease_f = kill_leases;
+ while (lease_f)
+ {
+ lease_tmp = lease_f->next;
+ free(lease_f);
+ lease_f = lease_tmp;
+ }
+ kill_leases = NULL;
+}
+/** WWH *************************************************************/
+#endif
+
void lease_init(time_t now)
{
unsigned long ei;
@@ -177,6 +278,12 @@
file_dirty = 0;
lease_prune(NULL, now);
dns_dirty = 1;
+
+#if 1 //oneconnect dhcp.leases2 file
+ //[WWH] add
+ system("touch /tmp/dhcp.leases2");
+#endif
+
}
void lease_update_from_configs(void)
@@ -222,7 +329,12 @@
rewind(daemon->lease_stream);
if (errno != 0 || ftruncate(fileno(daemon->lease_stream), 0) != 0)
err = errno;
-
+
+#if 1 //oneconnect dhcp.leases2 file
+ //WWH add
+ Removeoutputfile();
+#endif
+
for (lease = leases; lease; lease = lease->next)
{
@@ -251,6 +363,35 @@
ourprintf(&err, " %s ", daemon->addrbuff);
ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
+#if 1 //oneconnect dhcp.leases2 file
+ //[WWH] output file
+ int macCount = 0;
+ char outputdata[1024] = "";
+ char output_hwaddr[64] = "";
+ char output_hostname[512] = "";
+ for (macCount = 0; macCount < lease->hwaddr_len; macCount++)
+ {
+ sprintf(output_hwaddr+(macCount*3), "%.2x", lease->hwaddr[macCount]);
+ if (macCount != lease->hwaddr_len - 1)
+ {
+ sprintf(output_hwaddr+((macCount*3)+2), ":");
+ }
+ }
+
+ if ( !lease->hostname ) //lease->hostname is NULL, find kill_leases
+ {
+ //get hostname in kill_leases
+ get_kill_leases_hostname(output_hwaddr, output_hostname);
+ }
+ else
+ {
+ strcpy(output_hostname, lease->hostname);
+ }
+ sprintf(outputdata, "%s %s %s\0", output_hwaddr, daemon->addrbuff, output_hostname);
+ //output file
+ outputData(outputdata);
+#endif
+
if (lease->clid && lease->clid_len != 0)
{
for (i = 0; i < lease->clid_len - 1; i++)
@@ -351,6 +492,11 @@
}
send_alarm(next_event, now);
+
+#if 1 //oneconnect dhcp.leases2 file
+ //clear kill_leases
+ free_kill_leases();
+#endif
}
@@ -849,6 +995,13 @@
static void kill_name(struct dhcp_lease *lease)
{
+#if 1 //oneconnect dhcp.leases2 file
+ //save kill name
+ char hwaddr_tmp[64] = "";
+ sprintf(hwaddr_tmp, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", lease->hwaddr[0],lease->hwaddr[1],lease->hwaddr[2],lease->hwaddr[3],lease->hwaddr[4],lease->hwaddr[5]);
+ save_killname(hwaddr_tmp, lease->hostname);
+#endif
+
/* run script to say we lost our old name */
/* this shouldn't happen unless updates are very quick and the