--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/isc-dhcp/patches/004-dhcp_broadcast_offer_bug.patch Mon Feb 15 11:37:48 2016 -0800
@@ -0,0 +1,175 @@
+This patch file was developed in-house to fix a bug specific to solaris only.
+(Bug #17423148). We are working with upstream, but it is unclear at this point whether
+they are going to accept it or not. This is a higly visible bug which many customers
+have run into and it is very much desired that that this fix makes it to S12.
+
+--- old/includes/dhcpd.h Tue Nov 10 16:43:33 2015
++++ new/includes/dhcpd.h Tue Nov 10 16:38:06 2015
+@@ -1150,6 +1150,9 @@
+ int configured; /* If set to 1, interface has at least
+ * one valid IP address.
+ */
++#if defined (sun)
++ int set_arp_socket; /* IOCTL socket to set entry in cache */
++#endif
+ u_int32_t flags; /* Control flags... */
+ #define INTERFACE_REQUESTED 1
+ #define INTERFACE_AUTOMATIC 2
+@@ -2173,6 +2176,10 @@
+ struct sockaddr_in6 *, struct hardware *);
+ #endif
+
++#if defined (sun)
++int setup_arp(struct interface_info *, struct in_addr, unsigned char *);
++#endif
++
+ #ifdef USE_SOCKET_SEND
+ void if_reinitialize_send (struct interface_info *);
+ void if_register_send (struct interface_info *);
+--- old/relay/dhcrelay.c Thu Aug 23 12:23:54 2012
++++ new/relay/dhcrelay.c Tue Nov 10 16:36:52 2015
+@@ -630,6 +630,13 @@
+ to.sin_addr = packet->yiaddr;
+ to.sin_port = remote_port;
+
++#if defined (sun)
++ if (setup_arp(out, packet->yiaddr, packet->chaddr)) {
++ log_error("do_relay4 : Set arp entry failed");
++ return;
++ }
++#endif
++
+ /* and hardware address is not broadcast */
+ htop = &hto;
+ } else {
+--- old/common/socket.c Thu Aug 23 12:23:53 2012
++++ new/common/socket.c Tue Nov 10 16:33:30 2015
+@@ -46,6 +46,10 @@
+ #include <sys/uio.h>
+ #include <sys/uio.h>
+ #include <signal.h>
++#include <sys/types.h>
++#if defined (sun)
++#include <sys/ethernet.h>
++#endif
+
+ #if defined(sun) && defined(USE_V4_PKTINFO)
+ #include <sys/sysmacros.h>
+@@ -93,6 +97,33 @@
+ static int once = 0;
+ #endif /* !defined(SO_BINDTODEVICE) && !defined(USE_FALLBACK) */
+
++#if defined (sun)
++int
++setup_arp(struct interface_info *interface, struct in_addr ip_addr,
++ unsigned char *macaddr)
++{
++ struct xarpreq ar;
++ struct sockaddr_in *sin;
++
++ (void) memset(&ar, 0, sizeof (ar));
++ sin = (struct sockaddr_in *)&ar.xarp_pa;
++ sin->sin_family = AF_INET;
++ sin->sin_addr.s_addr = ip_addr.s_addr;
++
++ ar.xarp_ha.sdl_alen = ETHERADDRL;
++ (void) memcpy(LLADDR(&ar.xarp_ha), macaddr, ar.xarp_ha.sdl_alen);
++ ar.xarp_ha.sdl_family = AF_LINK;
++ if (ioctl(interface->set_arp_socket, SIOCSXARP, (caddr_t)&ar) < 0) {
++ log_error("setup_arp: ioctl error for IP %s MAC %s",
++ inet_ntoa(ip_addr), ether_ntoa((const struct ether_addr *)
++ macaddr));
++ return (1);
++ }
++ return (0);
++}
++#endif
++
++
+ /* Reinitializes the specified interface after an address change. This
+ is not required for packet-filter APIs. */
+
+@@ -328,6 +359,9 @@
+ #else
+ info->wfdesc = info->rfdesc;
+ #endif
++#if defined(sun)
++ info->set_arp_socket = socket(AF_INET, SOCK_DGRAM, 0);
++#endif
+ if (!quiet_interface_discovery)
+ log_info ("Sending on Socket/%s%s%s",
+ info->name,
+@@ -344,6 +378,9 @@
+ close (info -> wfdesc);
+ #endif
+ info -> wfdesc = -1;
++#if defined (sun)
++ close (info -> set_arp_socket);
++#endif
+
+ if (!quiet_interface_discovery)
+ log_info ("Disabling output on Socket/%s%s%s",
+@@ -1006,7 +1043,11 @@
+ int can_unicast_without_arp (ip)
+ struct interface_info *ip;
+ {
++#if defined (sun)
++ return 1;
++#else
+ return 0;
++#endif
+ }
+
+ int can_receive_unicast_unconfigured (ip)
+--- old/server/bootp.c Mon Aug 13 17:15:04 2012
++++ new/server/bootp.c Tue Nov 10 15:23:38 2015
+@@ -408,7 +408,12 @@
+ can_unicast_without_arp (packet -> interface)) {
+ to.sin_addr = raw.yiaddr;
+ to.sin_port = remote_port;
+-
++#if defined (__sun)
++ if (setup_arp(packet->interface, raw.yiaddr, raw.chaddr)) {
++ log_error("bootp : Set arp entry failed");
++ goto out;
++ }
++#endif
+ /* Otherwise, broadcast it on the local network. */
+ } else {
+ to.sin_addr = limited_broadcast;
+--- old/server/dhcp.c Tue Nov 10 16:43:33 2015
++++ new/server/dhcp.c Tue Nov 10 16:39:46 2015
+@@ -36,6 +36,8 @@
+ #include <errno.h>
+ #include <limits.h>
+ #include <sys/time.h>
++#include <sys/sockio.h>
++#include <sys/ioccom.h>
+
+ static void commit_leases_ackout(void *foo);
+
+@@ -3246,7 +3248,12 @@
+ can_unicast_without_arp (state -> ip)) {
+ to.sin_addr = raw.yiaddr;
+ to.sin_port = remote_port;
+-
++#if defined (sun)
++ if (setup_arp(state->ip, raw.yiaddr, raw.chaddr)) {
++ log_error("dhcp_reply : Set arp entry failed");
++ goto err_out;
++ }
++#endif
+ /* Otherwise, broadcast it on the local network. */
+ } else {
+ to.sin_addr = limited_broadcast;
+@@ -3268,7 +3275,9 @@
+
+ /* Free all of the entries in the option_state structure
+ now that we're done with them. */
+-
++#if defined (sun)
++err_out:
++#endif
+ free_lease_state (state, MDL);
+ lease -> state = (struct lease_state *)0;
+ }