Commits

Alan Maguire  committed 501806a

PSARC 2010/106 DTrace TCP and UDP providers
6742331 DTrace TCP Provider
6932981 DTrace UDP provider

  • Participants
  • Parent commits ead0f74

Comments (0)

Files changed (50)

File usr/src/cmd/dtrace/demo/Makefile

 # CDDL HEADER END
 #
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 
 include ../../Makefile.cmd
 	specopen.d \
 	ssd.d \
 	syscall.d \
+	tcp1stbyte.d \
+	tcpbytes.d \
+	tcpbytesstat.d \
+	tcpconnlat.d \
+	tcpio.d \
+	tcpioflags.d \
+	tcpsnoop.d \
+	tcpstate.d \
+	tcptop.d \
 	tick.d \
 	ticktime.d \
 	time.d \
 	tracewrite.d \
 	trunc.d \
 	trussrw.d \
+	udpbytes.d \
+	udpbytesstat.d \
+	udpio.d \
+	udpsnoop.d \
+	udptop.d \
 	userfunc.d \
 	whatfor.d \
 	whatlock.d \

File usr/src/cmd/dtrace/demo/chapters

 index: 101
 url: http://wikis.sun.com/display/DTrace/ip+Provider
 
+name: tcp
+title: tcp Provider
+index: 102
+url: http://wikis.sun.com/display/DTrace/tcp+Provider
+
+name: udp
+title: udp Provider
+index: 103
+url: http://wikis.sun.com/display/DTrace/udp+Provider
+

File usr/src/cmd/dtrace/demo/tcp/tcp1stbyte.d

+#!/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.
+ */
+
+tcp:::connect-established
+{
+	start[args[1]->cs_cid] = timestamp;
+}
+
+tcp:::receive
+/start[args[1]->cs_cid] && (args[2]->ip_plength - args[4]->tcp_offset) > 0/
+{
+	@latency["1st Byte Latency (ns)", args[2]->ip_saddr] =
+	    quantize(timestamp - start[args[1]->cs_cid]);
+	start[args[1]->cs_cid] = 0;
+}

File usr/src/cmd/dtrace/demo/tcp/tcpbytes.d

+#!/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.
+ */
+
+tcp:::receive
+{
+	@bytes[args[2]->ip_saddr, args[4]->tcp_dport] =
+	    sum(args[2]->ip_plength - args[4]->tcp_offset);
+}
+
+tcp:::send
+{
+	@bytes[args[2]->ip_daddr, args[4]->tcp_sport] =
+	    sum(args[2]->ip_plength - args[4]->tcp_offset);
+}

File usr/src/cmd/dtrace/demo/tcp/tcpbytesstat.d

+#!/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.
+ */
+
+#pragma D option quiet
+
+tcp:::receive
+{
+	@bytes[args[2]->ip_saddr, args[4]->tcp_dport] =
+	    sum(args[2]->ip_plength - args[4]->tcp_offset);
+}
+
+tcp:::send
+{
+	@bytes[args[2]->ip_daddr, args[4]->tcp_sport] =
+	    sum(args[2]->ip_plength - args[4]->tcp_offset);
+}
+
+profile:::tick-1sec
+{
+	printf("\n   %-32s %16s\n", "HOST", "BYTES/s");
+	printa("   %-32s %@16d\n", @bytes);
+	trunc(@bytes);
+}

File usr/src/cmd/dtrace/demo/tcp/tcpconnlat.d

+#!/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.
+ */
+
+tcp:::connect-request
+{
+	start[args[1]->cs_cid] = timestamp;
+}
+
+tcp:::connect-established
+/start[args[1]->cs_cid] /
+{
+	@latency["Connect Latency (ns)", args[3]->tcps_raddr] =
+	    quantize(timestamp - start[args[1]->cs_cid]);
+	start[args[1]->cs_cid] = 0;
+}

File usr/src/cmd/dtrace/demo/tcp/tcpio.d

+#!/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.
+ */
+
+tcp:::send,
+tcp:::receive
+{
+	printf("%15s:%-5d  ->  %15s:%-5d",
+	    args[2]->ip_saddr, args[4]->tcp_sport,
+	    args[2]->ip_daddr, args[4]->tcp_dport);
+}

File usr/src/cmd/dtrace/demo/tcp/tcpioflags.d

+#!/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.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+dtrace:::BEGIN
+{
+	printf(" %15s:%-5s      %15s:%-5s %6s %s\n",
+	    "LADDR", "PORT", "RADDR", "PORT", "BYTES", "FLAGS");
+}
+
+tcp:::send
+{
+	this->length = args[2]->ip_plength - args[4]->tcp_offset;
+	printf(" %15s:%-5d  ->  %15s:%-5d %6d (",
+	    args[2]->ip_saddr, args[4]->tcp_sport,
+	    args[2]->ip_daddr, args[4]->tcp_dport, this->length);
+}
+
+tcp:::receive
+{
+	this->length = args[2]->ip_plength - args[4]->tcp_offset;
+	printf(" %15s:%-5d  <-  %15s:%-5d %6d (",
+	    args[2]->ip_daddr, args[4]->tcp_dport,
+	    args[2]->ip_saddr, args[4]->tcp_sport, this->length);
+}
+
+tcp:::send,
+tcp:::receive
+{
+	printf("%s", args[4]->tcp_flags & TH_FIN ? "FIN|" : "");
+	printf("%s", args[4]->tcp_flags & TH_SYN ? "SYN|" : "");
+	printf("%s", args[4]->tcp_flags & TH_RST ? "RST|" : "");
+	printf("%s", args[4]->tcp_flags & TH_PUSH ? "PUSH|" : "");
+	printf("%s", args[4]->tcp_flags & TH_ACK ? "ACK|" : "");
+	printf("%s", args[4]->tcp_flags & TH_URG ? "URG|" : "");
+	printf("%s", args[4]->tcp_flags & TH_ECE ? "ECE|" : "");
+	printf("%s", args[4]->tcp_flags & TH_CWR ? "CWR|" : "");
+	printf("%s", args[4]->tcp_flags == 0 ? "null " : "");
+	printf("\b)\n");
+}

File usr/src/cmd/dtrace/demo/tcp/tcpsnoop.d

+#!/usr/sbin/dtrace -s
+/*
+ * tcpsnoop - snoop TCP network packets by process.
+ *	Written using DTrace tcp Provider.
+ *
+ * This analyses TCP network packets and prints the responsible PID plus
+ * standard details such as IP address and port. This captures traffic
+ * from existing and newly created TCP connections. It can help identify
+ * which processes are causing TCP traffic.
+ *
+ * SEE ALSO: snoop -rS
+ *
+ * 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.
+ *
+ * Portions Copyright 2010 Brendan Gregg
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+dtrace:::BEGIN
+{
+	printf("%6s %6s %15s:%-5s      %15s:%-5s %6s %s\n",
+	    "TIME", "PID", "LADDR", "PORT", "RADDR", "PORT", "BYTES", "FLAGS");
+}
+
+tcp:::send
+{
+	this->length = args[2]->ip_plength - args[4]->tcp_offset;
+	printf("%6d %6d %15s:%-5d  ->  %15s:%-5d %6d (",
+	    timestamp/1000, args[1]->cs_pid, args[2]->ip_saddr,
+	    args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport,
+	    this->length);
+}
+
+tcp:::receive
+{
+	this->length = args[2]->ip_plength - args[4]->tcp_offset;
+	printf("%6d %6d %15s:%-5d  <-  %15s:%-5d %6d (",
+	    timestamp/1000, args[1]->cs_pid, args[2]->ip_daddr,
+	    args[4]->tcp_dport, args[2]->ip_saddr, args[4]->tcp_sport,
+	    this->length);
+}
+
+tcp:::send,
+tcp:::receive
+{
+	printf("%s", args[4]->tcp_flags & TH_FIN ? "FIN|" : "");
+	printf("%s", args[4]->tcp_flags & TH_SYN ? "SYN|" : "");
+	printf("%s", args[4]->tcp_flags & TH_RST ? "RST|" : "");
+	printf("%s", args[4]->tcp_flags & TH_PUSH ? "PUSH|" : "");
+	printf("%s", args[4]->tcp_flags & TH_ACK ? "ACK|" : "");
+	printf("%s", args[4]->tcp_flags & TH_URG ? "URG|" : "");
+	printf("%s", args[4]->tcp_flags & TH_ECE ? "ECE|" : "");
+	printf("%s", args[4]->tcp_flags & TH_CWR ? "CWR|" : "");
+	printf("%s", args[4]->tcp_flags == 0 ? "null " : "");
+	printf("\b)\n");
+}

File usr/src/cmd/dtrace/demo/tcp/tcpstate.d

+#!/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.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+	printf("%-10s %-10s %-20s    %-20s\n", "C", "PID", "PREV", "NEW");
+}
+
+
+tcp:::state-change
+{
+	printf("%-10d %-10d %-20s -> %-20s\n", cpu, args[1]->cs_pid,
+	    tcp_state_string[args[5]->tcps_state],
+	    tcp_state_string[args[3]->tcps_state]);
+}

File usr/src/cmd/dtrace/demo/tcp/tcptop.d

+#!/usr/sbin/dtrace -s
+/*
+ * tcptop: display top TCP network packets by process.
+ *	Written using DTrace tcp Provider.
+ *
+ * Usage: dtrace -s tcptop.d [count] [interval]
+ *
+ * This analyses TCP network packets and prints the responsible PID plus
+ * standard details such as IP address and port. This captures traffic
+ * of newly created TCP connections that were established while this program
+ * was running along with traffic from existing connections. It can help
+ * identify which processes is causing TCP traffic.
+ *
+ * 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.
+ *
+ * Portions Copyright 2010 Brendan Gregg
+ */
+
+#pragma D option quiet
+#pragma D option defaultargs
+#pragma D option switchrate=10hz
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+	/* starting values */
+	counts = $1 ? $1 : 10;
+	secs = $2 ? $2 : 5;
+	TCP_out = 0;
+	TCP_in = 0;
+
+	printf("Sampling... Please wait.\n");
+}
+
+
+tcp:::send
+/ args[1]->cs_pid != -1 /
+{
+	@out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_saddr, 
+	    args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport] =
+	    sum(args[2]->ip_plength - args[4]->tcp_offset);
+}
+
+tcp:::receive
+/ args[1]->cs_pid != -1 /
+{
+	@out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_daddr, 
+	    args[4]->tcp_dport, args[2]->ip_saddr, args[4]->tcp_sport] =
+	    sum(args[2]->ip_plength - args[4]->tcp_offset);
+}
+
+/*
+ * TCP Systemwide Stats
+ */
+mib:::tcpOutDataBytes       { TCP_out += args[0]; }
+mib:::tcpRetransBytes       { TCP_out += args[0]; }
+mib:::tcpInDataInorderBytes { TCP_in  += args[0]; }
+mib:::tcpInDataDupBytes     { TCP_in  += args[0]; }
+mib:::tcpInDataUnorderBytes { TCP_in  += args[0]; }
+
+profile:::tick-1sec
+/secs != 0/
+{
+	secs--;
+}
+
+/*
+ * Print Report
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+	/* fetch 1 min load average */
+	this->load1a  = `hp_avenrun[0] / 65536;
+	this->load1b  = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+
+	/* convert TCP counters to Kb */
+	TCP_out /= 1024;
+	TCP_in  /= 1024;
+
+	/* print status */
+	printf("%Y,  load: %d.%02d,  TCPin: %6d Kb,  TCPout: %6d Kb\n\n",
+	    walltimestamp, this->load1a, this->load1b, TCP_in, TCP_out);
+
+	/* print headers */
+	printf("%6s %6s %-15s %5s %-15s %5s %9s\n",
+	    "ZONE", "PID", "LADDR", "LPORT", "RADDR", "RPORT", "SIZE");
+
+	/* print data */
+	printa("%6d %6d %-15s %5d %-15s %5d %@9d\n", @out);
+	printf("\n");
+
+	/* clear data */
+	trunc(@out);
+	TCP_in = 0;
+	TCP_out = 0;
+	secs = 5;
+	counts--;
+}
+
+/*
+ * End of program
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+	exit(0);
+}
+
+/*
+ * Cleanup for Ctrl-C
+ */
+dtrace:::END
+{
+	trunc(@out);
+}

File usr/src/cmd/dtrace/demo/udp/udpbytes.d

+#!/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.
+ */
+
+udp:::receive
+{
+	@bytes[args[2]->ip_saddr, args[4]->udp_dport] =
+	    sum(args[4]->udp_length);
+}
+
+udp:::send
+{
+	@bytes[args[2]->ip_daddr, args[4]->udp_sport] =
+	    sum(args[4]->udp_length);
+}

File usr/src/cmd/dtrace/demo/udp/udpbytesstat.d

+#!/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.
+ */
+
+#pragma D option quiet
+
+udp:::receive
+{
+	@bytes[args[2]->ip_saddr, args[4]->udp_dport] =
+	    sum(args[4]->udp_length);
+}
+
+udp:::send
+{
+	@bytes[args[2]->ip_daddr, args[4]->udp_sport] =
+	    sum(args[4]->udp_length);
+}
+
+profile:::tick-1sec
+{
+	printf("\n   %-32s %16s\n", "HOST", "BYTES/s");
+	printa("   %-32s %@16d\n", @bytes);
+	trunc(@bytes);
+}

File usr/src/cmd/dtrace/demo/udp/udpio.d

+#!/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.
+ */
+
+udp:::send,
+udp:::receive
+{
+	printf("%15s:%-5d  ->  %15s:%-5d",
+	    args[2]->ip_saddr, args[4]->udp_sport,
+	    args[2]->ip_daddr, args[4]->udp_dport);
+}

File usr/src/cmd/dtrace/demo/udp/udpsnoop.d

+#!/usr/sbin/dtrace -s
+/*
+ * udpsnoop - snoop UDP network packets by process.
+ *	Written using DTrace udp Provider.
+ *
+ * This analyses UDP network packets and prints the responsible PID plus
+ * standard details such as IP address and port. This captures traffic
+ * from existing and newly created UDP connections. It can help identify
+ * which processes are causing UDP traffic.
+ *
+ * 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.
+ *
+ * Portions Copyright 2010 Brendan Gregg
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+dtrace:::BEGIN
+{
+	printf("%6s %6s %15s:%-5s      %15s:%-5s %6s\n",
+	    "TIME", "PID", "LADDR", "PORT", "RADDR", "PORT", "BYTES");
+}
+
+udp:::send
+{
+	printf("%6d %6d %15s:%-5d  ->  %15s:%-5d %6d\n",
+	    timestamp/1000, args[1]->cs_pid, args[2]->ip_saddr,
+	    args[4]->udp_sport, args[2]->ip_daddr, args[4]->udp_dport,
+	    args[4]->udp_length);
+}
+
+udp:::receive
+{
+	printf("%6d %6d %15s:%-5d  <-  %15s:%-5d %6d\n",
+	    timestamp/1000, args[1]->cs_pid, args[2]->ip_daddr,
+	    args[4]->udp_dport, args[2]->ip_saddr, args[4]->udp_sport,
+	    args[4]->udp_length);
+}

File usr/src/cmd/dtrace/demo/udp/udptop.d

+#!/usr/sbin/dtrace -s
+/*
+ * udptop: display top UDP network packets by process.
+ *	Written using DTrace udp Provider.
+ *
+ * Usage: dtrace -s udptop.d [count] [interval]
+ *
+ * This analyses UDP network packets and prints the responsible PID plus
+ * standard details such as IP address and port. This captures traffic
+ * of newly created UDP connections that were established while this program
+ * was running along with traffic from existing connections. It can help
+ * identify which processes is causing UDP traffic.
+ *
+ * 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.
+ *
+ * Portions Copyright 2010 Brendan Gregg
+ */
+
+#pragma D option quiet
+#pragma D option defaultargs
+#pragma D option switchrate=10hz
+
+/*
+ * Print header
+ */
+dtrace:::BEGIN
+{
+	/* starting values */
+	counts = $1 ? $1 : 10;
+	secs = $2 ? $2 : 5;
+	UDP_out = 0;
+	UDP_in = 0;
+
+	printf("Sampling... Please wait.\n");
+}
+
+
+udp:::send
+/ args[1]->cs_pid != -1 /
+{
+	@out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_saddr, 
+	    args[4]->udp_sport, args[2]->ip_daddr, args[4]->udp_dport] =
+	    sum(args[4]->udp_length);
+}
+
+udp:::receive
+/ args[1]->cs_pid != -1 /
+{
+	@out[args[1]->cs_zoneid, args[1]->cs_pid, args[2]->ip_daddr, 
+	    args[4]->udp_dport, args[2]->ip_saddr, args[4]->udp_sport] =
+	    sum(args[4]->udp_length);
+}
+
+/*
+ * UDP Systemwide Stats
+ */
+mib:::udpHCOutDatagrams		{ UDP_out += args[0]; }
+mib:::udpHCInDatagrams		{ UDP_in  += args[0]; }
+
+profile:::tick-1sec
+/secs != 0/
+{
+	secs--;
+}
+
+/*
+ * Print Report
+ */
+profile:::tick-1sec
+/secs == 0/
+{
+	/* fetch 1 min load average */
+	this->load1a  = `hp_avenrun[0] / 65536;
+	this->load1b  = ((`hp_avenrun[0] % 65536) * 100) / 65536;
+
+	/* print status */
+	printf(%Y,  load: %d.%02d,  UDP datagrams in: %6d, ",
+	    walltimestamp, this->load1a, this->load1b, UDP_in);
+	printf("UDP datagrams out: %6d\n\n", UDP_out);
+
+	/* print headers */
+	printf("%6s %6s %-15s %5s %-15s %5s %9s\n",
+	    "ZONE", "PID", "LADDR", "LPORT", "RADDR", "RPORT", "SIZE");
+
+	/* print data */
+	printa("%6d %6d %-15s %5d %-15s %5d %@9d\n", @out);
+	printf("\n");
+
+	/* clear data */
+	trunc(@out);
+	UDP_in = 0;
+	UDP_out = 0;
+	secs = 5;
+	counts--;
+}
+
+/*
+ * End of program
+ */
+profile:::tick-1sec
+/counts == 0/
+{
+	exit(0);
+}
+
+/*
+ * Cleanup for Ctrl-C
+ */
+dtrace:::END
+{
+	trunc(@out);
+}

File usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh

 #
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 #
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #
-# Test ip:::{send,receive} of IPv4 TCP to a remote host.
+# Test {ip,tcp}:::{send,receive} of IPv4 TCP to local host.
 #
 # This may fail due to:
 #
 # following packet counts were traced:
 #
 # 3 x ip:::send (2 during the TCP handshake, then a FIN)
+# 3 x tcp:::send (2 during the TCP handshake, then a FIN)
 # 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK)
-#
+# 2 x tcp:::receive (1 during the TCP handshake, then the FIN ACK)
+
 # The actual count tested is 5 each way, since we are tracing both
 # source and destination events.
 #
 $dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
 BEGIN
 {
-	send = receive = 0;
+	ipsend = tcpsend = ipreceive = tcpreceive = 0;
 }
 
 ip:::send
 /args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
     args[4]->ipv4_protocol == IPPROTO_TCP/
 {
-	send++;
+	ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+	tcpsend++;
 }
 
 ip:::receive
 /args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
     args[4]->ipv4_protocol == IPPROTO_TCP/
 {
-	receive++;
+	ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+	tcpreceive++;
 }
 
 END
 {
 	printf("Minimum TCP events seen\n\n");
-	printf("ip:::send - %s\n", send >= 5 ? "yes" : "no");
-	printf("ip:::receive - %s\n", receive >= 5 ? "yes" : "no");
+	printf("ip:::send - %s\n", ipsend >= 5 ? "yes" : "no");
+	printf("ip:::receive - %s\n", ipreceive >= 5 ? "yes" : "no");
+	printf("tcp:::send - %s\n", tcpsend >= 5 ? "yes" : "no");
+	printf("tcp:::receive - %s\n", tcpreceive >= 5 ? "yes" : "no");
 }
 EODTRACE
 

File usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out

 
 ip:::send - yes
 ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
 

File usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh

 #
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 #
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #
 # Test ip:::{send,receive} of IPv4 UDP to a local address.
 # following counts were traced:
 #
 # 1 x ip:::send (UDP sent to ping's base UDP port)
+# 1 x udp:::send (UDP sent to ping's base UDP port)
 # 1 x ip:::receive (UDP received)
 # 
+# No udp:::receive event is expected as the response ping -U elicits is
+# an ICMP PORT_UNREACHABLE response rather than a UDP packet, and locally
+# the echo request UDP packet only reaches IP, so the udp:::receive probe
+# is not triggered by it.
+#
 
 if (( $# != 1 )); then
 	print -u2 "expected one argument: <dtrace-path>"
 $dtrace -c "/usr/sbin/ping -U $local" -qs /dev/stdin <<EOF | grep -v 'is alive'
 BEGIN
 {
-	send = receive = 0;
+	ipsend = udpsend = ipreceive = 0;
 }
 
 ip:::send
 /args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
     args[4]->ipv4_protocol == IPPROTO_UDP/
 {
-	send++;
+	ipsend++;
+}
+
+udp:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local"/
+{
+	udpsend++;
 }
 
 ip:::receive
 /args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
     args[4]->ipv4_protocol == IPPROTO_UDP/
 {
-	receive++;
+	ipreceive++;
 }
 
 END
 {
 	printf("Minimum UDP events seen\n\n");
-	printf("ip:::send - %s\n", send >= 1 ? "yes" : "no");
-	printf("ip:::receive - %s\n", receive >= 1 ? "yes" : "no");
+	printf("ip:::send - %s\n", ipsend >= 1 ? "yes" : "no");
+	printf("ip:::receive - %s\n", ipreceive >= 1 ? "yes" : "no");
+	printf("udp:::send - %s\n", udpsend >= 1 ? "yes" : "no");
 }
 EOF

File usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out

 
 ip:::send - yes
 ip:::receive - yes
+udp:::send - yes
 

File usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh

 #
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 #
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #
-# Test ip:::{send,receive} of IPv4 TCP to a remote host.
+# Test {tcp,ip}:::{send,receive} of IPv4 TCP to a remote host.
 #
 # This may fail due to:
 #
 # following packet counts were traced:
 #
 # 3 x ip:::send (2 during the TCP handshake, then a FIN)
+# 3 x tcp:::send (2 during the TCP handshake, then a FIN)
 # 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK)
+# 2 x tcp:::receive (1 during the TCP handshake, then the FIN ACK)
 # 
 
 if (( $# != 1 )); then
 $dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
 BEGIN
 {
-	send = receive = 0;
+	ipsend = tcpsend = ipreceive = tcpreceive = 0;
 }
 
 ip:::send
 /args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
     args[4]->ipv4_protocol == IPPROTO_TCP/
 {
-	send++;
+	ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest"/
+{
+	tcpsend++;
 }
 
 ip:::receive
 /args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
     args[4]->ipv4_protocol == IPPROTO_TCP/
 {
-	receive++;
+	ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source"/
+{
+	tcpreceive++;
 }
 
 END
 {
 	printf("Minimum TCP events seen\n\n");
-	printf("ip:::send - %s\n", send >= 3 ? "yes" : "no");
-	printf("ip:::receive - %s\n", receive >= 2 ? "yes" : "no");
+	printf("ip:::send - %s\n", ipsend >= 3 ? "yes" : "no");
+	printf("ip:::receive - %s\n", ipreceive >= 2 ? "yes" : "no");
+	printf("tcp:::send - %s\n", tcpsend >= 3 ? "yes" : "no");
+	printf("tcp:::receive - %s\n", tcpreceive >= 2 ? "yes" : "no");
 }
 EODTRACE
 

File usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out

 
 ip:::send - yes
 ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
 

File usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh

 #
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 #
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
 
 #
-# Test ip:::{send,receive} of IPv4 UDP to a remote host.
+# Test {udp,ip}:::{send,receive} of IPv4 UDP to a remote host.
 #
 # This may fail due to:
 #
 # following counts were traced:
 #
 # 1 x ip:::send (UDP sent to ping's base UDP port)
+# 1 x udp:::send (UDP sent to ping's base UDP port)
 # 
 
 if (( $# != 1 )); then
 $dtrace -c "/usr/sbin/ping -U $dest" -qs /dev/stdin <<EOF | grep -v 'is alive'
 BEGIN
 {
-	send = 0;
+	ipsend = udpsend = 0;
 }
 
 ip:::send
 /args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
     args[4]->ipv4_protocol == IPPROTO_UDP/
 {
-	send++;
+	ipsend++;
+}
+
+udp:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest"/
+{
+	udpsend++;
 }
 
 END
 {
 	printf("Minimum UDP events seen\n\n");
-	printf("ip:::send - %s\n", send >= 1 ? "yes" : "no");
+	printf("ip:::send - %s\n", ipsend >= 1 ? "yes" : "no");
+	printf("udp:::send - %s\n", udpsend >= 1 ? "yes" : "no");
 }
 EOF

File usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out

 Minimum UDP events seen
 
 ip:::send - yes
+udp:::send - yes
 

File usr/src/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh

+#!/usr/bin/ksh
+#
+# 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.
+#
+
+#
+# Test tcp:::state-change and tcp:::{send,receive} by connecting to
+# the local ssh service and sending a test message. This should result
+# in a "Protocol mismatch" response and a close of the connection.
+# A number of state transition events along with tcp fusion send and
+# receive events for the message should result.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+#    which is the reason we are testing.
+# 2. The lo0 interface missing or not up.
+# 3. The local ssh service is not online.
+# 4. An unlikely race causes the unlocked global send/receive
+#    variables to be corrupted.
+#
+# This test performs a TCP connection to the ssh service (port 22) and
+# checks that at least the following packet counts were traced:
+#
+# 3 x ip:::send (2 during the TCP handshake, then a FIN)
+# 4 x tcp:::send (2 during the TCP handshake, 1 message then a FIN)
+# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK)
+# 3 x tcp:::receive (1 during the TCP handshake, 1 message then the FIN ACK)
+#
+# The actual ip count tested is 5 each way, since we are tracing both
+# source and destination events.  The actual tcp count tested is 7
+# each way, since the TCP fusion send/receive events will not reach IP.
+#
+# For this test to work, we are assuming that the TCP handshake and
+# TCP close will enter the IP code path and not use tcp fusion.
+#
+
+if (( $# != 1 )); then
+	print -u2 "expected one argument: <dtrace-path>"
+	exit 2
+fi
+
+dtrace=$1
+local=127.0.0.1
+tcpport=22
+DIR=/var/tmp/dtest.$$
+
+mkdir $DIR
+cd $DIR
+
+cat > test.pl <<-EOPERL
+	use IO::Socket;
+	my \$s = IO::Socket::INET->new(
+	    Proto => "tcp",
+	    PeerAddr => "$local",
+	    PeerPort => $tcpport,
+	    Timeout => 3);
+	die "Could not connect to host $local port $tcpport" unless \$s;
+	print \$s "testing state machine transitions";
+	close \$s;
+EOPERL
+
+$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+	ipsend = tcpsend = ipreceive = tcpreceive = 0;
+	connreq = connest = connaccept = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+    args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+	ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ (args[4]->tcp_sport == $tcpport || args[4]->tcp_dport == $tcpport)/
+{
+	tcpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+    args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+	ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ (args[4]->tcp_sport == $tcpport || args[4]->tcp_dport == $tcpport)/
+{
+	tcpreceive++;
+}
+
+tcp:::state-change
+{
+	state_event[args[3]->tcps_state]++;
+}
+
+tcp:::connect-request
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->tcp_dport == $tcpport/
+{
+	connreq++;
+}
+
+tcp:::connect-established
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->tcp_sport == $tcpport/
+{
+	connest++;
+}
+
+tcp:::accept-established
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->tcp_dport == $tcpport/
+{
+	connaccept++;
+}
+
+END
+{
+	printf("Minimum TCP events seen\n\n");
+	printf("ip:::send - %s\n", ipsend >= 5 ? "yes" : "no");
+	printf("ip:::receive - %s\n", ipreceive >= 5 ? "yes" : "no");
+	printf("tcp:::send - %s\n", tcpsend >= 7 ? "yes" : "no");
+	printf("tcp:::receive - %s\n", tcpreceive >= 7 ? "yes" : "no");
+	printf("tcp:::state-change to syn-sent - %s\n",
+	    state_event[TCP_STATE_SYN_SENT] >=1 ? "yes" : "no");
+	printf("tcp:::state-change to syn-received - %s\n",
+	    state_event[TCP_STATE_SYN_RECEIVED] >=1 ? "yes" : "no");
+	printf("tcp:::state-change to established - %s\n",
+	    state_event[TCP_STATE_ESTABLISHED] >= 2 ? "yes" : "no");
+	printf("tcp:::state-change to fin-wait-1 - %s\n",
+	    state_event[TCP_STATE_FIN_WAIT_1] >= 1 ? "yes" : "no");
+	printf("tcp:::state-change to close-wait - %s\n",
+	    state_event[TCP_STATE_CLOSE_WAIT] >= 1 ? "yes" : "no");
+	printf("tcp:::state-change to fin-wait-2 - %s\n",
+	    state_event[TCP_STATE_FIN_WAIT_2] >= 1 ? "yes" : "no");
+	printf("tcp:::state-change to last-ack - %s\n",
+	    state_event[TCP_STATE_LAST_ACK] >= 1 ? "yes" : "no");
+	printf("tcp:::state-change to time-wait - %s\n",
+	    state_event[TCP_STATE_TIME_WAIT] >= 1 ? "yes" : "no");
+	printf("tcp:::connect-request - %s\n",
+	    connreq >=1 ? "yes" : "no");
+	printf("tcp:::connect-established - %s\n",
+	    connest >=1 ? "yes" : "no");
+	printf("tcp:::accept-established - %s\n",
+	    connaccept >=1 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $status

File usr/src/cmd/dtrace/test/tst/common/ip/tst.localtcpstate.ksh.out

+Minimum TCP events seen
+
+ip:::send - yes
+ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
+tcp:::state-change to syn-sent - yes
+tcp:::state-change to syn-received - yes
+tcp:::state-change to established - yes
+tcp:::state-change to fin-wait-1 - yes
+tcp:::state-change to close-wait - yes
+tcp:::state-change to fin-wait-2 - yes
+tcp:::state-change to last-ack - yes
+tcp:::state-change to time-wait - yes
+tcp:::connect-request - yes
+tcp:::connect-established - yes
+tcp:::accept-established - yes
+

File usr/src/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh

+#!/usr/bin/ksh
+#
+# 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.
+#
+
+#
+# Test tcp:::state-change and tcp:::{send,receive} by connecting to
+# the remote ssh service and sending a test message. This should result
+# in a "Protocol mismatch" response and a close of the connection.
+# A number of state transition events along with tcp send and receive
+# events for the message should result.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+#    which is the reason we are testing.
+# 2. The lo0 interface missing or not up.
+# 3. The remote ssh service is not online.
+# 4. An unlikely race causes the unlocked global send/receive
+#    variables to be corrupted.
+#
+# This test performs a TCP connection to the ssh service (port 22) and
+# checks that at least the following packet counts were traced:
+#
+# 4 x ip:::send (2 during the TCP handshake, the message, then a FIN)
+# 4 x tcp:::send (2 during the TCP handshake, the messages, then a FIN)
+# 3 x ip:::receive (1 during the TCP handshake, the response, then the FIN ACK)
+# 3 x tcp:::receive (1 during the TCP handshake, the response, then the FIN ACK)
+#
+# For this test to work, we are assuming that the TCP handshake and
+# TCP close will enter the IP code path and not use tcp fusion.
+#
+
+if (( $# != 1 )); then
+	print -u2 "expected one argument: <dtrace-path>"
+	exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv4remote.pl
+tcpport=22
+DIR=/var/tmp/dtest.$$
+
+if [[ ! -x $getaddr ]]; then
+	print -u2 "could not find or execute sub program: $getaddr"
+	exit 3
+fi
+$getaddr $tcpport | read source dest
+if (( $? != 0 )); then
+	exit 4
+fi
+
+mkdir $DIR
+cd $DIR
+
+cat > test.pl <<-EOPERL
+	use IO::Socket;
+	my \$s = IO::Socket::INET->new(
+	    Proto => "tcp",
+	    PeerAddr => "$dest",
+	    PeerPort => $tcpport,
+	    Timeout => 3);
+	die "Could not connect to host $dest port $tcpport" unless \$s;
+	print \$s "testing state machine transitions";
+	close \$s;
+EOPERL
+
+$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+	ipsend = tcpsend = ipreceive = tcpreceive = 0;
+	connreq = connest = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+    args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+	ipsend++;
+}
+
+tcp:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+    args[4]->tcp_dport == $tcpport/
+{
+	tcpsend++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+    args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+	ipreceive++;
+}
+
+tcp:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+    args[4]->tcp_sport == $tcpport/
+{
+	tcpreceive++;
+}
+
+tcp:::state-change
+{
+	state_event[args[3]->tcps_state]++;
+}
+
+tcp:::connect-request
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->tcp_dport == $tcpport/
+{
+	connreq++;
+}
+
+tcp:::connect-established
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->tcp_sport == $tcpport/
+{
+	connest++;
+}
+
+END
+{
+	printf("Minimum TCP events seen\n\n");
+	printf("ip:::send - %s\n", ipsend >= 4 ? "yes" : "no");
+	printf("ip:::receive - %s\n", ipreceive >= 3 ? "yes" : "no");
+	printf("tcp:::send - %s\n", tcpsend >= 4 ? "yes" : "no");
+	printf("tcp:::receive - %s\n", tcpreceive >= 3 ? "yes" : "no");
+	printf("tcp:::state-change to syn-sent - %s\n",
+	    state_event[TCP_STATE_SYN_SENT] >=1 ? "yes" : "no");
+	printf("tcp:::state-change to established - %s\n",
+	    state_event[TCP_STATE_ESTABLISHED] >= 1 ? "yes" : "no");
+	printf("tcp:::state-change to fin-wait-1 - %s\n",
+	    state_event[TCP_STATE_FIN_WAIT_1] >= 1 ? "yes" : "no");
+	printf("tcp:::state-change to fin-wait-2 - %s\n",
+	    state_event[TCP_STATE_FIN_WAIT_2] >= 1 ? "yes" : "no");
+	printf("tcp:::state-change to time-wait - %s\n",
+	    state_event[TCP_STATE_TIME_WAIT] >= 1 ? "yes" : "no");
+	printf("tcp:::connect-request - %s\n",
+	    connreq >=1 ? "yes" : "no");
+	printf("tcp:::connect-established - %s\n",
+	    connest >=1 ? "yes" : "no");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $status

File usr/src/cmd/dtrace/test/tst/common/ip/tst.remotetcpstate.ksh.out

+Minimum TCP events seen
+
+ip:::send - yes
+ip:::receive - yes
+tcp:::send - yes
+tcp:::receive - yes
+tcp:::state-change to syn-sent - yes
+tcp:::state-change to established - yes
+tcp:::state-change to fin-wait-1 - yes
+tcp:::state-change to close-wait - yes
+tcp:::state-change to fin-wait-2 - yes
+tcp:::state-change to time-wait - yes
+tcp:::connect-request - yes
+tcp:::connect-established - yes
+

File usr/src/lib/libdtrace/Makefile.com

 # CDDL HEADER END
 #
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
+# Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
 #
 #
 
 	scsi.d \
 	srp.d \
 	sysevent.d \
+	tcp.d \
+	udp.d \
 	unistd.d
 
 include ../../Makefile.lib
 CLEANFILES += ../common/errno.d ../common/signal.d
 CLEANFILES += ../common/dt_errtags.c ../common/dt_names.c
 CLEANFILES += ../common/sysevent.sed ../common/sysevent.d
+CLEANFILES += ../common/tcp.sed ../common/tcp.d
+CLEANFILES += ../common/udp.sed ../common/udp.d
 
 CLOBBERFILES += drti.o
 
 ../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
+	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 > $@
+
 pics/%.o: ../$(MACH)/%.c
 	$(COMPILE.c) -o $@ $<
 	$(POST_PROCESS_O)

File usr/src/lib/libdtrace/common/dt_open.c

  */
 
 /*
- * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <sys/types.h>
 #include <sys/modctl.h>
 #include <sys/systeminfo.h>
 #define	DT_VERS_1_6	DT_VERSION_NUMBER(1, 6, 0)
 #define	DT_VERS_1_6_1	DT_VERSION_NUMBER(1, 6, 1)
 #define	DT_VERS_1_6_2	DT_VERSION_NUMBER(1, 6, 2)
-#define	DT_VERS_LATEST	DT_VERS_1_6_2
-#define	DT_VERS_STRING	"Sun D 1.6.2"
+#define	DT_VERS_1_6_3	DT_VERSION_NUMBER(1, 6, 3)
+#define	DT_VERS_LATEST	DT_VERS_1_6_3
+#define	DT_VERS_STRING	"Sun D 1.6.3"
 
 const dt_version_t _dtrace_versions[] = {
 	DT_VERS_1_0,	/* D API 1.0.0 (PSARC 2001/466) Solaris 10 FCS */
 	DT_VERS_1_6,	/* D API 1.6 */
 	DT_VERS_1_6_1,	/* D API 1.6.1 */
 	DT_VERS_1_6_2,	/* D API 1.6.2 */
+	DT_VERS_1_6_3,	/* D API 1.6.3 */
 	0
 };
 

File usr/src/lib/libdtrace/common/ip.d.in

  * CDDL HEADER END
  */
 /*
- * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
 #pragma D depends_on module ip
 } pktinfo_t;
 
 /*
- * csinfo is where connection state info can be made available if
- * connection IDs become supported by the kernel in the future.
- * The cs_addr member is currently always NULL.
+ * csinfo is where connection state info is made available.
  */
 typedef struct csinfo {
 	uintptr_t cs_addr;
+	uint64_t cs_cid;
+	pid_t cs_pid;
+	zoneid_t cs_zoneid;
 } csinfo_t;
 
 /*
  */
 typedef ill_t __dtrace_ipsr_ill_t;
 
+/*
+ * __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.
+ * 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
+ * details of TCP fusion.
+ */
+typedef void * __dtrace_tcp_void_ip_t;
+
 #pragma D binding "1.5" translator
 translator pktinfo_t < mblk_t *M > {
 	pkt_addr = NULL;
 	cs_addr = NULL;
 };
 
+#pragma D binding "1.6.3" translator
+translator csinfo_t < ip_xmit_attr_t *C > {
+	cs_addr = (uintptr_t)C;
+	cs_cid = C ? C->ixa_conn_id : NULL;
+	cs_pid = C ? C->ixa_cpid : -1;
+	cs_zoneid = C ?
+	    (C->ixa_ipst == NULL || C->ixa_ipst->ips_netstack == NULL ||
+	    C->ixa_ipst->ips_netstack->netstack_stackid ==
+	    @GLOBAL_NETSTACKID@ ||
+	    C->ixa_cred == NULL ||
+	    C->ixa_cred->cr_zone == NULL ||
+	    C->ixa_cred->cr_uid == -1 ?
+	    C->ixa_zoneid : C->ixa_cred->cr_zone->zone_id) : -1;
+};
+
 #pragma D binding "1.5" translator
 translator ipinfo_t < ipha_t *I > {
 	ip_ver = I->ipha_version_and_hdr_length >> 4;
 	if_addr = (uintptr_t)I;
 };
 
+/*
+ * Translate to an ipinfo_t * from either the non-NULL void_ip_t * passed in,
+ * or use arg3 (tcp_t *) to fabricate ip header info.
+ */
+#pragma D binding "1.6.3" translator
+translator ipinfo_t < __dtrace_tcp_void_ip_t *I > {
+	ip_ver = I != NULL ? *(uint8_t *)I >> 4 :
+	    arg3 != NULL ? ((tcp_t *)arg3)->tcp_connp->conn_ipversion : 0;
+	ip_plength =
+	    I != NULL && *(uint8_t *)I >> 4 == 4 ?
+	    ntohs(((ipha_t *)I)->ipha_length) -
+	    ((((ipha_t *)I)->ipha_version_and_hdr_length & 0xf) << 2) :
+	    I != NULL && *(uint8_t *)I >> 4 == 6 ?
+	    ntohs(((ip6_t *)I)->ip6_ctlun.ip6_un1.ip6_un1_plen) :
+	    I != NULL ? 0 :
+	    arg3 != NULL && probename == "send" ?
+	    ((tcp_t *)arg3)->tcp_last_sent_len + @TCP_MIN_HEADER_LENGTH@ :
+	    arg3 != NULL && probename == "receive" ?
+	    ((tcp_t *)arg3)->tcp_last_recv_len + @TCP_MIN_HEADER_LENGTH@ :
+	    0;
+	ip_saddr =
+	    I != NULL && *(uint8_t *)I >> 4 == 4 ?
+	    inet_ntoa(&((ipha_t *)I)->ipha_src) :
+	    I != NULL && *(uint8_t *)I >> 4 == 6 ?
+	    inet_ntoa6(&((ip6_t *)I)->ip6_src) :
+	    I != NULL ? "<unknown>" :
+	    arg3 != NULL && probename == "send" ?
+	    inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_laddr):
+	    arg3 != NULL && probename == "receive" ?
+	    inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_faddr):
+	    "<unknown>";
+	ip_daddr =
+	    I != NULL && *(uint8_t *)I >> 4 == 4 ?
+	    inet_ntoa(&((ipha_t *)I)->ipha_dst) :
+	    I != NULL && *(uint8_t *)I >> 4 == 6 ?
+	    inet_ntoa6(&((ip6_t *)I)->ip6_dst) :
+	    I != NULL ? "<unknown>" :
+	    arg3 != NULL && probename == "send" ?
+	    inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_faddr):
+	    arg3 != NULL && probename == "receive" ?
+	    inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_laddr):
+	    "<unknown>";
+};
+
 #pragma D binding "1.5" translator
 translator ipv4info_t < ipha_t *I > {
 	ipv4_ver = I != NULL ? I->ipha_version_and_hdr_length >> 4 : 0;

File usr/src/lib/libdtrace/common/ip.sed.in

  * CDDL HEADER END
  */
 /*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * This file is a sed script which is first preprocessed by cpp or cc -E to
  * define a set of sed directives which replace #define tokens with their
  * Refer to the rules in libdtrace/Makefile.com for more information.
  */
 
+#include <sys/netstack.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <inet/ip.h>
+#include <inet/tcp.h>
 
 #define	SED_REPLACE(x)	s/#x/x/g
 
 SED_REPLACE(IPPROTO_SCTP)
 SED_REPLACE(IPPROTO_RAW)
 SED_REPLACE(IPPROTO_MAX)
+
+SED_REPLACE(TCP_MIN_HEADER_LENGTH)
+
+SED_REPLACE(GLOBAL_NETSTACKID)

File usr/src/lib/libdtrace/common/tcp.d.in