--- /dev/null	2014-04-12 11:18:53.000000000 +0000
+++ new/usr/src/cmd/dtrace/demo/sctpbytes.d	2014-04-12 11:18:53.806574477 +0000
@@ -0,0 +1,36 @@
+#!/usr/sbin/dtrace -s
+/*
+ * 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.
+ */
+
+sctp:::receive
+{
+	@bytes[args[2]->ip_saddr, args[4]->sctp_dport] =
+	    sum(args[4]->sctp_length);
+}
+
+sctp:::send
+{
+	@bytes[args[2]->ip_daddr, args[4]->sctp_sport] =
+	    sum(args[4]->sctp_length);
+}
--- old/usr/src/lib/libdtrace/Makefile.com	2014-04-12 11:18:54.105301296 +0000
+++ new/usr/src/lib/libdtrace/Makefile.com	2014-04-12 11:18:54.113966788 +0000
@@ -98,6 +98,7 @@
 	sysevent.d \
 	tcp.d \
 	udp.d \
+	sctp.d \
 	unistd.d
 
 include ../../Makefile.lib
@@ -117,6 +118,7 @@
 CLEANFILES += ../common/sysevent.sed ../common/sysevent.d
 CLEANFILES += ../common/tcp.sed ../common/tcp.d
 CLEANFILES += ../common/udp.sed ../common/udp.d
+CLEANFILES += ../common/sctp.sed ../common/sctp.d
 CLEANFILES += $(LIBDAUDITOBJS) $(DRTIOBJS)
 
 CLOBBERFILES += $(LIBDAUDIT) drti.o
@@ -209,12 +211,15 @@
 ../common/sysevent.d: ../common/sysevent.sed ../common/sysevent.d.in
 	sed -f ../common/sysevent.sed < ../common/sysevent.d.in > $@
 
-../common/tcp.d: ..//common/tcp.sed ../common/tcp.d.in
+../common/tcp.d: ../common/tcp.sed ../common/tcp.d.in
 	sed -f ../common/tcp.sed < ../common/tcp.d.in > $@
 
 ../common/udp.d: ../common/udp.sed ../common/udp.d.in
 	sed -f ../common/udp.sed < ../common/udp.d.in > $@
 
+../common/sctp.d: ../common/sctp.sed ../common/sctp.d.in
+	sed -f ../common/sctp.sed < ../common/sctp.d.in > $@
+
 pics/%.o: ../$(MACH)/%.c
 	$(COMPILE.c) -o $@ $<
 	$(POST_PROCESS_O)
--- old/usr/src/lib/libdtrace/common/dt_open.c	2014-04-12 11:18:54.390939047 +0000
+++ new/usr/src/lib/libdtrace/common/dt_open.c	2014-04-12 11:18:54.399679306 +0000
@@ -111,8 +111,9 @@
 #define	DT_VERS_1_8_1	DT_VERSION_NUMBER(1, 8, 1)
 #define	DT_VERS_1_9	DT_VERSION_NUMBER(1, 9, 0)
 #define	DT_VERS_1_9_1	DT_VERSION_NUMBER(1, 9, 1)
-#define	DT_VERS_LATEST	DT_VERS_1_9_1
-#define	DT_VERS_STRING	"Sun D 1.9.1"
+#define	DT_VERS_1_9_2	DT_VERSION_NUMBER(1, 9, 2)
+#define	DT_VERS_LATEST	DT_VERS_1_9_2
+#define	DT_VERS_STRING	"Sun D 1.9.2"
 
 const dt_version_t _dtrace_versions[] = {
 	DT_VERS_1_0,	/* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
@@ -134,6 +135,7 @@
 	DT_VERS_1_8_1,	/* D API 1.8.1 */
 	DT_VERS_1_9,	/* D API 1.9 */
 	DT_VERS_1_9_1,	/* D API 1.9.1 */
+	DT_VERS_1_9_2,	/* D API 1.9.2 */
 	0
 };
 
--- old/usr/src/lib/libdtrace/common/ip.d.in	2014-04-12 11:18:54.685048155 +0000
+++ new/usr/src/lib/libdtrace/common/ip.d.in	2014-04-12 11:18:54.691761103 +0000
@@ -176,7 +176,7 @@
 
 /*
  * __dtrace_ipsr_ill_t is used by the translator to take an ill_t plus an
- * additional arg6 from the ip:::send and ip:::recieve probes, and translate
+ * additional arg6 from the ip:::send and ip:::receive probes, and translate
  * them to an ifinfo_t.
  */
 typedef ill_t __dtrace_ipsr_ill_t;
@@ -184,7 +184,7 @@
 /*
  * __dtrace_tcp_void_ip_t is used by the translator to take either the
  * non-NULL void_ip_t * passed in or, if it is NULL, uses arg3 (tcp_t *)
- * from the tcp:::send and tcp:::recieve probes to translate to an ipinfo_t.
+ * from the tcp:::send and tcp:::receive probes to translate to an ipinfo_t.
  * When no headers are available in the TCP fusion case for tcp:::send
  * and tcp:::receive case, this allows us to present the consumer with header
  * data based on the tcp_t * content in order to hide the implementation
--- /dev/null	2014-04-12 11:18:54.000000000 +0000
+++ new/usr/src/lib/libdtrace/common/sctp.d.in	2014-04-12 11:18:54.941189046 +0000
@@ -0,0 +1,88 @@
+/*
+ * 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 2013 David Hoeppner.  All rights reserved.
+ */
+
+#pragma D depends_on module unix
+#pragma D depends_on provider sctp
+
+/*
+ * SCTP connection states.
+ */
+inline int32_t SCTP_STATE_IDLE = @SCTPS_IDLE@;
+#pragma D binding "1.9.2" SCTP_STATE_IDLE
+inline int32_t SCTP_STATE_BOUND = @SCTPS_BOUND@;
+#pragma D binding "1.9.2" SCTP_STATE_BOUND
+inline int32_t SCTP_STATE_LISTEN = @SCTPS_LISTEN@;
+#pragma D binding "1.9.2" SCTP_STATE_LISTEN
+inline int32_t SCTP_STATE_COOKIE_WAIT = @SCTPS_COOKIE_WAIT@;
+#pragma D binding "1.9.2" SCTP_STATE_COOKIE_WAIT
+inline int32_t SCTP_STATE_COOKIE_ECHOED = @SCTPS_COOKIE_ECHOED@;
+#pragma D binding "1.9.2" SCTP_STATE_COOKIE_ECHOED
+inline int32_t SCTP_STATE_ESTABLISHED = @SCTPS_ESTABLISHED@;
+#pragma D binding "1.9.2" SCTP_STATE_ESTABLISHED
+inline int32_t SCTP_STATE_SHUTDOWN_PENDING = @SCTPS_SHUTDOWN_PENDING@;
+#pragma D binding "1.9.2" SCTP_STATE_SHUTDOWN_PENDING
+inline int32_t SCTP_STATE_SHUTDOWN_SENT = @SCTPS_SHUTDOWN_SENT@;
+#pragma D binding "1.9.2" SCTP_STATE_SHUTDOWN_SENT
+inline int32_t SCTP_STATE_SHUTDOWN_RECEIVED = @SCTPS_SHUTDOWN_RECEIVED@;
+#pragma D binding "1.9.2" SCTP_STATE_SHUTDOWN_RECEIVED
+inline int32_t SCTP_STATE_SHUTDOWN_ACK_SENT = @SCTPS_SHUTDOWN_ACK_SENT@;
+#pragma D binding "1.9.2" SCTP_STATE_SHUTDOWN_ACK_SENT
+
+/*
+ * Convert a SCTP state value to a string.
+ */
+inline string sctp_state_string[int32_t state] =
+	state == SCTP_STATE_IDLE ? "state-idle" :
+	state == SCTP_STATE_BOUND ? "state-bound" :
+	state == SCTP_STATE_LISTEN ? "state-listen" :
+	state == SCTP_STATE_COOKIE_WAIT ? "state-cookie-wait" :
+	state == SCTP_STATE_COOKIE_ECHOED ? "state-cookie-echoed" :
+	state == SCTP_STATE_ESTABLISHED ? "state-established" :
+	state == SCTP_STATE_SHUTDOWN_PENDING ? "state-shutdown-pending" :
+	state == SCTP_STATE_SHUTDOWN_SENT ? "state-shutdown-sent" :
+	state == SCTP_STATE_SHUTDOWN_RECEIVED ? "state-shutdown-received" :
+	state == SCTP_STATE_SHUTDOWN_ACK_SENT ? "state-shutdown-ack-sent" :
+	"<unknown>";
+#pragma D binding "1.9.2" sctp_state_string
+
+/*
+ * sctpinfo is the SCTP header fields.
+ */
+typedef struct sctpinfo {
+	uint16_t	sctp_sport;	/* source port */
+	uint16_t	sctp_dport;	/* destination port */
+	uint32_t	sctp_verify;	/* verification tag */
+	uint32_t	sctp_checksum;	/* headers + data checksum */
+	sctp_chunk_hdr_t sctp_chunk_hdr;
+	sctp_hdr_t	*sctp_hdr;	/* raw SCTP header */
+} sctpinfo_t;
+
+/*
+ * sctpsinfo sctp state info.
+ */
+typedef struct sctpsinfo {
+	string	sctps_laddr;		/* local address */
+	string	sctps_raddr;		/* remote address */
+	int32_t	sctps_state;		/* connection state */
+} sctpsinfo_t;
+
+#pragma D binding "1.9.2" translator
+translator sctpinfo_t < sctp_hdr_t *S > {
+	sctp_sport = ntohs(S->sh_sport);
+	sctp_dport = ntohs(S->sh_dport);
+	sctp_verify = ntohl(S->sh_verf);
+	sctp_checksum = ntohl(S->sh_chksum);
+	sctp_hdr = S;
+};
--- /dev/null	2014-04-12 11:18:55.000000000 +0000
+++ new/usr/src/lib/libdtrace/common/sctp.sed.in	2014-04-12 11:18:55.054954241 +0000
@@ -0,0 +1,20 @@
+/*
+ * 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 2013 David Hoeppner.  All rights reserved.
+ */
+
+#include <netinet/sctp.h>
+
+#define	SED_REPLACE(x)	s/#x/x/g
+
+SED_REPLACE(SCTPS_IDLE)
--- old/usr/src/lib/libdtrace/common/tcp.d.in	2014-04-12 11:18:55.165725499 +0000
+++ new/usr/src/lib/libdtrace/common/tcp.d.in	2014-04-12 11:18:55.173397589 +0000
@@ -145,7 +145,7 @@
 /*
  * __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 *
+ * from the tcp:::send and tcp:::receive 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
--- old/usr/src/pkg/manifests/developer-dtrace.mf	2014-04-12 11:18:55.427110296 +0000
+++ new/usr/src/pkg/manifests/developer-dtrace.mf	2014-04-12 11:18:55.436862891 +0000
@@ -198,6 +198,7 @@
 file path=usr/lib/dtrace/regs.d mode=0444
 file path=usr/lib/dtrace/sched.d mode=0444
 file path=usr/lib/dtrace/scsi.d mode=0444
+file path=usr/lib/dtrace/sctp.d mode=0444
 file path=usr/lib/dtrace/signal.d mode=0444
 file path=usr/lib/dtrace/srp.d mode=0444
 file path=usr/lib/dtrace/sysevent.d mode=0444
--- old/usr/src/uts/common/dtrace/sdt_subr.c	2014-04-12 11:18:55.682144226 +0000
+++ new/usr/src/uts/common/dtrace/sdt_subr.c	2014-04-12 11:18:55.691055116 +0000
@@ -107,6 +107,7 @@
 	{ "ip", "__ip_", &stab_attr, 0 },
 	{ "tcp", "__tcp_", &stab_attr, 0 },
 	{ "udp", "__udp_", &stab_attr, 0 },
+	{ "sctp", "__sctp_", &stab_attr, 0 },
 	{ "mib", "__mib_", &stab_attr, 0 },
 	{ "fsinfo", "__fsinfo_", &fsinfo_attr, 0 },
 	{ "iscsi", "__iscsi_", &iscsi_attr, 0 },
@@ -943,6 +944,12 @@
 	{ "udp", "receive", 3, 3, "udp_t *", "udpsinfo_t *" },
 	{ "udp", "receive", 4, 4, "udpha_t *", "udpinfo_t *" },
 
+	{ "sctp", "send", 0, 0, "mblk_t *", "pktinfo_t *" },
+	{ "sctp", "send", 1, 1, "ip_xmit_attr_t *", "csinfo_t *" },
+	{ "sctp", "send", 2, 2, "void_ip_t *", "ipinfo_t *" },
+	{ "sctp", "send", 3, 3, "sctp_t *", "sctpsinfo_t *" },
+	{ "sctp", "send", 4, 4, "sctp_hdr_t *", "sctpinfo_t *" },
+
 	{ "sysevent", "post", 0, 0, "evch_bind_t *", "syseventchaninfo_t *" },
 	{ "sysevent", "post", 1, 1, "sysevent_impl_t *", "syseventinfo_t *" },
 
--- old/usr/src/uts/common/inet/sctp/sctp_bind.c	2014-04-12 11:18:55.963316809 +0000
+++ new/usr/src/uts/common/inet/sctp/sctp_bind.c	2014-04-12 11:18:55.971805937 +0000
@@ -162,6 +162,9 @@
 		connp->conn_ixa->ixa_tsl = crgetlabel(connp->conn_cred);
 
 	sctp->sctp_state = SCTPS_LISTEN;
+	DTRACE_SCTP6(state__change, void, NULL, ip_xmit_attr_t *,
+	    connp->conn_ixa, void, NULL, sctp_t *, sctp, void, NULL,
+	    int32_t, SCTPS_BOUND);
 	(void) random_get_pseudo_bytes(sctp->sctp_secret, SCTP_SECRET_LEN);
 	sctp->sctp_last_secret_update = ddi_get_lbolt64();
 	bzero(sctp->sctp_old_secret, SCTP_SECRET_LEN);
@@ -708,6 +711,10 @@
 			 * number.
 			 */
 			sctp->sctp_state = SCTPS_BOUND;
+			DTRACE_SCTP6(state__change, void, NULL,
+			    ip_xmit_attr_t *, connp->conn_ixa, void, NULL,
+			    scpt_t *, sctp, void, NULL,
+			    int32_t, SCTPS_IDLE);
 			connp->conn_lport = lport;
 
 			ASSERT(&sctps->sctps_bind_fanout[
--- old/usr/src/uts/common/inet/sctp/sctp_output.c	2014-04-12 11:18:56.226900530 +0000
+++ new/usr/src/uts/common/inet/sctp/sctp_output.c	2014-04-12 11:18:56.234329235 +0000
@@ -977,6 +977,11 @@
 	}
 
 	sctp_set_iplen(sctp, head, fp->sf_ixa);
+
+	DTRACE_SCTP5(send, mblk_t *, NULL, ip_xmit_attr_t *, fp->sf_ixa,
+	    void_ip_t *, mp->b_rptr, sctp_t *, sctp, sctp_hdr_t *,
+	    &mp->b_rptr[fp->sf_ixa->ixa_ip_hdr_length]);
+
 	(void) conn_ip_output(head, fp->sf_ixa);
 	BUMP_LOCAL(sctp->sctp_opkts);
 	sctp->sctp_active = fp->sf_lastactive = ddi_get_lbolt64();
@@ -1279,6 +1284,11 @@
 		    ntohs(sdc->sdh_ssn), (void *)fp, sctp->sctp_frwnd,
 		    cansend, sctp->sctp_lastack_rxd));
 		sctp_set_iplen(sctp, head, fp->sf_ixa);
+
+		DTRACE_SCTP5(send, mblk_t *, NULL, ip_xmit_attr_t *, fp->sf_ixa,
+		    void_ip_t *, head->b_rptr, sctp_t *, sctp, sctp_hdr_t *,
+		    &head->b_rptr[fp->sf_ixa->ixa_ip_hdr_length]);
+
 		(void) conn_ip_output(head, fp->sf_ixa);
 		BUMP_LOCAL(sctp->sctp_opkts);
 		/* arm rto timer (if not set) */
@@ -1803,6 +1813,12 @@
 		if (pkt != NULL) {
 			ASSERT(pkt_len <= fp->sf_pmss);
 			sctp_set_iplen(sctp, pkt, fp->sf_ixa);
+
+			DTRACE_SCTP5(send, mblk_t *, NULL,
+			    ip_xmit_attr_t *, fp->sf_ixa,
+			    void_ip_t *, mp->b_rptr, sctp_t *, sctp, sctp_hdr_t *,
+			    &mp->b_rptr[fp->sf_ixa->ixa_ip_hdr_length]);
+
 			(void) conn_ip_output(pkt, fp->sf_ixa);
 			BUMP_LOCAL(sctp->sctp_opkts);
 		} else {
@@ -2023,6 +2039,11 @@
 	sctp->sctp_rxt_nxttsn = first_ua_tsn;
 	sctp->sctp_rxt_maxtsn = sctp->sctp_ltsn - 1;
 	sctp_set_iplen(sctp, head, fp->sf_ixa);
+
+	DTRACE_SCTP5(send, mblk_t *, NULL, ip_xmit_attr_t *, fp->sf_ixa,
+	    void_ip_t *, mp->b_rptr, sctp_t *, sctp, sctp_hdr_t *,
+	    &mp->b_rptr[fp->sf_ixa->ixa_ip_hdr_length]);
+
 	(void) conn_ip_output(head, fp->sf_ixa);
 	BUMP_LOCAL(sctp->sctp_opkts);
 
@@ -2307,6 +2328,11 @@
 		iph->ipha_fragment_offset_and_flags = 0;
 	}
 	sctp_set_iplen(sctp, pkt, fp->sf_ixa);
+
+	DTRACE_SCTP5(send, mblk_t *, NULL, ip_xmit_attr_t *, fp->sf_ixa,
+	    void_ip_t *, mp->b_rptr, sctp_t *, sctp, sctp_hdr_t *,
+	    &mp->b_rptr[fp->sf_ixa->ixa_ip_hdr_length]);
+
 	(void) conn_ip_output(pkt, fp->sf_ixa);
 	BUMP_LOCAL(sctp->sctp_opkts);
 
--- old/usr/src/uts/common/sys/sdt.h	2014-04-12 11:18:56.552856244 +0000
+++ new/usr/src/uts/common/sys/sdt.h	2014-04-12 11:18:56.560193414 +0000
@@ -332,6 +332,32 @@
 	DTRACE_PROBE5(__udp_##name, type1, arg1, type2, arg2,		\
 	    type3, arg3, type4, arg4, type5, arg5);
 
+#define	DTRACE_SCTP(name)						\
+	DTRACE_PROBE(__sctp_##name);
+
+#define	DTRACE_SCTP1(name, type1, arg1)					\
+	DTRACE_PROBE1(__sctp_##name, type1, arg1);
+
+#define	DTRACE_SCTP2(name, type1, arg1, type2, arg2)			\
+	DTRACE_PROBE2(__sctp_##name, type1, arg1, type2, arg2);
+
+#define	DTRACE_SCTP3(name, type1, arg1, type2, arg2, type3, arg3)	\
+	DTRACE_PROBE3(__sctp_##name, type1, arg1, type2, arg2, type3, arg3);
+
+#define	DTRACE_SCTP4(name, type1, arg1, type2, arg2,			\
+    type3, arg3, type4, arg4)						\
+	DTRACE_PROBE4(__sctp_##name, type1, arg1, type2, arg2,		\
+	    type3, arg3, type4, arg4);
+
+#define	DTRACE_SCTP5(name, type1, arg1, type2, arg2,			\
+    type3, arg3, type4, arg4, type5, arg5)				\
+	DTRACE_PROBE5(__sctp_##name, type1, arg1, type2, arg2,		\
+	    type3, arg3, type4, arg4, type5, arg5);
+
+#define	DTRACE_SCTP6(name, type1, arg1, type2, arg2,			\
+    type3, arg3, type4, arg4, type5, arg5, type6, arg6)			\
+	DTRACE_PROBE6(__sctp_##name, type1, arg1, type2, arg2,		\
+	    type3, arg3, type4, arg4, type5, arg5, type6, arg6);
 
 #define	DTRACE_SYSEVENT2(name, type1, arg1, type2, arg2)		\
 	DTRACE_PROBE2(__sysevent_##name, type1, arg1, type2, arg2);
