--- /dev/null	2012-08-08 12:42:03.000000000 +0000
+++ new/usr/src/lib/libdtrace/common/dccp.d.in	2012-08-08 12:42:03.362175896 +0000
@@ -0,0 +1,181 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#pragma D depends_on module unix
+#pragma D depends_on provider dccp
+
+inline int32_t DCCP_STATE_CLOSED = @DCCPS_CLOSED@;
+#pragma D binding "1.10" DCCP_STATE_CLOSED
+inline int32_t DCCP_STATE_BOUND = @DCCPS_BOUND@;
+#pragma D binding "1.10" DCCP_STATE_BOUND
+inline int32_t DCCP_STATE_REQUEST = @DCCPS_REQUEST@;
+#pragma D binding "1.10" DCCP_STATE_REQUEST
+inline int32_t DCCP_STATE_LISTEN = @DCCPS_LISTEN@;
+#pragma D binding "1.10" DCCP_STATE_LISTEN
+inline int32_t DCCP_STATE_PARTOPEN = @DCCPS_PARTOPEN@;
+#pragma D binding "1.10" DCCP_STATE_PARTOPEN
+inline int32_t DCCP_STATE_RESPOND = @DCCPS_RESPOND@;
+#pragma D binding "1.10" DCCP_STATE_RESPOND
+inline int32_t DCCP_STATE_OPEN = @DCCPS_OPEN@;
+#pragma D binding "1.10" DCCP_STATE_OPEN
+inline int32_t DCCP_STATE_CLOSING = @DCCPS_CLOSING@;
+#pragma D binding "1.10" DCCP_STATE_CLOSING
+inline int32_t DCCP_STATE_CLOSEREQ = @DCCPS_CLOSEREQ@;
+#pragma D binding "1.10" DCCP_STATE_CLOSEREQ
+inline int32_t DCCP_STATE_TIMEWAIT = @DCCPS_TIMEWAIT@;
+#pragma D binding "1.10" DCCP_STATE_TIMEWAIT
+
+/*
+ * Convert a DCCP state value to a string.
+ */
+inline string dccp_state_string[int32_t state] =
+	state == DCCP_STATE_CLOSED ? "state-closed" :
+	state == DCCP_STATE_BOUND ? "state-bound" :
+	state == DCCP_STATE_REQUEST ? "state-request" :
+	state == DCCP_STATE_LISTEN ? "state-listen" :
+	state == DCCP_STATE_PARTOPEN ? "state-partopen" :
+	state == DCCP_STATE_RESPOND ? "state-respond" :
+	state == DCCP_STATE_OPEN ? "state-open" :
+	state == DCCP_STATE_CLOSING ? "state-closing" :
+	state == DCCP_STATE_CLOSEREQ ? "state-closereq" :
+	state == DCCP_STATE_TIMEWAIT ? "state-timewait" :
+	"<unknown>";
+#pragma D binding "1.10" dccp_state_string
+
+/*
+ * dccpinfo is the DCCP header fields.
+ */
+typedef struct dccpinfo {
+	uint16_t dccp_sport;		/* source port */
+	uint16_t dccp_dport;		/* destination port */
+	uint32_t dccp_seq;		/* sequence number */
+	uint8_t dccp_offset;		/* data offset, in bytes */
+	uint16_t dccp_checksum;		/* checksum */
+	dccph_t *dccp_hdr;		/* raw DCCP header */
+} dccpinfo_t;
+
+/*
+ * dccpsinfo contains stable DCCP details from dccp_t.
+ */
+typedef struct dccpsinfo {
+	uintptr_t dccps_addr;
+	int dccps_local;		/* Is delivered locally, boolean */
+	int dccps_active;		/* Active open (from here), boolean */
+	uint16_t dccps_lport;		/* Local port */
+	uint16_t dccps_rport;		/* Remote port */
+	string dccps_laddr;		/* Local address, as a string */
+	string dccps_raddr;		/* Remote address, as a string */
+	int32_t dccps_state;		/* DCCP state */
+	uint32_t dccps_iss;		/* Initial sequence # sent */
+} dccpsinfo_t;
+
+/*
+ * dccplsinfo provides the old dccp state for state changes.
+ */
+typedef struct dccplsinfo {
+	int32_t dccps_state;		/* Previous DCCP state */
+} dccplsinfo_t;
+
+/*
+ * __dtrace_tcp_tcph_t is used by the tcpinfo_t * translator to take either
+ * the non-NULL tcph_t * passed in or, if it is NULL, uses arg3 (tcp_t *)
+ * from the tcp:::send and tcp:::recieve probes and translates the tcp_t *
+ * into the tcpinfo_t.  When no headers are available - as is the case for
+ * TCP fusion tcp:::send and tcp:::receive - this allows us to present the
+ * consumer with header data based on tcp_t * content and hide TCP fusion
+ * implementation details.
+ */
+typedef dccph_t * __dtrace_dccp_dccph_t;
+
+#pragma D binding "1.10" translator
+translator dccpinfo_t < dccph_t *T > {
+	dccp_sport = ntohs(*(uint16_t *)T->dh_lport);
+	dccp_dport = ntohs(*(uint16_t *)T->dh_fport);
+	dccp_seq = ntohl(*(uint32_t *)T->dh_seq); /* XXX */
+	dccp_offset = (*(uint8_t *)T->dh_offset & 0xf0) >> 2;
+	dccp_checksum = ntohs(*(uint16_t *)T->dh_sum);
+	dccp_hdr = T;
+};
+
+#pragma D binding "1.10" translator
+translator dccpinfo_t < __dtrace_dccp_dccph_t *T > {
+	dccp_sport =
+	    T != NULL ? ntohs(*(uint16_t *)((dccph_t *)T)->dh_lport) :
+	    arg3 != NULL && probename == "send" ?
+	    ntohs(((dccp_t *)arg3)->dccp_connp->u_port.connu_ports.connu_lport) :
+	    arg3 != NULL && probename == "receive" ?
+	    ntohs(((dccp_t *)arg3)->dccp_connp->u_port.connu_ports.connu_fport) :
+	    0;
+	dccp_dport =
+	    T != NULL ? ntohs(*(uint16_t *)((dccph_t *)T)->dh_fport) :
+	    arg3 != NULL && probename == "send" ?
+	    ntohs(((dccp_t *)arg3)->dccp_connp->u_port.connu_ports.connu_fport) :
+	    arg3 != NULL && probename == "receive" ?
+	    ntohs(((dccp_t *)arg3)->dccp_connp->u_port.connu_ports.connu_lport) :
+	    0;
+	dccp_seq =
+	    T != NULL ? ntohl(*(uint32_t *)((dccph_t *)T)->dh_seq) :
+	    0;
+	dccp_offset = T != NULL ?
+	    (*(uint8_t *)((dccph_t *)T)->dh_offset & 0xf0) >> 2 :
+	    @DCCP_MIN_HEADER_LENGTH@;
+	dccp_checksum = T != NULL ? ntohs(*(uint16_t *)((dccph_t *)T)->dh_sum) :
+	    0;
+	dccp_hdr = NULL;
+};
+
+#pragma D binding "1.10" translator
+translator dccpsinfo_t < dccp_t *T > {
+	dccps_addr = (uintptr_t)T;
+	/*
+	 * The following two members should just use tcp_t->tcp_loopback
+	 * and tcp_t->tcp_active_open, however these are bit fields and
+	 * can't be used until CR 6876830 is fixed.  Meanwhile we source
+	 * them a different way.
+	 */
+	dccps_local = T ? T->dccp_ipha ?
+	    T->dccp_ipha->ipha_src == T->dccp_ipha->ipha_dst : 1 : 0;
+	dccps_active = T ? !T->dccp_saved_listener : 0;
+	dccps_lport = T ?
+	    ntohs(T->dccp_connp->u_port.connu_ports.connu_lport) : 0;
+	dccps_rport = T ?
+	    ntohs(T->dccp_connp->u_port.connu_ports.connu_fport) : 0;
+	dccps_laddr = T ?
+	    inet_ntoa6(&T->dccp_connp->connua_v6addr.connua_laddr) : "<unknown>";
+	dccps_raddr = T ?
+	    inet_ntoa6(&T->dccp_connp->connua_v6addr.connua_faddr) : "<unknown>";
+	dccps_state = T ? T->dccp_state : DCCP_STATE_CLOSED;
+	dccps_iss = T ? T->dccp_iss : 0;
+};
+
+/*
+ * Note: although we specify that the old state argument used as the
+ * input to the tcplsinfo_t translator is an int32_t, it reaches us as an
+ * int64_t (since it is a probe argument) so explicitly cast it back to
+ * interpret the negatively-valued states correctly.
+ */
+#pragma D binding "1.10" translator
+translator dccplsinfo_t < int64_t I > {
+	dccps_state = (int32_t) I;
+};
