#!/bin/sh /etc/rc.common
-START=19
+START=25
USE_PROCD=1
PROG=/usr/sbin/dhcpd
+TTL=3600
+PREFIX="update add"
+
lease_file=/tmp/dhcpd.leases
config_file=/tmp/run/dhcpd.conf
+dyndir=/tmp/bind
+conf_local_file=$dyndir/named.conf.local
+
+session_key_name=local-ddns
+session_key_file=/var/run/named/session.key
+
+dyn_file=$(mktemp -u /tmp/dhcpd.XXXXXX)
+
time2seconds() {
local timestring=$1
local multiplier number suffix
'
}
+rev_quad() {
+ local ip="$1"
+
+ echo "$ip" | awk -F '.' '{ printf "%s.%s.%s.%s\n", $4, $3, $2, $1; }'
+}
+
+update() {
+ local lhs="$1" family="$2" type="$3"
+ shift 3
+
+ echo -e "$PREFIX" "$lhs $family $type $@\nsend"
+}
+
explode() {
local arg="$1"
echo "$arg" | sed -e 's/\./, /g'
}
+create_empty_zone()
+{
+ local zone="$1"
+
+ if [ ! -f $dyndir/db."$zone" ]; then
+ cp -p /etc/bind/db.empty $dyndir/db."$zone"
+ chmod g+w $dyndir/db."$zone"
+ chgrp bind $dyndir/db."$zone"
+ fi
+}
+
append_routes() {
local tuple tuples="$1"
local string=
echo " option $tag $formatted;"
}
+static_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
+
+ update "$cname.$domain." IN CNAME "$target.$domain."
+}
+
+static_cnames() {
+ config_foreach static_cname_add cname "$@"
+}
+
+static_domain_add() {
+ local cfg="$1"
+ local name ip revip
+
+ config_get name "$cfg" "name"
+ [ -n "$name" ] || return 0
+ config_get ip "$cfg" "ip"
+ [ -n "$ip" ] || return 0
+
+ revip="$(rev_quad "$ip")"
+
+ update "$name.$domain." IN A "$ip"
+ update "$revip.in-addr.arpa." IN PTR "$name.$domain."
+}
+
+static_domains() {
+ config_foreach static_domain_add domain "$@"
+}
+
+static_mxhost_add() {
+ local cfg="$1"
+ local domain2 relay pref
+
+ config_get domain2 "$cfg" "domain"
+ [ -n "$domain2" ] || return 0
+ config_get relay "$cfg" "relay"
+ [ -n "$relay" ] || return 0
+ config_get pref "$cfg" "pref"
+ [ -n "$pref" ] || return 0
+
+ if [ "$domain2" = "@" ]; then
+ update "$domain." IN MX "$pref" "$relay.$domain."
+ else
+ update "$domain2.$domain." IN MX "$pref" "$relay.$domain."
+ fi
+}
+
+static_mxhosts() {
+ config_foreach static_mxhost_add mxhost "$@"
+}
+
+static_srvhost_add() {
+ local cfg="$1"
+ local srv target port priority weight
+
+ 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 priority "$cfg" "priority"
+ [ -n "$priority" ] || return 0
+ config_get weight "$cfg" "weight"
+ [ -n "$weight" ] || return 0
+
+ update "$srv.$domain." IN SRV "$priority" "$weight" "$port" "$target"
+}
+
+static_srvhosts() {
+ config_foreach static_srvhost_add srvhost "$@"
+}
+
static_host_add() {
local cfg="$1"
local broadcast hostid macn macs mac name ip leasetime
config_get log_facility "isc_dhcpd" "log_facility"
config_get domain "isc_dhcpd" "domain"
+ config_get_bool dynamicdns "isc_dhcpd" dynamicdns 0
[ $always_broadcast -eq 1 ] && echo "always-broadcast true;"
[ $authoritative -eq 1 ] && echo "authoritative;"
max_lease_time="$(time2seconds "$max_lease_time")"
[ "$?" -ne 0 ] && return 1
+ if [ $dynamicdns -eq 1 ]; then
+ create_empty_zone "$domain"
+
+ create_empty_zone "168.192.in-addr.arpa"
+
+ cat <<EOF > $conf_local_file
+zone "$domain" {
+ type master;
+ file "$dyndir/db.$domain";
+ allow-update { key $session_key_name; };
+ allow-transfer { key $session_key_name; };
+};
+
+zone "168.192.in-addr.arpa" {
+ type master;
+ file "$dyndir/db.168.192.in-addr.arpa";
+ allow-update { key $session_key_name; };
+ allow-transfer { key $session_key_name; };
+};
+
+EOF
+ /etc/init.d/named reload
+ sleep 1
+
+ cat <<EOF
+ddns-domainname "$domain.";
+ddns-update-style standard;
+ddns-updates on;
+ignore client-updates;
+
+update-static-leases on;
+use-host-decl-names on;
+update-conflict-detection off;
+update-optimization off;
+
+include "$session_key_file";
+
+zone $domain. {
+ primary 127.0.0.1;
+ key local-ddns;
+}
+
+zone 168.192.in-addr.arpa. {
+ primary 127.0.0.1;
+ key local-ddns;
+}
+
+EOF
+ fi
+
if [ -n "$log_facility" ] ; then
echo "log-facility $log_facility;"
fi
}
start_service() {
- local domain dhcp_ifs authoritative
+ local domain dhcp_ifs authoritative dynamicdns
if [ -n "$DHCPD_BOOT" ] ; then
return 0
static_hosts >> $config_file
+ if [ $dynamicdns -eq 1 ]; then
+ cat <<EOF > $dyn_file
+; Generated by /etc/init.d/dhcpd at $(date)
+
+ttl $TTL
+
+EOF
+
+ static_cnames >> $dyn_file
+
+ static_domains >> $dyn_file
+
+ static_mxhosts >> $dyn_file
+
+ static_srvhosts >> $dyn_file
+
+ nsupdate -l -v $dyn_file
+
+ rm -f $dyn_file
+ fi
+
[ -z "$dhcp_ifs" ] && return 0
fi