PSARC 2011/043 Import ISC DHCP
authorRishi Srivatsavai <Rishi.Srivatsavai@oracle.com>
Thu, 02 Jun 2011 13:26:03 -0700
changeset 280 c0dae1e3ca2f
parent 279 c6af843791cd
child 281 d8461ade59a0
PSARC 2011/043 Import ISC DHCP 7022308 Integrate ISC DHCP server and relay agent
components/isc-dhcp/Makefile
components/isc-dhcp/SmfDHCPStates.html
components/isc-dhcp/SmfValueDHCP.html
components/isc-dhcp/dhcp.p5m
components/isc-dhcp/dhcp_auths
components/isc-dhcp/isc-dhcp
components/isc-dhcp/isc-dhcp-relay.xml
components/isc-dhcp/isc-dhcp-server.xml
components/isc-dhcp/isc-dhcp.5
components/isc-dhcp/patches/nopidfile.patch
components/isc-dhcp/patches/sockets.patch
transforms/defaults
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/Makefile	Thu Jun 02 13:26:03 2011 -0700
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+#
+include ../../make-rules/shared-macros.mk
+
+COMPONENT_NAME=		dhcp
+COMPONENT_VERSION=	4.1
+COMPONENT_SRC=		$(COMPONENT_NAME)-$(COMPONENT_VERSION)-ESV-R1
+COMPONENT_ARCHIVE=	$(COMPONENT_SRC).tar.gz
+COMPONENT_ARCHIVE_HASH= sha1:64664b2fd3ce9e372785cbbef685f86ee3dcd53a
+COMPONENT_ARCHIVE_URL=  http://ftp.isc.org/isc/dhcp/$(COMPONENT_ARCHIVE)
+
+include ../../make-rules/prep.mk
+include ../../make-rules/configure.mk
+include ../../make-rules/ips.mk
+
+COMPONENT_PRE_CONFIGURE_ACTION = \
+	($(CLONEY) $(SOURCE_DIR) $(@D))
+
+CONFIGURE_OPTIONS  +=	--sysconfdir=$(ETCDIR)/inet
+CONFIGURE_OPTIONS  +=	--sbindir=$(USRLIBDIR)/inet
+CONFIGURE_OPTIONS  +=	--bindir=$(USRSBINDIR)
+CONFIGURE_OPTIONS  +=	CFLAGS="$(CFLAGS) -DUSE_SOCKETS"
+
+build:		$(BUILD_32)
+
+install:	build $(INSTALL_32) $(PROTO_DIR)/dhcpd.leases
+
+BUILD_PKG_DEPENDENCIES =	$(BUILD_TOOLS)
+
+test:	build
+	@cd $(BUILD_DIR_32); $(MAKE) check
+
+$(PROTO_DIR)/dhcpd.leases:	$(INSTALL_32)
+	$(TOUCH) [email protected]
+
+include ../../make-rules/depend.mk
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/SmfDHCPStates.html	Thu Jun 02 13:26:03 2011 -0700
@@ -0,0 +1,37 @@
+<HTML>
+<!--
+    Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+    CDDL HEADER START
+
+    The contents of this file are subject to the terms of the
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
+
+    You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+    or http://www.opensolaris.org/os/licensing.
+    See the License for the specific language governing permissions
+    and limitations under the License.
+
+    When distributing Covered Code, include this CDDL HEADER in each
+    file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+    If applicable, add the following below this CDDL HEADER, with the
+    fields enclosed by brackets "[]" replaced with your own identifying
+    information: Portions Copyright [yyyy] [name of copyright owner]
+
+    CDDL HEADER END
+-->
+<!--
+   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+   <META NAME="GENERATOR" CONTENT="Mozilla/4.02 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]">
+-->
+<BODY>
+When Manage ISC DHCP Server and Relay Agent Service States is in
+the Authorizations Included column, it grants the authorization to
+enable, disable, or restart the ISC DHCP Server and Relay Agent services.
+<p>
+If Manage ISC DHCP Server and Relay Agent Service States is grayed, then you
+are not entitled to Add or Remove this authorization.
+<BR>&nbsp;
+</BODY>
+</HTML>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/SmfValueDHCP.html	Thu Jun 02 13:26:03 2011 -0700
@@ -0,0 +1,37 @@
+<HTML>
+<!--
+    Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+    CDDL HEADER START
+
+    The contents of this file are subject to the terms of the
+    Common Development and Distribution License (the "License").
+    You may not use this file except in compliance with the License.
+
+    You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+    or http://www.opensolaris.org/os/licensing.
+    See the License for the specific language governing permissions
+    and limitations under the License.
+
+    When distributing Covered Code, include this CDDL HEADER in each
+    file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+    If applicable, add the following below this CDDL HEADER, with the
+    fields enclosed by brackets "[]" replaced with your own identifying
+    information: Portions Copyright [yyyy] [name of copyright owner]
+
+    CDDL HEADER END
+-->
+<!--
+   <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+   <META NAME="GENERATOR" CONTENT="Mozilla/4.02 [en] (X11; U; SunOS 5.6 sun4u) [Netscape]">
+-->
+<BODY>
+When Change Values of ISC DHCP Server and Relay Agent Service Properties is
+in the Authorizations Include column, it grants the the authorization to change
+ISC DHCP Server and Rely Agent service property values.
+<P> 
+If Change Values of ISC DHCP Server and Relay Agent Service Properties is
+grayed, then you are not entitled to Add or Remove this authorization.
+<BR>&nbsp;
+</BODY>
+</HTML>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/dhcp.p5m	Thu Jun 02 13:26:03 2011 -0700
@@ -0,0 +1,96 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+#
+<transform file path=usr.*/man/.+ -> default mangler.man.stability uncommitted>
+set name=pkg.fmri \
+    value=pkg:/service/network/dhcp/[email protected]$(IPS_COMPONENT_VERSION),$(BUILD_VERSION)
+set name=pkg.description \
+    value="ISC DHCP is open source software that implements the Dynamic Host Configuration Protocols for connection to a local network. This package includes the ISC DHCP server, relay agent and the omshell tool."
+set name=pkg.summary value="ISC DHCP Server and Relay Agent."
+set name=info.classification \
+    value=org.opensolaris.category.2008:System/Services
+set name=info.source_url value=$(COMPONENT_ARCHIVE_URL)
+set name=info.upstream_url value=http://www.isc.org/software/dhcp/
+set name=opensolaris.arc_url \
+    value=http://arc.opensolaris.org/caselog/PSARC/2011/043
+set name=org.opensolaris.consolidation value=$(CONSOLIDATION)
+#
+dir path=etc
+dir path=etc/inet
+dir path=etc/security
+dir path=lib
+dir path=lib/svc
+dir path=lib/svc/manifest
+dir path=lib/svc/manifest/network
+dir path=lib/svc/manifest/network/dhcp
+dir path=lib/svc/method
+dir path=usr
+dir path=usr/lib
+dir path=usr/lib/help
+dir path=usr/lib/help/auths
+dir path=usr/lib/help/auths/locale
+dir path=usr/lib/inet
+dir path=usr/sbin
+dir path=usr/share
+dir path=usr/share/man
+dir path=usr/share/man/man1
+dir path=usr/share/man/man5
+dir path=usr/share/man/man8
+dir path=var
+dir path=var/db
+#
+# isc-dhcp lease database directory with mode 0755 to allow isc-dhcp
+# start method to create empty lease files if needed and is world
+# readable to allow any user scripts to parse the lease db files.
+dir path=var/db/isc-dhcp group=netadm mode=0755 owner=dhcpserv
+file server/dhcpd.conf path=etc/inet/dhcpd.conf.example group=sys
+file dhcp_auths path=etc/security/auth_attr.d/service%2Fnetwork%2Fisc-dhcp
+file isc-dhcp-relay.xml path=lib/svc/manifest/network/dhcp/isc-dhcp-relay.xml \
+    group=sys mode=0444
+file isc-dhcp-server.xml \
+    path=lib/svc/manifest/network/dhcp/isc-dhcp-server.xml group=sys \
+    mode=0444
+file isc-dhcp path=lib/svc/method/isc-dhcp mode=0555
+file SmfDHCPStates.html path=usr/lib/help/auths/locale/SmfDHCPStates.html
+file SmfValueDHCP.html path=usr/lib/help/auths/locale/SmfValueDHCP.html
+file path=usr/lib/inet/dhcpd
+file path=usr/lib/inet/dhcrelay
+file path=usr/sbin/omshell
+file path=usr/share/man/man1/omshell.1
+file path=usr/share/man/man5/dhcp-eval.5
+file path=usr/share/man/man5/dhcp-options.5
+file path=usr/share/man/man5/dhcpd.conf.5
+file path=usr/share/man/man5/dhcpd.leases.5
+file isc-dhcp.5 path=usr/share/man/man5/isc-dhcp.5
+file path=usr/share/man/man8/dhcpd.8
+file path=usr/share/man/man8/dhcrelay.8
+file dhcpd.leases path=var/db/isc-dhcp/dhcpd4.leases group=netadm mode=0644 \
+    owner=dhcpserv preserve=true
+file dhcpd.leases path=var/db/isc-dhcp/dhcpd4.leases~ group=netadm mode=0644 \
+    owner=dhcpserv preserve=true
+file dhcpd.leases path=var/db/isc-dhcp/dhcpd6.leases group=netadm mode=0644 \
+    owner=dhcpserv preserve=true
+file dhcpd.leases path=var/db/isc-dhcp/dhcpd6.leases~ group=netadm mode=0644 \
+    owner=dhcpserv preserve=true
+license LICENSE license="ISC BSD"
+user username=dhcpserv ftpuser=false gcos-field="DHCP Configuration Admin" \
+    group=netadm uid=18
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/dhcp_auths	Thu Jun 02 13:26:03 2011 -0700
@@ -0,0 +1,2 @@
+solaris.smf.manage.dhcp:::Manage ISC DHCP Server and Relay Agent Service States::help=SmfDHCPStates.html
+solaris.smf.value.dhcp:::Change Values of ISC DHCP Server and Relay Agent Service Properties::help=SmfValueDCP.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/isc-dhcp	Thu Jun 02 13:26:03 2011 -0700
@@ -0,0 +1,262 @@
+#!/sbin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+#
+
+. /lib/svc/share/smf_include.sh
+. /lib/svc/share/net_include.sh
+
+SVCPROP=/usr/bin/svcprop
+CHMOD=/usr/bin/chmod
+TOUCH=/usr/bin/touch
+
+DHCPD_IPV4="svc:/network/dhcp/server:ipv4"
+DHCPD_IPV6="svc:/network/dhcp/server:ipv6"
+DHCPRELAY_IPV4="svc:/network/dhcp/relay:ipv4"
+DHCRELAY_IPV6="svc:/network/dhcp/relay:ipv6"
+
+DHCPD_BIN="/usr/lib/inet/dhcpd"
+DHCPRELAY_BIN="/usr/lib/inet/dhcrelay"
+
+#
+# dhcpd/dhcprelay can run in a global or exclusive-stack zone only
+#
+smf_configure_ip || exit $SMF_EXIT_OK
+
+if [ -z $SMF_FMRI ]; then
+	echo "SMF framework variables are not initialized."
+	exit $SMF_EXIT_ERR
+fi
+
+#
+# get_prop fmri propname
+#
+get_prop () {
+	VALUE="`$SVCPROP -p config/$1 $SMF_FMRI 2>/dev/null`"
+	# Empty astring_list values show up as "" - do not return this.
+	if [ "$VALUE" != "\"\"" ]; then
+		echo $VALUE
+	fi
+}
+
+errlog () {
+	echo $1 >&2
+}
+
+get_common_options() {
+	#
+	# get debug property value 
+	#
+	if [ "`get_prop debug`" = "true" ]; then
+		DEBUG="-d"
+	else
+		DEBUG="-q"
+	fi
+
+	export OPTIONS="$OPTIONS $DEBUG"
+	return 0
+}
+
+get_dhcpd_options() {
+	# get listen_ifname property value.
+	LISTENIFNAMES="`get_prop listen_ifnames`"
+
+	#
+	# get common config file properties
+	#
+	CONFIGFILE=`get_prop config_file`
+	if [ -z "$CONFIGFILE" ]; then
+		errlog "No config_file specified, exiting"
+		return 1
+	fi
+	if [ ! -f "$CONFIGFILE" ]; then
+		errlog "Required config_file $CONFIGFILE not found, exiting"
+		return 1
+	fi
+
+	#
+	# If a leasefile does not exist, create an empty file.
+	#
+	LEASEFILE=`get_prop lease_file`
+	if [ -z "$LEASEFILE" ]; then
+		errlog "No lease_file specified, exiting"
+		return 1
+	fi
+	if [ ! -f "$LEASEFILE" ]; then
+		$TOUCH $LEASEFILE
+		$CHMOD u=rw,go=r $LEASEFILE
+	fi
+
+	export OPTIONS="$OPTIONS -cf $CONFIGFILE -lf $LEASEFILE $LISTENIFNAMES"
+	return 0
+}
+
+get_dhcprelay_options_v4() {
+	#
+	# Get append_agent_option V4 property value 
+	#
+	if [ "`get_prop append_agent_option`" = "true" ]; then
+		APPEND="-m"
+	else
+		APPEND=""
+	fi
+
+	#
+	# get listen_ifname property value and modify it.  
+	# If listen_ifnames property value is "e1000g01 iprb0" then the
+	# command line option will look like  "- i e1000g0 -i iprb0"
+	#
+	LISTENIFNAMES="`get_prop listen_ifnames`"
+	IIFLIST=""
+	if [ ! -z "$LISTENIFNAMES" ]; then
+		IIFLIST="`echo $LISTENIFNAMES | sed -e 's/[ \t]/ -i /g'`"
+	fi
+
+	#
+	# Get servers  V4 property value - command line option will look
+	# like  "1.2.3.5 4.5.6.7".
+	#
+	# NOTE: By default server property value is empty. User must
+	# first specify a server using svccfg/setprop command
+	# before enabling service.
+	#
+	DHCPSERVERS=`get_prop servers`
+	if [  -z "$DHCPSERVERS" ]; then
+		errlog "Must specify at least one servers prop value, exiting"
+		return 1
+	fi
+
+	export OPTIONS="$OPTIONS -4 $APPEND $IIFLIST $DHCPSERVERS"
+	return 0
+}
+
+get_dhcprelay_options_v6() {
+	#
+	# Get receivelinks  V6 property value and modify it:
+	# Given property values of "1.2.3.4%bge0#1 bge2,1.2.3.4%iprb",
+	# the command line option will look like  "-l 1.2.3.4%bge0#1 -l
+	# bge2 -l 1.2.3.4%iprb".
+	#
+	# NOTE: By default receivelinks value is empty. User must
+	# first specify a server using svccfg/setprop command
+	# before enabling service.
+	#
+	RECVLINKS=`get_prop receive_query_links`
+	if [  -z "$RECVLINKS" ]; then
+        	errlog "Must specify at least one receive_query_links propvalue"
+		errlog "Exiting."
+		return 1
+	fi
+	IRECVLINKS=""
+	if [ ! -z "$RECVLINKS" ]; then
+		IRECVLINKS="-l `echo $RECVLINKS | sed -e 's/[ \t]/ -l /g'`"
+	fi
+	#
+	# Get forwardlinks V6 property value and modify it:
+	# Given forwardquery_links property value is "1.2.3.4%bge0 bge2,"
+	# then the command line option will look like  "-u 1.2.3.4%bge0 -u
+	# bge2"
+	#
+	# NOTE: By default forwardlinks value is empty. User must
+	# first specify a server using svccfg/setprop command
+	# before enabling service.
+	#
+	FWDLINKS=`get_prop forwardquery_links`
+	if [ -z "$FWDLINKS" ]; then
+        	errlog "Must specify at least one forwardquery_links propvalue"
+		errlog "Exiting"
+		return 1
+	fi
+	IFWDLINKS=""
+	if [ ! -z "$FWDLINKS" ]; then
+		IFWDLINKS="-u `echo $FWDLINKS sed -e 's/,/ -u /g'`"
+	fi
+
+	export OPTIONS="$OPTIONS -6 $IRECVLINKS $IFWDLINKS"
+}
+
+export EXECFILE=$DHCPD_BIN
+export OPTIONS="--no-pid"
+
+case "$SMF_FMRI" in
+"$DHCPD_IPV4"|"$DHCPD_IPV6")
+	get_common_options
+	if [ "$?" != "0" ]; then
+		exit $SMF_EXIT_ERR_CONFIG
+	fi
+	get_dhcpd_options
+	if [ "$?" != "0" ]; then
+		exit $SMF_EXIT_ERR_CONFIG
+	fi
+	if [ "$SMF_FMRI" = "$DHCPD_IPV4" ]; then
+		OPTIONS="-4 $OPTIONS"
+	else
+		OPTIONS="-6 $OPTIONS"
+	fi
+	export EXECFILE=$DHCPD_BIN
+	;;
+
+$DHCPRELAY_IPV4)
+	get_common_options
+	if [ $? != "0" ]; then
+		exit $SMF_EXIT_ERR_CONFIG
+	fi
+	get_dhcprelay_options_v4
+	if [ $? != "0" ]; then
+		exit $SMF_EXIT_ERR_CONFIG
+	fi
+	export EXECFILE=$DHCPRELAY_BIN
+	;;
+
+$DHCPRELAY_IPV6)
+	get_common_options
+	if [ $? != "0" ]; then
+		exit $SMF_EXIT_ERR_CONFIG
+	fi
+	get_dhcprelay_options_v6
+	if [ $? != "0" ]; then
+		exit $SMF_EXIT_ERR_CONFIG
+	fi
+	export EXECFILE=$DHCPRELAY_BIN
+	;;
+
+*)
+        echo "isc-dhcp must be invoked from within SMF"
+        exit $SMF_EXIT_ERR_FATAL
+	;;
+
+esac
+
+# Now start the daemon
+if [ "$DEBUG" = "-d" ]; then
+	$EXECFILE $OPTIONS &
+else
+	$EXECFILE $OPTIONS
+fi
+
+if [ "$?" != "0" ]; then
+	exit $SMF_EXIT_ERR_FATAL
+fi
+
+exit $SMF_EXIT_OK
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/isc-dhcp-relay.xml	Thu Jun 02 13:26:03 2011 -0700
@@ -0,0 +1,153 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+	NOTE:  This service manifest is not editable; its contents will
+	be overwritten by package or patch operations, including
+	operating system upgrade.  Make customizations in a different
+	file.
+
+	Service manifest for the ISC DHCP Relay service.
+-->
+<!--
+    Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+-->
+<service_bundle type='manifest' name='isc-dhcp:relay'>
+
+<service name='network/dhcp/relay' type='service' version='1'>
+
+	<!--
+		We historically ran only in run-level 3, so depend on the
+		equivalent milestone to level 2.  We restart on refresh in
+		order to handle any changes to nameservice or filesystem
+		or other service configuration which may affect DHCP service.
+	-->
+	<dependency name='multi-user'
+		grouping='require_all' 
+		restart_on='refresh'
+		type='service'>
+		<service_fmri value='svc:/milestone/multi-user'/>
+	</dependency>
+
+	<!--
+		Running both DHCP flavors on a system is not supported - either
+		run ISC or Solaris.
+	-->
+	<dependency name='dhcp-server'
+		grouping='exclude_all'
+		restart_on='none' 
+		type='service'>
+		<service_fmri value='svc:/network/dhcp-server'/>
+	</dependency>
+
+	<exec_method type='method' name='start' 
+		exec='/lib/svc/method/isc-dhcp' timeout_seconds='60'>
+		<method_context>
+			<method_credential user='dhcpserv' group='netadm' 
+		privileges='basic,net_rawaccess,net_icmpaccess,net_privaddr,sys_ip_config'/>
+		</method_context>
+	</exec_method>
+
+	<exec_method type='method' name='stop' exec=':kill' 
+		timeout_seconds='60'/>
+
+	<exec_method type='method' name='refresh' exec=':kill -HUP' 
+		timeout_seconds='60'/>
+
+	<property_group name='firewall_context' type='com.sun,fw_definition'>
+		<propval name='name' type='astring' value='bootps'/>
+	</property_group>
+
+	<property_group name='firewall_config' type='com.sun,fw_configuration'>
+		<propval name='policy' type='astring' value='use_global'/>
+		<propval name='apply_to' type='astring' value=''/>
+		<propval name='exceptions' type='astring' value=''/>
+		<propval name='value_authorization' type='astring' 
+			value='solaris.smf.value.firewall.config'/>
+	</property_group>
+
+	<property_group name='general' type='framework'>
+		<!-- to start stop dhcp services -->
+		<propval name='action_authorization' type='astring'
+			value='solaris.smf.manage.dhcp' />
+		<propval name='value_authorization' type='astring'
+                        value='solaris.smf.manage.dhcp' />
+        </property_group>
+
+	<instance name='ipv4' enabled='false'>
+		<property_group name='config' type='application'>
+			<propval name='debug' type='boolean' value='false'/>
+			<propval name='append_agent_option' type='boolean' 
+			    value='false'/>
+			<property name='servers' type='astring'> 
+				<astring_list>
+					<value_node value=''/>
+				</astring_list>
+			</property>
+			<property name='listen_ifnames' type='astring' >
+				<astring_list>
+					<value_node value=''/>
+				</astring_list>
+			</property>
+			<propval name='value_authorization' type='astring'
+				value='solaris.smf.value.dhcp' />
+		</property_group>
+	</instance>
+
+	<instance name='ipv6' enabled='false'>
+		<property_group name='config' type='application'>
+			<propval name='debug' type='boolean' value='false'/>
+			<property name='receive_query_links' type='astring'>
+				<astring_list>
+					<value_node value=''/>
+				</astring_list>
+			</property>
+			<property name='forward_query_links' type='astring'>
+				<astring_list>
+					<value_node value=''/>
+				</astring_list>
+			</property>
+			<propval name='value_authorization' type='astring'
+                                value='solaris.smf.value.dhcp' />
+		</property_group>
+	</instance>
+
+	<stability value='Unstable'/>
+
+	<template>
+		<common_name>
+			<loctext xml:lang='C'>
+				ISC DHCP Relay
+			</loctext>
+		</common_name>
+		<description>
+			<loctext xml:lang='C'>
+ISC DHCP Relay service relays DHCP and BOOTP requests from one subnet with no DHCP server to another subnet with a DHCP server.
+			</loctext>
+		</description>
+		<documentation>
+			<manpage title='dhcrelay' section='1M'
+				manpath='/usr/share/man'/>
+		</documentation>
+	</template>
+</service>
+
+</service_bundle>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/isc-dhcp-server.xml	Thu Jun 02 13:26:03 2011 -0700
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ Common Development and Distribution License (the "License").
+ You may not use this file except in compliance with the License.
+
+ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ or http://www.opensolaris.org/os/licensing.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+	NOTE:  This service manifest is not editable; its contents will
+	be overwritten by package or patch operations, including
+	operating system upgrade.  Make customizations in a different
+	file.
+
+	Service manifest for the ISC DHCP Server service.
+-->
+<!--
+    Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+-->
+<service_bundle type='manifest' name='isc-dhcp:server'>
+
+<service name='network/dhcp/server' type='service' version='1'>
+
+	<!--
+	    We historically ran only in run-level 3, so depend on the
+	    equivalent milestone to level 2.  We restart on refresh in
+	    order to handle any changes to nameservice or filesystem
+	    or other service configuration which may affect DHCP service.
+	-->
+	<dependency name='multi-user'
+		grouping='require_all'
+		restart_on='refresh'
+		type='service'>
+		<service_fmri value='svc:/milestone/multi-user'/>
+	</dependency>
+
+	<!--
+	   Cant run both DHCP flavors on a system Either run ISC or
+	   Solaris
+	-->
+	<dependency name='dhcp-server'
+		grouping='exclude_all'
+		restart_on='none' 
+		type='service'>
+		<service_fmri value='svc:/network/dhcp-server'/>
+	</dependency>
+	<exec_method type='method' name='start' 
+		exec='/lib/svc/method/isc-dhcp' timeout_seconds='60'>
+		<method_context>
+			<method_credential
+				user='dhcpserv' group='netadm' 
+				privileges='basic,net_rawaccess,net_icmpaccess,net_privaddr,sys_ip_config'
+			/>
+		</method_context>
+	</exec_method>
+
+	<exec_method type='method' name='stop' exec=':kill' 
+		timeout_seconds='60'/>
+
+	<exec_method type='method' name='refresh' exec=':kill -HUP' 
+		timeout_seconds='60'/>
+
+	<property_group name='firewall_context' type='com.sun,fw_definition'>
+		<propval name='name' type='astring' value='bootps'/>
+	</property_group>
+
+	<property_group name='firewall_config' type='com.sun,fw_configuration'>
+		<propval name='policy' type='astring' value='use_global'/>
+		<propval name='apply_to' type='astring' value=''/>
+		<propval name='exceptions' type='astring' value=''/>
+		<propval name='value_authorization' type='astring' 
+			value='solaris.smf.value.firewall.config'/>
+	</property_group>
+
+	<property_group name='general' type='framework'>
+		<!-- to start stop dhcp services -->
+		<propval name='action_authorization' type='astring'
+			value='solaris.smf.manage.dhcp' />
+		<propval name='value_authorization' type='astring'
+			value='solaris.smf.manage.dhcp' />
+	</property_group>
+
+	<instance name='ipv4' enabled='false'>
+		<property_group name='config' type='application'>
+			<propval name='debug' type='boolean' value='false'/>
+			<propval name='config_file' type='astring' 
+				value='/etc/inet/dhcpd4.conf'/>
+			<propval name='lease_file' type='astring'
+				value='/var/db/isc-dhcp/dhcpd4.leases'/>
+			<property name='listen_ifnames' type='astring' >
+				<astring_list>
+					<value_node value='' />
+				</astring_list>
+			</property>
+			<propval name='value_authorization' type='astring'
+				value='solaris.smf.value.dhcp' />
+		</property_group>
+	</instance>
+
+	<instance name='ipv6' enabled='false'>
+		<property_group name='config' type='application'>
+			<propval name='debug' type='boolean' value='false'/>
+			<propval name='config_file' type='astring'
+				value='/etc/inet/dhcpd6.conf'/>
+			<propval name='lease_file' type='astring'
+				value='/var/db/isc-dhcp/dhcpd6.leases'/>
+			<property name='listen_ifnames' type='astring'>
+				<astring_list>
+					<value_node value='' />
+				</astring_list>
+			</property>
+			<propval name='value_authorization' type='astring'
+				value='solaris.smf.value.dhcp' />
+		</property_group>
+	</instance>
+
+	<stability value='Unstable'/>
+
+	<template>
+		<common_name>
+			<loctext xml:lang='C'>
+				ISC DHCP Server
+			</loctext>
+		</common_name>
+		<description>
+			<loctext xml:lang='C'>
+ISC DHCP server provides DHCP and BOOTP protocol services to network clients.
+			</loctext>
+		</description>
+		<documentation>
+			<manpage title='dhcpd' section='1M'
+				manpath='/usr/share/man'/>
+		</documentation>
+	</template>
+</service>
+
+</service_bundle>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/isc-dhcp.5	Thu Jun 02 13:26:03 2011 -0700
@@ -0,0 +1,259 @@
+.TH isc-dhcp 5 "17 May 2011" "SunOS 5.11"
+.SH NAME
+isc\-dhcp \- ISC Dynamic Host Configuration Protocol Software
+
+.SH DESCRIPTION
+.sp
+.LP
+The Internet Systems Consortium (ISC) DHCP Server (dhcpd)
+implements the Dynamic Host Configuration Protocol
+(DHCPv4 and DHCPv6), and the Internet Bootstrap Protocol
+(BOOTP). DHCP allows hosts on a TCP/IP network to request
+and be assigned IP addresses, and also to discover information
+about the network to which they are attached.  BOOTP
+provides similar functionality, with certain restrictions.
+.sp
+.LP
+ISC Relay Agent (dhcrelay) provides a means for relaying DHCP
+and BOOTP requests from a subnet to which no DHCP server is
+directly connected to one or more DHCP servers on other subnets.
+.sp
+.LP
+The services above (dhcpd and dhcrelay) are managed using the Service
+Management Facility (SMF) on Solaris, and should be administered by
+the svcadm(1M) command using  the following fault management resource
+identifiers (FMRIs):
+.sp
+.LP
+.in +2
+.nf
+svc:/network/dhcp/server:ipv4
+svc:/network/dhcp/server:ipv6
+svc:/network/dhcp/relay:ipv4
+svc:/network/dhcp/relay:ipv6
+.fi
+.sp
+.LP
+The following dhcpd service configuration properties can be viewed with
+svcprop(1M) and modified via svccfg(1M):
+.sp
+.ne 2
+.mk
+.na
+debug
+.ad
+.sp .6
+.RS 4n
+Send log messages from the DHCP daemon to  the  standard  error  descriptor.
+Setting this property to true ensures the -d command-line option is
+used when starting dhcpd. This property is set to false by default.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+config_file
+.ad
+.sp .6
+.RS 4n
+Path to alternate configuration file. The value of this property
+is passed as an argument to the -cf command-line option of dhcpd.
+The default is set to /etc/inet/dhcpd6.conf and /etc/inet/dhcpd4.conf
+for DHCP v6 and v4 servers respectively.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+lease_file
+.ad
+.sp .6
+.RS 4n
+Path to alternate lease file. The value of this property is passed
+as an argument to the -lf command-line option of dhcpd. The default value
+is set to /var/db/isc-dhcp/v4.leases for DHCPv4 and /var/db/isc-dhcp/v6.leases for
+DHCPv6.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+listen_ifnames
+.ad
+.sp .6
+.RS 4n
+optional parameter that allows users to specify one or more network
+interfaces on which dhcpd should serve DHCP requests. This property
+matches the "if0" command-line option of dhcpd.  Note that the
+interface names must be seperated by a comma.  Please see Example 4.
+.RE
+
+.sp
+.LP
+The following dhcrelay options are available as
+service configuration properties and can be viewed with svcprop(1M)
+and modified via svccfg(1M):
+.sp
+.ne 2
+.mk
+.na
+append_agent_option (v4 only)
+.ad
+.sp .6
+.RS 4n
+Setting this option to true ensures the DHCP relay appends an agent option
+field to each request before forwarding the request to the DHCP
+server. When this property is set to true, the -a command-line option
+is used when launching dhcrelay. The default value of this property is
+false. This option is only applicable to the svc:/network/dhcp/relay:ipv4 service. 
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+listen_ifnames (v4 only)
+.ad
+.sp .6
+.RS 4n
+This option allows users to specify one or more interfaces on which
+the DHCP relay should listen for DHCPv4/BOOTP queries. This option is
+only applicable to the svc:/network/dhcp/relay:ipv4 service. 
+
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+servers (v4 only)
+.ad
+.sp .6
+.RS 4n
+Users must set this property to the IP addresses of one or more
+servers before enabling the relay service
+(svc:/network/dhcp/relay:ipv4). The servers property value must be a
+comma-separated list of IP addresses. This option is
+only applicable to the svc:/network/dhcp/relay:ipv4 service. 
+
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+receive_query_links (v6 only)
+.ad
+.sp .6
+.RS 4n
+Users must set this property value to specify the interface(s) on which
+queries will be received from clients or from other relay agents
+before enabling the relay service (svc:/network/dhcp/relay:ipv6).
+This option is only applicable to the svc:/network/dhcp/relay:ipv6 service. 
+See also Example 3.
+.RE
+
+.sp
+.ne 2
+.mk
+.na
+forward_query_links (v6 only)
+.ad
+.sp .6
+.RS 4n
+Users must set this property value to specify the interface(s) on which
+queries from clients and other relay agents should be forwarded before
+enabling the relay service (svc:/network/dhcp/relay:ipv6).  The
+property value is passed as the argument for the -u command-line
+option to the dhcrelay program. The interface(s) specified must be
+comma-separated. This option is only applicable to the
+svc:/network/dhcp/relay:ipv6 service. 
+.RE
+
+.sp
+.LP
+Since dhcpd and dhcrelay are managed using SMF no pid files are created.  
+.sp
+.LP
+
+.SH EXAMPLES
+.sp
+.LP
+\fBExample 1 \fR Enabling DHCPv4 Server 
+ISC DHCPv4 server service is disabled by default. The following
+command enables the ISC DHCPv4 service:
+
+.in +2
+.nf
+example# svcadm enable svc:/network/dhcp/server:ipv4
+.fi
+.in -2
+
+\fBExample 2 \fR Displaying the configurable properties of DHCPv6 Relay
+Agent service.  The following command displays all configurable properties of 
+DHCPv6 Relay Agent Service:
+
+.in +2
+.nf
+example# svccfg -s dhcp/relay:ipv6 listprop config
+config                      application
+config/forward_query_links  astring  
+config/listen_ifnames       astring  
+config/receive_query_links  astring  
+config/value_authorization  astring  solaris.smf.value.dhcp
+.fi
+.in -2
+
+.PP
+\fBExample 3 \fR Setting the receive_query_links property value of DHCPv6 Relay
+Agent service.  The following commands will set the receive_links property value to the
+following values: 10.0.0.1%e10000g#0,bge0,iprb#1
+
+.in +2
+.nf
+example# svccfg -s dhcp/relay:ipv6 setprop \\
+    config/receive_query_links= \\
+    \\(\\"10.0.0.1%e10000g#0\\"\\"bge0\\"\\"iprb#1\\"\\)
+example# svccfg -s dhcp/relay:ipv6 refresh
+
+NOTE: spaces are not allowed in the string within quotes in the
+      setprop command 
+
+To verify that the property values are set type either
+the svccfg command or the svcprop command below:
+
+example# svccfg -s dhcp/relay:ipv6 listprop config/receive_query_links
+config/receive_query_links  astring  "10.0.0.1%e10000g#0" "bge0" "iprb#1"
+
+example# svcprop -p config/receive_query_links dhcp/relay:ipv6
+10.0.0.1%e10000g#0 bge0 iprb#1
+.fi
+.in -2
+
+\fBExample 4 \fR Setting the listen_ifnames property value for dhcpd.
+The following commands will set the listen_ifnames property to 
+"bge0, bge1" and then display the updated values.
+
+.in +2
+.nf
+example# svccfg -s dhcp/server:ipv4 setprop \\
+    config/listen_ifnames = \\(\\"bge0\\"\\"bge1\\"\\) 
+example# svccfg -s dhcp/server:ipv4 refresh
+
+NOTE: spaces are not allowed in the string within quotes in the
+      setprop command 
+
+To verify that the property values are set type:
+
+example# svccfg -s dhcp/server:ipv4 listprop config/listen_ifnames
+config/listen_ifnames  astring  "bge0" "bge1" 
+.fi
+.in -2
+
+.SH SEE ALSO
+.sp
+.LP
+svccfg(1M), svcprop(1), svcadm(1M), dhcpd(8), dhcrelay(8)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/patches/nopidfile.patch	Thu Jun 02 13:26:03 2011 -0700
@@ -0,0 +1,657 @@
+Index: DHCP/configure
+===================================================================
+RCS file: /proj/cvs/prod/DHCP/configure,v
+retrieving revision 1.119
+retrieving revision 1.119.6.1
+diff -u -c -r1.119 -r1.119.6.1
+*** DHCP/configure	18 Feb 2011 18:48:44 -0000	1.119
+--- DHCP/configure	11 Apr 2011 21:12:20 -0000	1.119.6.1
+***************
+*** 1328,1333 ****
+--- 1328,1336 ----
+    --with-relay-pid-file=PATH
+                            File for dhcrelay process information (default is
+                            LOCALSTATEDIR/run/dhcrelay.pid)
++   --with-relay6-pid-file=PATH
++                           File for dhcrelay6 process information (default is
++                           LOCALSTATEDIR/run/dhcrelay6.pid)
+
+ Some influential environment variables:
+   CC          C compiler command
+***************
+*** 5062,5067 ****
+--- 5065,5080 ----
+  fi
+  
+  
++ # Check whether --with-relay6-pid-file was given.
++ if test "${with_relay6_pid_file+set}" = set; then
++   withval=$with_relay6_pid_file;
++ cat >>confdefs.h <<_ACEOF
++ #define _PATH_DHCRELAY6_PID "$withval"
++ _ACEOF
++ 
++ fi
++ 
++ 
+  # Check basic types.
+  
+    { echo "$as_me:$LINENO: checking for int8_t" >&5
+Index: DHCP/configure.ac
+===================================================================
+RCS file: /proj/cvs/prod/DHCP/configure.ac,v
+retrieving revision 1.47
+retrieving revision 1.47.6.1
+diff -u -c -r1.47 -r1.47.6.1
+*** DHCP/configure.ac	18 Feb 2011 18:41:25 -0000	1.47
+--- DHCP/configure.ac	9 Apr 2011 00:03:51 -0000	1.47.6.1
+***************
+*** 317,322 ****
+--- 317,328 ----
+  		        (default is LOCALSTATEDIR/run/dhcrelay.pid)]),
+  	AC_DEFINE_UNQUOTED([_PATH_DHCRELAY_PID], ["$withval"],
+  			   [File for dhcrelay process information.]))
++ AC_ARG_WITH(relay6-pid-file,
++ 	AC_HELP_STRING([--with-relay6-pid-file=PATH],
++ 		       [File for dhcrelay6 process information
++ 		        (default is LOCALSTATEDIR/run/dhcrelay6.pid)]),
++ 	AC_DEFINE_UNQUOTED([_PATH_DHCRELAY6_PID], ["$withval"],
++ 			   [File for dhcrelay6 process information.]))
+  
+  # Check basic types.
+  AC_TYPE_INT8_T
+Index: DHCP/client/dhclient.8
+===================================================================
+RCS file: /proj/cvs/prod/DHCP/client/dhclient.8,v
+retrieving revision 1.35
+retrieving revision 1.35.56.2
+diff -u -c -r1.35 -r1.35.56.2
+*** DHCP/client/dhclient.8	14 Jul 2010 20:01:14 -0000	1.35
+--- DHCP/client/dhclient.8	12 Apr 2011 20:47:25 -0000	1.35.56.2
+***************
+*** 90,95 ****
+--- 90,98 ----
+  .I pid-file
+  ]
+  [
++ .B --no-pid
++ ]
++ [
+  .B -cf
+  .I config-file
+  ]
+***************
+*** 99,105 ****
+  ]
+  [
+  .B -s
+! .I server
+  ]
+  [
+  .B -g
+--- 102,108 ----
+  ]
+  [
+  .B -s
+! .I server-addr
+  ]
+  [
+  .B -g
+***************
+*** 305,311 ****
+  transmit, the client will also use a different destination port -
+  one less than the specified port.
+  .TP
+! .BI \-s \ server
+  Specify the server IP address or fully qualified domain name to use as
+  a destination for DHCP protocol messages before 
+  .B dhclient
+--- 308,314 ----
+  transmit, the client will also use a different destination port -
+  one less than the specified port.
+  .TP
+! .BI \-s \ server-addr
+  Specify the server IP address or fully qualified domain name to use as
+  a destination for DHCP protocol messages before 
+  .B dhclient
+***************
+*** 381,386 ****
+--- 384,395 ----
+  .B RUNDIR/dhclient.pid
+  is used.
+  .TP
++ .BI \--no-pid
++ Option to disable writing pid files.  By default the program
++ will write a pid file.  If the program is invoked with this
++ option it will not attempt to kill any existing client processes
++ even if invoked with \fB-r\fR or \fB-x\fR.
++ .TP
+  .BI \-sf \ script-file
+  Path to the network configuration script invoked by
+  .B dhclient
+Index: DHCP/client/dhclient.c
+===================================================================
+RCS file: /proj/cvs/prod/DHCP/client/dhclient.c,v
+retrieving revision 1.178
+retrieving revision 1.178.2.2
+diff -u -c -r1.178 -r1.178.2.2
+*** DHCP/client/dhclient.c	24 Mar 2011 21:11:00 -0000	1.178
+--- DHCP/client/dhclient.c	12 Apr 2011 20:47:25 -0000	1.178.2.2
+***************
+*** 48,53 ****
+--- 48,56 ----
+  static char path_dhclient_script_array[] = _PATH_DHCLIENT_SCRIPT;
+  char *path_dhclient_script = path_dhclient_script_array;
+  
++ /* False (default) => we write and use a pid file */
++ isc_boolean_t no_pid_file = ISC_FALSE;
++ 
+  int dhcp_max_agent_option_packet_length = 0;
+  
+  int interfaces_requested = 0;
+***************
+*** 196,201 ****
+--- 199,206 ----
+  				usage();
+  			path_dhclient_pid = argv[i];
+  			no_dhclient_pid = 1;
++ 		} else if (!strcmp(argv[i], "--no-pid")) {
++ 			no_pid_file = ISC_TRUE;
+  		} else if (!strcmp(argv[i], "-cf")) {
+  			if (++i == argc)
+  				usage();
+***************
+*** 385,392 ****
+  			log_fatal("%s: %s", path, strerror(errno));
+  	}
+  
+! 	/* first kill off any currently running client */
+! 	if (release_mode || exit_mode) {
+  		FILE *pidfd;
+  		pid_t oldpid;
+  		long temp;
+--- 390,402 ----
+  			log_fatal("%s: %s", path, strerror(errno));
+  	}
+  
+! 	/*
+! 	 * See if we should  kill off any currently running client
+! 	 * we don't try to kill it off if the user told us not
+! 	 * to write a pid file - we assume they are controlling
+! 	 * the process in some other fashion.
+! 	 */
+! 	if ((release_mode || exit_mode) && (no_pid_file == ISC_FALSE)) {
+  		FILE *pidfd;
+  		pid_t oldpid;
+  		long temp;
+***************
+*** 677,692 ****
+  	log_info(arr);
+  	log_info(url);
+  
+! 	log_error("Usage: dhclient %s %s",
+  #ifdef DHCPv6
+! 		  "[-4|-6] [-SNTP1dvrx] [-nw] [-p <port>]",
+  #else /* DHCPv6 */
+! 		  "[-1dvrx] [-nw] [-p <port>]",
+  #endif /* DHCPv6 */
+! 		  "[-s server]");
+! 	log_error("                [-cf config-file] [-lf lease-file]%s",
+! 		  "[-pf pid-file] [-e VAR=val]");
+! 	log_fatal("                [-sf script-file] [interface]");
+  }
+  
+  void run_stateless(int exit_mode)
+--- 687,703 ----
+  	log_info(arr);
+  	log_info(url);
+  
+! 
+! 	log_fatal("Usage: dhclient "
+  #ifdef DHCPv6
+! 		  "[-4|-6] [-SNTP1dvrx] [-nw] [-p <port>]\n"
+  #else /* DHCPv6 */
+! 		  "[-1dvrx] [-nw] [-p <port>]\n"
+  #endif /* DHCPv6 */
+! 		  "                [-s server-addr] [-cf config-file] "
+! 		  "[-lf lease-file]\n"
+! 		  "                [-pf pid-file] [--no-pid] [-e VAR=val]\n"
+! 		  "                [-sf script-file] [interface]");
+  }
+  
+  void run_stateless(int exit_mode)
+***************
+*** 3369,3374 ****
+--- 3380,3390 ----
+  	FILE *pf;
+  	int pfdesc;
+  
++ 	/* nothing to do if the user doesn't want a pid file */
++ 	if (no_pid_file == ISC_TRUE) {
++ 		return;
++ 	}
++ 
+  	pfdesc = open (path_dhclient_pid, O_CREAT | O_TRUNC | O_WRONLY, 0644);
+  
+  	if (pfdesc < 0) {
+Index: DHCP/includes/config.h.in
+===================================================================
+RCS file: /proj/cvs/prod/DHCP/includes/config.h.in,v
+retrieving revision 1.60
+retrieving revision 1.60.6.1
+diff -u -c -r1.60 -r1.60.6.1
+*** DHCP/includes/config.h.in	18 Feb 2011 18:48:15 -0000	1.60
+--- DHCP/includes/config.h.in	11 Apr 2011 21:12:03 -0000	1.60.6.1
+***************
+*** 175,180 ****
+--- 175,183 ----
+  /* File for dhcpd process information. */
+  #undef _PATH_DHCPD_PID
+  
++ /* File for dhcrelay6 process information. */
++ #undef _PATH_DHCRELAY6_PID
++ 
+  /* File for dhcrelay process information. */
+  #undef _PATH_DHCRELAY_PID
+  
+Index: DHCP/relay/dhcrelay.8
+===================================================================
+RCS file: /proj/cvs/prod/DHCP/relay/dhcrelay.8,v
+retrieving revision 1.18
+retrieving revision 1.18.58.2
+diff -u -c -r1.18 -r1.18.58.2
+*** DHCP/relay/dhcrelay.8	2 Jul 2010 23:09:14 -0000	1.18
+--- DHCP/relay/dhcrelay.8	12 Apr 2011 20:47:26 -0000	1.18.58.2
+***************
+*** 54,59 ****
+--- 54,66 ----
+  .I length
+  ]
+  [
++ .B -pf
++ .I pid-file
++ ]
++ [
++ .B --no-pid
++ ]
++ [
+  .B -m
+  .I append
+  |
+***************
+*** 89,94 ****
+--- 96,108 ----
+  .B -c
+  .I count
+  ]
++ [
++ .B -pf
++ .I pid-file
++ ]
++ [
++ .B --no-pid
++ ]
+  .B -l
+  .I lower0
+  [
+***************
+*** 150,155 ****
+--- 164,176 ----
+  -q
+  Quiet mode.  Prevents dhcrelay6 from printing its network configuration
+  on startup.
++ .TP
++ -pf pid-file
++ Path to alternate pid file.
++ .TP
++ --no-pid
++ Option to disable writing pid files.  By default the program
++ will write a pid file.
+  .PP
+  \fIOptions available in DHCPv4 mode only:\fR
+  .TP
+Index: DHCP/relay/dhcrelay.c
+===================================================================
+RCS file: /proj/cvs/prod/DHCP/relay/dhcrelay.c,v
+retrieving revision 1.79
+retrieving revision 1.79.106.2
+diff -u -c -r1.79 -r1.79.106.2
+*** DHCP/relay/dhcrelay.c	2 Feb 2010 19:58:18 -0000	1.79
+--- DHCP/relay/dhcrelay.c	12 Apr 2011 20:47:26 -0000	1.79.106.2
+***************
+*** 49,54 ****
+--- 49,57 ----
+  char *tlname;
+  
+  const char *path_dhcrelay_pid = _PATH_DHCRELAY_PID;
++ isc_boolean_t no_dhcrelay_pid = ISC_FALSE;
++ /* False (default) => we write and use a pid file */
++ isc_boolean_t no_pid_file = ISC_FALSE;
+  
+  int bogus_agent_drops = 0;	/* Packets dropped because agent option
+  				   field was specified and we're not relaying
+***************
+*** 138,147 ****
+--- 141,152 ----
+  #define DHCRELAY_USAGE \
+  "Usage: dhcrelay [-4] [-d] [-q] [-a] [-D]\n"\
+  "                     [-A <length>] [-c <hops>] [-p <port>]\n" \
++ "                     [-pf <pid-file>] [--no-pid]\n"\
+  "                     [-m append|replace|forward|discard]\n" \
+  "                     [-i interface0 [ ... -i interfaceN]\n" \
+  "                     server0 [ ... serverN]\n\n" \
+  "       dhcrelay -6   [-d] [-q] [-I] [-c <hops>] [-p <port>]\n" \
++ "                     [-pf <pid-file>] [--no-pid]\n"\
+  "                     -l lower0 [ ... -l lowerN]\n" \
+  "                     -u upper0 [ ... -u upperN]\n" \
+  "       lower (client link): [address%%]interface[#index]\n" \
+***************
+*** 149,154 ****
+--- 154,160 ----
+  #else
+  #define DHCRELAY_USAGE \
+  "Usage: dhcrelay [-d] [-q] [-a] [-D] [-A <length>] [-c <hops>] [-p <port>]\n" \
++ "                [-pf <pid-file>] [--no-pid]\n"\
+  "                [-m append|replace|forward|discard]\n" \
+  "                [-i interface0 [ ... -i interfaceN]\n" \
+  "                server0 [ ... serverN]\n\n"
+***************
+*** 350,355 ****
+--- 356,368 ----
+  			sl->next = upstreams;
+  			upstreams = sl;
+  #endif
++ 		} else if (!strcmp(argv[i], "-pf")) {
++ 			if (++i == argc)
++ 				usage();
++ 			path_dhcrelay_pid = argv[i];
++ 			no_dhcrelay_pid = ISC_TRUE;
++ 		} else if (!strcmp(argv[i], "--no-pid")) {
++ 			no_pid_file = ISC_TRUE;
+  		} else if (!strcmp(argv[i], "--version")) {
+  			log_info("isc-dhcrelay-%s", PACKAGE_VERSION);
+  			exit(0);
+***************
+*** 394,411 ****
+   		}
+  	}
+  
+! 	if (local_family == AF_INET) {
+! 		path_dhcrelay_pid = getenv("PATH_DHCRELAY_PID");
+! 		if (path_dhcrelay_pid == NULL)
+! 			path_dhcrelay_pid = _PATH_DHCRELAY_PID;
+! 	}
+  #ifdef DHCPv6
+! 	else {
+! 		path_dhcrelay_pid = getenv("PATH_DHCRELAY6_PID");
+! 		if (path_dhcrelay_pid == NULL)
+! 			path_dhcrelay_pid = _PATH_DHCRELAY6_PID;
+! 	}
+  #endif
+  
+  	if (!quiet) {
+  		log_info("%s %s", message, PACKAGE_VERSION);
+--- 407,430 ----
+   		}
+  	}
+  
+! 	/*
+! 	 * If the user didn't specify a pid file directly
+! 	 * find one from environment variables or defaults
+! 	 */
+! 	if (no_dhcrelay_pid == ISC_FALSE) {
+! 		if (local_family == AF_INET) {
+! 			path_dhcrelay_pid = getenv("PATH_DHCRELAY_PID");
+! 			if (path_dhcrelay_pid == NULL)
+! 				path_dhcrelay_pid = _PATH_DHCRELAY_PID;
+! 		}
+  #ifdef DHCPv6
+! 		else {
+! 			path_dhcrelay_pid = getenv("PATH_DHCRELAY6_PID");
+! 			if (path_dhcrelay_pid == NULL)
+! 				path_dhcrelay_pid = _PATH_DHCRELAY6_PID;
+! 		}
+  #endif
++ 	}
+  
+  	if (!quiet) {
+  		log_info("%s %s", message, PACKAGE_VERSION);
+***************
+*** 519,538 ****
+  		else if (pid)
+  			exit(0);
+  
+! 		pfdesc = open(path_dhcrelay_pid,
+! 			       O_CREAT | O_TRUNC | O_WRONLY, 0644);
+! 
+! 		if (pfdesc < 0) {
+! 			log_error("Can't create %s: %m", path_dhcrelay_pid);
+! 		} else {
+! 			pf = fdopen(pfdesc, "w");
+! 			if (!pf)
+! 				log_error("Can't fdopen %s: %m",
+! 				      path_dhcrelay_pid);
+! 			else {
+! 				fprintf(pf, "%ld\n",(long)getpid());
+! 				fclose(pf);
+! 			}	
+  		}
+  
+  		close(0);
+--- 538,560 ----
+  		else if (pid)
+  			exit(0);
+  
+! 		if (no_pid_file == ISC_FALSE) {
+! 			pfdesc = open(path_dhcrelay_pid,
+! 				      O_CREAT | O_TRUNC | O_WRONLY, 0644);
+! 
+! 			if (pfdesc < 0) {
+! 				log_error("Can't create %s: %m",
+! 					  path_dhcrelay_pid);
+! 			} else {
+! 				pf = fdopen(pfdesc, "w");
+! 				if (!pf)
+! 					log_error("Can't fdopen %s: %m",
+! 						  path_dhcrelay_pid);
+! 				else {
+! 					fprintf(pf, "%ld\n",(long)getpid());
+! 					fclose(pf);
+! 				}	
+! 			}
+  		}
+  
+  		close(0);
+Index: DHCP/server/dhcpd.8
+===================================================================
+RCS file: /proj/cvs/prod/DHCP/server/dhcpd.8,v
+retrieving revision 1.33
+retrieving revision 1.33.56.2
+diff -u -c -r1.33 -r1.33.56.2
+*** DHCP/server/dhcpd.8	14 Jul 2010 20:01:14 -0000	1.33
+--- DHCP/server/dhcpd.8	12 Apr 2011 20:47:26 -0000	1.33.56.2
+***************
+*** 75,80 ****
+--- 75,83 ----
+  .I pid-file
+  ]
+  [
++ .B --no-pid
++ ]
++ [
+  .B -tf
+  .I trace-output-file
+  ]
+***************
+*** 283,288 ****
+--- 286,296 ----
+  .TP
+  .BI \-pf \ pid-file
+  Path to alternate pid file.
++ .TP
++ .BI \--no-pid
++ Option to disable writing pid files.  By default the program
++ will write a pid file.  If the program is invoked with this
++ option it will not check for an existing server process.
+  .PP
+  .SH CONFIGURATION
+  The syntax of the dhcpd.conf(5) file is discussed separately.   This
+Index: DHCP/server/dhcpd.c
+===================================================================
+RCS file: /proj/cvs/prod/DHCP/server/dhcpd.c,v
+retrieving revision 1.156
+retrieving revision 1.156.42.2
+diff -u -c -r1.156 -r1.156.42.2
+*** DHCP/server/dhcpd.c	8 Sep 2010 22:13:05 -0000	1.156
+--- DHCP/server/dhcpd.c	12 Apr 2011 20:47:26 -0000	1.156.42.2
+***************
+*** 160,165 ****
+--- 160,167 ----
+  const char *path_dhcpd_conf = _PATH_DHCPD_CONF;
+  const char *path_dhcpd_db = _PATH_DHCPD_DB;
+  const char *path_dhcpd_pid = _PATH_DHCPD_PID;
++ /* False (default) => we write and use a pid file */
++ isc_boolean_t no_pid_file = ISC_FALSE;
+  
+  int dhcp_max_agent_option_packet_length = DHCP_MTU_MAX;
+  
+***************
+*** 351,356 ****
+--- 353,360 ----
+  				usage ();
+  			path_dhcpd_pid = argv [i];
+  			no_dhcpd_pid = 1;
++ 		} else if (!strcmp(argv[i], "--no-pid")) {
++ 			no_pid_file = ISC_TRUE;
+                  } else if (!strcmp (argv [i], "-t")) {
+  			/* test configurations only */
+  #ifndef DEBUG
+***************
+*** 783,815 ****
+  	}
+  #endif /* PARANOIA */
+  
+! 	/* Read previous pid file. */
+! 	if ((i = open (path_dhcpd_pid, O_RDONLY)) >= 0) {
+! 		status = read(i, pbuf, (sizeof pbuf) - 1);
+! 		close (i);
+! 		if (status > 0) {
+! 			pbuf[status] = 0;
+! 			pid = atoi(pbuf);
+! 
+! 			/*
+!                          * If there was a previous server process and it's
+!                          * is still running, abort
+!                          */
+! 			if (!pid || (pid != getpid() && kill(pid, 0) == 0))
+! 				log_fatal("There's already a "
+!                                           "DHCP server running.");
+  		}
+- 	}
+- 
+-         /* Write new pid file. */
+-         if ((i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC, 0644)) >= 0) {
+-                 sprintf(pbuf, "%d\n", (int) getpid());
+-                 IGNORE_RET (write(i, pbuf, strlen(pbuf)));
+-                 close(i);
+-         } else {
+-                 log_error("Can't create PID file %s: %m.", path_dhcpd_pid);
+-         }
+  
+  
+  	/* If we were requested to log to stdout on the command line,
+  	   keep doing so; otherwise, stop. */
+--- 787,827 ----
+  	}
+  #endif /* PARANOIA */
+  
+! 	/*
+! 	 * Deal with pid files.  If the user told us
+! 	 * not to write a file we don't read one either
+! 	 */
+! 	if (no_pid_file == ISC_FALSE) {
+! 		/*Read previous pid file. */
+! 		if ((i = open (path_dhcpd_pid, O_RDONLY)) >= 0) {
+! 			status = read(i, pbuf, (sizeof pbuf) - 1);
+! 			close (i);
+! 			if (status > 0) {
+! 				pbuf[status] = 0;
+! 				pid = atoi(pbuf);
+! 
+! 				/*
+! 				 * If there was a previous server process and
+! 				 * it is still running, abort
+! 				 */
+! 				if (!pid ||
+! 				    (pid != getpid() && kill(pid, 0) == 0))
+! 					log_fatal("There's already a "
+! 						  "DHCP server running.");
+! 			}
+  		}
+  
++ 		/* Write new pid file. */
++ 		i = open(path_dhcpd_pid, O_WRONLY|O_CREAT|O_TRUNC, 0644);
++ 		if (i >= 0) {
++ 			sprintf(pbuf, "%d\n", (int) getpid());
++ 			IGNORE_RET (write(i, pbuf, strlen(pbuf)));
++ 			close(i);
++ 		} else {
++ 			log_error("Can't create PID file %s: %m.",
++ 				  path_dhcpd_pid);
++ 		}
++ 	}
+  
+  	/* If we were requested to log to stdout on the command line,
+  	   keep doing so; otherwise, stop. */
+***************
+*** 902,908 ****
+  				   &global_scope, oc, MDL)) {
+  		s = dmalloc (db.len + 1, MDL);
+  		if (!s)
+! 			log_fatal ("no memory for lease db filename.");
+  		memcpy (s, db.data, db.len);
+  		s [db.len] = 0;
+  		data_string_forget (&db, MDL);
+--- 914,920 ----
+  				   &global_scope, oc, MDL)) {
+  		s = dmalloc (db.len + 1, MDL);
+  		if (!s)
+! 			log_fatal ("no memory for pid filename.");
+  		memcpy (s, db.data, db.len);
+  		s [db.len] = 0;
+  		data_string_forget (&db, MDL);
+***************
+*** 938,944 ****
+                                            oc, MDL)) {
+                          s = dmalloc (db.len + 1, MDL);
+                          if (!s)
+!                                 log_fatal ("no memory for lease db filename.");
+                          memcpy (s, db.data, db.len);
+                          s [db.len] = 0;
+                          data_string_forget (&db, MDL);
+--- 950,956 ----
+                                            oc, MDL)) {
+                          s = dmalloc (db.len + 1, MDL);
+                          if (!s)
+!                                 log_fatal ("no memory for pid filename.");
+                          memcpy (s, db.data, db.len);
+                          s [db.len] = 0;
+                          data_string_forget (&db, MDL);
+***************
+*** 1210,1216 ****
+  		  "             [-tf trace-output-file]\n"
+  		  "             [-play trace-input-file]\n"
+  #endif /* TRACING */
+! 		  "             [-pf pid-file] [-s server] [if0 [...ifN]]");
+  }
+  
+  void lease_pinged (from, packet, length)
+--- 1222,1229 ----
+  		  "             [-tf trace-output-file]\n"
+  		  "             [-play trace-input-file]\n"
+  #endif /* TRACING */
+! 		  "             [-pf pid-file] [--no-pid] [-s server]\n"
+! 		  "             [if0 [...ifN]]");
+  }
+  
+  void lease_pinged (from, packet, length)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/patches/sockets.patch	Thu Jun 02 13:26:03 2011 -0700
@@ -0,0 +1,457 @@
+--- dhcp-4.1-ESV-R1/common/discover.c	Tue Sep 29 12:44:49 2009
++++ dhcp-4.1-ESV-R1-patched/common/discover.c	Thu May 26 11:49:33 2011
[email protected]@ -309,6 +309,7 @@
+ next_iface(struct iface_info *info, int *err, struct iface_conf_list *ifaces) {
+ 	struct LIFREQ *p;
+ 	struct LIFREQ tmp;
++	isc_boolean_t foundif;
+ #if defined(sun) || defined(__linux)
+ 	/* Pointer used to remove interface aliases. */
+ 	char *s;
[email protected]@ -315,6 +316,7 @@
+ #endif
+ 
+ 	do {
++		foundif = ISC_FALSE;
+ 		if (ifaces->next >= ifaces->num) {
+ 			*err = 0;
+ 			return 0;
[email protected]@ -328,6 +330,13 @@
+ 			log_error("Interface name '%s' too long", p->lifr_name);
+ 			return 0;
+ 		}
++
++		/* Reject if interface address family does not match */
++		if (p->lifr_addr.ss_family != local_family) {
++			ifaces->next++;
++			continue;
++		}
++
+ 		strcpy(info->name, p->lifr_name);
+ 		memset(&info->addr, 0, sizeof(info->addr));
+ 		memcpy(&info->addr, &p->lifr_addr, sizeof(p->lifr_addr));
[email protected]@ -340,7 +349,9 @@
+ 		}
+ #endif /* defined(sun) || defined(__linux) */
+ 
+-	} while (strncmp(info->name, "dummy", 5) == 0);
++		foundif = ISC_TRUE;
++	} while ((foundif == ISC_FALSE) ||
++	    (strncmp(p->lifr_name, "dummy", 5) == 0));
+ 	
+ 	memset(&tmp, 0, sizeof(tmp));
+ 	strcpy(tmp.lifr_name, info->name);
[email protected]@ -958,7 +969,12 @@
+ 		   point-to-point in case an OS incorrectly marks them
+ 		   as broadcast). Also skip down interfaces unless we're
+ 		   trying to get a list of configurable interfaces. */
+-		if (((!(info.flags & IFF_BROADCAST) ||
++		if ((((local_family == AF_INET &&
++		    !(info.flags & IFF_BROADCAST)) ||
++#ifdef DHCPv6
++		    (local_family == AF_INET6 &&
++		    !(info.flags & IFF_MULTICAST)) ||
++#endif
+ 		      info.flags & IFF_LOOPBACK ||
+ 		      info.flags & IFF_POINTOPOINT) && !tmp) ||
+ 		    (!(info.flags & IFF_UP) &&
[email protected]@ -1386,6 +1402,25 @@
+ 	if (result < DHCP_FIXED_NON_UDP - DHCP_SNAME_LEN - DHCP_FILE_LEN)
+ 		return ISC_R_UNEXPECTED;
+ 
++#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO)
++	{
++		/* We retrieve the ifindex from the unused hfrom variable */
++		unsigned int ifindex;
++
++		memcpy(&ifindex, hfrom.hbuf, sizeof (ifindex));
++
++		/*
++		 * Seek forward from the first interface to find the matching
++		 * source interface by interface index.
++		 */
++		ip = interfaces;
++		while ((ip != NULL) && (if_nametoindex(ip->name) != ifindex))
++			ip = ip->next;
++		if (ip == NULL)
++			return ISC_R_NOTFOUND;
++	}
++#endif
++
+ 	if (bootp_packet_handler) {
+ 		ifrom.len = 4;
+ 		memcpy (ifrom.iabuf, &from.sin_addr, ifrom.len);
[email protected]@ -1442,7 +1477,11 @@
+ 		ifrom.len = 16;
+ 		memcpy(ifrom.iabuf, &from.sin6_addr, ifrom.len);
+ 
+-		/* Seek forward to find the matching source interface. */
++		/*
++		 * Seek forward from the first interface to find the matching
++		 * source interface by interface index.
++		 */
++		ip = interfaces;
+ 		while ((ip != NULL) && (if_nametoindex(ip->name) != if_idx))
+ 			ip = ip->next;
+ 
+--- dhcp-4.1-ESV-R1/common/socket.c	Tue Oct  5 17:32:52 2010
++++ dhcp-4.1-ESV-R1-patched/common/socket.c	Thu May 12 16:11:13 2011
[email protected]@ -45,6 +45,16 @@
+ #include <sys/ioctl.h>
+ #include <sys/uio.h>
+ #include <sys/uio.h>
++#if defined(sun)
++#include <sys/sysmacros.h>
++#include <net/if.h>
++#include <sys/sockio.h>
++#if defined(SIOCGLIFHWADDR)
++#include <net/if_dl.h>
++#else
++#include <libdlpi.h>
++#endif
++#endif
+ #include <signal.h>
+ 
+ #ifdef USE_SOCKET_FALLBACK
[email protected]@ -67,6 +77,16 @@
+ #endif
+ 
+ /*
++ * We can use a single socket for AF_INET (similar to AF_INET6) on all
++ * interfaces configured for DHCP if the system has support for IP_PKTINFO
++ * and IP_RECVPKTINFO (f.e. Solaris 11).
++ */
++#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO)
++static unsigned int global_v4_socket_references = 0;
++static int global_v4_socket = -1;
++#endif
++
++/*
+  * If we can't bind() to a specific interface, then we can only have
+  * a single socket. This variable insures that we don't try to listen
+  * on two sockets.
[email protected]@ -242,6 +262,20 @@
+ 		log_fatal("Can't set IP_BROADCAST_IF on dhcp socket: %m");
+ #endif
+ 
++#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO)
++	/*
++	 * If we turn on IP_RECVPKTINFO we will be able to receive
++	 * the interface index information of the received packet.
++	 */
++	if (family == AF_INET) {
++		int on = 1;
++		if (setsockopt(sock, IPPROTO_IP, IP_RECVPKTINFO, 
++		               &on, sizeof(on)) != 0) {
++			log_fatal("setsockopt: IPV_RECVPKTINFO: %m");
++		}
++	}
++#endif
++
+ #ifdef DHCPv6
+ 	/*
+ 	 * If we turn on IPV6_PKTINFO, we will be able to receive 
[email protected]@ -275,10 +309,6 @@
+ 	}
+ #endif /* DHCPv6 */
+ 
+-	/* If this is a normal IPv4 address, get the hardware address. */
+-	if ((local_family == AF_INET) && (strcmp(info->name, "fallback") != 0))
+-		get_hw_addr(info->name, &info->hw_address);
+-
+ 	return sock;
+ }
+ #endif /* USE_SOCKET_SEND || USE_SOCKET_RECEIVE || USE_SOCKET_FALLBACK */
[email protected]@ -328,9 +358,25 @@
+ void if_register_receive (info)
+ 	struct interface_info *info;
+ {
++#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO)
++	if (global_v4_socket_references == 0) {
++		global_v4_socket = if_register_socket(info, AF_INET, 0);
++		if (global_v4_socket < 0) {
++			/*
++			 * if_register_socket() fatally logs if it fails to
++			 * create a socket, this is just a sanity check.
++			 */
++			log_fatal("Failed to create AF_INET socket %s:%d", MDL);
++		}
++	}
++		
++	info->rfdesc = global_v4_socket;
++	global_v4_socket_references++;
++#else
+ 	/* If we're using the socket API for sending and receiving,
+ 	   we don't need to register this interface twice. */
+ 	info -> rfdesc = if_register_socket (info, AF_INET, 0);
++#endif
+ 	if (!quiet_interface_discovery)
+ 		log_info ("Listening on Socket/%s%s%s",
+ 		      info -> name,
[email protected]@ -337,13 +383,34 @@
+ 		      (info -> shared_network ? "/" : ""),
+ 		      (info -> shared_network ?
+ 		       info -> shared_network -> name : ""));
++
++	/* If this is a normal IPv4 address, get the hardware address. */
++	if (strcmp(info->name, "fallback") != 0)
++		get_hw_addr(info->name, &info->hw_address);
+ }
+ 
+ void if_deregister_receive (info)
+ 	struct interface_info *info;
+ {
++#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO)
++	/* Dereference the global v4 socket. */
++	if ((info->rfdesc == global_v4_socket) &&
++	    (info->wfdesc == global_v4_socket) &&
++	    (global_v4_socket_references > 0)) {
++		global_v4_socket_references--;
++		info->rfdesc = -1;
++	} else {
++		log_fatal("Impossible condition at %s:%d", MDL);
++	}
++
++	if (global_v4_socket_references == 0) {
++		close(global_v4_socket);
++		global_v4_socket = -1;
++	}
++#else
+ 	close (info -> rfdesc);
+ 	info -> rfdesc = -1;
++#endif
+ 
+ 	if (!quiet_interface_discovery)
+ 		log_info ("Disabling input on Socket/%s%s%s",
[email protected]@ -489,6 +556,17 @@
+ 	int retry = 0;
+ 	do {
+ #endif
++#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO)
++		struct in_pktinfo pktinfo;
++
++		if (interface->ifp != NULL) {
++			memset(&pktinfo, 0, sizeof (pktinfo));
++			pktinfo.ipi_ifindex = interface->ifp->ifr_index;
++			if (setsockopt(interface -> wfdesc, IPPROTO_IP,
++			    IP_PKTINFO, (char *)&pktinfo, sizeof (pktinfo)) < 0)
++				log_fatal("setsockopt: IP_PKTINFO: %m");
++		}
++#endif
+ 		result = sendto (interface -> wfdesc, (char *)raw, len, 0,
+ 				 (struct sockaddr *)to, sizeof *to);
+ #ifdef IGNORE_HOSTUNREACH
[email protected]@ -559,11 +637,13 @@
+ 
+ #endif /* DHCPv6 */
+ 
+-#ifdef DHCPv6
++#ifdef DHCPv6 || (defined(IP_PKTINFO) && defined(IP_RECVPKTINFO))
+ /*
+  * For both send_packet6() and receive_packet6() we need to allocate
+  * space for the cmsg header information.  We do this once and reuse
+- * the buffer.
++ * the buffer. We also need the control buf for send_packet and
++ * receive_packet for AF_INET when we use a single socket and IP_PKTINFO
++ * to send the packet out the right interface.
+  */
+ static void   *control_buf = NULL;
+ static size_t  control_buf_len = 0;
[email protected]@ -574,7 +654,9 @@
+ 	control_buf = dmalloc(control_buf_len, MDL);
+ 	return;
+ }
++#endif
+ 
++#ifdef DHCPv6
+ /* 
+  * For both send_packet6() and receive_packet6() we need to use the 
+  * sendmsg()/recvmsg() functions rather than the simpler send()/recv()
[email protected]@ -687,8 +769,97 @@
+ 	int retry = 0;
+ 	do {
+ #endif
++#if defined(IP_PKTINFO) && defined(IP_RECVPKTINFO)
++	struct msghdr m;
++	struct iovec v;
++	struct cmsghdr *cmsg;
++	struct in_pktinfo *pktinfo;
++	unsigned int ifindex;
++	int found_pktinfo;
++
++	/*
++	 * If necessary allocate space for the control message header.
++	 * The space is common between send and receive.
++	 */
++	if (control_buf == NULL) {
++		allocate_cmsg_cbuf();
++		if (control_buf == NULL) {
++			log_error("receive_packet: unable to allocate cmsg "
++				  "header");
++			return(ENOMEM);
++		}
++	}
++	memset(control_buf, 0, control_buf_len);
++
++	/*
++	 * Initialize our message header structure.
++	 */
++	memset(&m, 0, sizeof(m));
++
++	/*
++	 * Point so we can get the from address.
++	 */
++	m.msg_name = from;
++	m.msg_namelen = sizeof(*from);
++
++	/*
++	 * Set the data buffer we're receiving. (Using this wacky 
++	 * "scatter-gather" stuff... but we that doesn't really make
++	 * sense for us, so we use a single vector entry.)
++	 */
++	v.iov_base = buf;
++	v.iov_len = len;
++	m.msg_iov = &v;
++	m.msg_iovlen = 1;
++
++	/*
++	 * Getting the interface is a bit more involved.
++	 *
++	 * We set up some space for a "control message". We have 
++	 * previously asked the kernel to give us packet 
++	 * information (when we initialized the interface), so we
++	 * should get the destination address from that.
++	 */
++	m.msg_control = control_buf;
++	m.msg_controllen = control_buf_len;
++
++	result = recvmsg(interface->rfdesc, &m, 0);
++
++	if (result >= 0) {
++		/*
++		 * If we did read successfully, then we need to loop
++		 * through the control messages we received and 
++		 * find the one with our destination address.
++		 *
++		 * We also keep a flag to see if we found it. If we 
++		 * didn't, then we consider this to be an error.
++		 */
++		found_pktinfo = 0;
++		cmsg = CMSG_FIRSTHDR(&m);
++		while (cmsg != NULL) {
++			if ((cmsg->cmsg_level == IPPROTO_IP) && 
++			    (cmsg->cmsg_type == IP_PKTINFO)) {
++				pktinfo = (struct in_pktinfo *)CMSG_DATA(cmsg);
++				ifindex = pktinfo->ipi_ifindex;
++				/*
++				 * We pass the ifindex back to the caller using
++				 * the unused hfrom parameter avoiding interface
++				 * changes between sockets and the discover code.
++				 */
++				memcpy(hfrom->hbuf, &ifindex, sizeof (ifindex));
++				found_pktinfo = 1;
++			}
++			cmsg = CMSG_NXTHDR(&m, cmsg);
++		}
++		if (!found_pktinfo) {
++			result = -1;
++			errno = EIO;
++		}
++	}
++#else
+ 		result = recvfrom (interface -> rfdesc, (char *)buf, len, 0,
+ 				   (struct sockaddr *)from, &flen);
++#endif
+ #ifdef IGNORE_HOSTUNREACH
+ 	} while (result < 0 &&
+ 		 (errno == EHOSTUNREACH ||
[email protected]@ -842,7 +1013,7 @@
+ int supports_multiple_interfaces (ip)
+ 	struct interface_info *ip;
+ {
+-#if defined (SO_BINDTODEVICE)
++#if defined (SO_BINDTODEVICE) || (defined(IP_PKTINFO) && defined(IP_RECVPKTINFO))
+ 	return 1;
+ #else
+ 	return 0;
[email protected]@ -876,6 +1047,80 @@
+ 	}
+ #endif
+ }
++
++#if defined(sun)
++void
++get_hw_addr(const char *name, struct hardware *hw) {
++#if defined(SIOCGLIFHWADDR)
++	struct sockaddr_dl *dladdrp;
++#else
++	dlpi_handle_t dh;
++	uint8_t pa_buf[DLPI_PHYSADDR_MAX];
++	size_t  len = sizeof (pa_buf);
++#endif
++	int rv, sock, i;
++	struct lifreq lifr;
++
++	memset(&lifr, 0, sizeof (lifr));
++	(void) strlcpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
++	/*
++	 * Check if the interface is a virtual or IPMP interface - in those
++	 * cases it has no hw address, so generate a random one.
++	 */
++	if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ||
++	    ioctl(sock, SIOCGLIFFLAGS, &lifr) < 0) {
++		/*
++		 * If the interface only has IPv6, try this with an IPv6 socket.
++		 */
++		if (sock != -1)
++			(void) close(sock);
++
++		if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0 ||
++		    ioctl(sock, SIOCGLIFFLAGS, &lifr) < 0) {
++			log_fatal("Couldn't get interface flags for %s: %m", name);
++		}
++	}
++
++	if (lifr.lifr_flags & (IFF_VIRTUAL|IFF_IPMP)) {
++		hw->hlen = sizeof (hw->hbuf);
++		srandom((long)gethrtime());
++
++		for (i = 0; i < hw->hlen; ++i) {
++			hw->hbuf[i] = random() % 256;
++		}
++
++		if (sock != -1)
++			(void) close(sock);
++		return;
++	}
++
++#if defined(SIOCGLIFHWADDR)
++	if (ioctl(sock, SIOCGLIFHWADDR, &lifr) < 0)
++		log_fatal("Couldn't get interface hardware address for %s: %m", name);
++	dladdrp = (struct sockaddr_dl *)&lifr.lifr_addr;
++	hw->hlen = dladdrp->sdl_alen;
++	memcpy(hw->hbuf, LLADDR(dladdrp), hw->hlen);
++#else
++	if ((rv = dlpi_open(name, &dh, 0)) != DLPI_SUCCESS) {
++		log_fatal("Couldn't open DLPI device for %s: %s", name,
++		dlpi_strerror(rv));
++	}
++
++	if ((rv = dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, pa_buf, &len))
++	    != DLPI_SUCCESS) {
++		log_fatal("Couldn't get physical address for device %s: %s",
++		name, dlpi_strerror(rv));
++	}
++
++	hw->hlen = MIN(sizeof (hw->hbuf), len);
++	memcpy(hw->hbuf, pa_buf, hw->hlen);
++
++	dlpi_close(dh);
++#endif
++	if (sock != -1)
++		(void) close(sock);
++}
++#endif /* defined(sun) */
+ #endif /* USE_SOCKET_SEND */
+ 
+ /*
--- a/transforms/defaults	Thu Jun 02 09:52:40 2011 -0700
+++ b/transforms/defaults	Thu Jun 02 13:26:03 2011 -0700
@@ -75,6 +75,7 @@
 <transform file path=usr/share/pixmaps/.* -> default group other>
 
 <transform dir path=usr/gnu/share$ -> default group sys>
+<transform dir path=var/db$ -> default group sys>
 
 # usr/share/icons, and all its subdirectories at any level are group other
 <transform dir path=usr/share/icons(/.*){0,1}$ -> default group other>