--- old/usr/src/cmd/cmd-inet/usr.sbin/ipadm/ipadm.c	2012-06-13 12:04:11.255317323 +0000
+++ new/usr/src/cmd/cmd-inet/usr.sbin/ipadm/ipadm.c	2012-06-13 12:04:11.374649312 +0000
@@ -633,7 +633,7 @@
 
 /*
  * Properties to be displayed is in `statep->sps_proplist'. If it is NULL,
- * for all the properties for the specified object, relavant information, will
+ * for all the properties for the specified object, relevant information, will
  * be displayed. Otherwise, for the selected property set, display relevant
  * information
  */
@@ -855,7 +855,7 @@
 
 /*
  * Display information for all or specific protocol properties, either for a
- * given protocol or for supported protocols (IP/IPv4/IPv6/TCP/UDP/SCTP)
+ * given protocol or for supported protocols (IP/IPv4/IPv6/TCP/UDP/SCTP/DCCP)
  */
 static void
 do_show_prop(int argc, char **argv, const char *use)
--- old/usr/src/cmd/mdb/common/modules/ip/ip.c	2012-06-13 12:04:13.826592671 +0000
+++ new/usr/src/cmd/mdb/common/modules/ip/ip.c	2012-06-13 12:04:13.926324603 +0000
@@ -341,7 +341,7 @@
 
 /*
  * Generic network stack walker initialization function.  It is used by all
- * other netwrok stack walkers.
+ * other network stack walkers.
  */
 int
 ns_walk_init(mdb_walk_state_t *wsp)
@@ -374,6 +374,15 @@
 }
 
 /*
+ * DCCP network stack walker stepping function.
+ */
+int
+dccp_stacks_walk_step(mdb_walk_state_t *wsp)
+{
+	return (ns_walk_step(wsp, NS_DCCP));
+}
+
+/*
  * IP network stack walker stepping function.
  */
 int
@@ -1953,6 +1962,8 @@
 		nce_walk_init, nce_walk_step, NULL },
 	{ "dce", "walk active dce_t structures",
 		dce_walk_init, dce_walk_step, NULL },
+	{ "dccp_stacks", "walk all the dccp_stack_t",
+		ns_walk_init, dccp_stacks_walk_step, NULL },
 	{ "ip_stacks", "walk all the ip_stack_t",
 		ns_walk_init, ip_stacks_walk_step, NULL },
 	{ "tcp_stacks", "walk all the tcp_stack_t",
--- old/usr/src/lib/libipadm/common/ipadm_prop.c	2012-06-13 12:04:15.993388028 +0000
+++ new/usr/src/lib/libipadm/common/ipadm_prop.c	2012-06-13 12:04:19.081843425 +0000
@@ -26,7 +26,7 @@
  * This file contains routines that are used to modify/retrieve protocol or
  * interface property values. It also holds all the supported properties for
  * both IP interface and protocols in `ipadm_prop_desc_t'. Following protocols
- * are supported: IP, IPv4, IPv6, TCP, SCTP, UDP and ICMP.
+ * are supported: IP, IPv4, IPv6, TCP, SCTP, UDP, ICMP and DCCP.
  *
  * This file also contains walkers, which walks through the property table and
  * calls the callback function, of the form `ipadm_prop_wfunc_t' , for every
@@ -82,7 +82,7 @@
 /* array of protocols we support */
 static int protocols[] = { MOD_PROTO_IP, MOD_PROTO_RAWIP,
 			    MOD_PROTO_TCP, MOD_PROTO_UDP,
-			    MOD_PROTO_SCTP };
+			    MOD_PROTO_SCTP, MOD_PROTO_DCCP };
 
 /*
  * Supported IP protocol properties.
@@ -239,6 +239,30 @@
 	{ NULL, 0, 0, 0, NULL, NULL, NULL }
 };
 
+/* Supported DCCP protocol properties */
+static ipadm_prop_desc_t ipadm_dccp_prop_table[] = {
+	{ "extra_priv_ports", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP,
+	    IPADMPROP_MULVAL, i_ipadm_set_eprivport, i_ipadm_get_prop,
+	    i_ipadm_get_prop },
+
+	{ "largest_anon_port", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP, 0,
+	    i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
+
+	{ "recv_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP, 0,
+	    i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
+
+	{ "send_maxbuf", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP, 0,
+	    i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
+
+	{ "smallest_anon_port", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP, 0,
+	    i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
+
+	{ "smallest_nonpriv_port", IPADMPROP_CLASS_MODULE, MOD_PROTO_DCCP, 0,
+	    i_ipadm_set_prop, i_ipadm_get_prop, i_ipadm_get_prop },
+
+	{ NULL, 0, 0, 0, NULL, NULL, NULL }
+};
+
 /*
  * A dummy private property structure, used while handling private
  * protocol properties (properties not yet supported by libipadm).
@@ -266,6 +290,8 @@
 		return (ipadm_udp_prop_table);
 	case MOD_PROTO_SCTP:
 		return (ipadm_sctp_prop_table);
+	case MOD_PROTO_DCCP:
+		return (ipadm_dccp_prop_table);
 	}
 
 	return (NULL);
@@ -320,6 +346,8 @@
 		return ("udp");
 	case MOD_PROTO_SCTP:
 		return ("sctp");
+	case MOD_PROTO_DCCP:
+		return ("dccp");
 	}
 
 	return (NULL);
@@ -346,6 +374,8 @@
 		return (MOD_PROTO_SCTP);
 	else if (strcmp(protostr, "arp") == 0)
 		return (MOD_PROTO_IP);
+	else if (strcmp(protostr, "dccp") == 0)
+		return (MOD_PROTO_DCCP);
 
 	return (MOD_PROTO_NONE);
 }
--- old/usr/src/pkg/manifests/system-kernel.mf	2012-06-13 12:04:20.732798323 +0000
+++ new/usr/src/pkg/manifests/system-kernel.mf	2012-06-13 12:04:20.806956310 +0000
@@ -126,6 +126,8 @@
 driver name=crypto perms="crypto 0666 root sys"
 driver name=cryptoadm perms="cryptoadm 0644 root sys"
 $(sparc_ONLY)driver name=dad alias=ide-disk perms="* 0640 root sys"
+driver name=dccp perms="dccp 0666 root sys"
+driver name=dccp6 perms="dccp6 0666 root sys"
 driver name=devinfo perms="devinfo 0640 root sys" \
     perms="devinfo,ro 0444 root sys"
 driver name=dld perms="* 0666 root sys"
@@ -341,6 +343,8 @@
 file path=kernel/drv/$(ARCH64)/crypto group=sys
 file path=kernel/drv/$(ARCH64)/cryptoadm group=sys
 $(sparc_ONLY)file path=kernel/drv/$(ARCH64)/dad group=sys
+file path=kernel/drv/$(ARCH64)/dccp group=sys
+file path=kernel/drv/$(ARCH64)/dccp6 group=sys
 file path=kernel/drv/$(ARCH64)/devinfo group=sys
 file path=kernel/drv/$(ARCH64)/dld group=sys
 file path=kernel/drv/$(ARCH64)/dlpistub group=sys
@@ -439,6 +443,10 @@
 $(i386_ONLY)file path=kernel/drv/cryptoadm group=sys
 file path=kernel/drv/cryptoadm.conf group=sys
 $(sparc_ONLY)file path=kernel/drv/dad.conf group=sys
+$(i386_ONLY)file path=kernel/drv/dccp group=sys
+file path=kernel/drv/dccp.conf group=sys
+$(i386_ONLY)file path=kernel/drv/dccp6 group=sys
+file path=kernel/drv/dccp6.conf group=sys
 $(i386_ONLY)file path=kernel/drv/devinfo group=sys
 file path=kernel/drv/devinfo.conf group=sys
 $(i386_ONLY)file path=kernel/drv/dld group=sys
@@ -826,6 +834,8 @@
 $(i386_ONLY)hardlink path=kernel/misc/md5 target=../../kernel/crypto/md5
 $(i386_ONLY)hardlink path=kernel/misc/sha1 target=../../kernel/crypto/sha1
 $(i386_ONLY)hardlink path=kernel/misc/sha2 target=../../kernel/crypto/sha2
+hardlink path=kernel/socketmod/$(ARCH64)/dccp \
+    target=../../../kernel/drv/$(ARCH64)/dccp
 hardlink path=kernel/socketmod/$(ARCH64)/icmp \
     target=../../../kernel/drv/$(ARCH64)/icmp
 hardlink path=kernel/socketmod/$(ARCH64)/rts \
@@ -834,12 +844,15 @@
     target=../../../kernel/drv/$(ARCH64)/tcp
 hardlink path=kernel/socketmod/$(ARCH64)/udp \
     target=../../../kernel/drv/$(ARCH64)/udp
+$(i386_ONLY)hardlink path=kernel/socketmod/dccp target=../../kernel/drv/dccp
 $(i386_ONLY)hardlink path=kernel/socketmod/icmp target=../../kernel/drv/icmp
 $(i386_ONLY)hardlink path=kernel/socketmod/rts target=../../kernel/drv/rts
 $(i386_ONLY)hardlink path=kernel/socketmod/tcp target=../../kernel/drv/tcp
 $(i386_ONLY)hardlink path=kernel/socketmod/udp target=../../kernel/drv/udp
 hardlink path=kernel/strmod/$(ARCH64)/arp \
     target=../../../kernel/drv/$(ARCH64)/arp
+hardlink path=kernel/strmod/$(ARCH64)/dccp \
+    target=../../../kernel/drv/$(ARCH64)/dccp
 hardlink path=kernel/strmod/$(ARCH64)/icmp \
     target=../../../kernel/drv/$(ARCH64)/icmp
 hardlink path=kernel/strmod/$(ARCH64)/ip \
@@ -855,6 +868,7 @@
 hardlink path=kernel/strmod/$(ARCH64)/udp \
     target=../../../kernel/drv/$(ARCH64)/udp
 $(i386_ONLY)hardlink path=kernel/strmod/arp target=../../kernel/drv/arp
+$(i386_ONLY)hardlink path=kernel/strmod/dccp target=../../kernel/drv/dccp
 $(i386_ONLY)hardlink path=kernel/strmod/icmp target=../../kernel/drv/icmp
 $(i386_ONLY)hardlink path=kernel/strmod/ip target=../../kernel/drv/ip
 $(i386_ONLY)hardlink path=kernel/strmod/ipsecah \
--- old/usr/src/uts/common/Makefile.files	2012-06-13 12:04:22.752652253 +0000
+++ new/usr/src/uts/common/Makefile.files	2012-06-13 12:04:22.824277069 +0000
@@ -543,6 +543,8 @@
 		sctp_addr.o tn_ipopt.o tnet.o ip_netinfo.o \
 		sctp_misc.o
 IP_ILB_OBJS =	ilb.o ilb_nat.o ilb_conn.o ilb_alg_hash.o ilb_alg_rr.o
+IP_DCCP_OBJS =	dccp.o dccp_bind.o dccp_input.o dccp_opt_data.o dccp_output.o \
+		dccp_stats.o dccp_socket.o dccp_tpi.o dccp_tunables.o
 
 IP_OBJS +=	igmp.o ipmp.o ip.o ip6.o ip6_asp.o ip6_if.o ip6_ire.o \
 		ip6_rts.o ip_if.o ip_ire.o ip_listutils.o ip_mroute.o \
@@ -558,7 +560,8 @@
 		$(IP_TCP_OBJS) \
 		$(IP_UDP_OBJS) \
 		$(IP_SCTP_OBJS) \
-		$(IP_ILB_OBJS)
+		$(IP_ILB_OBJS) \
+		$(IP_DCCP_OBJS)
 
 IP6_OBJS +=	ip6ddi.o
 
@@ -617,6 +620,10 @@
 
 UDP6_OBJS +=	udp6ddi.o
 
+DCCP_OBJS +=	dccpddi.o
+
+DCCP6_OBJS +=	dccp6ddi.o
+
 SY_OBJS +=	gentty.o
 
 TCO_OBJS +=	ticots.o
--- old/usr/src/uts/common/Makefile.rules	2012-06-13 12:04:24.342048958 +0000
+++ new/usr/src/uts/common/Makefile.rules	2012-06-13 12:04:24.402777879 +0000
@@ -476,6 +476,10 @@
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
 
+$(OBJS_DIR)/%.o:		$(UTSBASE)/common/inet/dccp/%.c
+	$(COMPILE.c) -o $@ $<
+	$(CTFCONVERT_O)
+
 $(OBJS_DIR)/%.o:		$(UTSBASE)/common/inet/ip/%.c
 	$(COMPILE.c) -o $@ $<
 	$(CTFCONVERT_O)
@@ -1877,6 +1881,9 @@
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/common/inet/arp/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
+$(LINTS_DIR)/%.ln:		$(UTSBASE)/common/inet/dccp/%.c
+	@($(LHEAD) $(LINT.c) $< $(LTAIL))
+
 $(LINTS_DIR)/%.ln:		$(UTSBASE)/common/inet/ip/%.c
 	@($(LHEAD) $(LINT.c) $< $(LTAIL))
 
--- /dev/null	2012-06-13 12:04:29.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp.c	2012-06-13 12:04:29.030621901 +0000
@@ -0,0 +1,876 @@
+/*
+ * 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 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2012 David Hoeppner.  All rights reserved.
+ */
+
+/*
+ * This file implements the Data Congestion Control Protocol (DCCP).
+ */
+
+#include <sys/types.h>
+#include <sys/stream.h>
+#include <sys/stropts.h>
+#include <sys/strlog.h>
+#include <sys/strsun.h>
+#define	_SUN_TPI_VERSION 2
+#include <sys/tihdr.h>
+#include <sys/socket.h>
+#include <sys/socketvar.h>
+#include <sys/sockio.h>
+#include <sys/vtrace.h>
+#include <sys/sdt.h>
+#include <sys/debug.h>
+#include <sys/isa_defs.h>
+#include <sys/tsol/label.h>
+#include <sys/tsol/tnet.h>
+#include <inet/kstatcom.h>
+#include <inet/snmpcom.h>
+
+#include <sys/cmn_err.h>
+
+#include "dccp_impl.h"
+#include "dccp_stack.h"
+
+/* Setable in /etc/system */
+uint_t dccp_bind_fanout_size = DCCP_BIND_FANOUT_SIZE;
+
+static void	dccp_notify(void *, ip_xmit_attr_t *, ixa_notify_type_t,
+		    ixa_notify_arg_t);
+
+/* Functions to register netstack */
+static void	*dccp_stack_init(netstackid_t, netstack_t *);
+static void	dccp_stack_fini(netstackid_t, void *);
+
+static int	dccp_openv4(queue_t *, dev_t *, int, int, cred_t *);
+static int	dccp_openv6(queue_t *, dev_t *, int, int, cred_t *);
+
+/* Write service routine */
+static void	dccp_wsrv(queue_t *);
+
+/* Connection related functions */
+static int	dccp_connect_ipv4(dccp_t *, ipaddr_t *, in_port_t, uint_t);
+static int	dccp_connect_ipv6(dccp_t *, in6_addr_t *, in_port_t, uint32_t,
+    uint_t, uint32_t);
+
+struct module_info dccp_rinfo = {
+	DCCP_MOD_ID, DCCP_MOD_NAME, 0, INFPSZ, DCCP_RECV_HIWATER,
+	DCCP_RECV_LOWATER
+};
+
+static struct module_info dccp_winfo = {
+	DCCP_MOD_ID, DCCP_MOD_NAME, 0, INFPSZ, 127, 16
+};
+
+/*
+ * Queue information structure with DCCP entry points.
+ */
+struct qinit dccp_rinitv4 = {
+	NULL, (pfi_t)dccp_rsrv, dccp_openv4, dccp_tpi_close, NULL, &dccp_rinfo
+};
+
+struct qinit dccp_rinitv6 = {
+	NULL, (pfi_t)dccp_rsrv, dccp_openv6, dccp_tpi_close, NULL, &dccp_rinfo
+};
+
+struct qinit dccp_winit = {
+	(pfi_t)dccp_wput, (pfi_t)dccp_wsrv, NULL, NULL, NULL, &dccp_winfo
+};
+
+/* AF_INET /dev/dccp */
+struct streamtab dccpinfov4 = {
+	&dccp_rinitv4, &dccp_winit
+};
+
+/* AF_INET6 /dev/dccp6 */
+struct streamtab dccpinfov6 = {
+	&dccp_rinitv6, &dccp_winit
+};
+
+/*
+ * Tunables.
+ */
+extern mod_prop_info_t dccp_propinfo_tbl[];
+extern int dccp_propinfo_count;
+
+/*
+ * Register DCCP netstack.
+ */
+void
+dccp_ddi_g_init(void)
+{
+	netstack_register(NS_DCCP, dccp_stack_init, NULL, dccp_stack_fini);
+}
+
+#define	INET_NAME	"ip"
+
+/*
+ * Initialize the DCCP stack instance.
+ */
+static void *
+dccp_stack_init(netstackid_t stackid, netstack_t *ns)
+{
+	dccp_stack_t	*dccps;
+	major_t		major;
+	size_t		arrsz;
+	int		error;
+	int		i;
+
+	dccps = kmem_zalloc(sizeof (*dccps), KM_SLEEP);
+	if (dccps == NULL) {
+		return (NULL);
+	}
+	dccps->dccps_netstack = ns;
+
+	/* Ports */
+	mutex_init(&dccps->dccps_epriv_port_lock, NULL, MUTEX_DEFAULT, NULL);
+	dccps->dccps_num_epriv_ports = DCCP_NUM_EPRIV_PORTS;
+	dccps->dccps_epriv_ports[0] = ULP_DEF_EPRIV_PORT1;
+	dccps->dccps_epriv_ports[1] = ULP_DEF_EPRIV_PORT2;
+	dccps->dccps_min_anonpriv_port = 512;
+
+	dccps->dccps_bind_fanout_size = dccp_bind_fanout_size;
+
+	/* Bind fanout */
+	dccps->dccps_bind_fanout = kmem_zalloc(dccps->dccps_bind_fanout_size *
+	    sizeof (dccp_df_t), KM_SLEEP);
+	for (i = 0; i < dccps->dccps_bind_fanout_size; i++) {
+		mutex_init(&dccps->dccps_bind_fanout[i].df_lock, NULL,
+		    MUTEX_DEFAULT, NULL);
+	}
+
+	/* Tunable properties */
+	arrsz = dccp_propinfo_count * sizeof (mod_prop_info_t);
+	dccps->dccps_propinfo_tbl = kmem_alloc(arrsz, KM_SLEEP);
+	if (dccps->dccps_propinfo_tbl == NULL) {
+		kmem_free(dccps, sizeof (*dccps));
+		return (NULL);
+	}
+	bcopy(dccp_propinfo_tbl, dccps->dccps_propinfo_tbl, arrsz);
+
+	/* Allocate per netstack cpu stats */
+	mutex_enter(&cpu_lock);
+	dccps->dccps_sc_cnt = MAX(ncpus, boot_ncpus);
+	mutex_exit(&cpu_lock);
+
+	dccps->dccps_sc = kmem_zalloc(max_ncpus * sizeof (dccp_stats_cpu_t *),
+	    KM_SLEEP);
+	for (i = 0; i < dccps->dccps_sc_cnt; i++) {
+		dccps->dccps_sc[i] = kmem_zalloc(sizeof (dccp_stats_cpu_t),
+		    KM_SLEEP);
+	}
+
+	/* Driver major number */
+	major = mod_name_to_major(INET_NAME);
+	error = ldi_ident_from_major(major, &dccps->dccps_ldi_ident);
+	ASSERT(error == 0);
+
+	return (dccps);
+}
+
+/*
+ * Destroy the DCCP stack instance.
+ */
+void
+dccp_ddi_g_destroy(void)
+{
+	cmn_err(CE_NOTE, "dccp.c: dccp_ddi_g_destroy\n");
+
+	netstack_unregister(NS_DCCP);
+}
+
+static void
+dccp_stack_fini(netstackid_t stackid, void *arg)
+{
+	dccp_stack_t	*dccps = (dccp_stack_t *)arg;
+	int		i;
+
+	/* Cpu stats */
+	for (i = 0; i < dccps->dccps_sc_cnt; i++) {
+		kmem_free(dccps->dccps_sc[i], sizeof (dccp_stats_cpu_t));
+	}
+	kmem_free(dccps->dccps_sc, max_ncpus * sizeof (dccp_stats_cpu_t *));
+
+	/* Tunable properties */
+	kmem_free(dccps->dccps_propinfo_tbl,
+	    dccp_propinfo_count * sizeof (mod_prop_info_t));
+	dccps->dccps_propinfo_tbl = NULL;
+
+	/* Bind fanout */
+	for (i = 0; i < dccps->dccps_bind_fanout_size; i++) {
+		ASSERT(dccps->dccps_bind_fanout[i].df_dccp == NULL);
+		mutex_destroy(&dccps->dccps_bind_fanout[i].df_lock);
+	}
+	kmem_free(dccps->dccps_bind_fanout, dccps->dccps_bind_fanout_size *
+	    sizeof (dccp_df_t));
+	dccps->dccps_bind_fanout = NULL;
+
+	kmem_free(dccps, sizeof (*dccps));
+}
+
+/* /dev/dccp */
+static int
+dccp_openv4(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
+{
+	cmn_err(CE_NOTE, "dccp.c: dccp_openv4\n");
+
+	return (ENOTSUP);
+}
+
+/* /dev/dccp6 */
+static int
+dccp_openv6(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp)
+{
+	cmn_err(CE_NOTE, "dccp.c: dccp_openv6\n");
+
+	return (ENOTSUP);
+}
+
+/*
+ * IXA notify
+ */
+static void
+dccp_notify(void *arg, ip_xmit_attr_t *ixa, ixa_notify_type_t ntype,
+    ixa_notify_arg_t narg)
+{
+	cmn_err(CE_NOTE, "dccp.c: dccp_notify");
+}
+
+/*
+ * Build the template headers.
+ */
+int
+dccp_build_hdrs(dccp_t *dccp)
+{
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+	conn_t		*connp = dccp->dccp_connp;
+	dccpha_t	*dccpha;
+	uint32_t	cksum;
+	char		buf[DCCP_MAX_HDR_LENGTH];
+	uint_t		buflen;
+	uint_t		ulplen = 12;
+	uint_t		extralen = 0;
+	int		error;
+
+	cmn_err(CE_NOTE, "dccp.c: dccp_build_hdrs");
+
+	buflen = connp->conn_ht_ulp_len;
+	if (buflen != 0) {
+		cmn_err(CE_NOTE, "buflen != 0");
+		bcopy(connp->conn_ht_ulp, buf, buflen);
+		extralen -= buflen - ulplen;
+		ulplen = buflen;
+	}
+
+	mutex_enter(&connp->conn_lock);
+	error = conn_build_hdr_template(connp, ulplen, extralen,
+	    &connp->conn_laddr_v6, &connp->conn_faddr_v6, connp->conn_flowinfo);
+	mutex_exit(&connp->conn_lock);
+	if (error != 0) {
+		cmn_err(CE_NOTE, "conn_build_hdr_template failed");
+		return (error);
+	}
+
+	dccpha = (dccpha_t *)connp->conn_ht_ulp;
+	dccp->dccp_dccpha = dccpha;
+
+	if (buflen != 0) {
+		bcopy(buf, connp->conn_ht_ulp, buflen);
+	} else {
+		dccpha->dha_sum = 0;
+		dccpha->dha_lport = connp->conn_lport;
+		dccpha->dha_fport = connp->conn_fport;
+	}
+
+	cksum = sizeof (dccpha_t) + connp->conn_sum;
+	cksum = (cksum >> 16) + (cksum & 0xFFFF);
+	dccpha->dha_sum = htons(cksum);
+	dccpha->dha_offset = 7;
+	dccpha->dha_x = 1;
+
+	return (0);
+}
+
+/*
+ * DCCP write service routine.
+ */
+static void
+dccp_wsrv(queue_t *q)
+{
+	/* XXX:DCCP */
+}
+
+/*
+ * Common create function for streams and sockets.
+ */
+conn_t *
+dccp_create_common(cred_t *credp, boolean_t isv6, boolean_t issocket,
+    int *errorp)
+{
+	conn_t		*connp;
+	dccp_t		*dccp;
+	dccp_stack_t	*dccps;
+	netstack_t	*ns;
+	squeue_t	*sqp;
+	zoneid_t	zoneid;
+
+	cmn_err(CE_NOTE, "dccp.c: dccp_create_common\n");
+
+	ASSERT(errorp != NULL);
+
+	*errorp = secpolicy_basic_net_access(credp);
+	if (*errorp != 0) {
+		return (NULL);
+	}
+
+	/*
+	 * Find the right netstack
+	 */
+	ns = netstack_find_by_cred(credp);
+	ASSERT(ns != NULL);
+	dccps = ns->netstack_dccp;
+	ASSERT(dccps != NULL);
+
+	/*
+	 * XXX
+	 */
+	if (ns->netstack_stackid != GLOBAL_NETSTACKID) {
+		zoneid = GLOBAL_ZONEID;
+	} else {
+		zoneid = crgetzoneid(credp);
+	}
+
+	sqp = IP_SQUEUE_GET((uint_t)gethrtime());
+	connp = (conn_t *)dccp_get_conn(sqp, dccps);
+	netstack_rele(dccps->dccps_netstack);
+	if (connp == NULL) {
+		*errorp = ENOSR;
+		return (NULL);
+	}
+	ASSERT(connp->conn_ixa->ixa_protocol == connp->conn_proto);
+
+	connp->conn_sqp = sqp;
+	connp->conn_initial_sqp = connp->conn_sqp;
+	connp->conn_ixa->ixa_sqp = connp->conn_sqp;
+	dccp = connp->conn_dccp;
+
+	/* Setting flags for ip output */
+	connp->conn_ixa->ixa_flags |= IXAF_SET_ULP_CKSUM | IXAF_VERIFY_SOURCE |
+	    IXAF_VERIFY_PMTU | IXAF_VERIFY_LSO;
+
+	ASSERT(connp->conn_proto == IPPROTO_DCCP);
+	ASSERT(connp->conn_dccp == dccp);
+	ASSERT(dccp->dccp_connp == connp);
+
+	if (isv6) {
+		connp->conn_ixa->ixa_src_preferences = IPV6_PREFER_SRC_DEFAULT;
+		connp->conn_ipversion = IPV6_VERSION;
+		connp->conn_family = AF_INET6;
+		/* XXX mms, ttl */
+	} else {
+		connp->conn_ipversion = IPV4_VERSION;
+		connp->conn_family = AF_INET;
+		/* XXX mms, ttl */
+	}
+	connp->conn_xmit_ipp.ipp_unicast_hops = connp->conn_default_ttl;
+
+	crhold(credp);
+	connp->conn_cred = credp;
+	connp->conn_cpid = curproc->p_pid;
+	connp->conn_open_time = ddi_get_lbolt64();
+
+	ASSERT(!(connp->conn_ixa->ixa_free_flags & IXA_FREE_CRED));
+	connp->conn_ixa->ixa_cred = credp;
+	connp->conn_ixa->ixa_cpid = connp->conn_cpid;
+
+	connp->conn_zoneid = zoneid;
+	connp->conn_zone_is_global = (crgetzoneid(credp) == GLOBAL_ZONEID);
+	connp->conn_ixa->ixa_zoneid = zoneid;
+	connp->conn_mlp_type = mlptSingle;
+
+
+	dccp->dccp_dccps = dccps;
+	dccp->dccp_state = DCCPS_CLOSED;
+
+	ASSERT(connp->conn_netstack == dccps->dccps_netstack);
+	ASSERT(dccp->dccp_dccps == dccps);
+
+	/* XXX rcvbuf, sndbuf etc */
+
+	SOCK_CONNID_INIT(dccp->dccp_connid);
+	dccp_init_values(dccp, NULL);
+
+	return (connp);
+}
+
+/*
+ * Common close function for streams and sockets.
+ */
+void
+dccp_close_common(conn_t *connp)
+{
+	dccp_t		*dccp = connp->conn_dccp;
+	boolean_t	conn_ioctl_cleanup_reqd = B_FALSE;
+
+	ASSERT(connp->conn_ref >= 2);
+
+	mutex_enter(&connp->conn_lock);
+	connp->conn_state_flags |= CONN_CLOSING;
+	if (connp->conn_oper_pending_ill != NULL) {
+		conn_ioctl_cleanup_reqd = B_TRUE;
+	}
+
+	CONN_INC_REF_LOCKED(connp);
+	mutex_exit(&connp->conn_lock);
+
+	//ipcl_conn_destroy(connp);
+}
+
+/*
+ * Common bind function.
+ */
+int
+dccp_do_bind(conn_t *connp, struct sockaddr *sa, socklen_t len, cred_t *cr,
+    boolean_t bind_to_req_port_only)
+{
+	dccp_t	*dccp = connp->conn_dccp;
+	int	error;
+
+	cmn_err(CE_NOTE, "dccp.c: dccp_do_bind");
+
+	if (dccp->dccp_state >= DCCPS_BOUND) {
+		if (connp->conn_debug) {
+			(void) strlog(DCCP_MOD_ID, 0, 1, SL_ERROR|SL_TRACE,
+			    "dccp_bind: bad state, %d", dccp->dccp_state);
+		}
+		return (-TOUTSTATE);
+	}
+
+	error = dccp_bind_check(connp, sa, len, cr, bind_to_req_port_only);
+	if (error != 0) {
+		return (error);
+	}
+
+	ASSERT(dccp->dccp_state == DCCPS_LISTEN);
+	/* XXX dccp_conn_req_max = 0 */	
+
+	return (0);
+}
+
+/*
+ * Common unbind function.
+ */
+int
+dccp_do_unbind(conn_t *connp)
+{
+	dccp_t	*dccp = connp->conn_dccp;
+
+	cmn_err(CE_NOTE, "dccp.c: dccp_do_unbind");
+
+	switch (dccp->dccp_state) {
+	case DCCPS_BOUND:
+	case DCCPS_LISTEN:
+		break;
+	default:
+		return (-TOUTSTATE);
+	}
+
+	/* XXX:DCCP */
+
+	return (0);
+}
+
+/*
+ * Common listen function.
+ */
+int
+dccp_do_listen(conn_t *connp, struct sockaddr *sa, socklen_t len,
+    int backlog, cred_t *cr, boolean_t bind_to_req_port_only)
+{
+	dccp_t		*dccp = connp->conn_dccp;
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+	int32_t		oldstate;
+	int		error;
+
+	cmn_err(CE_NOTE, "dccp.c: dccp_do_listen");
+
+	/* All Solaris components should pass a cred for this operation */
+	ASSERT(cr != NULL);
+
+	if (dccp->dccp_state >= DCCPS_BOUND) {
+
+		if ((dccp->dccp_state == DCCPS_BOUND ||
+		    dccp->dccp_state == DCCPS_LISTEN) && backlog > 0) {
+			goto do_listen;
+		}
+		cmn_err(CE_NOTE, "DCCPS_BOUND, bad state");
+
+		if (connp->conn_debug) {
+			(void) strlog(DCCP_MOD_ID, 0, 1, SL_ERROR|SL_TRACE,
+			    "dccp_listen: bad state, %d", dccp->dccp_state);
+		}
+		return (-TOUTSTATE);
+	} else {
+		if (sa == NULL) {
+			sin6_t	addr;
+			sin6_t	*sin6;
+			sin_t	*sin;
+
+			ASSERT(IPCL_IS_NONSTR(connp));
+
+			if (connp->conn_family == AF_INET) {
+				len = sizeof (sin_t);
+				sin = (sin_t *)&addr;
+				*sin = sin_null;
+				sin->sin_family = AF_INET;
+			} else {
+				ASSERT(connp->conn_family == AF_INET6);
+
+				len = sizeof (sin6_t);
+				sin6 = (sin6_t *)&addr;
+				*sin6 = sin6_null;
+				sin6->sin6_family = AF_INET6;
+			}
+
+			sa = (struct sockaddr *)&addr;
+		}
+
+		error = dccp_bind_check(connp, sa, len, cr,
+		    bind_to_req_port_only);
+		if (error != 0) {
+			cmn_err(CE_NOTE, "dccp_bind_check failed");
+			return (error);
+		}
+		/* Fall through and do the fanout insertion */
+	}
+
+do_listen:
+	ASSERT(dccp->dccp_state == DCCPS_BOUND ||
+	    dccp->dccp_state == DCCPS_LISTEN);
+
+	/* XXX backlog */
+
+	connp->conn_recv = dccp_input_listener_unbound;
+
+	/* Insert into the classifier table */
+	error = ip_laddr_fanout_insert(connp);
+	if (error != 0) {
+		/* Error - undo the bind */
+		oldstate = dccp->dccp_state;
+		dccp->dccp_state = DCCPS_CLOSED;
+
+		connp->conn_bound_addr_v6 = ipv6_all_zeros;
+
+		connp->conn_laddr_v6 = ipv6_all_zeros;
+		connp->conn_saddr_v6 = ipv6_all_zeros;
+		connp->conn_ports = 0;
+
+		if (connp->conn_anon_port) {
+			zone_t	*zone;
+
+			zone = crgetzone(cr);
+			connp->conn_anon_port = B_FALSE;
+			(void) tsol_mlp_anon(zone, connp->conn_mlp_type,
+			    connp->conn_proto, connp->conn_lport, B_FALSE);
+		}
+		connp->conn_mlp_type = mlptSingle;
+
+		/* XXX dccp_bind_hash_remove */
+
+		return (error);
+	} else {
+		/* XXX connection limits */
+	}
+
+	return (error);
+}
+
+/*
+ * Common connect function.
+ */
+int
+dccp_do_connect(conn_t *connp, const struct sockaddr *sa, socklen_t len,
+    cred_t *cr, pid_t pid)
+{
+	dccp_t		*dccp = connp->conn_dccp;
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+	ip_xmit_attr_t	*ixa = connp->conn_ixa;
+	sin_t		*sin = (sin_t *)sa;
+	sin6_t		*sin6 = (sin6_t *)sa;
+	ipaddr_t	*dstaddrp;
+	in_port_t	dstport;
+	int32_t		oldstate;
+	uint_t		srcid;
+	int		error;
+
+	cmn_err(CE_NOTE, "dccp.c: dccp_do_connect");
+
+	oldstate = dccp->dccp_state;
+
+	switch (len) {
+	case sizeof (sin_t):
+		sin = (sin_t *)sa;
+		if (sin->sin_port == 0) {
+			return (-TBADADDR);
+		}
+		if (connp->conn_ipv6_v6only) {
+			return (EAFNOSUPPORT);
+		}
+		break;
+
+	case sizeof (sin6_t):
+		sin6 = (sin6_t *)sa;
+		if (sin6->sin6_port == 0) {
+			return (-TBADADDR);
+		}
+		break;
+
+	default:
+		return (EINVAL);
+	}
+
+	if (connp->conn_family == AF_INET6 &&
+	    connp->conn_ipversion == IPV6_VERSION &&
+	    IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
+		if (connp->conn_ipv6_v6only) {
+			return (EADDRNOTAVAIL);
+		}
+
+		connp->conn_ipversion = IPV4_VERSION;
+	}
+
+	switch (dccp->dccp_state) {
+	case DCCPS_LISTEN:
+		if (IPCL_IS_NONSTR(connp)) {
+			return (EOPNOTSUPP);
+		}
+
+	case DCCPS_CLOSED:
+		/* XXX */
+		break;
+
+	default:
+		return (-TOUTSTATE);
+	}
+
+	if (connp->conn_cred != cr) {
+		crhold(cr);
+		crfree(connp->conn_cred);
+		connp->conn_cred = cr;
+	}
+	connp->conn_cpid = pid;
+
+	ASSERT(!(ixa->ixa_free_flags & IXA_FREE_CRED));
+	ixa->ixa_cred = cr;
+	ixa->ixa_cpid = pid;
+
+	if (is_system_labeled()) {
+		ip_xmit_attr_restore_tsl(ixa, ixa->ixa_cred);
+	}
+
+	if (connp->conn_family == AF_INET6) {
+		if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
+			error = dccp_connect_ipv6(dccp, &sin6->sin6_addr,
+			    sin6->sin6_port, sin6->sin6_flowinfo,
+			    sin6->__sin6_src_id, sin6->sin6_scope_id);
+		} else {
+			/* XXX */
+		}
+	} else {
+		dstaddrp = &sin->sin_addr.s_addr;
+		dstport = sin->sin_port;
+		srcid = 0;
+		error = dccp_connect_ipv4(dccp, dstaddrp, dstport, srcid);
+	}
+
+	if (error != 0) {
+		goto connect_failed;
+	}
+
+	/* XXX cluster */
+
+	//DCCPS_BUMP_MIB(dccps, dccpActiveOpens);
+
+	return (0);
+
+connect_failed:
+	cmn_err(CE_NOTE, "dccp_do_connect failed");
+
+	connp->conn_faddr_v6 = ipv6_all_zeros;
+	connp->conn_fport = 0;
+	dccp->dccp_state = oldstate;
+
+	return (error);
+}
+
+/*
+ * Init values of a connection.
+ */
+void
+dccp_init_values(dccp_t *dccp, dccp_t *parent)
+{
+	conn_t		*connp = dccp->dccp_connp;
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+
+	connp->conn_mlp_type = mlptSingle;
+}
+
+void *
+dccp_get_conn(void *arg, dccp_stack_t *dccps)
+{
+	dccp_t		*dccp = NULL;
+	conn_t		*connp;
+	squeue_t	*sqp = (squeue_t *)arg;
+	netstack_t	*ns;
+
+	/* XXX timewait */
+
+	connp = ipcl_conn_create(IPCL_DCCPCONN, KM_NOSLEEP,
+	    dccps->dccps_netstack);
+	if (connp == NULL) {
+		return (NULL);
+	}
+
+	dccp = connp->conn_dccp;
+	dccp->dccp_dccps = dccps;
+
+	connp->conn_recv = dccp_input_data;
+	connp->conn_recvicmp = dccp_icmp_input;
+	connp->conn_verifyicmp = dccp_verifyicmp;
+
+	connp->conn_ixa->ixa_notify = dccp_notify;
+	connp->conn_ixa->ixa_notify_cookie = dccp;
+
+	return ((void *)connp);
+}
+
+/*
+ * IPv4 connect.
+ */
+static int
+dccp_connect_ipv4(dccp_t *dccp, ipaddr_t *dstaddrp, in_port_t dstport,
+    uint_t srcid)
+{
+	conn_t		*connp = dccp->dccp_connp;
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+	ipaddr_t	dstaddr = *dstaddrp;
+	uint16_t	lport;
+	int		error;
+
+	cmn_err(CE_NOTE, "dccp.c: dccp_connect_ipv4");
+
+	ASSERT(connp->conn_ipversion == IPV4_VERSION);
+
+	if (dstaddr == INADDR_ANY) {
+		dstaddr = htonl(INADDR_LOOPBACK);
+		*dstaddrp = dstaddr;
+	}
+
+	if (srcid != 0 && connp->conn_laddr_v4 == INADDR_ANY) {
+		ip_srcid_find_id(srcid, &connp->conn_laddr_v6,
+		    IPCL_ZONEID(connp), dccps->dccps_netstack);
+		connp->conn_saddr_v6 = connp->conn_laddr_v6;
+	}
+
+	IN6_IPADDR_TO_V4MAPPED(dstaddr, &connp->conn_faddr_v6);
+	connp->conn_fport = dstport;
+
+	if (dccp->dccp_state == DCCPS_CLOSED) {
+		lport = dccp_update_next_port(dccps->dccps_next_port_to_try,
+		    dccp, B_TRUE);
+		lport = dccp_bindi(dccp, lport, &connp->conn_laddr_v6, 0,
+		    B_TRUE, B_FALSE, B_FALSE);
+
+		if (lport == 0) {
+			return (-TNOADDR);
+		}
+	}
+
+	error = dccp_set_destination(dccp);
+	if (error != 0) {
+		return (error);
+	}
+
+	/*
+	 * Don't connect to oneself.
+	 */
+	if (connp->conn_faddr_v4 == connp->conn_laddr_v4 &&
+	    connp->conn_fport == connp->conn_lport) {
+		return (-TBADADDR);
+	}
+
+	/* XXX state */
+
+	return (ipcl_conn_insert_v4(connp));
+}
+
+/*
+ * IPv6 connect.
+ */
+static int
+dccp_connect_ipv6(dccp_t *dccp, in6_addr_t *dstaddrp, in_port_t dstport,
+    uint32_t flowinfo, uint_t srcid, uint32_t scope_id)
+{
+	cmn_err(CE_NOTE, "dccp.c: dccp_connect_ipv6");
+
+	return (0);
+}
+
+/*
+ * Set the ports via conn_connect and build the template
+ * headers.
+ */
+int
+dccp_set_destination(dccp_t *dccp)
+{
+	conn_t		*connp = dccp->dccp_connp;
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+	iulp_t		uinfo;
+	uint32_t	flags;
+	int		error;
+
+	flags = IPDF_LSO | IPDF_ZCOPY;
+	flags |= IPDF_UNIQUE_DCE;
+
+	mutex_enter(&connp->conn_lock);
+	error = conn_connect(connp, &uinfo, flags);
+	mutex_exit(&connp->conn_lock);
+	if (error != 0) {
+		cmn_err(CE_NOTE, "conn_connect failed");
+		return (error);
+	}
+
+	error = dccp_build_hdrs(dccp);
+	if (error != 0) {
+		cmn_err(CE_NOTE, "dccp_build_hdrs failed");
+		return (error);
+	}
+
+	/* XXX */
+
+	mutex_enter(&connp->conn_lock);
+	connp->conn_state_flags &= ~CONN_INCIPIENT;
+	mutex_exit(&connp->conn_lock);
+
+	return (0);
+}
--- /dev/null	2012-06-13 12:04:30.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp.conf	2012-06-13 12:04:29.949373107 +0000
@@ -0,0 +1,26 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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) 1992, by Sun Microsystems, Inc.
+#
+
+name="dccp" parent="pseudo" instance=0;
--- /dev/null	2012-06-13 12:04:30.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp6.conf	2012-06-13 12:04:30.771556726 +0000
@@ -0,0 +1,26 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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) 1992, by Sun Microsystems, Inc.
+#
+
+name="dccp6" parent="pseudo" instance=0;
--- /dev/null	2012-06-13 12:04:31.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp6ddi.c	2012-06-13 12:04:31.466763174 +0000
@@ -0,0 +1,60 @@
+/*
+ * 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 2009 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/modctl.h>
+#include <inet/common.h>
+#include <inet/ip.h>
+
+#define	INET_NAME	"dccp6"
+#define	INET_DEVSTRTAB	dccpinfov6
+#define	INET_DEVDESC	"DCCP6 STREAMS driver"
+#define	INET_DEVMINOR	0
+#define	INET_DEVMTFLAGS	(D_MP|_D_DIRECT)
+
+#include "../inetddi.c"
+
+int
+_init(void)
+{
+	/*
+	 * device initialization happens when the actual code containing
+	 * module (/kernel/drv/ip) is loaded, and driven from ip_ddi_init()
+	 */
+	return (mod_install(&modlinkage));
+}
+
+int
+_fini(void)
+{
+	return (mod_remove(&modlinkage));
+}
+
+int
+_info(struct modinfo *modinfop)
+{
+	return (mod_info(&modlinkage, modinfop));
+}
--- /dev/null	2012-06-13 12:04:32.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp_bind.c	2012-06-13 12:04:32.181136259 +0000
@@ -0,0 +1,450 @@
+/*
+ * 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 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner.  All rights reserved.
+ */
+
+/*
+ * This file contains function related to binding.
+ */
+
+#include <sys/types.h>
+#include <sys/stream.h>
+#include <sys/strsun.h>
+#include <sys/strsubr.h>
+#include <sys/stropts.h>
+#include <sys/strlog.h>
+#define	_SUN_TPI_VERSION 2
+#include <sys/tihdr.h>
+#include <sys/suntpi.h>
+#include <sys/xti_inet.h>
+#include <sys/squeue_impl.h>
+#include <sys/squeue.h>
+#include <sys/tsol/tnet.h>
+
+#include <inet/common.h>
+#include <inet/ip.h>
+#include <inet/proto_set.h>
+
+#include <sys/cmn_err.h>
+
+#include "dccp_impl.h"
+
+/* Setable in /etc/system */
+static uint32_t dccp_random_anon_port = 1;
+
+static int dccp_bind_select_lport(dccp_t *, in_port_t *, boolean_t,
+    cred_t *);
+
+void
+dccp_bind_hash_insert(dccp_df_t *tbf, dccp_t *dccp, int caller_holds_lock)
+{
+	conn_t	*connp = dccp->dccp_connp;
+	conn_t	*connext;
+	dccp_t	**dccpp;
+	dccp_t	*dccpnext;
+	dccp_t	*dccphash;
+
+	cmn_err(CE_NOTE, "dccp_bind.c: dccp_bind_hash_insert");
+
+	/* XXX:DCCP */
+
+	dccpp = &tbf->df_dccp;
+	if (!caller_holds_lock) {
+		mutex_enter(&tbf->df_lock);
+	} else {
+		ASSERT(MUTEX_HELD(&tbf->df_lock));
+	}
+	dccphash = dccpp[0];
+	dccpnext = NULL;
+
+	if (dccphash != NULL) {
+		/* XXX:DCCP */
+	}
+
+insert:
+	dccp->dccp_bind_hash_port = dccpnext;
+	dccp->dccp_bind_hash = dccphash;
+	dccp->dccp_ptpbhn = dccpp;
+	dccpp[0] = dccp;
+
+	if (!caller_holds_lock) {
+		mutex_exit(&tbf->df_lock);
+	}
+}
+
+void
+dccp_bind_hash_remove(dccp_t *dccp)
+{
+}
+
+/*
+ * Check for a valid address and get a local port.
+ */
+int
+dccp_bind_check(conn_t *connp, struct sockaddr *sa, socklen_t len, cred_t *cr,
+    boolean_t bind_to_req_port_only)
+{
+	dccp_t		*dccp = connp->conn_dccp;
+	ip_stack_t	*ips = connp->conn_netstack->netstack_ip;
+	ip_xmit_attr_t	*ixa = connp->conn_ixa;
+	sin_t		*sin;
+	sin6_t		*sin6;
+	ipaddr_t	v4addr;
+	in6_addr_t	v6addr;
+	ip_laddr_t	laddr_type = IPVL_UNICAST_UP;
+	zoneid_t	zoneid = IPCL_ZONEID(connp);
+	in_port_t	requested_port;
+	uint_t		scopeid = 0;
+	int		error;
+
+	cmn_err(CE_NOTE, "dccp_bind.c: dccp_bind_check");
+
+	ASSERT((uintptr_t)len <= (uintptr_t)INT_MAX);
+
+	/*
+	 * We should be in a pre-listen state.
+	 */
+	if (dccp->dccp_state == DCCPS_LISTEN) {
+		return (0);
+	} else if (dccp->dccp_state > DCCPS_LISTEN) {
+		if (connp->conn_debug) {
+			(void) strlog(DCCP_MOD_ID, 0, 1, SL_ERROR|SL_TRACE,
+			    "dccp_bind: bad state, %d", dccp->dccp_state);
+		}
+		return (-TOUTSTATE);
+	}
+
+	/*
+	 * Check for a valid address parameter. Then validate the
+	 * addresses and copy them and the required port in.
+	 */
+	ASSERT(sa != NULL && len != 0);
+	if (!OK_32PTR((char *)sa)) {
+		if (connp->conn_debug) {
+			(void) strlog(DCCP_MOD_ID, 0, 1, SL_ERROR|SL_TRACE,
+			    "dccp_bind: bad address parameter, "
+			    "address %p, len %d", (void *)sa, len);
+		}
+		return (-TPROTO);
+	}
+
+	error = proto_verify_ip_addr(connp->conn_family, sa, len);
+	if (error != 0) {
+		return (error);
+	}
+
+	switch (len) {
+	case sizeof (sin_t):
+		sin = (sin_t *)sa;
+		v4addr = sin->sin_addr.s_addr;
+		requested_port = ntohs(sin->sin_port);
+		IN6_IPADDR_TO_V4MAPPED(v4addr, &v6addr);
+		if (v4addr != INADDR_ANY) {
+			laddr_type = ip_laddr_verify_v4(v4addr, zoneid, ips,
+			    B_FALSE);
+		}
+		break;
+
+	case sizeof (sin6_t):
+		sin6 = (sin6_t *)sa;
+		v6addr = sin6->sin6_addr;
+		requested_port = ntohs(sin6->sin6_port);
+		if (IN6_IS_ADDR_V4MAPPED(&v6addr)) {
+			if (connp->conn_ipv6_v6only) {
+				return (EADDRNOTAVAIL);
+			}
+
+			IN6_V4MAPPED_TO_IPADDR(&v6addr, v4addr);
+			if (v4addr != INADDR_ANY) {
+				laddr_type = ip_laddr_verify_v4(v4addr, zoneid,
+				    ips, B_FALSE);
+			}
+		} else {
+			if (!IN6_IS_ADDR_UNSPECIFIED(&v6addr)) {
+				if (IN6_IS_ADDR_LINKSCOPE(&v6addr)) {
+					scopeid = sin6->sin6_scope_id;
+					laddr_type = ip_laddr_verify_v6(&v6addr,
+					    zoneid, ips, B_FALSE, scopeid);
+				}
+			}
+		}
+		break;
+
+	default:
+		if (connp->conn_debug) {
+			(void) strlog(DCCP_MOD_ID, 0, 1, SL_ERROR|SL_TRACE,
+			    "dccp_bind: bad address length, %d", len);
+		}
+		return (EAFNOSUPPORT);
+	}
+
+	if (laddr_type == IPVL_BAD) {
+		return (EADDRNOTAVAIL);
+	}
+
+	connp->conn_bound_addr_v6 = v6addr;
+	if (scopeid != 0) {
+		ixa->ixa_flags |= IXAF_SCOPEID_SET;
+		ixa->ixa_scopeid = scopeid;
+		connp->conn_incoming_ifindex = scopeid;
+	} else {
+		ixa->ixa_flags &= ~IXAF_SCOPEID_SET;
+		connp->conn_incoming_ifindex = connp->conn_bound_if;
+	}
+
+	connp->conn_laddr_v6 = v6addr;
+	connp->conn_saddr_v6 = v6addr;
+
+	bind_to_req_port_only = requested_port != 0 && bind_to_req_port_only;
+
+	error = dccp_bind_select_lport(dccp, &requested_port,
+	    bind_to_req_port_only, cr);
+	if (error != 0) {
+		connp->conn_laddr_v6 = ipv6_all_zeros;
+		connp->conn_saddr_v6 = ipv6_all_zeros;
+		connp->conn_bound_addr_v6 = ipv6_all_zeros;
+	}
+
+	return (error);
+}
+
+/*
+ * Bind to a local port.
+ */
+static int
+dccp_bind_select_lport(dccp_t *dccp, in_port_t *requested_port_ptr,
+    boolean_t bind_to_req_port_only, cred_t *cr)
+{
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+	conn_t		*connp = dccp->dccp_connp;
+	zone_t		*zone;
+	in_port_t	allocated_port;
+	in_port_t	requested_port = *requested_port_ptr;
+	in6_addr_t	v6addr = connp->conn_laddr_v6;
+	boolean_t	user_specified;
+
+	cmn_err(CE_NOTE, "dccp_bind.c: dccp_bind_select_lport");
+
+	ASSERT(cr != NULL);
+
+	if (requested_port == 0) {
+		requested_port =
+		    dccp_update_next_port(dccps->dccps_next_port_to_try,
+		    dccp, B_TRUE);
+		if (requested_port == 0) {
+			return (-TNOADDR);
+		}
+		user_specified = B_FALSE;
+
+	}  else {
+		int		i;
+		boolean_t	priv = B_FALSE;
+
+		if (requested_port < dccps->dccps_smallest_nonpriv_port) {
+			priv = B_TRUE;
+		} else {
+			for (i = 0; i < dccps->dccps_num_epriv_ports; i++) {
+				if (requested_port ==
+				    dccps->dccps_epriv_ports[i]) {
+					priv = B_TRUE;
+					break;
+				}
+			}
+		}
+
+		if (priv) {
+			if (secpolicy_net_privaddr(cr, requested_port,
+			    IPPROTO_DCCP) != 0) {
+				if (connp->conn_debug) {
+					(void) strlog(DCCP_MOD_ID, 0, 1,
+					    SL_ERROR|SL_TRACE,
+					    "tcp_bind: no priv for port %d",
+					    requested_port);
+				}
+				return (-TACCES);
+			}
+		}
+
+		user_specified = B_TRUE;
+		//connp = dccp->dccp_connp;
+
+		/* XXX */
+	}
+
+	allocated_port = dccp_bindi(dccp, requested_port, &v6addr,
+	    connp->conn_reuseaddr, B_FALSE, bind_to_req_port_only,
+	    user_specified);
+
+	if (allocated_port == 0) {
+		/* XXX */
+		if (bind_to_req_port_only) {
+			if (connp->conn_debug) {
+				(void) strlog(DCCP_MOD_ID, 0, 1,
+				    SL_ERROR|SL_TRACE,
+				    "dccp_bind: requested addr busy");
+			}
+			return (-TADDRBUSY);
+		} else {
+			if (connp->conn_debug) {
+				(void) strlog(DCCP_MOD_ID, 0, 1,
+				    SL_ERROR|SL_TRACE,
+				    "dccp_bind: out of ports?");
+			}
+			return (-TNOADDR);
+		}
+	}
+
+	*requested_port_ptr = allocated_port;
+	return (0);
+}
+
+in_port_t
+dccp_bindi(dccp_t *dccp, in_port_t port, const in6_addr_t *laddr,
+    int reuseaddr, boolean_t quick_connect, boolean_t bind_to_req_port_only,
+    boolean_t user_specified)
+{
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+	conn_t		*connp = dccp->dccp_connp;
+	int		count = 0;
+	int		loopmax;
+
+	cmn_err(CE_NOTE, "dccp_bind.c: dccp_bindi");
+
+	if (bind_to_req_port_only) {
+		loopmax = 1;
+	} else {
+		if (connp->conn_anon_priv_bind) {
+			loopmax = IPPORT_RESERVED -
+			    dccps->dccps_min_anonpriv_port;
+		} else {
+			loopmax = (dccps->dccps_largest_anon_port -
+			    dccps->dccps_smallest_anon_port + 1);
+		}
+	}
+
+	do {
+		conn_t		*lconnp;
+		dccp_t		*ldccp;
+		dccp_df_t	*ldf;
+		uint16_t	lport;
+
+		lport = htons(port);
+
+		dccp_bind_hash_remove(dccp);
+		ldf = &dccps->dccps_bind_fanout[DCCP_BIND_HASH(lport,
+		    dccps->dccps_bind_fanout_size)];
+		mutex_enter(&ldf->df_lock);
+		for (ldccp = ldf->df_dccp; ldccp != NULL;
+		    ldccp = ldccp->dccp_bind_hash) {
+			if (lport == ldccp->dccp_connp->conn_lport) {
+				break;
+			}
+		}
+
+		if (ldccp != NULL) {
+			mutex_exit(&ldf->df_lock);
+		} else {
+			dccp->dccp_state = DCCPS_BOUND;
+
+			connp->conn_lport = htons(port);
+
+			ASSERT(&dccps->dccps_bind_fanout[DCCP_BIND_HASH(
+			     connp->conn_lport,
+			     dccps->dccps_bind_fanout_size)] == ldf);
+			dccp_bind_hash_insert(ldf, dccp, 1);
+
+			mutex_exit(&ldf->df_lock);
+
+			if (user_specified) {
+				return (port);
+			}
+
+			if (!connp->conn_anon_priv_bind) {
+				dccps->dccps_next_port_to_try = port + 1;
+			}
+
+			return (port);
+		}
+
+		if (port == 0) {
+			break;
+		}
+
+	} while (++count < loopmax);
+
+	cmn_err(CE_NOTE, "dccp_bind.c: dccp_bindi exit");
+
+	return (0);
+}
+
+in_port_t
+dccp_update_next_port(in_port_t port, const dccp_t *dccp, boolean_t random)
+{
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+	boolean_t	restart = B_FALSE;
+	int		i;
+
+	cmn_err(CE_NOTE, "dccp_bind.c: dccp_update_next_port");
+
+	if (random && dccp_random_anon_port != 0) {
+		(void) random_get_pseudo_bytes((uint8_t *)&port,
+		    sizeof (in_port_t));
+
+		if (port < dccps->dccps_smallest_anon_port) {
+			port = dccps->dccps_smallest_anon_port +
+			    port % (dccps->dccps_largest_anon_port -
+			    dccps->dccps_smallest_anon_port);
+		}
+	}
+
+retry:
+	if (port < dccps->dccps_smallest_anon_port) {
+		port = (in_port_t)dccps->dccps_smallest_anon_port;
+	}
+
+	if (port > dccps->dccps_largest_anon_port) {
+		if (restart) {
+			return (0);
+		}
+		restart = B_TRUE;
+		port = (in_port_t)dccps->dccps_smallest_anon_port;
+	}
+
+	if (port < dccps->dccps_smallest_nonpriv_port) {
+		port = (in_port_t)dccps->dccps_smallest_nonpriv_port;
+	}
+
+	for (i = 0; i < dccps->dccps_num_epriv_ports; i++) {
+		if (port == dccps->dccps_epriv_ports[i]) {
+			port++;
+			goto retry;
+		}
+	}
+
+	return (port);
+}
--- /dev/null	2012-06-13 12:04:32.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp_impl.h	2012-06-13 12:04:32.873007135 +0000
@@ -0,0 +1,247 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner. All rights reserved.
+ */
+
+#ifndef	_INET_DCCP_IMPL_H
+#define	_INET_DCCP_IMPL_H
+
+#include <sys/int_types.h>
+#include <sys/netstack.h>
+#include <sys/socket.h>
+#include <sys/socket_proto.h>
+
+#include <netinet/in.h>
+#include <netinet/ip6.h>
+#include <netinet/dccp.h>
+
+#include <inet/common.h>
+#include <inet/ip.h>
+#include <inet/ip6.h>
+#include <inet/optcom.h>
+#include <inet/tunables.h>
+
+#include "dccp_stack.h"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+#ifdef	_KERNEL
+
+#define	DCCP_MOD_ID	5999 /* XXX */
+
+#define	DCCP_XMIT_LOWATER	(4 * 1024)
+#define	DCCP_XMIT_HIWATER	49152
+#define	DCCP_RECV_LOWATER	(2 * 1024)
+#define	DCCP_RECV_HIWATER	128000
+
+/*
+ * Bind hash array size and hash function.
+ */
+#define	DCCP_BIND_FANOUT_SIZE		128
+#define	DCCP_BIND_HASH(lport, size)	((ntohs((uint16_t)lport)) & (size - 1))
+
+
+#define	DCCP_HDR_LENGTH(dccph)		(dccph_t *)dccph->dh_offset
+#define	DCCP_MAX_HDR_LENGTH		1020
+#define	DCCP_MIN_HEADER_LENGTH		12
+
+/* Packet types (RFC 4340, Section 5.1.) */
+#define	DCCP_PKT_REQUEST	0
+#define	DCCP_PKT_RESPONSE	1
+#define	DCCP_PKT_DATA		2
+#define	DCCP_PKT_ACK		3
+#define	DCCP_PKT_DATAACK	4
+#define	DCCP_PKT_CLOSEREQ	5
+#define	DCCP_PKT_CLOSE		6
+#define	DCCP_PKT_RESET		7
+#define	DCCP_PKT_SYNC		8
+#define	DCCP_PKT_SYNCACK	9
+
+/* Generic protocol header (RFC 4340, Section 5.1.) */
+typedef struct dccphdr_s {
+	uint8_t		dh_lport[2];
+	uint8_t		dh_fport[2];
+	uint8_t		dh_offset;
+	uint8_t		dh_ccval:4,
+			dh_cscov:4;
+	uint8_t		db_sum[2];
+	uint8_t		dh_reserved:3,
+			dh_type:4,
+			dh_x:1;
+	uint8_t		dh_res_seq;
+	uint8_t		dh_seq[2];
+} dccph_t;
+
+
+/* Generic protocol header aligned (RFC 4340, Section 5.1.) */
+typedef struct dccphdra_s {
+	in_port_t	dha_lport;		/* Source port */
+	in_port_t	dha_fport;		/* Destination port */
+	uint8_t		dha_offset;		/* Data offset */
+	uint8_t		dha_ccval:4,		/* */
+			dha_cscov:4;		/* */
+	uint16_t	dha_sum;		/* Checksum */
+	uint8_t		dha_x:1,		/* Reserved */
+			dha_type:4,		/* Packet type */
+			dha_reserved:3;		/* Header type */
+	uint8_t		dha_res_seq;
+	uint16_t	dha_seq;		/* Partial sequence number */
+} dccpha_t;
+
+typedef struct dccphdra_ext_s {
+	uint32_t	dha_ext_seq;
+} dccpha_ext_t;
+
+/* Acknowledgement number */
+typedef struct dccphdra_ack {
+	uint16_t	dha_ack_reserved;
+	uint16_t	dha_ack_high;
+	uint32_t	dha_ack_low;
+} dccpha_ack_t;
+
+typedef	struct dccphdra_srv {
+	uint32_t	dha_srv_code;
+} dccpha_srv_t;
+
+typedef struct dccphdra_reset {
+	uint8_t		dha_reset_code;
+	uint8_t		dha_reset_data[3];
+} dccpha_reset_t;
+
+/* Internal DCCP structure */
+typedef struct dccp_s {
+
+	conn_t		*dccp_connp;		/* Backpointer to conn_t */
+	dccp_stack_t	*dccp_dccps;		/* Backpointer to dccp_stack_t */
+
+	uint32_t	dccp_state;
+
+	/* Bind related */
+	struct dccp_s	*dccp_bind_hash;	/* Bind hash chain */
+	struct dccp_s	*dccp_bind_hash_port;	/* Bound to the same port */
+	struct dccp_s	**dccp_ptpbhn;
+
+	struct dccphdra_s *dccp_dccpha;		/* Template header */
+
+	mblk_t		*dccp_xmit_head;
+
+	sock_connid_t	dccp_connid;
+} dccp_t;
+
+#define	dccps_smallest_nonpriv_port	dccps_propinfo_tbl[0].prop_cur_uval
+#define	dccps_smallest_anon_port	dccps_propinfo_tbl[1].prop_cur_uval
+#define	dccps_largest_anon_port		dccps_propinfo_tbl[2].prop_cur_uval
+
+#define	dccps_dbg			dccps_propinfo_tbl[4].prop_cur_uval
+#define	dccps_rst_sent_rate_enabled	dccps_propinfo_tbl[5].prop_cur_uval
+#define	dccps_rst_sent_rate		dccps_propinfo_tbl[6].prop_cur_uval
+
+typedef struct dccp_df_s {
+	struct dccp_s	*df_dccp;
+	kmutex_t	df_lock;
+	uchar_t		df_pad[TF_CACHEL_PAD - (sizeof (dccp_t *) +
+			    sizeof (kmutex_t))];
+} dccp_df_t;
+
+extern struct qinit dccp_rinitv4, dccp_rinitv6;
+
+extern optdb_obj_t	dccp_opt_obj;
+extern uint_t		dccp_max_optsize;
+
+/*
+ * Functions in dccp.c
+ */
+extern int	dccp_build_hdrs(dccp_t *);
+extern conn_t	*dccp_create_common(cred_t *, boolean_t, boolean_t, int *);
+extern void	dccp_close_common(conn_t *);
+extern int	dccp_do_bind(conn_t *, struct sockaddr *, socklen_t, cred_t *,
+		    boolean_t);
+extern int	dccp_do_unbind(conn_t *);
+extern int	dccp_do_listen(conn_t *, struct sockaddr *, socklen_t, int,
+		    cred_t *, boolean_t);
+extern int	dccp_do_connect(conn_t *, const struct sockaddr *, socklen_t,
+		    cred_t *, pid_t);
+extern void	dccp_init_values(dccp_t *, dccp_t *);
+extern void	*dccp_get_conn(void *, dccp_stack_t *);
+extern int	dccp_set_destination(dccp_t *dccp);
+
+/*
+ * Bind related functions in dccp_bind.c
+ */
+extern void	dccp_bind_hash_insert(dccp_df_t *, dccp_t *, int);
+extern void	dccp_bind_hash_remove(dccp_t *);
+extern int	dccp_bind_check(conn_t *, struct sockaddr *, socklen_t, cred_t *cr,
+		    boolean_t);
+extern in_port_t dccp_bindi(dccp_t *, in_port_t, const in6_addr_t *, int,
+		    boolean_t, boolean_t, boolean_t);
+extern in_port_t dccp_update_next_port(in_port_t, const dccp_t *, boolean_t);
+
+/*
+ * MIB-II and kstat related functions.
+ */
+extern mblk_t	*dccp_snmp_get(queue_t *, mblk_t *);
+
+/*
+ * Socket related functions in dccp_socket.c
+ */
+extern sock_lower_handle_t	dccp_create(int, int, int, sock_downcalls_t **,
+				    uint_t *, int *, int, cred_t *);
+extern int	dccp_fallback(sock_lower_handle_t, queue_t *, boolean_t,
+		    so_proto_quiesced_cb_t, sock_quiesce_arg_t *);
+
+/*
+ * Input path related functions in dccp_input.c
+ */
+extern void	dccp_icmp_input(void *, mblk_t *, void *, ip_recv_attr_t *);
+extern void	dccp_input_data(void *, mblk_t *, void *, ip_recv_attr_t *);
+extern void	dccp_rsrv(queue_t *);
+extern void	dccp_input_listener_unbound(void *, mblk_t *, void *,
+		    ip_recv_attr_t *);
+extern boolean_t	dccp_verifyicmp(conn_t *, void *, icmph_t *, icmp6_t *,
+			    ip_recv_attr_t *);
+/*
+ * Output path related functions in dccp_output.c
+ */
+extern void	dccp_wput(queue_t *, mblk_t *);
+extern void	dccp_xmit_listeners_reset(mblk_t *, ip_recv_attr_t *,
+		    ip_stack_t *, conn_t *);
+extern void	dccp_send_synack(void *, mblk_t *, void *, ip_recv_attr_t *);
+extern mblk_t	*dccp_xmit_mp(dccp_t *, mblk_t *, int32_t, int32_t *,
+		    mblk_t **, uint32_t, boolean_t, uint32_t *, boolean_t);
+extern mblk_t	*dccp_generate_packet(conn_t *, mblk_t *);
+/*
+ * Options related functions in dccp_opt_data.c
+ */
+extern int	dccp_opt_get(conn_t *, int, int, uchar_t *);
+extern int	dccp_opt_set(conn_t *, uint_t, int, int, uint_t, uchar_t *,
+		    uint_t *, uchar_t *, void *, cred_t *);
+
+/*
+ * dccp_tpi.c
+ */
+extern void	dccp_err_ack(dccp_t *, mblk_t *, int, int);
+extern void	dccp_tpi_connect(dccp_t *, mblk_t *);
+extern int	dccp_tpi_close(queue_t *, int);
+extern int	dccp_tpi_opt_get(queue_t *, t_scalar_t, t_scalar_t, uchar_t *);
+extern int	dccp_tpi_opt_set(queue_t *, uint_t, int, int, uint_t, uchar_t *,
+		    uint_t *, uchar_t *, void *, cred_t *);
+
+#endif	/* _KERNEL */
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _INET_DCCP_IMPL_H */
--- /dev/null	2012-06-13 12:04:33.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp_input.c	2012-06-13 12:04:33.609296820 +0000
@@ -0,0 +1,353 @@
+/*
+ * 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 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner.  All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/stream.h>
+#include <sys/strsun.h>
+#include <sys/strsubr.h>
+#include <sys/stropts.h>
+#include <sys/strlog.h>
+#define	_SUN_TPI_VERSION 2
+#include <sys/tihdr.h>
+#include <sys/suntpi.h>
+#include <sys/xti_inet.h>
+#include <sys/squeue_impl.h>
+#include <sys/squeue.h>
+#include <sys/tsol/tnet.h>
+
+#include <inet/common.h>
+#include <inet/ip.h>
+
+#include <sys/cmn_err.h>
+
+#include "dccp_impl.h"
+
+static mblk_t	*dccp_conn_create_v4(conn_t *, conn_t *, mblk_t *,
+		    ip_recv_attr_t *);
+static mblk_t	*dccp_conn_create_v6(conn_t *, conn_t *, mblk_t *,
+		    ip_recv_attr_t *);
+static void	dccp_input_listener(void *, mblk_t *, void *, ip_recv_attr_t *);
+
+void
+dccp_input_data(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
+{
+	cmn_err(CE_NOTE, "dccp_input.c: dccp_input_data");
+}
+
+void
+dccp_icmp_input(void *arg1, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
+{
+	cmn_err(CE_NOTE, "dccp_input.c: dccp_icmp_input");
+}
+
+void
+dccp_rsrv(queue_t *q)
+{
+	cmn_err(CE_NOTE, "dccp_input.c: dccp_rsrv");
+}
+
+static mblk_t *
+dccp_conn_create_v6(conn_t *lconnp, conn_t *connp, mblk_t *mp,
+    ip_recv_attr_t *ira)
+{
+	return (NULL);
+}
+
+static mblk_t *
+dccp_conn_create_v4(conn_t *lconnp, conn_t *connp, mblk_t *mp,
+    ip_recv_attr_t *ira)
+{
+	dccp_t		*ldccp = lconnp->conn_dccp;
+	dccp_t		*dccp = connp->conn_dccp;
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+	ipha_t		*ipha;
+	mblk_t		*tpi_mp;
+	sin_t		sin;
+
+	ASSERT(ira->ira_flags & IRAF_IS_IPV4);
+	ipha = (ipha_t *)mp->b_rptr;
+
+	connp->conn_ipversion = IPV4_VERSION;
+	IN6_IPADDR_TO_V4MAPPED(ipha->ipha_dst, &connp->conn_laddr_v6);
+	IN6_IPADDR_TO_V4MAPPED(ipha->ipha_src, &connp->conn_faddr_v6);
+	connp->conn_saddr_v6 = connp->conn_laddr_v6;
+
+	sin = sin_null;
+	sin.sin_addr.s_addr = connp->conn_faddr_v4;
+	sin.sin_port = connp->conn_fport;
+	sin.sin_family = AF_INET;
+
+	if (lconnp->conn_recv_ancillary.crb_recvdstaddr) {
+		cmn_err(CE_NOTE, "ancillary");
+
+		sin_t   sind;
+
+		sind = sin_null;
+		sind.sin_addr.s_addr = connp->conn_laddr_v4;
+		sind.sin_port = connp->conn_lport;
+		sind.sin_family = AF_INET;
+
+		tpi_mp = mi_tpi_extconn_ind(NULL,
+		    (char *)&sind, sizeof (sin_t), (char *)&dccp,
+		    (t_scalar_t)sizeof (intptr_t), (char *)&sind,
+		    sizeof (sin_t), (t_scalar_t) 1); /* XXX */
+
+	} else {
+		tpi_mp = mi_tpi_conn_ind(NULL,
+		(char *)&sin, sizeof (sin_t),
+		(char *)&dccp, (t_scalar_t)sizeof (intptr_t),
+		(t_scalar_t) 1); /* XXX */
+	}
+
+	return (tpi_mp);
+}
+
+static void
+dccp_input_listener(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *ira)
+{
+	conn_t		*lconnp = (conn_t *)arg;
+	conn_t		*econnp;
+	dccp_t		*listener = lconnp->conn_dccp;
+	dccp_t		*eager;
+	dccp_stack_t	*dccps = listener->dccp_dccps;
+	ip_stack_t	*ipst = dccps->dccps_netstack->netstack_ip;
+	dccpha_t	*dccpha;
+	squeue_t	*new_sqp;
+	mblk_t		*tpi_mp;
+	mblk_t		*mp1;
+	uint_t		ip_hdr_len;
+	uint_t		type;
+	int		error;
+
+	cmn_err(CE_NOTE, "dccp_input.c: dccp_input_listener");
+
+	ip_hdr_len = ira->ira_ip_hdr_length;
+	dccpha = (dccpha_t *)&mp->b_rptr[ip_hdr_len];
+	type = (uint_t)dccpha->dha_type;
+
+	if (type != DCCP_PKT_REQUEST) {
+		cmn_err(CE_NOTE, "not request pkt");
+
+		/* XXX do something with a reset packet sent? */
+		freemsg(mp);
+		return;
+	}
+
+	/* XXX memory pressure */
+
+	/* XXX request defense */
+
+	/* XXX number of connections per listener */
+
+	ASSERT(ira->ira_sqp != NULL);
+	new_sqp = ira->ira_sqp;
+
+	econnp = (conn_t *)dccp_get_conn(arg2, dccps);
+	if (econnp == NULL) {
+		cmn_err(CE_NOTE, "econnp not found (eager)");
+		goto error2;
+	}
+
+	ASSERT(econnp->conn_netstack == lconnp->conn_netstack);
+	econnp->conn_sqp = new_sqp;
+	econnp->conn_initial_sqp = new_sqp;
+	econnp->conn_ixa->ixa_sqp = new_sqp;
+
+	econnp->conn_fport = dccpha->dha_lport;
+	econnp->conn_lport = dccpha->dha_fport;
+
+	error = conn_inherit_parent(lconnp, econnp);
+	if (error != 0) {
+		cmn_err(CE_NOTE, "conn_inherit_parent failed");
+		goto error3;
+	}
+
+	econnp->conn_ixa->ixa_src_generation = ipst->ips_src_generation;
+
+
+	ASSERT(OK_32PTR(mp->b_rptr));
+	ASSERT(IPH_HDR_VERSION(mp->b_rptr) == IPV4_VERSION ||
+	    IPH_HDR_VERSION(mp->b_rptr) == IPV6_VERSION);
+
+	if (lconnp->conn_family == AF_INET) {
+		ASSERT(IPH_HDR_VERSION(mp->b_rptr) == IPV4_VERSION);
+		tpi_mp = dccp_conn_create_v4(lconnp, econnp, mp, ira);
+	} else {
+		tpi_mp = dccp_conn_create_v6(lconnp, econnp, mp, ira);
+	}
+
+	if (tpi_mp == NULL) {
+		cmn_err(CE_NOTE, "tpi_mo == NULL");
+		goto error3;
+	}
+
+	eager = econnp->conn_dccp;
+	SOCK_CONNID_INIT(eager->dccp_connid);
+
+	dccp_init_values(eager, listener);
+
+	ASSERT((econnp->conn_ixa->ixa_flags &
+	    (IXAF_SET_ULP_CKSUM | IXAF_VERIFY_SOURCE |
+	    IXAF_VERIFY_PMTU | IXAF_VERIFY_LSO)) ==
+	    (IXAF_SET_ULP_CKSUM | IXAF_VERIFY_SOURCE |
+	    IXAF_VERIFY_PMTU | IXAF_VERIFY_LSO));
+
+	if (ira->ira_cred != NULL) {
+		mblk_setcred(tpi_mp, ira->ira_cred, ira->ira_cpid);
+	}
+
+	if (IPCL_IS_NONSTR(lconnp)) {
+		econnp->conn_flags |= IPCL_NONSTR;
+	}
+
+	/* XXX dccps is right? */
+	dccp_bind_hash_insert(&dccps->dccps_bind_fanout[
+	    DCCP_BIND_HASH(econnp->conn_lport, dccps->dccps_bind_fanout_size)], eager, 0);
+
+	SOCK_CONNID_BUMP(eager->dccp_connid);
+
+	error = dccp_set_destination(eager);
+	if (error != 0) {
+		cmn_err(CE_NOTE, "dccp_set_destination failed.");
+		dccp_bind_hash_remove(eager);
+		goto error3;
+	}
+
+	CONN_INC_REF(lconnp);
+
+/*
+	mp1 = dccp_xmit_mp(eager, eager->dccp_xmit_head, 0,
+	    NULL, NULL, 0, B_FALSE, NULL, B_FALSE);
+*/
+	mp1 = dccp_generate_packet(lconnp, mp);
+	if (mp1 == NULL) {
+		cmn_err(CE_NOTE, "dccp_xmit_mp failed");
+
+		CONN_INC_REF(econnp);
+		goto error;
+	}
+
+	CONN_INC_REF(econnp);
+
+	error = ipcl_conn_insert(econnp);
+	if (error != 0) {
+		cmn_err(CE_NOTE, "ipcl_conn_insert(econnp) failed");
+		goto error;
+	}
+
+	freemsg(mp);
+
+	if (econnp->conn_sqp == lconnp->conn_sqp) {
+		(void) conn_ip_output(mp1, econnp->conn_ixa);
+		CONN_DEC_REF(econnp);
+	} else {
+		SQUEUE_ENTER_ONE(econnp->conn_sqp, mp1, dccp_send_synack,
+		    econnp, NULL, SQ_PROCESS, SQTAG_TCP_SEND_SYNACK); /* XXX */
+	}
+
+	return;
+error:
+error2:
+error3:
+	freemsg(mp);
+}
+
+void
+dccp_input_listener_unbound(void *arg, mblk_t *mp, void *arg2,
+    ip_recv_attr_t *ira)
+{
+	conn_t		*connp = (conn_t *)arg;
+	squeue_t	*sqp = (squeue_t *)arg2;
+	squeue_t	*new_sqp;
+	uint32_t	conn_flags;
+
+	cmn_err(CE_NOTE, "dccp_input.c: dccp_input_listener_unbound");
+
+	ASSERT(ira->ira_sqp != NULL);
+	new_sqp = ira->ira_sqp;
+
+	if (connp->conn_fanout == NULL) {
+		goto done;
+	}
+
+	/*
+	 * Bind to correct squeue.
+	 */
+	if (!(connp->conn_flags & IPCL_FULLY_BOUND)) {
+		cmn_err(CE_NOTE, "not fully bound");
+
+		mutex_enter(&connp->conn_fanout->connf_lock);
+		mutex_enter(&connp->conn_lock);
+
+		if (connp->conn_ref != 4 ||
+		    connp->conn_dccp->dccp_state != DCCPS_LISTEN) {
+			mutex_exit(&connp->conn_lock);
+			mutex_exit(&connp->conn_fanout->connf_lock);
+			goto done;
+		}
+
+		if (connp->conn_sqp != new_sqp) {
+			while (connp->conn_sqp != new_sqp) {
+				(void) casptr(&connp->conn_sqp, sqp, new_sqp);
+			}
+			connp->conn_ixa->ixa_sqp = new_sqp;
+		}
+
+		do {
+			conn_flags = connp->conn_flags;
+			conn_flags |= IPCL_FULLY_BOUND;
+			(void) cas32(&connp->conn_flags, connp->conn_flags,
+			    conn_flags);
+		} while (!(connp->conn_flags & IPCL_FULLY_BOUND));
+
+		mutex_exit(&connp->conn_lock);
+		mutex_exit(&connp->conn_fanout->connf_lock);
+
+		connp->conn_recv = dccp_input_listener;
+	}
+
+done:
+	if (connp->conn_sqp != sqp) {
+		CONN_INC_REF(connp);
+		SQUEUE_ENTER_ONE(connp->conn_sqp, mp, connp->conn_recv, connp,
+		    ira, SQ_FILL, SQTAG_DCCP_CONN_REQ_UNBOUND);
+	} else {
+		dccp_input_listener(connp, mp, sqp, ira);
+	}
+}
+
+boolean_t
+dccp_verifyicmp(conn_t *connp, void *arg2, icmph_t *icmph, icmp6_t *icmp6,
+    ip_recv_attr_t *ira)
+{
+	cmn_err(CE_NOTE, "dccp_input.c: dccp_verifyicmp");
+
+	return (B_TRUE);
+}
--- /dev/null	2012-06-13 12:04:34.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp_ip.h	2012-06-13 12:04:34.290890541 +0000
@@ -0,0 +1,37 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner. All rights reserved.
+ */
+
+#ifndef	_INET_DCCP_DCCP_IP_H
+#define	_INET_DCCP_DCCP_IP_H
+
+#include <netinet/dccp.h>
+#include <inet/dccp/dccp_stack.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * DCCP functions for IP
+ */
+extern void dccp_ddi_g_init(void);
+extern void dccp_ddi_g_destroy(void);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _INET_DCCP_DCCP_IP_H */
--- /dev/null	2012-06-13 12:04:35.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp_opt_data.c	2012-06-13 12:04:35.012350386 +0000
@@ -0,0 +1,154 @@
+/*
+ * 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 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner.  All rights reserved.
+ */
+
+/*
+ * This file contains functions related to getting and setting options
+ * thought the getsockopt and setsockopt socket functions.
+ */
+
+#include <sys/types.h>
+#include <sys/stream.h>
+#define	_SUN_TPI_VERSION 2
+#include <sys/tihdr.h>
+#include <sys/xti_xtiopt.h>
+#include <sys/xti_inet.h>
+#include <sys/policy.h>
+
+#include <inet/common.h>
+#include <inet/ip.h>
+#include <inet/optcom.h>
+#include <netinet/ip.h>
+
+#include <sys/cmn_err.h>
+
+#include "dccp_impl.h"
+
+static int dccp_opt_default(queue_t *, int, int, uchar_t *);
+
+/*
+ * Supported options.
+ */
+opdes_t dccp_opt_arr[] = {
+{ SO_DEBUG, SOL_SOCKET, OA_RW, OA_RW, OP_NP, 0, sizeof (int), 0 },
+}; 
+
+/*
+ * Supported levels.
+ */
+optlevel_t dccp_valid_levels_arr[] = {
+	SOL_SOCKET,
+};
+
+#define	DCCP_OPT_ARR_CNT	A_CNT(dccp_opt_arr)
+#define	DCCP_VALID_LEVELS_CNT	A_CNT(dccp_valid_levels_arr)
+
+uint_t dccp_max_optsize;
+
+/*
+ * Options database object.
+ */
+optdb_obj_t dccp_opt_obj = {
+	dccp_opt_default,
+	dccp_tpi_opt_get,
+	dccp_tpi_opt_set,
+	DCCP_OPT_ARR_CNT,
+	dccp_opt_arr,
+	DCCP_VALID_LEVELS_CNT,
+	dccp_valid_levels_arr,
+};
+
+/*
+ * Default value for certain options.
+ */
+int
+dccp_opt_default(queue_t *q, int level, int name, uchar_t *ptr)
+{
+	dccp_stack_t	*dccps = Q_TO_DCCP(q)->dccp_dccps;
+	int32_t		*il = (int32_t *)ptr;
+
+	return (sizeof (int));
+}
+
+int
+dccp_opt_get(conn_t *connp, int level, int name, uchar_t *ptr)
+{
+	dccp_t		*dccp = connp->conn_dccp;
+	conn_opt_arg_t	coas;
+	int		retval;
+
+	coas.coa_connp = connp;
+	coas.coa_ixa = connp->conn_ixa;
+	coas.coa_ipp = &connp->conn_xmit_ipp;
+	coas.coa_ancillary = B_FALSE;
+	coas.coa_changed = 0;
+
+	switch (level) {
+	case SOL_SOCKET:
+		break;
+	case IPPROTO_TCP:
+		break;
+	case IPPROTO_IP:
+		break;
+	case IPPROTO_IPV6:
+		break;
+	}
+
+	mutex_enter(&connp->conn_lock);
+	retval = conn_opt_get(&coas, level, name, ptr);
+	mutex_exit(&connp->conn_lock);
+
+	return (retval);
+}
+
+/* ARGSUSED */
+int
+dccp_opt_set(conn_t *connp, uint_t optset_context, int level, int name,
+    uint_t inlen, uchar_t *invalp, uint_t *outlenp, uchar_t *outvalp,
+    void *thisdg_attrs, cred_t *cr)
+{
+	dccp_t		*dccp = connp->conn_dccp;
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+	conn_opt_arg_t	coas;
+	int		*i1 = (int *)invalp;
+	int		error;
+
+	coas.coa_connp = connp;
+	coas.coa_ancillary = B_FALSE;
+	coas.coa_changed = 0;
+
+	error = conn_opt_set(&coas, level, name, inlen, invalp,
+	    B_FALSE, cr);
+	if (error !=0) {
+		*outlenp = 0;
+		return (error);
+	}
+
+	return (0);
+}
--- /dev/null	2012-06-13 12:04:35.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp_output.c	2012-06-13 12:04:35.810109899 +0000
@@ -0,0 +1,375 @@
+/*
+ * 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 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner.  All rights reserved.
+ */
+
+/*
+ * Functions related to the output path.
+ */
+
+#include <sys/types.h>
+#include <sys/stream.h>
+#include <sys/strsun.h>
+#include <sys/strsubr.h>
+#include <sys/stropts.h>
+#include <sys/strlog.h>
+#define	_SUN_TPI_VERSION 2
+#include <sys/tihdr.h>
+#include <sys/suntpi.h>
+#include <sys/xti_inet.h>
+#include <sys/squeue_impl.h>
+#include <sys/squeue.h>
+#include <sys/tsol/tnet.h>
+
+#include <inet/common.h>
+#include <inet/ip.h>
+
+#include <sys/cmn_err.h>
+
+#include "dccp_impl.h"
+#include "dccp_stack.h"
+
+static void	dccp_xmit_early_reset(char *, mblk_t *, uint32_t, uint32_t,
+		    int, ip_recv_attr_t *, ip_stack_t *, conn_t *);
+static boolean_t	dccp_send_rst_chk(dccp_stack_t *);
+
+/*
+ * STREAMS
+ */
+void
+dccp_wput(queue_t *q, mblk_t *mp)
+{
+	cmn_err(CE_NOTE, "dccp_output.c: dccp_wput\n");
+}
+
+/*
+ * Send a reset as response to an incoming packet or
+ * reset a connection.
+ */
+void
+dccp_xmit_listeners_reset(mblk_t *mp, ip_recv_attr_t *ira, ip_stack_t *ipst,
+    conn_t *connp)
+{
+	dccpha_t	*dccpha;
+	uint32_t	seg_seq;
+	uint32_t	seg_ack;
+	uint32_t	seq_len;
+	uint_t		ip_hdr_len = ira->ira_ip_hdr_length;
+	uchar_t		*rptr;
+
+	cmn_err(CE_NOTE, "dccp_output.c: dccp_xmit_listeners_reset");
+
+	rptr = mp->b_rptr;
+
+	dccpha = (dccpha_t *)&rptr[ip_hdr_len];
+
+	//seg_seq = ntonl(dccpha->dha_seq);
+	//seg_ack = htonl(dccpha->dha_ack);
+
+	seq_len = msgdsize(mp) - (ip_hdr_len);
+
+	dccp_xmit_early_reset("no dccp, reset", mp, 0,
+	    0, 0, ira, ipst, connp);
+}
+
+/*
+ * RFC 4340, Section 8.1.3
+ */
+static void
+dccp_xmit_early_reset(char *str, mblk_t *mp, uint32_t seq, uint32_t ack, int ctl,
+    ip_recv_attr_t *ira, ip_stack_t *ipst, conn_t *connp)
+{
+	dccpha_t	*dccpha;
+	dccpha_t	*nmp_dccpha;
+	dccpha_ack_t	*nmp_dccpha_ack;
+	dccpha_reset_t	*dccpha_reset;
+	dccpha_reset_t	*nmp_dccpha_reset;
+	dccpha_ext_t	*dccpha_ext;
+	dccpha_ext_t	*nmp_dccpha_ext;
+	netstack_t	*ns = ipst->ips_netstack;
+	dccp_stack_t	*dccps = ns->netstack_dccp;
+	ip6_t		*ip6h;
+	ipha_t		*ipha;
+	ipha_t		*nmp_ipha;
+	ip_xmit_attr_t	ixas;
+	ip_xmit_attr_t	*ixa;
+	in6_addr_t	v6addr;
+	ipaddr_t	v4addr;
+	mblk_t		*nmp;
+	uint64_t	pkt_ack;
+	uint_t		ip_hdr_len = ira->ira_ip_hdr_length;
+	ushort_t	port;
+	ushort_t	len;
+
+	cmn_err(CE_NOTE, "dccp_output.c: dccp_xmit_early_reset");
+
+	if (!dccp_send_rst_chk(dccps)) {
+		cmn_err(CE_NOTE, "dccp_output.c: not sending reset packet");
+		DCCP_STAT(dccps, dccp_rst_unsent);
+		freemsg(mp);
+		return;
+	}
+
+		bzero(&ixas, sizeof (ixas));
+		ixa = &ixas;
+
+		ixa->ixa_flags |= IXAF_SET_ULP_CKSUM | IXAF_VERIFY_SOURCE;
+		ixa->ixa_protocol = IPPROTO_DCCP;
+		ixa->ixa_zoneid = ira->ira_zoneid;
+		ixa->ixa_ifindex = 0;
+		ixa->ixa_ipst = ipst;
+		ixa->ixa_cred = kcred;
+		ixa->ixa_cpid = NOPID;
+
+	if (str && dccps->dccps_dbg) {
+		(void) strlog(DCCP_MOD_ID, 0, 1, SL_TRACE,
+		    "dccp_xmit_early_reset: '%s', seq 0x%x, ack 0x%x, "
+		    "flags 0x%x",
+		    str, seq, ack, ctl);
+	}
+
+	if (IPH_HDR_VERSION(mp->b_rptr) == IPV4_VERSION) {
+		ipha = (ipha_t *)mp->b_rptr;
+
+	} else {
+		/* XXX */
+	}
+
+	/*
+	 * Allocate a new DCCP reset message
+	 */
+	len = ip_hdr_len + sizeof (dccpha_t) + sizeof (dccpha_ext_t) + sizeof (dccpha_ack_t) + sizeof (dccpha_reset_t);
+	nmp = allocb(len, BPRI_MED);
+	if (nmp == NULL) {
+		cmn_err(CE_NOTE, "alloc failed");
+		return;
+	}
+	bcopy(mp->b_rptr, nmp->b_wptr, ip_hdr_len + sizeof (dccpha_t));
+
+	nmp_dccpha = (dccpha_t *)&nmp->b_rptr[ip_hdr_len];
+	nmp_dccpha->dha_offset = 7;
+
+	if (IPH_HDR_VERSION(mp->b_rptr) == IPV4_VERSION) {
+		nmp_ipha = (ipha_t *)nmp->b_rptr;
+
+		nmp_ipha->ipha_length = htons(len);
+		nmp_ipha->ipha_src = ipha->ipha_dst;
+		nmp_ipha->ipha_dst = ipha->ipha_src;
+
+		ixa->ixa_flags |= IXAF_IS_IPV4;
+		ixa->ixa_ip_hdr_length = ip_hdr_len;
+	} else {
+		cmn_err(CE_NOTE, "not v4");
+	}
+
+	dccpha = (dccpha_t *)&mp->b_rptr[ip_hdr_len];
+
+	nmp->b_wptr = &nmp->b_rptr[len];
+
+	ixa->ixa_pktlen = len; // ?
+
+	nmp_dccpha->dha_fport = dccpha->dha_lport;
+	nmp_dccpha->dha_lport = dccpha->dha_fport;
+	nmp_dccpha->dha_type = DCCP_PKT_RESET;
+	nmp_dccpha->dha_x = 1;
+	nmp_dccpha->dha_res_seq = 0;
+	nmp_dccpha->dha_seq = 0;
+
+	nmp_dccpha->dha_sum = htons(sizeof (dccpha_t) + sizeof (dccpha_ext_t) + sizeof (dccpha_ack_t) + sizeof (dccpha_reset_t));
+
+	dccpha_ext = (dccpha_ext_t *)&mp->b_rptr[ip_hdr_len + sizeof (dccpha_t)];
+	nmp_dccpha_ext = (dccpha_ext_t *)&nmp->b_rptr[ip_hdr_len + sizeof (dccpha_t)];
+	nmp_dccpha_ext->dha_ext_seq = 0;
+
+	len = ip_hdr_len + sizeof (dccpha_t) + sizeof (dccpha_ext_t);
+	nmp_dccpha_ack = (dccpha_ack_t *)&nmp->b_rptr[len];
+	nmp_dccpha_ack->dha_ack_high = dccpha->dha_seq;
+	nmp_dccpha_ack->dha_ack_low = dccpha_ext->dha_ext_seq;
+
+	len = ip_hdr_len + sizeof (dccpha_t) + sizeof (dccpha_ext_t) + sizeof (dccpha_ack_t);
+	nmp_dccpha_reset = (dccpha_reset_t *)&nmp->b_rptr[len];
+	nmp_dccpha_reset->dha_reset_code = 7;
+	nmp_dccpha_reset->dha_reset_data[0] = 0;
+	nmp_dccpha_reset->dha_reset_data[1] = 0;
+	nmp_dccpha_reset->dha_reset_data[2] = 0;
+
+	(void) ip_output_simple(nmp, ixa);
+
+	ixa_cleanup(ixa);
+}
+
+/*
+ *
+ */
+static boolean_t
+dccp_send_rst_chk(dccp_stack_t *dccps)
+{
+	int64_t	now;
+
+	if (dccps->dccps_rst_sent_rate_enabled != 0) {
+		now = ddi_get_lbolt64();
+		if (TICK_TO_MSEC(now - dccps->dccps_last_rst_intrvl) >
+		    1 * SECONDS) {
+			dccps->dccps_last_rst_intrvl = now;
+			dccps->dccps_rst_cnt = 1;
+		} else if (++dccps->dccps_rst_cnt > dccps->dccps_rst_sent_rate) {
+			return (B_FALSE);
+		}
+	}
+
+	return (B_TRUE);
+}
+
+void
+dccp_send_synack(void *arg, mblk_t *mp, void *arg2, ip_recv_attr_t *dummy)
+{
+	cmn_err(CE_NOTE, "dccp_output.c: dccp_send_synack");
+}
+
+mblk_t *
+dccp_xmit_mp(dccp_t *dccp, mblk_t *mp, int32_t max_to_send, int32_t *offset,
+    mblk_t **end_mp, uint32_t seq, boolean_t sendall, uint32_t *seg_len,
+    boolean_t rexmit)
+{
+	conn_t		*connp = dccp->dccp_connp;
+	dccp_stack_t	*dccps = dccp->dccp_dccps;
+	dccpha_t	*dccpha;
+	dccpha_ext_t	*dccpha_ext;
+	dccpha_ack_t	*dccpha_ack;
+	dccpha_srv_t	*dccpha_srv;
+	ip_xmit_attr_t	*ixa = connp->conn_ixa;
+	mblk_t		*mp1;
+	uchar_t		*rptr;
+	ushort_t	len;
+	int		data_length;
+
+	cmn_err(CE_NOTE, "dccp_output.c: dccp_xmit_mp");
+
+	// dccpha_t already in iphc_len?
+	len = connp->conn_ht_iphc_len + sizeof (dccpha_ext_t) + sizeof (dccpha_ack_t) + 4;
+
+	//mp1 = dccp_generate_packet(connp, mp);
+	mp1 = allocb(len, BPRI_MED);
+	if (mp1 == NULL) {
+		cmn_err(CE_NOTE, "allocb failed");
+		return (NULL);
+	}
+
+	data_length = 0;
+
+	rptr = mp1->b_rptr;
+	mp1->b_wptr = &mp1->b_rptr[len];
+	bcopy(connp->conn_ht_iphc, rptr, connp->conn_ht_iphc_len);
+	dccpha = (dccpha_t *)&rptr[ixa->ixa_ip_hdr_length];
+	dccpha->dha_type = DCCP_PKT_RESPONSE;
+	dccpha->dha_offset = 8;
+	dccpha->dha_x = 1;
+	dccpha->dha_ccval = 0;
+	dccpha->dha_cscov = 0;
+	dccpha->dha_reserved = 0;
+	dccpha->dha_res_seq = 0;
+	dccpha->dha_seq = 0;
+
+	dccpha_ext = (dccpha_ext_t *)&rptr[ixa->ixa_ip_hdr_length + sizeof (dccpha_t)];
+	dccpha_ext->dha_ext_seq = 0;
+
+	dccpha_ack = (dccpha_ack_t *)&rptr[ixa->ixa_ip_hdr_length + sizeof (dccpha_t) + sizeof (dccpha_ext_t)];
+	dccpha_ack->dha_ack_reserved = 0;
+	dccpha_ack->dha_ack_high = 0;
+	dccpha_ack->dha_ack_low = 0;
+
+	dccpha_srv = (dccpha_srv_t *)&rptr[ixa->ixa_ip_hdr_length + sizeof (dccpha_t) + sizeof (dccpha_ext_t) + sizeof (dccpha_ack_t)];
+	dccpha_srv->dha_srv_code = 0;
+
+	return (mp1);
+}
+
+mblk_t *
+dccp_generate_packet(conn_t *connp, mblk_t *mp)
+{
+	dccpha_t	*dccpha;
+	dccpha_ext_t	*dccpha_ext;
+	dccpha_ack_t	*dccpha_ack;
+	mblk_t		*mp1;
+	uint16_t	ack_high;
+	uint32_t	ack_low;
+//	uint_t          ip_hdr_len = ira->ira_ip_hdr_length;
+	ip_xmit_attr_t  *ixa = connp->conn_ixa;
+	uint_t		ip_hdr_len;
+	uint_t		len;
+	uchar_t		*rptr;
+
+	cmn_err(CE_NOTE, "dccp_output.c: dccp_generate_packet");
+
+	ip_hdr_len = ixa->ixa_ip_hdr_length;
+
+	if (mp == NULL) {
+		cmn_err(CE_NOTE, "NULL pointer mp");
+		return (NULL);
+	}
+
+	dccpha = (dccpha_t *)&mp->b_rptr[ip_hdr_len];
+	dccpha_ext = (dccpha_ext_t *)&mp->b_rptr[ip_hdr_len + sizeof (dccpha_t)];
+
+	ack_high = dccpha->dha_seq;
+	ack_low = dccpha_ext->dha_ext_seq;
+
+	len = connp->conn_ht_iphc_len + sizeof (dccpha_t) + sizeof (dccpha_ext_t) + sizeof (dccpha_ack_t) + 4;
+	//len = ip_hdr_len + sizeof (dccpha_t) + sizeof (dccpha_ext_t) + sizeof (dccpha_ack_t) + 4;
+	mp1 = allocb(len, BPRI_MED);
+	if (mp1 == NULL) {
+		cmn_err(CE_NOTE, "allocb failed");
+		return (NULL);
+	}
+
+        rptr = mp1->b_rptr;
+        mp1->b_wptr = &mp1->b_rptr[len];
+
+        bcopy(connp->conn_ht_iphc, rptr, connp->conn_ht_iphc_len);
+        dccpha = (dccpha_t *)&rptr[ixa->ixa_ip_hdr_length];
+	//dccpha = (dccpha_t *)&mp1->b_rptr[ip_hdr_len];
+
+        dccpha->dha_type = DCCP_PKT_RESPONSE;
+        dccpha->dha_offset = 8;
+        dccpha->dha_x = 1;
+        dccpha->dha_ccval = 0;
+        dccpha->dha_cscov = 0;
+        dccpha->dha_reserved = 0;
+	dccpha->dha_res_seq = 0;
+	dccpha->dha_seq = 1;
+	dccpha->dha_sum = htons(len);
+
+	dccpha_ext = (dccpha_ext_t *)&mp1->b_rptr[ip_hdr_len + sizeof (dccpha_t)];
+	dccpha_ext->dha_ext_seq = 1;
+
+	dccpha_ack = (dccpha_ack_t *)&mp1->b_rptr[ip_hdr_len + sizeof (dccpha_t) + sizeof (dccpha_ext_t)];
+	dccpha_ack->dha_ack_high = ack_high;
+	dccpha_ack->dha_ack_low = ack_low;
+
+	return (mp1);
+}
--- /dev/null	2012-06-13 12:04:36.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp_socket.c	2012-06-13 12:04:36.558983964 +0000
@@ -0,0 +1,579 @@
+/*
+ * 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 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner.  All rights reserved.
+ */
+
+/*
+ * This file contains function related to the socket interface.
+ */
+
+#include <sys/types.h>
+#include <sys/strlog.h>
+#include <sys/policy.h>
+#include <sys/sockio.h>
+#include <sys/strsubr.h>
+#include <sys/strsun.h>
+#define	_SUN_TPI_VERSION 2
+#include <sys/tihdr.h>
+#include <sys/squeue_impl.h>
+#include <sys/squeue.h>
+#include <sys/socketvar.h>
+
+#include <inet/common.h>
+#include <inet/proto_set.h>
+#include <inet/ip.h>
+
+#include <sys/cmn_err.h>
+
+#include "dccp_impl.h"
+#include "dccp_stack.h"
+
+static void	dccp_activate(sock_lower_handle_t, sock_upper_handle_t,
+		    sock_upcalls_t *, int, cred_t *);
+static int	dccp_accept(sock_lower_handle_t, sock_lower_handle_t,
+		    sock_upper_handle_t, cred_t *);
+static int	dccp_bind(sock_lower_handle_t, struct sockaddr *,
+		    socklen_t, cred_t *);
+static int	dccp_listen(sock_lower_handle_t, int, cred_t *);
+static int	dccp_connect(sock_lower_handle_t, const struct sockaddr *,
+		    socklen_t, sock_connid_t *, cred_t *);
+static int	dccp_getpeername(sock_lower_handle_t, struct sockaddr *,
+		    socklen_t *, cred_t *);
+static int	dccp_getsockname(sock_lower_handle_t, struct sockaddr *,
+		    socklen_t *, cred_t *);
+static int	dccp_getsockopt(sock_lower_handle_t, int, int, void *,
+		    socklen_t *, cred_t *);
+static int	dccp_setsockopt(sock_lower_handle_t, int, int, const void *,
+		    socklen_t, cred_t *);
+static int	dccp_sendmsg(sock_lower_handle_t, mblk_t *, struct nmsghdr *,
+		    cred_t *);
+static int	dccp_shutdown(sock_lower_handle_t, int, cred_t *);
+static void	dccp_clr_flowctrl(sock_lower_handle_t);
+static int	dccp_ioctl(sock_lower_handle_t, int, intptr_t, int, int32_t *,
+		    cred_t *);
+static int	dccp_close(sock_lower_handle_t, int, cred_t *);
+
+sock_downcalls_t sock_dccp_downcalls = {
+	dccp_activate,
+	dccp_accept,
+	dccp_bind,
+	dccp_listen,
+	dccp_connect,
+	dccp_getpeername,
+	dccp_getsockname,
+	dccp_getsockopt,
+	dccp_setsockopt,
+	dccp_sendmsg,
+	NULL,
+	NULL,
+	NULL,
+	dccp_shutdown,
+	dccp_clr_flowctrl,
+	dccp_ioctl,
+	dccp_close,
+};
+
+/* ARGSUSED */
+static void
+dccp_activate(sock_lower_handle_t proto_handle, sock_upper_handle_t sock_handle,
+    sock_upcalls_t *sock_upcalls, int flags, cred_t *cr)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+	struct sock_proto_props		sopp;
+	//extern struct module_info	tcp_rinfo;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_activate");
+
+	ASSERT(cr != NULL);
+
+	sopp.sopp_flags = SOCKOPT_RCVHIWAT | SOCKOPT_RCVLOWAT |
+	    SOCKOPT_MAXPSZ | SOCKOPT_MAXBLK | SOCKOPT_RCVTIMER |
+	    SOCKOPT_RCVTHRESH | SOCKOPT_MAXADDRLEN | SOCKOPT_MINPSZ;
+
+
+	sopp.sopp_rxhiwat = SOCKET_RECVHIWATER;
+	sopp.sopp_rxlowat = SOCKET_RECVLOWATER;
+	sopp.sopp_maxpsz = INFPSZ;
+	sopp.sopp_maxblk = INFPSZ;
+	sopp.sopp_rcvtimer = SOCKET_TIMER_INTERVAL;
+	sopp.sopp_rcvthresh = SOCKET_RECVHIWATER >> 3;
+	sopp.sopp_maxaddrlen = sizeof (sin6_t);
+/*
+	sopp.sopp_minpsz = (dccp_rinfo.mi_minpsz == 1) ? 0 :
+	    dccp_rinfo.mi_minpsz;
+*/
+	connp->conn_upcalls = sock_upcalls;
+	connp->conn_upper_handle = sock_handle;
+
+	/* XXX */
+	(*connp->conn_upcalls->su_set_proto_props)(connp->conn_upper_handle,
+	    &sopp);
+}
+
+/*ARGSUSED*/
+static int
+dccp_accept(sock_lower_handle_t lproto_handle,
+    sock_lower_handle_t eproto_handle, sock_upper_handle_t sock_handle,
+    cred_t *cr)
+{
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_accept");
+
+	return (ENOTSUP);
+}
+
+static int
+dccp_bind(sock_lower_handle_t proto_handle, struct sockaddr *sa,
+    socklen_t len, cred_t *cr)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+	int	error;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_bind");
+
+	ASSERT(cr != NULL);
+	ASSERT(connp->conn_upper_handle != NULL);
+
+	error = squeue_synch_enter(connp, NULL);
+	if (error != 0) {
+		/* Failed to enter */
+		return (ENOSR);
+	}
+
+	/* Binding to NULL address means unbind */
+	if (sa == NULL) {
+		if (connp->conn_dccp->dccp_state < DCCPS_LISTEN) {
+			error = dccp_do_unbind(connp);
+		} else {
+			error = EINVAL;
+		}
+	} else {
+		error = dccp_do_bind(connp, sa, len, cr, B_TRUE);
+	}
+
+	squeue_synch_exit(connp);
+
+	if (error < 0) {
+		if (error == -TOUTSTATE) {
+			error = EINVAL;
+		} else {
+			error = proto_tlitosyserr(-error);
+		}
+	}
+
+	return (error);
+}
+
+/* ARGSUSED */
+static int
+dccp_listen(sock_lower_handle_t proto_handle, int backlog, cred_t *cr)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+	dccp_t	*dccp = connp->conn_dccp;
+	int	error;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_listen");
+
+	ASSERT(connp->conn_upper_handle != NULL);
+	ASSERT(cr != NULL);
+
+	error = squeue_synch_enter(connp, NULL);
+	if (error != 0) {
+		/* Failed to enter */
+		return (ENOBUFS);
+	}
+
+	error = dccp_do_listen(connp, NULL, 0, backlog, cr, B_FALSE);
+	if (error == 0) {
+		/* XXX:DCCP */
+		(*connp->conn_upcalls->su_opctl)(connp->conn_upper_handle,
+		    SOCK_OPCTL_ENAB_ACCEPT,
+		    (uintptr_t)(10));
+	} else if (error < 0) {
+		if (error == -TOUTSTATE) {
+			error = EINVAL;
+		} else {
+			error = proto_tlitosyserr(-error);
+		}
+	}
+
+	squeue_synch_exit(connp);
+
+	return (error);
+}
+
+static int
+dccp_connect(sock_lower_handle_t proto_handle, const struct sockaddr *sa,
+    socklen_t len, sock_connid_t *id, cred_t *cr)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+	int	error;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_connect");
+
+	ASSERT(connp->conn_upper_handle != NULL);
+	ASSERT(cr != NULL);
+
+	error = proto_verify_ip_addr(connp->conn_family, sa, len);
+	if (error != 0) {
+		return (error);
+	}
+
+	error = squeue_synch_enter(connp, NULL);
+	if (error != 0) {
+		/* Failed to enter */
+		return (ENOSR);
+	}
+
+	error = dccp_do_connect(connp, sa, len, cr, curproc->p_pid);
+	if (error == 0) {
+		*id = connp->conn_dccp->dccp_connid;
+	} else if (error < 0) {
+		if (error == -TOUTSTATE) {
+			switch (connp->conn_dccp->dccp_state) {
+			/* XXX */
+			case DCCPS_LISTEN:
+				error = EOPNOTSUPP;
+				break;
+			default:
+				error = EINVAL;
+				break;
+			}
+		} else {
+			error = proto_tlitosyserr(-error);
+		}
+	}
+
+	squeue_synch_exit(connp);
+
+	cmn_err(CE_NOTE, "dccp_connect.c: exit %d", error);
+	return ((error == 0) ? EINPROGRESS : error);
+}
+
+/* ARGSUSED3 */
+static int
+dccp_getpeername(sock_lower_handle_t proto_handle, struct sockaddr *addr,
+    socklen_t *addrlenp, cred_t *cr)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+	dccp_t	*dccp = connp->conn_dccp;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_getpeername");
+
+	ASSERT(cr != NULL);
+
+	ASSERT(dccp != NULL);
+	/* XXX:DCCP */
+
+	return (conn_getpeername(connp, addr, addrlenp));
+}
+
+/* ARGSUSED3 */
+static int
+dccp_getsockname(sock_lower_handle_t proto_handle, struct sockaddr *addr,
+    socklen_t *addrlenp, cred_t *cr)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+	int	error;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_getsockname");
+
+	ASSERT(cr != NULL);
+
+	/* XXX UDP has locks here, TCP not */
+	mutex_enter(&connp->conn_lock);
+	error = conn_getsockname(connp, addr, addrlenp);
+	mutex_exit(&connp->conn_lock);
+
+	return (error);
+}
+
+static int
+dccp_getsockopt(sock_lower_handle_t proto_handle, int level, int option_name,
+    void *optvalp, socklen_t *optlen, cred_t *cr)
+{
+	conn_t		*connp = (conn_t *)proto_handle;
+	t_uscalar_t	max_optbuf_len;
+	void		*optvalp_buf;
+	int		len;
+	int		error;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_getsockopt");
+
+	ASSERT(connp->conn_upper_handle != NULL);
+
+	error = proto_opt_check(level, option_name, *optlen, &max_optbuf_len,
+	    dccp_opt_obj.odb_opt_des_arr,
+	    dccp_opt_obj.odb_opt_arr_cnt,
+	    B_FALSE, B_TRUE, cr);
+	if (error != 0) {
+		if (error < 0) {
+			error = proto_tlitosyserr(-error);
+		}
+		return (error);
+	}
+
+	optvalp_buf = kmem_alloc(max_optbuf_len, KM_SLEEP);
+	if (optvalp_buf == NULL) {
+		return (ENOMEM);
+	}
+
+	error = squeue_synch_enter(connp, NULL);
+	if (error == ENOMEM) {
+		kmem_free(optvalp_buf, max_optbuf_len);
+		return (ENOMEM);
+	}
+
+	len = dccp_opt_get(connp, level, option_name, optvalp_buf);
+	squeue_synch_exit(connp);
+
+	if (len == -1) {
+		kmem_free(optvalp_buf, max_optbuf_len);
+		return (EINVAL);
+	}
+
+	t_uscalar_t size = MIN(len, *optlen);
+
+	bcopy(optvalp_buf, optvalp, size);
+	bcopy(&size, optlen, sizeof (size));
+
+	kmem_free(optvalp_buf, max_optbuf_len);
+
+	return (0);
+}
+
+static int
+dccp_setsockopt(sock_lower_handle_t proto_handle, int level, int option_name,
+    const void *optvalp, socklen_t optlen, cred_t *cr)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+	int	error;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_setsockopt");
+
+	ASSERT(connp->conn_upper_handle != NULL);
+
+	error = squeue_synch_enter(connp, NULL);
+	if (error = ENOMEM) {
+		return (ENOMEM);
+	}
+
+	error = proto_opt_check(level, option_name, optlen, NULL,
+	    dccp_opt_obj.odb_opt_des_arr,
+	    dccp_opt_obj.odb_opt_arr_cnt,
+	    B_TRUE, B_FALSE, cr);
+	if (error != 0) {
+		if (error < 0) {
+			error = proto_tlitosyserr(-error);
+		}
+		squeue_synch_exit(connp);
+		return (error);
+	}
+
+	error = dccp_opt_set(connp, SETFN_OPTCOM_NEGOTIATE, level, option_name,
+	    optlen, (uchar_t *)optvalp, (uint_t *)&optlen, (uchar_t *)optvalp,
+	    NULL, cr);
+	squeue_synch_exit(connp);
+
+	ASSERT(error >= 0);
+
+	return (error);
+}
+
+/* ARGSUSED */
+static int
+dccp_sendmsg(sock_lower_handle_t proto_handle, mblk_t *mp, struct nmsghdr *msg,
+    cred_t *cr)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+	dccp_t	*dccp;
+	uint32_t msize;
+	int32_t	dccpstate;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_sendmsg");
+
+	/* All Solaris components should pass a cred for this operation. */
+	ASSERT(cr != NULL);
+
+	ASSERT(connp->conn_ref >= 2);
+	ASSERT(connp->conn_upper_handle != NULL);
+
+	if (msg->msg_controllen != 0) {
+		freemsg(mp);
+		return (EOPNOTSUPP);
+	}
+
+	switch (DB_TYPE(mp)) {
+	case M_DATA:
+		dccp = connp->conn_dccp;
+		ASSERT(dccp != NULL);
+
+		dccpstate = dccp->dccp_state;
+
+		/* XXX */
+
+		return (0);
+
+	default:
+		ASSERT(0);
+	}
+
+	freemsg(mp);
+
+	return (0);
+}
+
+/* ARGSUSED */
+static int
+dccp_shutdown(sock_lower_handle_t proto_handle, int how, cred_t *cr)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+	dccp_t	*dccp = connp->conn_dccp;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_shutdown");
+
+	/* All Solaris components should pass a cred for this operation. */
+	ASSERT(cr != NULL);
+
+	ASSERT(connp->conn_upper_handle != NULL);
+
+
+	return (ENOTSUP);
+}
+
+static void
+dccp_clr_flowctrl(sock_lower_handle_t proto_handle)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+	dccp_t	*dccp = connp->conn_dccp;
+	mblk_t	*mp;
+	int	error;
+
+	ASSERT(connp->conn_upper_handle != NULL);
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_clr_flowctrl");
+
+	error = squeue_synch_enter(connp, mp);
+
+	squeue_synch_exit(connp);
+}
+
+/* ARGSUSED */
+static int
+dccp_ioctl(sock_lower_handle_t proto_handle, int cmd, intptr_t arg,
+    int mode, int32_t *rvalp, cred_t *cr)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+	int	error;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_ioctl");
+
+	ASSERT(connp->conn_upper_handle != NULL);
+
+	/* All Solaris components should pass a cred for this operation. */
+	ASSERT(cr != NULL);
+
+	return (ENOTSUP);
+}
+
+/* ARGSUSED */
+static int
+dccp_close(sock_lower_handle_t proto_handle, int flags, cred_t *cr)
+{
+	conn_t	*connp = (conn_t *)proto_handle;
+
+	cmn_err(CE_NOTE, "dccp_socket.c: dccp_close\n");
+
+	ASSERT(connp->conn_upper_handle != NULL);
+
+	/* All Solaris components should pass a cred for this operation. */
+
+	ASSERT(cr != NULL);
+
+	dccp_close_common(connp);
+
+	ip_free_helper_stream(connp);
+
+	CONN_DEC_REF(connp);
+
+	return (EINPROGRESS);
+}
+
+
+/*
+ * Socket create function.
+ */
+sock_lower_handle_t
+dccp_create(int family, int type, int proto, sock_downcalls_t **sockdowncalls,
+    uint_t *smodep, int *errorp, int flags, cred_t *credp)
+{
+	conn_t		*connp;
+	boolean_t	isv6;
+
+	/* XXX (type != SOCK_STREAM */
+	if ((family != AF_INET && family != AF_INET6) ||
+	    (proto != 0 && proto != IPPROTO_DCCP)) {
+		*errorp = EPROTONOSUPPORT;
+		return (NULL);
+	}
+
+	cmn_err(CE_NOTE, "dccp_socket: dccp_create\n");
+
+	isv6 = family == AF_INET6 ? B_TRUE: B_FALSE;
+	connp = dccp_create_common(credp, isv6, B_TRUE, errorp);
+	if (connp == NULL) {
+		return (NULL);
+	}
+
+	/*
+	 * Increment ref for DCCP connection.
+	 */
+	mutex_enter(&connp->conn_lock);
+	CONN_INC_REF_LOCKED(connp);
+	ASSERT(connp->conn_ref == 2);
+	connp->conn_state_flags &= ~CONN_INCIPIENT;
+	connp->conn_flags |= IPCL_NONSTR;
+	mutex_exit(&connp->conn_lock);
+
+	ASSERT(errorp != NULL);
+	*errorp = 0;
+	*sockdowncalls = &sock_dccp_downcalls;
+	*smodep = SM_CONNREQUIRED | SM_EXDATA | SM_ACCEPTSUPP |
+	    SM_SENDFILESUPP;
+
+	return ((sock_lower_handle_t)connp);
+}
+
+int
+dccp_fallback(sock_lower_handle_t proto_handle, queue_t *q,
+    boolean_t issocket, so_proto_quiesced_cb_t quiesced_cb,
+    sock_quiesce_arg_t *arg)
+{
+	cmn_err(CE_NOTE, "dccp_socket: dccp_fallback\n");
+
+	return (0);
+}
--- /dev/null	2012-06-13 12:04:40.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp_stack.h	2012-06-13 12:04:40.260398619 +0000
@@ -0,0 +1,75 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner.  All rights reserved.
+ */
+
+#ifndef	_INET_DCCP_DCCP_STACK_H
+#define	_INET_DCCP_DCCP_STACK_H
+
+#include <sys/netstack.h>
+#include <sys/cpuvar.h>
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+typedef struct dccp_stat_counter_s {
+	uint64_t	dccp_rst_unsent;
+} dccp_stat_counter_t;
+
+typedef struct {
+	uint64_t		dccp_stats_cnt;
+	dccp_stat_counter_t	dccp_sc_stats;
+} dccp_stats_cpu_t;
+
+#define	DCCP_STAT(dccps, x)	\
+	((dccps)->dccps_sc[CPU->cpu_seqid]->dccp_sc_stats.x++)
+
+/*
+ * DCCP stack instances
+ */
+typedef struct dccp_stack {
+	netstack_t		*dccps_netstack;	/* Common netstack */
+
+	uint_t			dccps_bind_fanout_size;
+	struct dccp_df_s	*dccps_bind_fanout;
+
+	/* Ports */
+#define	DCCP_NUM_EPRIV_PORTS	64
+	int			dccps_num_epriv_ports;
+	in_port_t		dccps_epriv_ports[DCCP_NUM_EPRIV_PORTS];
+	kmutex_t		dccps_epriv_port_lock;
+
+	uint_t			dccps_next_port_to_try;
+
+	in_port_t		dccps_min_anonpriv_port;
+
+	/* Reset rate control */
+	int64_t			dccps_last_rst_intrvl;
+	uint32_t		dccps_rst_cnt;
+
+	/* Tunables table */
+	struct mod_prop_info_s	*dccps_propinfo_tbl;
+
+	ldi_ident_t		dccps_ldi_ident;
+
+	/* Cpu stats counter */
+	dccp_stats_cpu_t	**dccps_sc;
+	int			dccps_sc_cnt;
+} dccp_stack_t;
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _INET_DCCP_DCCP_STACK_H */
--- /dev/null	2012-06-13 12:04:41.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp_stats.c	2012-06-13 12:04:40.933848015 +0000
@@ -0,0 +1,153 @@
+/*
+ * 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 2010 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner.  All rights reserved.
+ */
+
+/*
+ * Functions related to MIB-II and kstat.
+ */
+
+#include <sys/types.h>
+#include <sys/tihdr.h>
+#include <sys/policy.h>
+#include <sys/tsol/tnet.h>
+
+#include <inet/common.h>
+#include <inet/ip.h>
+#include <inet/kstatcom.h>
+#include <inet/snmpcom.h>
+
+#include <sys/cmn_err.h>
+
+#include "dccp_impl.h"
+
+static int dccp_snmp_state(dccp_t *);
+
+static int
+dccp_snmp_state(dccp_t *dccp)
+{
+	if (dccp == NULL) {
+		return (0);
+	}
+
+	switch(dccp->dccp_state) {
+	case DCCPS_CLOSED:
+		return (MIB2_DCCP_closed);
+	default:
+		return (0);
+	}
+}
+
+/*
+ * Get the MIB-II stats.
+ */
+mblk_t *
+dccp_snmp_get(queue_t *q, mblk_t *mpctl)
+{
+	conn_t		*connp = Q_TO_CONN(q);
+	connf_t		*connfp;
+	ip_stack_t	*ips;
+	dccp_stack_t	*dccps;
+	struct opthdr	*optp;
+	mblk_t		*mp2ctl;
+	mblk_t		*mpdata;
+	mblk_t		*mp_conn_ctl = NULL;
+	mblk_t		*mp_conn_tail;
+	mblk_t		*mp_attr_ctl = NULL;
+	mblk_t		*mp_attr_tail;
+	size_t		dccp_mib_size;
+	size_t		dce_size;
+	zoneid_t	zoneid;
+	int		i;
+	mib2_dccpConnEntry_t	dce;
+
+	mp2ctl = copymsg(mpctl);
+
+	if (mpctl == NULL ||
+	    (mpdata = mpctl->b_cont) == NULL ||
+	    (mp_conn_ctl = copymsg(mpctl)) == NULL ||
+	    (mp_attr_ctl = copymsg(mpctl)) == NULL) {
+		freemsg(mp_conn_ctl);
+		freemsg(mp_attr_ctl);
+		freemsg(mpctl);
+		freemsg(mp2ctl);
+		return (NULL);
+	}
+
+	ips = connp->conn_netstack->netstack_ip;
+	dccps = connp->conn_netstack->netstack_dccp;
+	dce_size = sizeof (mib2_dccpConnEntry_t);
+	zoneid = Q_TO_CONN(q)->conn_zoneid;
+
+	for (i = 0; i < CONN_G_HASH_SIZE; i++) {
+		ips = dccps->dccps_netstack->netstack_ip;
+
+		connfp = &ips->ips_ipcl_globalhash_fanout[i];
+		connp = NULL;
+
+		while ((connp = ipcl_get_next_conn(connfp, connp,
+		    IPCL_DCCPCONN)) != NULL) {
+			dccp_t	*dccp;
+
+			if (connp->conn_zoneid != zoneid) {
+				continue;
+			}
+
+			dccp = connp->conn_dccp;
+
+			dce.dccpConnState = dccp_snmp_state(dccp);
+
+			if (connp->conn_ipversion == IPV4_VERSION ||
+			    (dccp->dccp_state <= DCCPS_LISTEN)) {
+				dce.dccpConnRemAddress =
+				    connp->conn_faddr_v4;
+				dce.dccpConnLocalAddress =
+				    connp->conn_laddr_v4;
+			}
+
+			dce.dccpConnLocalPort = ntohs(connp->conn_lport);
+			dce.dccpConnRemPort = ntohs(connp->conn_fport);
+
+			dce.dccpConnCreationProcess = (connp->conn_cpid < 0) ?
+			    MIB2_UNKNOWN_PROCESS : connp->conn_cpid;
+			dce.dccpConnCreationTime = connp->conn_open_time;
+
+			(void) snmp_append_data2(mp_conn_ctl->b_cont,
+			    &mp_conn_tail, (char *)&dce, dce_size);
+		}
+	}
+
+	optp = (struct opthdr *)&mp_conn_ctl->b_rptr[
+	    sizeof (struct T_optmgmt_ack)];
+	optp->level = MIB2_DCCP;
+	optp->name = MIB2_DCCP_CONN;
+	optp->len = msgdsize(mp_conn_ctl->b_cont);
+	qreply(q, mp_conn_ctl);
+
+	return (mp2ctl);
+}
--- /dev/null	2012-06-13 12:04:41.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp_tpi.c	2012-06-13 12:04:41.602241957 +0000
@@ -0,0 +1,113 @@
+/*
+ * 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
+ */
+
+/*
+ * Functions related to TPI.
+ */
+
+#include <sys/types.h>
+#include <sys/stream.h>
+#include <sys/strsun.h>
+#include <sys/strsubr.h>
+#include <sys/stropts.h>
+#include <sys/strlog.h>
+#define _SUN_TPI_VERSION 2
+#include <sys/tihdr.h>
+#include <sys/suntpi.h>
+#include <sys/xti_inet.h>
+#include <sys/squeue_impl.h>
+#include <sys/squeue.h>
+#include <sys/tsol/tnet.h>
+
+#include <inet/common.h>
+#include <inet/ip.h>
+
+#include <sys/cmn_err.h>
+
+#include "dccp_impl.h"
+
+/*
+ * Helper function to generate TPI errors acks.
+ */
+void
+dccp_err_ack(dccp_t *dccp, mblk_t *mp, int t_error, int sys_error)
+{
+	if ((mp = mi_tpi_err_ack_alloc(mp, t_error, sys_error)) != NULL) {
+		putnext(dccp->dccp_connp->conn_rq, mp);
+	}
+}
+
+void
+dccp_tpi_connect(dccp_t *dccp, mblk_t *mp)
+{
+	struct T_conn_req	*tcr;
+	conn_t	*connp = dccp->dccp_connp;
+	sin_t	*sin;
+	sin6_t	*sin6;
+	cred_t	*cr;
+	pid_t	cpid;
+	int	error;
+
+	cmn_err(CE_NOTE, "dccp_tpi.c: dccp_tpi_connect");
+
+	cr = msg_getcred(mp, &cpid);
+	ASSERT(cr != NULL);
+	if (cr == NULL) {
+		dccp_err_ack(dccp, mp, TSYSERR, EINVAL);
+		return;
+	}
+
+	tcr = (struct T_conn_req *)mp->b_rptr;
+
+	ASSERT((uintptr_t)(mp->b_wptr - mp->b_rptr) <= (uintptr_t)INT_MAX);
+	if ((mp->b_wptr - mp->b_rptr) < sizeof (*tcr)) {
+		dccp_err_ack(dccp, mp, TPROTO, 0);
+		return;
+	}
+
+}
+
+int
+dccp_tpi_close(queue_t *q, int flags)
+{
+	return (0);
+}
+
+/*
+ * Options related functions.
+ */
+int
+dccp_tpi_opt_get(queue_t *q, int level, int name, uchar_t *ptr)
+{
+	return (tcp_opt_get(Q_TO_CONN(q), level, name, ptr));
+}
+
+/* ARGSUSED */
+int
+dccp_tpi_opt_set(queue_t *q, uint_t optset_context, int level, int name,
+    uint_t inlen, uchar_t *invalp, uint_t *outlenp, uchar_t *outvalp,
+    void *thisdg_attrs, cred_t *cr)
+{
+	conn_t	*connp =  Q_TO_CONN(q);
+
+	return (tcp_opt_set(connp, optset_context, level, name, inlen, invalp,
+	    outlenp, outvalp, thisdg_attrs, cr));
+}
--- /dev/null	2012-06-13 12:04:42.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccp_tunables.c	2012-06-13 12:04:42.302565926 +0000
@@ -0,0 +1,60 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner.  All rights reserved.
+ */
+
+/*
+ * This file contains tunable properties for DCCP.
+ */
+#include <inet/ip.h>
+#include <inet/ip6.h>
+#include <inet/dccp/dccp_impl.h>
+#include <sys/sunddi.h>
+
+mod_prop_info_t dccp_propinfo_tbl[] = {
+	/* tunable - 0 */
+	{ "smallest_nonpriv_port", MOD_PROTO_DCCP,
+	    mod_set_uint32, mod_get_uint32,
+	    {1024, (32 * 1024), 1024}, {1024} },
+
+	{ "smallest_anon_port", MOD_PROTO_DCCP,
+	    mod_set_uint32, mod_get_uint32,
+	    {1024, ULP_MAX_PORT, 32*1024}, {32*1024} },
+
+	{ "largest_anon_port", MOD_PROTO_DCCP,
+	    mod_set_uint32, mod_get_uint32,
+	    {1024, ULP_MAX_PORT, ULP_MAX_PORT}, {ULP_MAX_PORT} },
+
+	{ "_xmit_lowat", MOD_PROTO_DCCP,
+	    mod_set_uint32, mod_get_uint32,
+	    {0, (1<<30), DCCP_XMIT_LOWATER},
+	    {DCCP_XMIT_LOWATER} },
+
+	{ "_debug", MOD_PROTO_DCCP,
+	    mod_set_uint32, mod_get_uint32,
+	    {0, 10, 0}, {0} },
+
+	{ "_rst_sent_rate_enabled", MOD_PROTO_DCCP,
+	    mod_set_boolean, mod_get_boolean,
+	    {B_TRUE}, {B_TRUE} },
+
+	{ "_rst_sent_rate", MOD_PROTO_DCCP,
+	    mod_set_uint32, mod_get_uint32,
+	    {0, UINT32_MAX, 40}, {40} },
+
+	/* tunable - 10 */
+
+	{ NULL, 0, NULL, NULL, {0}, {0} }
+};
+
+int dccp_propinfo_count = A_CNT(dccp_propinfo_tbl);
--- /dev/null	2012-06-13 12:04:43.000000000 +0000
+++ new/usr/src/uts/common/inet/dccp/dccpddi.c	2012-06-13 12:04:42.953684027 +0000
@@ -0,0 +1,59 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner.  All rights reserved.
+ */
+
+#include <sys/types.h>
+#include <sys/conf.h>
+#include <sys/modctl.h>
+#include <inet/common.h>
+#include <inet/ip.h>
+#include <sys/strsubr.h>
+#include <sys/socketvar.h>
+
+#include "dccp_impl.h"
+
+#define	INET_NAME	"dccp"
+#define	INET_MODDESC	"DCCP dummy STREAMS module"
+#define	INET_DEVDESC	"DCCP STREAMS driver"
+#define	INET_SOCKDESC	"DCCP socket module"
+#define	INET_MODSTRTAB	dummymodinfo
+#define	INET_DEVSTRTAB	dccpinfov4
+#define	INET_MODMTFLAGS	D_MP
+#define	INET_SOCK_PROTO_CREATE_FUNC	(*dccp_create)
+#define	INET_SOCK_PROTO_FB_FUNC		(*dccp_fallback)
+#define	INET_SOCK_FALLBACK_DEV_V4	"/dev/dccp"
+#define	INET_SOCK_FALLBACK_DEV_V6	"/dev/dccp6"
+#define	INET_DEVMINOR	0
+#define INET_MODMTFLAGS	D_MP
+#define	INET_DEVMTFLAGS (D_MP|_D_DIRECT)
+
+#include "../inetddi.c"
+
+int
+_init(void)
+{
+	return (mod_install(&modlinkage));
+}
+
+int
+_fini(void)
+{
+	return (mod_remove(&modlinkage));
+}
+
+int
+_info(struct modinfo *modinfop)
+{
+	return (mod_info(&modlinkage, modinfop));
+}
--- old/usr/src/uts/common/inet/ip.h	2012-06-13 12:04:43.712593501 +0000
+++ new/usr/src/uts/common/inet/ip.h	2012-06-13 12:04:43.838742741 +0000
@@ -84,6 +84,10 @@
 
 #define	SCTP_MOD_NAME	"sctp"
 
+#define	DCCP_MOD_NAME	"dccp"
+#define	DCCP_DEV_NAME	"/dev/dccp"
+#define	DCCP6_DEV_NAME	"/dev/dccp6"
+
 #ifndef	_IPADDR_T
 #define	_IPADDR_T
 typedef uint32_t ipaddr_t;
@@ -217,6 +221,7 @@
 #define	Q_TO_UDP(q)	(Q_TO_CONN((q))->conn_udp)
 #define	Q_TO_ICMP(q)	(Q_TO_CONN((q))->conn_icmp)
 #define	Q_TO_RTS(q)	(Q_TO_CONN((q))->conn_rts)
+#define	Q_TO_DCCP(q)	(Q_TO_CONN((q))->conn_dccp)
 
 #define	CONNP_TO_WQ(connp)	((connp)->conn_wq)
 #define	CONNP_TO_RQ(connp)	((connp)->conn_rq)
@@ -3748,6 +3753,8 @@
 #define	SQTAG_TCP_SHUTDOWN_OUTPUT	43
 #define	SQTAG_TCP_IXA_CLEANUP		44
 #define	SQTAG_TCP_SEND_SYNACK		45
+#define	SQTAG_IP_DCCP_INPUT		46
+#define	SQTAG_DCCP_CONN_REQ_UNBOUND	47
 
 extern sin_t	sin_null;	/* Zero address for quick clears */
 extern sin6_t	sin6_null;	/* Zero address for quick clears */
--- old/usr/src/uts/common/inet/ip/ip.c	2012-06-13 12:04:45.867566072 +0000
+++ new/usr/src/uts/common/inet/ip/ip.c	2012-06-13 12:04:45.992782513 +0000
@@ -111,6 +111,8 @@
 #include <ipp/ipgpc/ipgpc.h>
 
 #include <sys/pattr.h>
+#include <inet/dccp/dccp_ip.h>
+#include <inet/dccp/dccp_impl.h>
 #include <inet/ipclassifier.h>
 #include <inet/sctp_ip.h>
 #include <inet/sctp/sctp_impl.h>
@@ -4311,6 +4313,7 @@
 	icmp_ddi_g_destroy();
 	rts_ddi_g_destroy();
 	udp_ddi_g_destroy();
+	dccp_ddi_g_destroy();
 	sctp_ddi_g_destroy();
 	tcp_ddi_g_destroy();
 	ilb_ddi_g_destroy();
@@ -4547,6 +4550,7 @@
 	ipsec_policy_g_init();
 	tcp_ddi_g_init();
 	sctp_ddi_g_init();
+	dccp_ddi_g_init();
 	dce_g_init();
 
 	/*
--- old/usr/src/uts/common/inet/ip/ip_if.c	2012-06-13 12:04:51.702233928 +0000
+++ new/usr/src/uts/common/inet/ip/ip_if.c	2012-06-13 12:04:52.678287601 +0000
@@ -104,6 +104,7 @@
 
 #include <inet/rawip_impl.h> /* needed for icmp_stack_t */
 #include <inet/udp_impl.h> /* needed for udp_stack_t */
+#include <inet/dccp/dccp_stack.h> /* needed for dccp_stack_t */
 
 /* The character which tells where the ill_name ends */
 #define	IPIF_SEPARATOR_CHAR	':'
@@ -8857,6 +8858,7 @@
 	icmp_stack_t	*is;
 	tcp_stack_t	*tcps;
 	sctp_stack_t	*sctps;
+	dccp_stack_t	*dccps;
 	udp_stack_t	*us;
 	netstack_t	*stack;
 	void		*cbarg;
@@ -8902,6 +8904,10 @@
 		ptbl = sctps->sctps_propinfo_tbl;
 		cbarg = sctps;
 		break;
+	case MOD_PROTO_DCCP:
+		dccps = stack->netstack_dccp;
+		ptbl = dccps->dccps_propinfo_tbl;
+		cbarg = dccps;
 	default:
 		miocnak(q, mp, 0, EINVAL);
 		return;
--- old/usr/src/uts/common/inet/ip/ip_input.c	2012-06-13 12:04:55.547239675 +0000
+++ new/usr/src/uts/common/inet/ip/ip_input.c	2012-06-13 12:04:55.629651329 +0000
@@ -116,6 +116,7 @@
 #include <inet/sctp_ip.h>
 #include <inet/sctp/sctp_impl.h>
 #include <inet/udp_impl.h>
+#include <inet/dccp/dccp_impl.h>
 #include <sys/sunddi.h>
 
 #include <sys/tsol/label.h>
@@ -2389,6 +2390,9 @@
 	case IPPROTO_ICMP:
 		min_ulp_header_length = ICMPH_SIZE;
 		break;
+	case IPPROTO_DCCP:
+		min_ulp_header_length = DCCP_MIN_HEADER_LENGTH;
+		break;
 	default:
 		min_ulp_header_length = 0;
 		break;
@@ -2714,6 +2718,58 @@
 		ira->ira_ill = ill;
 		ira->ira_rill = rill;
 		return;
+	case IPPROTO_DCCP:
+		/* For DCCP, discard broadcast and multicast packets */
+		if (iraflags & IRAF_MULTIBROADCAST) {
+			goto discard;
+		}
+
+		/* Checked above */
+		ASSERT(len >= ip_hdr_length + DCCP_MIN_HEADER_LENGTH);
+
+		/* Squeue hint */
+		if (ira->ira_sqp == NULL) {
+			ira->ira_sqp = ip_squeue_get(ira->ira_ring);
+		}
+
+		connp = ipcl_classify_v4(mp, IPPROTO_DCCP, ip_hdr_length,
+		    ira, ipst);
+		if (connp == NULL) {
+			cmn_err(CE_NOTE, "ip_input.c: ip_fanout_v4 connp not found");
+			BUMP_MIB(ill->ill_ip_mib, ipIfStatsHCInDelivers);
+			dccp_xmit_listeners_reset(mp, ira, ipst, NULL);
+			return;
+		}
+
+		if (connp->conn_incoming_ifindex != 0 &&
+		    connp->conn_incoming_ifindex != ira->ira_ruifindex) {
+			cmn_err(CE_NOTE, "ip_input.c: ip_fanout_v4 ifindex problem");
+			BUMP_MIB(ill->ill_ip_mib, ipIfStatsHCInDelivers);
+			dccp_xmit_listeners_reset(mp, ira, ipst, NULL);
+			return;
+		}
+
+		if (CONN_INBOUND_POLICY_PRESENT(connp, ipss) ||
+		    (iraflags & IRAF_IPSEC_SECURE)) {
+			mp = ipsec_check_inbound_policy(mp, connp,
+			    ipha, NULL, ira);
+			if (mp == NULL) {
+				BUMP_MIB(ill->ill_ip_mib, ipIfStatsInDiscards);
+				ip_drop_input("ipIfStatsInDiscards", mp, ill);
+				CONN_DEC_REF(connp);
+				return;
+			}
+		}
+
+		BUMP_MIB(ill->ill_ip_mib, ipIfStatsHCInDelivers);
+		ira->ira_ill = ira->ira_rill = NULL;
+
+		SQUEUE_ENTER_ONE(connp->conn_sqp, mp, connp->conn_recv,
+		    connp, ira, ip_squeue_flag, SQTAG_IP_DCCP_INPUT);
+
+		ira->ira_ill = ill;
+		ira->ira_rill = rill;
+		return;
 	default:
 		break;
 	}
--- old/usr/src/uts/common/inet/ip/ip_output.c	2012-06-13 12:05:01.252080154 +0000
+++ new/usr/src/uts/common/inet/ip/ip_output.c	2012-06-13 12:05:01.305493077 +0000
@@ -1648,6 +1648,9 @@
 #endif
 			sctph->sh_chksum = sctp_cksum(mp, ip_hdr_length);
 		goto ip_hdr_cksum;
+	} else if (protocol == IPPROTO_DCCP) {
+		cksump = IPH_DCCPH_CHECKSUMP(ipha, ip_hdr_length);
+		cksum = IP_DCCP_CSUM_COMP;
 	} else {
 		goto ip_hdr_cksum;
 	}
@@ -1737,6 +1740,9 @@
 #endif
 			sctph->sh_chksum = sctp_cksum(mp, ip_hdr_length);
 		goto ip_hdr_cksum;
+	} else if (protocol == IPPROTO_DCCP) {
+		cksump = IPH_DCCPH_CHECKSUMP(ipha, ip_hdr_length);
+		cksum = IP_DCCP_CSUM_COMP;
 	} else {
 	ip_hdr_cksum:
 		/* Calculate IPv4 header checksum */
--- old/usr/src/uts/common/inet/ip/ipclassifier.c	2012-06-13 12:05:02.874321107 +0000
+++ new/usr/src/uts/common/inet/ip/ipclassifier.c	2012-06-13 12:05:02.920149883 +0000
@@ -223,6 +223,7 @@
  *		IPCL_UDPCONN	indicates a UDP conn_t.
  *		IPCL_RAWIPCONN	indicates a RAWIP/ICMP conn_t.
  *		IPCL_RTSCONN	indicates a RTS conn_t.
+ *		IPCL_DCCPCONN	indicates a DCCP conn_t.
  *		IPCL_IPCCONN	indicates all other connections.
  *
  * void ipcl_conn_destroy(connp)
@@ -257,6 +258,7 @@
 #include <inet/ip_ndp.h>
 #include <inet/ip_impl.h>
 #include <inet/udp_impl.h>
+#include <inet/dccp/dccp_impl.h>
 #include <inet/sctp_ip.h>
 #include <inet/sctp/sctp_impl.h>
 #include <inet/rawip_impl.h>
@@ -280,8 +282,9 @@
 uint_t ipcl_conn_hash_memfactor = 8192;
 uint_t ipcl_conn_hash_maxsize = 82500;
 
-/* bind/udp fanout table size */
+/* bind/dccp/udp fanout table size */
 uint_t ipcl_bind_fanout_size = 512;
+uint_t ipcl_dccp_fanout_size = 512;
 uint_t ipcl_udp_fanout_size = 16384;
 
 /* Raw socket fanout size.  Must be a power of 2. */
@@ -319,6 +322,7 @@
 struct kmem_cache  *udp_conn_cache;
 struct kmem_cache  *rawip_conn_cache;
 struct kmem_cache  *rts_conn_cache;
+struct kmem_cache  *dccp_conn_cache;
 
 extern void	tcp_timermp_free(tcp_t *);
 extern mblk_t	*tcp_timermp_alloc(int);
@@ -338,6 +342,9 @@
 static int	rts_conn_constructor(void *, void *, int);
 static void	rts_conn_destructor(void *, void *);
 
+static int	dccp_conn_constructor(void *, void *, int);
+static void	dccp_conn_destructor(void *, void *);
+
 /*
  * Global (for all stack instances) init routine
  */
@@ -368,6 +375,12 @@
 	    sizeof (itc_t) + sizeof (rts_t), CACHE_ALIGN_SIZE,
 	    rts_conn_constructor, rts_conn_destructor,
 	    NULL, NULL, NULL, 0);
+
+	/* XXX:DCCP reclaim */
+	dccp_conn_cache = kmem_cache_create("dccp_conn_cache",
+	    sizeof (itc_t) + sizeof (dccp_t), CACHE_ALIGN_SIZE,
+	    dccp_conn_constructor, dccp_conn_destructor,
+	    NULL, NULL, NULL, 0);
 }
 
 /*
@@ -410,6 +423,7 @@
 
 	/* Take values from /etc/system */
 	ipst->ips_ipcl_bind_fanout_size = ipcl_bind_fanout_size;
+	ipst->ips_ipcl_dccp_fanout_size = ipcl_dccp_fanout_size;
 	ipst->ips_ipcl_udp_fanout_size = ipcl_udp_fanout_size;
 	ipst->ips_ipcl_raw_fanout_size = ipcl_raw_fanout_size;
 	ipst->ips_ipcl_iptun_fanout_size = ipcl_iptun_fanout_size;
@@ -477,6 +491,13 @@
 		mutex_init(&ipst->ips_ipcl_globalhash_fanout[i].connf_lock,
 		    NULL, MUTEX_DEFAULT, NULL);
 	}
+
+	ipst->ips_ipcl_dccp_fanout = kmem_zalloc(
+	    ipst->ips_ipcl_dccp_fanout_size * sizeof (connf_t), KM_SLEEP);
+	for (i = 0; i < ipst->ips_ipcl_dccp_fanout_size; i++) {
+		mutex_init(&ipst->ips_ipcl_dccp_fanout[i].connf_lock, NULL,
+		    MUTEX_DEFAULT, NULL);
+	}
 }
 
 void
@@ -487,6 +508,7 @@
 	kmem_cache_destroy(udp_conn_cache);
 	kmem_cache_destroy(rawip_conn_cache);
 	kmem_cache_destroy(rts_conn_cache);
+	kmem_cache_destroy(dccp_conn_cache);
 }
 
 /*
@@ -562,6 +584,14 @@
 	    sizeof (connf_t) * CONN_G_HASH_SIZE);
 	ipst->ips_ipcl_globalhash_fanout = NULL;
 
+	for (i = 0; i < ipst->ips_ipcl_dccp_fanout_size; i++) {
+		ASSERT(ipst->ips_ipcl_dccp_fanout[i].connf_head == NULL);
+		mutex_destroy(&ipst->ips_ipcl_dccp_fanout[i].connf_lock);
+	}
+	kmem_free(ipst->ips_ipcl_dccp_fanout, ipst->ips_ipcl_dccp_fanout_size *
+	    sizeof (connf_t));
+	ipst->ips_ipcl_dccp_fanout = NULL;
+
 	ASSERT(ipst->ips_rts_clients->connf_head == NULL);
 	mutex_destroy(&ipst->ips_rts_clients->connf_lock);
 	kmem_free(ipst->ips_rts_clients, sizeof (connf_t));
@@ -610,6 +640,10 @@
 		conn_cache = ip_conn_cache;
 		break;
 
+	case IPCL_DCCPCONN:
+		conn_cache = dccp_conn_cache;
+		break;
+
 	default:
 		connp = NULL;
 		ASSERT(0);
@@ -720,6 +754,23 @@
 		return;
 	}
 
+	if (connp->conn_flags & IPCL_DCCPCONN) {
+		dccp_t	*dccp = connp->conn_dccp;
+
+		cmn_err(CE_NOTE, "ipclassifier: conn_flags DCCP cache_free");
+
+		/* XXX:DCCP */
+		/* Crash bug here: udp_conn_cache and dccp_conn_cache */
+/*
+		ipcl_conn_cleanup(connp);
+		connp->conn_flags = IPCL_DCCPCONN;
+		bzero(dccp, sizeof (dccp_t));
+		dccp->dccp_connp = connp;
+		kmem_cache_free(dccp_conn_cache, connp);
+		return;
+*/
+	}
+
 	ipcl_conn_cleanup(connp);
 	if (ns != NULL) {
 		connp->conn_netstack = NULL;
@@ -1236,8 +1287,22 @@
 	case IPPROTO_SCTP:
 		ret = ipcl_sctp_hash_insert(connp, lport);
 		break;
+
+	case IPPROTO_DCCP:
+		cmn_err(CE_NOTE, "ipcl_bind_insert_v4");
+		ASSERT(connp->conn_zoneid != ALL_ZONES);
+		connfp = &ipst->ips_ipcl_dccp_fanout[
+		    IPCL_DCCP_HASH(lport, ipst)];
+		if (connp->conn_laddr_v4 != INADDR_ANY) {
+			IPCL_HASH_INSERT_BOUND(connfp, connp);
+		} else {
+			IPCL_HASH_INSERT_WILDCARD(connfp, connp);
+		}
+		/* XXX:DCCP */
+		break;
 	}
 
+
 	return (ret);
 }
 
@@ -1309,6 +1374,10 @@
 	case IPPROTO_SCTP:
 		ret = ipcl_sctp_hash_insert(connp, lport);
 		break;
+
+	case IPPROTO_DCCP:
+		/* XXX:DCCP */
+		break;
 	}
 
 	return (ret);
@@ -1393,6 +1462,18 @@
 		ret = ipcl_sctp_hash_insert(connp, lport);
 		break;
 
+	case IPPROTO_DCCP:
+		cmn_err(CE_NOTE, "insert v4");
+
+		connfp = &ipst->ips_ipcl_conn_fanout[
+		    IPCL_CONN_HASH(connp->conn_faddr_v4,
+		    connp->conn_ports, ipst)];
+		mutex_enter(&connfp->connf_lock);
+		IPCL_HASH_INSERT_CONNECTED_LOCKED(connfp, connp);
+		mutex_exit(&connfp->connf_lock);
+		/* XXX:DCCP */
+		break;
+
 	default:
 		/*
 		 * Check for conflicts among MAC exempt bindings.  For
@@ -1488,6 +1569,10 @@
 		ret = ipcl_sctp_hash_insert(connp, lport);
 		break;
 
+	case IPPROTO_DCCP:
+		/* XXX:DCCP */
+		break;
+
 	default:
 		if (is_system_labeled() &&
 		    check_exempt_conflict_v6(connp, ipst))
@@ -1655,6 +1740,31 @@
 
 		break;
 
+	case IPPROTO_DCCP:
+		fport = up[0];
+		lport = up[1];
+		connfp = &ipst->ips_ipcl_dccp_fanout[IPCL_DCCP_HASH(
+		    lport, ipst)];
+		mutex_enter(&connfp->connf_lock);
+		for (connp = connfp->connf_head; connp != NULL;
+		    connp = connp->conn_next) {
+			cmn_err(CE_NOTE, "connfp found");
+			/* XXX:DCCP */
+			if (IPCL_UDP_MATCH(connp, lport, ipha->ipha_dst,
+			    fport, ipha->ipha_src)) {
+				break;
+			}
+		}
+
+		if (connp != NULL) {
+			CONN_INC_REF(connp);
+			mutex_exit(&connfp->connf_lock);
+			return (connp);
+		}
+
+		mutex_exit(&connfp->connf_lock);
+		break;
+
 	case IPPROTO_ENCAP:
 	case IPPROTO_IPV6:
 		return (ipcl_iptun_classify_v4(&ipha->ipha_src,
@@ -2175,6 +2285,60 @@
 	}
 }
 
+/* ARGSUSED */
+static int
+dccp_conn_constructor(void *buf, void *cdrarg, int kmflags)
+{
+	itc_t	*itc = (itc_t *)buf;
+	conn_t	*connp = &itc->itc_conn;
+	dccp_t	*dccp = (dccp_t *)&itc[1];
+
+	bzero(connp, sizeof (conn_t));
+	bzero(dccp, sizeof (dccp_t));
+
+	mutex_init(&connp->conn_lock, NULL, MUTEX_DEFAULT, NULL);
+	cv_init(&connp->conn_cv, NULL, CV_DEFAULT, NULL);
+	rw_init(&connp->conn_ilg_lock, NULL, RW_DEFAULT, NULL);
+
+	connp->conn_dccp = dccp;
+	connp->conn_flags = IPCL_DCCPCONN;
+	connp->conn_proto = IPPROTO_DCCP;
+	dccp->dccp_connp = connp;
+	connp->conn_ixa = kmem_zalloc(sizeof (ip_xmit_attr_t), kmflags);
+	if (connp->conn_ixa == NULL)
+		return (NULL);
+	connp->conn_ixa->ixa_refcnt = 1;
+	connp->conn_ixa->ixa_protocol = connp->conn_proto;
+	connp->conn_ixa->ixa_xmit_hint = CONN_TO_XMIT_HINT(connp);
+
+	return (0);
+}
+
+/* ARGSUSED */
+static void
+dccp_conn_destructor(void *buf, void *cdrarg)
+{
+	itc_t	*itc = (itc_t *)buf;
+	conn_t	*connp = &itc->itc_conn;
+	dccp_t	*dccp = (dccp_t *)&itc[1];
+
+	ASSERT(connp->conn_flags & IPCL_DCCPCONN);
+	ASSERT(dccp->dccp_connp == connp);
+	ASSERT(connp->conn_dccp == dccp);
+
+	mutex_destroy(&connp->conn_lock);
+	cv_destroy(&connp->conn_cv);
+	rw_destroy(&connp->conn_ilg_lock);
+
+	if (connp->conn_ixa != NULL) {
+		ASSERT(connp->conn_ixa->ixa_refcnt == 1);
+		ASSERT(connp->conn_ixa->ixa_ire == NULL);
+		ASSERT(connp->conn_ixa->ixa_nce == NULL);
+
+		ixa_refrele(connp->conn_ixa);
+	}
+}
+
 /*
  * Called as part of ipcl_conn_destroy to assert and clear any pointers
  * in the conn_t.
--- old/usr/src/uts/common/inet/ip_impl.h	2012-06-13 12:05:04.481581533 +0000
+++ new/usr/src/uts/common/inet/ip_impl.h	2012-06-13 12:05:04.551968145 +0000
@@ -52,11 +52,13 @@
 #define	IP_TCP_CSUM_COMP	IPPROTO_TCP
 #define	IP_UDP_CSUM_COMP	IPPROTO_UDP
 #define	IP_ICMPV6_CSUM_COMP	IPPROTO_ICMPV6
+#define	IP_DCCP_CSUM_COMP	IPPROTO_DCCP
 #else
 #define	IP_HDR_CSUM_TTL_ADJUST	1
 #define	IP_TCP_CSUM_COMP	(IPPROTO_TCP << 8)
 #define	IP_UDP_CSUM_COMP	(IPPROTO_UDP << 8)
 #define	IP_ICMPV6_CSUM_COMP	(IPPROTO_ICMPV6 << 8)
+#define	IP_DCCP_CSUM_COMP	(IPPROTO_DCCP << 8)
 #endif
 
 #define	TCP_CHECKSUM_OFFSET	16
@@ -68,6 +70,9 @@
 #define	ICMPV6_CHECKSUM_OFFSET	2
 #define	ICMPV6_CHECKSUM_SIZE	2
 
+#define	DCCP_CHECKSUM_OFFSET	6
+#define	DCCP_CHECKSUM_SIZE	2
+
 #define	IPH_TCPH_CHECKSUMP(ipha, hlen)	\
 	((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + TCP_CHECKSUM_OFFSET)))
 
@@ -77,6 +82,9 @@
 #define	IPH_ICMPV6_CHECKSUMP(ipha, hlen)	\
 	((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + ICMPV6_CHECKSUM_OFFSET)))
 
+#define	IPH_DCCPH_CHECKSUMP(ipha, hlen)	\
+	((uint16_t *)(((uchar_t *)(ipha)) + ((hlen) + DCCP_CHECKSUM_OFFSET)))
+
 #define	ILL_HCKSUM_CAPABLE(ill)		\
 	(((ill)->ill_capabilities & ILL_CAPAB_HCKSUM) != 0)
 
--- old/usr/src/uts/common/inet/ip_stack.h	2012-06-13 12:05:06.176494076 +0000
+++ new/usr/src/uts/common/inet/ip_stack.h	2012-06-13 12:05:06.237644825 +0000
@@ -195,11 +195,13 @@
 	struct connf_s	*ips_ipcl_udp_fanout;
 	struct connf_s	*ips_ipcl_raw_fanout;		/* RAW SCTP sockets */
 	struct connf_s	*ips_ipcl_iptun_fanout;
+	struct connf_s	*ips_ipcl_dccp_fanout;
 	uint_t		ips_ipcl_conn_fanout_size;
 	uint_t		ips_ipcl_bind_fanout_size;
 	uint_t		ips_ipcl_udp_fanout_size;
 	uint_t		ips_ipcl_raw_fanout_size;
 	uint_t		ips_ipcl_iptun_fanout_size;
+	uint_t		ips_ipcl_dccp_fanout_size;
 	struct connf_s	*ips_ipcl_globalhash_fanout;
 	int		ips_conn_g_index;
 
--- old/usr/src/uts/common/inet/ipclassifier.h	2012-06-13 12:05:10.570356677 +0000
+++ new/usr/src/uts/common/inet/ipclassifier.h	2012-06-13 12:05:10.627755964 +0000
@@ -86,6 +86,7 @@
 #define	IPCL_RTSCONN		0x00000020	/* From rts_conn_cache */
 /* Unused			0x00000040 */
 #define	IPCL_IPTUN		0x00000080	/* iptun module above us */
+#define	IPCL_DCCPCONN		0x00000100	/* From dccp_conn_cache */
 
 #define	IPCL_NONSTR		0x00001000	/* A non-STREAMS socket */
 /* Unused			0x10000000 */
@@ -121,6 +122,9 @@
 #define	IPCL_IS_IPTUN(connp)						\
 	((connp)->conn_flags & IPCL_IPTUN)
 
+#define	IPCL_IS_DCCP(connp)						\
+	((connp)->conn_flags & IPCL_DCCPCONN)
+
 #define	IPCL_IS_NONSTR(connp)	((connp)->conn_flags & IPCL_NONSTR)
 
 typedef struct connf_s connf_t;
@@ -237,6 +241,7 @@
 		struct rts_s	*cp_rts;	/* Pointer to rts struct */
 		struct iptun_s	*cp_iptun;	/* Pointer to iptun_t */
 		struct sctp_s	*cp_sctp;	/* For IPCL_SCTPCONN */
+		struct dccp_s	*cp_dccp;	/* Pointer to dccp struct */
 		void		*cp_priv;
 	} conn_proto_priv;
 #define	conn_tcp	conn_proto_priv.cp_tcp
@@ -245,6 +250,7 @@
 #define	conn_rts	conn_proto_priv.cp_rts
 #define	conn_iptun	conn_proto_priv.cp_iptun
 #define	conn_sctp	conn_proto_priv.cp_sctp
+#define	conn_dccp	conn_proto_priv.cp_dccp
 #define	conn_priv	conn_proto_priv.cp_priv
 
 	kcondvar_t	conn_cv;
@@ -651,6 +657,9 @@
 #define	IPCL_UDP_HASH(lport, ipst)	\
 	IPCL_PORT_HASH(lport, (ipst)->ips_ipcl_udp_fanout_size)
 
+#define	IPCL_DCCP_HASH(lport, ipst)	\
+	IPCL_PORT_HASH(lport, (ipst)->ips_ipcl_dccp_fanout_size)
+
 #define	CONN_G_HASH_SIZE	1024
 
 /* Raw socket hash function. */
--- old/usr/src/uts/common/inet/mib2.h	2012-06-13 12:05:11.954182928 +0000
+++ new/usr/src/uts/common/inet/mib2.h	2012-06-13 12:05:11.997695543 +0000
@@ -96,12 +96,13 @@
 #define	MIB2_TCP6		(IPPROTO_MAX+14)
 #define	MIB2_UDP6		(IPPROTO_MAX+15)
 #define	MIB2_SCTP		(IPPROTO_MAX+16)
+#define	MIB2_DCCP		(IPPROTO_MAX+17)
 
 /*
  * Define range of levels for use with MIB2_*
  */
 #define	MIB2_RANGE_START	(IPPROTO_MAX+1)
-#define	MIB2_RANGE_END		(IPPROTO_MAX+16)
+#define	MIB2_RANGE_END		(IPPROTO_MAX+17)
 
 
 #define	EXPER			1024	/* experimental - not part of mib */
@@ -1786,6 +1787,50 @@
 #pragma pack()
 #endif
 
+/*
+ * the DCCP group
+ */
+#define	MIB2_DCCP_CONN		18
+
+#define	MIB2_DCCP_closed	1
+#define	MIB2_DCCP_listen	2
+
+/* Pack data to make struct size the same for 32- and 64-bits */
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack(4)
+#endif
+
+typedef struct mib2_dccp {
+
+	Counter	dccpActiveOpens;
+
+	int	dccpEntrySize;
+} mib2_dccp_t;
+
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack()
+#endif
+
+/* Pack data to make struct size the same for 32- and 64-bits */
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack(4)
+#endif
+
+typedef struct mib2_dccpConnEntry {
+	int		dccpConnState;
+	IpAddress	dccpConnLocalAddress;
+	int		dccpConnLocalPort;
+	IpAddress	dccpConnRemAddress;
+	int		dccpConnRemPort;
+
+	uint32_t	dccpConnCreationProcess;
+	uint64_t	dccpConnCreationTime;
+} mib2_dccpConnEntry_t;
+#define	MIB_FIRST_NEW_ELM_mib2_dccpConnEntry_t	dccpConnCreationProcess
+
+#if _LONG_LONG_ALIGNMENT == 8 && _LONG_LONG_ALIGNMENT_32 == 4
+#pragma pack()
+#endif
 
 #ifdef	__cplusplus
 }
--- old/usr/src/uts/common/inet/sctp/sctp_impl.h	2012-06-13 12:05:13.781228635 +0000
+++ new/usr/src/uts/common/inet/sctp/sctp_impl.h	2012-06-13 12:05:13.858918781 +0000
@@ -445,6 +445,9 @@
 typedef struct sctp_tf_s {
 	struct sctp_s	*tf_sctp;
 	kmutex_t	tf_lock;
+#define	SF_CACHEL_PAD	64
+	uchar_t		tf_pad[SF_CACHEL_PAD - (sizeof (struct sctp_s *) +
+			    sizeof (kmutex_t))];
 } sctp_tf_t;
 
 /* Round up the value to the nearest mss. */
--- old/usr/src/uts/common/inet/tcp/tcp.c	2012-06-13 12:05:15.389154443 +0000
+++ new/usr/src/uts/common/inet/tcp/tcp.c	2012-06-13 12:05:15.464627899 +0000
@@ -2699,7 +2699,6 @@
 	connp->conn_zoneid = zoneid;
 	/* conn_allzones can not be set this early, hence no IPCL_ZONEID */
 	connp->conn_ixa->ixa_zoneid = zoneid;
-	connp->conn_mlp_type = mlptSingle;
 	ASSERT(connp->conn_netstack == tcps->tcps_netstack);
 	ASSERT(tcp->tcp_tcps == tcps);
 
--- old/usr/src/uts/common/inet/tcp/tcp_opt_data.c	2012-06-13 12:05:20.331172546 +0000
+++ new/usr/src/uts/common/inet/tcp/tcp_opt_data.c	2012-06-13 12:05:20.377331006 +0000
@@ -42,6 +42,8 @@
 #include <inet/proto_set.h>
 #include <inet/tcp_impl.h>
 
+static int      tcp_opt_default(queue_t *, t_scalar_t, t_scalar_t, uchar_t *);
+
 /*
  * Table of all known options handled on a TCP protocol stack.
  *
--- old/usr/src/uts/common/inet/tcp/tcp_socket.c	2012-06-13 12:05:24.201150090 +0000
+++ new/usr/src/uts/common/inet/tcp/tcp_socket.c	2012-06-13 12:05:24.367808149 +0000
@@ -54,12 +54,16 @@
 static int	tcp_listen(sock_lower_handle_t, int, cred_t *);
 static int	tcp_connect(sock_lower_handle_t, const struct sockaddr *,
 		    socklen_t, sock_connid_t *, cred_t *);
+static int	tcp_getpeername(sock_lower_handle_t, struct sockaddr *,
+		    socklen_t *, cred_t *);
+static int	tcp_getsockname(sock_lower_handle_t, struct sockaddr *,
+		    socklen_t *, cred_t *);
 static int	tcp_getsockopt(sock_lower_handle_t, int, int, void *,
 		    socklen_t *, cred_t *);
 static int	tcp_setsockopt(sock_lower_handle_t, int, int, const void *,
 		    socklen_t, cred_t *);
 static int	tcp_sendmsg(sock_lower_handle_t, mblk_t *, struct nmsghdr *,
-		    cred_t *cr);
+		    cred_t *);
 static int	tcp_shutdown(sock_lower_handle_t, int, cred_t *);
 static void	tcp_clr_flowctrl(sock_lower_handle_t);
 static int	tcp_ioctl(sock_lower_handle_t, int, intptr_t, int, int32_t *,
@@ -752,6 +756,7 @@
 {
 	conn_t		*connp;
 	boolean_t	isv6 = family == AF_INET6;
+
 	if (type != SOCK_STREAM || (family != AF_INET && family != AF_INET6) ||
 	    (proto != 0 && proto != IPPROTO_TCP)) {
 		*errorp = EPROTONOSUPPORT;
@@ -765,8 +770,8 @@
 
 	/*
 	 * Put the ref for TCP. Ref for IP was already put
-	 * by ipcl_conn_create. Also Make the conn_t globally
-	 * visible to walkers
+	 * by ipcl_conn_create. Also make the conn_t globally
+	 * visible to walkers.
 	 */
 	mutex_enter(&connp->conn_lock);
 	CONN_INC_REF_LOCKED(connp);
--- old/usr/src/uts/common/inet/tcp_impl.h	2012-06-13 12:05:25.899974274 +0000
+++ new/usr/src/uts/common/inet/tcp_impl.h	2012-06-13 12:05:25.956051712 +0000
@@ -546,10 +546,6 @@
 extern void	tcp_eager_cleanup(tcp_t *, boolean_t);
 extern void	tcp_eager_kill(void *, mblk_t *, void *, ip_recv_attr_t *);
 extern void	tcp_eager_unlink(tcp_t *);
-extern int	tcp_getpeername(sock_lower_handle_t, struct sockaddr *,
-		    socklen_t *, cred_t *);
-extern int	tcp_getsockname(sock_lower_handle_t, struct sockaddr *,
-		    socklen_t *, cred_t *);
 extern void	tcp_init_values(tcp_t *, tcp_t *);
 extern void	tcp_ipsec_cleanup(tcp_t *);
 extern int	tcp_maxpsz_set(tcp_t *, boolean_t);
@@ -679,7 +675,6 @@
 /*
  * TCP option processing related functions in tcp_opt_data.c
  */
-extern int	tcp_opt_default(queue_t *, t_scalar_t, t_scalar_t, uchar_t *);
 extern int	tcp_opt_get(conn_t *, int, int, uchar_t *);
 extern int	tcp_opt_set(conn_t *, uint_t, int, int, uint_t, uchar_t *,
 		    uint_t *, uchar_t *, void *, cred_t *);
--- old/usr/src/uts/common/inet/tcp_stats.h	2012-06-13 12:05:30.453505748 +0000
+++ new/usr/src/uts/common/inet/tcp_stats.h	2012-06-13 12:05:30.522054049 +0000
@@ -48,7 +48,7 @@
  *
  * TCP_DBGSTAT(name) does atomic increment of a named stat counter. It is
  * supposed to be used for DEBUG purposes and may be used on a hot path.
- * These counters are only available in a debugged kerel.  They are grouped
+ * These counters are only available in a debugged kernel.  They are grouped
  * under the TCP_DEBUG_COUNTER C pre-processor condition.
  *
  * Both TCP_STAT and TCP_DBGSTAT counters are available using kstat
--- old/usr/src/uts/common/inet/tunables.c	2012-06-13 12:05:31.977060593 +0000
+++ new/usr/src/uts/common/inet/tunables.c	2012-06-13 12:05:32.030973882 +0000
@@ -34,6 +34,8 @@
 #include <inet/tcp_stack.h>
 #include <inet/tcp_impl.h>
 #include <inet/udp_impl.h>
+#include <inet/dccp/dccp_stack.h>
+#include <inet/dccp/dccp_impl.h>
 #include <inet/sctp/sctp_stack.h>
 #include <inet/sctp/sctp_impl.h>
 #include <inet/tunables.h>
@@ -205,6 +207,7 @@
 	ip_stack_t	*ipst;
 	tcp_stack_t	*tcps;
 	sctp_stack_t	*sctps;
+	dccp_stack_t	*dccps;
 	udp_stack_t	*us;
 	icmp_stack_t	*is;
 	uint_t		size;
@@ -236,6 +239,10 @@
 		sctps = (sctp_stack_t *)cbarg;
 		ptbl = sctps->sctps_propinfo_tbl;
 		break;
+	case MOD_PROTO_DCCP:
+		dccps = (dccp_stack_t *)cbarg;
+		ptbl = dccps->dccps_propinfo_tbl;
+		break;
 	default:
 		return (EINVAL);
 	}
--- old/usr/src/uts/common/inet/tunables.h	2012-06-13 12:05:33.547902739 +0000
+++ new/usr/src/uts/common/inet/tunables.h	2012-06-13 12:05:33.585884377 +0000
@@ -79,6 +79,7 @@
 #define	MOD_PROTO_TCP		0x08	/* property is applicable to TCP */
 #define	MOD_PROTO_UDP		0x10	/* property is applicable to UDP */
 #define	MOD_PROTO_SCTP		0x20	/* property is applicable to SCTP */
+#define	MOD_PROTO_DCCP		0x40	/* property is applicable to DCCP */
 
 /* property is applicable to both IPV[4|6] */
 #define	MOD_PROTO_IP		(MOD_PROTO_IPV4|MOD_PROTO_IPV6)
--- /dev/null	2012-06-13 12:05:35.000000000 +0000
+++ new/usr/src/uts/common/netinet/dccp.h	2012-06-13 12:05:35.293318468 +0000
@@ -0,0 +1,38 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012 David Hoeppner.  All rights reserved.
+ */
+
+#ifndef	_NETINET_DCCP_H
+#define	_NETINET_DCCP_H
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ * DCCP states
+ */
+#define	DCCPS_CLOSED	-5
+#define	DCCPS_BOUND	-4
+#define DCCPS_LISTEN	-3
+#define	DCCPS_REQUEST	-2
+#define	DCCPS_RESPOND	-1
+#define DCCPS_PARTOPEN	0
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _NETINET_DCCP_H */
--- old/usr/src/uts/common/netinet/in.h	2012-06-13 12:05:36.059167290 +0000
+++ new/usr/src/uts/common/netinet/in.h	2012-06-13 12:05:36.125202370 +0000
@@ -159,6 +159,7 @@
 #define	IPPROTO_PUP		12		/* pup */
 #define	IPPROTO_UDP		17		/* user datagram protocol */
 #define	IPPROTO_IDP		22		/* xns idp */
+#define	IPPROTO_DCCP		33		/* DCCP */
 #define	IPPROTO_IPV6		41		/* IPv6 encapsulated in IP */
 #define	IPPROTO_ROUTING		43		/* Routing header for IPv6 */
 #define	IPPROTO_FRAGMENT	44		/* Fragment header for IPv6 */
--- old/usr/src/uts/common/sys/netstack.h	2012-06-13 12:05:41.026491211 +0000
+++ new/usr/src/uts/common/sys/netstack.h	2012-06-13 12:05:41.094931490 +0000
@@ -81,7 +81,8 @@
 #define	NS_IPSECESP	16
 #define	NS_IPNET	17
 #define	NS_ILB		18
-#define	NS_MAX		(NS_ILB+1)
+#define	NS_DCCP		19
+#define	NS_MAX		(NS_DCCP+1)
 
 /*
  * State maintained for each module which tracks the state of
@@ -157,6 +158,7 @@
 			struct ipsecesp_stack	*nu_ipsecesp;
 			struct ipnet_stack	*nu_ipnet;
 			struct ilb_stack	*nu_ilb;
+			struct dccp_stack	*nu_dccp;
 		} nu_s;
 	} netstack_u;
 #define	netstack_modules	netstack_u.nu_modules
@@ -179,6 +181,7 @@
 #define	netstack_ipsecesp	netstack_u.nu_s.nu_ipsecesp
 #define	netstack_ipnet		netstack_u.nu_s.nu_ipnet
 #define	netstack_ilb		netstack_u.nu_s.nu_ilb
+#define	netstack_dccp		netstack_u.nu_s.nu_dccp
 
 	nm_state_t	netstack_m_state[NS_MAX]; /* module state */
 
--- old/usr/src/uts/intel/Makefile.intel.shared	2012-06-13 12:05:42.711908862 +0000
+++ new/usr/src/uts/intel/Makefile.intel.shared	2012-06-13 12:05:42.788753919 +0000
@@ -230,6 +230,7 @@
 DRV_KMODS	+= crypto
 DRV_KMODS	+= cryptoadm
 DRV_KMODS	+= dca
+DRV_KMODS	+= dccp
 DRV_KMODS	+= devinfo
 DRV_KMODS	+= dld
 DRV_KMODS	+= dlpistub
--- /dev/null	2012-06-13 12:05:44.000000000 +0000
+++ new/usr/src/uts/intel/dccp/Makefile	2012-06-13 12:05:44.209134242 +0000
@@ -0,0 +1,98 @@
+#
+# 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
+#
+#
+# uts/intel/dccp/Makefile
+#
+# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#	This makefile drives the production of the dccp driver kernel module.
+#
+#	intel implementation architecture dependent
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE	= ../..
+
+#
+#	Define the module and object file sets.
+#
+MODULE		= dccp
+OBJECTS		= $(DCCP_OBJS:%=$(OBJS_DIR)/%)
+LINTS		= $(DCCP_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_DRV_DIR)/$(MODULE)
+ROOTLINK	= $(ROOT_STRMOD_DIR)/$(MODULE) $(ROOT_SOCK_DIR)/$(MODULE)
+CONF_SRCDIR	= $(UTSBASE)/common/inet/dccp
+
+#
+# Extra for $(MODULE).check target
+#
+# Need to remove ipddi.o since it has non-static defines for _init etc.
+IP_CHECK_OBJS	= $(IP_OBJS:ipddi.o=ip.o)
+EXTRA_CHECK_OBJS = $(IP_CHECK_OBJS:%=../ip/$(OBJS_DIR)/%)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/intel/Makefile.intel
+
+#
+#	Define targets
+#
+ALL_TARGET	= $(BINARY) $(SRC_CONFILE)
+LINT_TARGET	= $(MODULE).lint
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE) $(ROOTLINK) $(ROOT_CONFFILE)
+
+#
+#	depends on ip and sockfs
+#
+LDFLAGS		+= -dy -Ndrv/ip -Nfs/sockfs
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+$(ROOTLINK):	$(ROOT_STRMOD_DIR) $(ROOT_SOCK_DIR) $(ROOTMODULE)
+	-$(RM) $@; ln $(ROOTMODULE) $@
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/intel/Makefile.targ
--- /dev/null	2012-06-13 12:05:44.000000000 +0000
+++ new/usr/src/uts/intel/dccp6/Makefile	2012-06-13 12:05:44.905544203 +0000
@@ -0,0 +1,93 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (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 2004 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#	This makefile drives the production of the dccp6 driver kernel module.
+#
+#	intel implementation architecture dependent
+#
+
+#
+#	Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE	= ../..
+
+#
+#	Define the module and object file sets.
+#
+MODULE		= dccp6
+OBJECTS		= $(TCP6_OBJS:%=$(OBJS_DIR)/%)
+LINTS		= $(TCP6_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE	= $(ROOT_DRV_DIR)/$(MODULE)
+CONF_SRCDIR	= $(UTSBASE)/common/inet/dccp
+
+#
+# Extra for $(MODULE).check target
+#
+# Need to remove ipddi.o since it has non-static defines for _init etc.
+IP_CHECK_OBJS	= $(IP_OBJS:ipddi.o=ip.o)
+EXTRA_CHECK_OBJS = $(IP_CHECK_OBJS:%=../ip/$(OBJS_DIR)/%)
+
+#
+#	Include common rules.
+#
+include $(UTSBASE)/intel/Makefile.intel
+
+#
+#	Define targets
+#
+ALL_TARGET	= $(BINARY) $(SRC_CONFFILE)
+LINT_TARGET	= $(MODULE).lint
+INSTALL_TARGET	= $(BINARY) $(ROOTMODULE) $(ROOT_CONFFILE)
+
+#
+#	depends on tcp ip and ip6
+#
+LDFLAGS		+= -dy -Ndrv/tcp -Ndrv/ip -Ndrv/ip6
+
+#
+#	Default build targets.
+#
+.KEEP_STATE:
+
+def:		$(DEF_DEPS)
+
+all:		$(ALL_DEPS)
+
+clean:		$(CLEAN_DEPS)
+
+clobber:	$(CLOBBER_DEPS)
+
+lint:		$(LINT_DEPS)
+
+modlintlib:	$(MODLINTLIB_DEPS)
+
+clean.lint:	$(CLEAN_LINT_DEPS)
+
+install:	$(INSTALL_DEPS)
+
+#
+#	Include common targets.
+#
+include $(UTSBASE)/intel/Makefile.targ
--- old/usr/src/uts/intel/ip/ip.global-objs.debug64	2012-06-13 12:05:45.644357295 +0000
+++ new/usr/src/uts/intel/ip/ip.global-objs.debug64	2012-06-13 12:05:45.703961061 +0000
@@ -48,6 +48,22 @@
 cl_sctp_listen
 cl_sctp_unlisten
 conn_drain_nthreads
+dccp_bind_fanout_size
+dccp_conn_cache
+dccp_max_optsize
+dccp_opt_arr
+dccp_opt_obj
+dccp_propinfo_count
+dccp_propinfo_tbl
+dccp_random_anon_port
+dccp_rinfo
+dccp_rinitv4
+dccp_rinitv6
+dccp_valid_levels_arr
+dccp_winfo
+dccp_winit
+dccpinfov4
+dccpinfov6
 dce_cache
 default_ip6_asp_table
 do_tcp_fusion
@@ -144,6 +160,7 @@
 ipcl_conn_hash_maxsize
 ipcl_conn_hash_memfactor
 ipcl_conn_hash_size
+ipcl_dccp_fanout_size
 ipcl_iptun_fanout_size
 ipcl_raw_fanout_size
 ipcl_udp_fanout_size
@@ -236,6 +253,7 @@
 sin6_null
 sin_null
 skip_sctp_cksum
+sock_dccp_downcalls
 sock_rawip_downcalls
 sock_rts_downcalls
 sock_tcp_downcalls
--- old/usr/src/uts/intel/ip/ip.global-objs.obj64	2012-06-13 12:05:47.263274118 +0000
+++ new/usr/src/uts/intel/ip/ip.global-objs.obj64	2012-06-13 12:05:47.327377570 +0000
@@ -48,6 +48,22 @@
 cl_sctp_listen
 cl_sctp_unlisten
 conn_drain_nthreads
+dccp_bind_fanout_size
+dccp_conn_cache
+dccp_max_optsize
+dccp_opt_arr
+dccp_opt_obj
+dccp_propinfo_count
+dccp_propinfo_tbl
+dccp_random_anon_port
+dccp_rinfo
+dccp_rinitv4
+dccp_rinitv6
+dccp_valid_levels_arr
+dccp_winfo
+dccp_winit
+dccpinfov4
+dccpinfov6
 dce_cache
 default_ip6_asp_table
 do_tcp_fusion
@@ -144,6 +160,7 @@
 ipcl_conn_hash_maxsize
 ipcl_conn_hash_memfactor
 ipcl_conn_hash_size
+ipcl_dccp_fanout_size
 ipcl_iptun_fanout_size
 ipcl_raw_fanout_size
 ipcl_udp_fanout_size
@@ -233,6 +250,7 @@
 sctpdebug
 sin6_null
 sin_null
+sock_dccp_downcalls
 sock_rawip_downcalls
 sock_rts_downcalls
 sock_tcp_downcalls
