summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorbrendan <none@none>2008-06-13 19:06:55 -0700
committerbrendan <none@none>2008-06-13 19:06:55 -0700
commit10e6dadfe63181edabc58c8f42e3c56a1cd9ec95 (patch)
tree95d4edf9068228f58a3abddd6b718c98d6f0b919 /usr/src
parent90bcde942a3919300ffc73f98ea903b58386c395 (diff)
downloadillumos-joyent-10e6dadfe63181edabc58c8f42e3c56a1cd9ec95.tar.gz
PSARC 2008/302 DTrace IP Provider
6640019 DTrace IP Provider 6655707 sdt arguments are off-by-one past the 5th 6667364 /usr/demo/dtrace/index.html: URLs to dtrace guide chapters wrong --HG-- rename : usr/src/lib/libdtrace/common/net.d => deleted_files/usr/src/lib/libdtrace/common/net.d
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/dtrace/demo/Makefile2
-rw-r--r--usr/src/cmd/dtrace/demo/chapters93
-rwxr-xr-xusr/src/cmd/dtrace/demo/ip/ipio.d52
-rwxr-xr-xusr/src/cmd/dtrace/demo/ip/ipproto.d45
-rwxr-xr-xusr/src/cmd/dtrace/demo/mkdemo.pl12
-rw-r--r--usr/src/cmd/dtrace/test/tst/Makefile.com6
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl104
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl88
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh70
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out6
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh111
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out5
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh82
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out5
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh81
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out3
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh114
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out5
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh82
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out4
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh82
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out6
-rwxr-xr-xusr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh88
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out3
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c45
-rw-r--r--usr/src/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d61
-rw-r--r--usr/src/lib/libdtrace/Makefile.com6
-rw-r--r--usr/src/lib/libdtrace/common/ip.d.in283
-rw-r--r--usr/src/lib/libdtrace/common/ip.sed.in34
-rw-r--r--usr/src/lib/libdtrace/common/net.d.in (renamed from usr/src/lib/libdtrace/common/net.d)7
-rw-r--r--usr/src/lib/libdtrace/common/net.sed.in41
-rw-r--r--usr/src/pkgdefs/SUNWdtrc/prototype_com4
-rw-r--r--usr/src/pkgdefs/SUNWdtrt/prototype_com22
-rw-r--r--usr/src/uts/common/dtrace/sdt_subr.c16
-rw-r--r--usr/src/uts/common/inet/ip.h7
-rw-r--r--usr/src/uts/common/inet/ip/ip.c88
-rw-r--r--usr/src/uts/common/inet/ip/ip6.c69
-rw-r--r--usr/src/uts/common/inet/ip/ip_multi.c7
-rw-r--r--usr/src/uts/common/inet/ip/ip_netinfo.c11
-rw-r--r--usr/src/uts/common/inet/ip_impl.h6
-rw-r--r--usr/src/uts/common/inet/tcp/tcp.c27
-rw-r--r--usr/src/uts/common/inet/udp/udp.c6
-rw-r--r--usr/src/uts/common/netinet/in.h6
-rw-r--r--usr/src/uts/common/sys/sdt.h59
-rw-r--r--usr/src/uts/common/sys/socket.h6
-rw-r--r--usr/src/uts/common/sys/uadmin.h1
-rw-r--r--usr/src/uts/common/syscall/uadmin.c11
-rw-r--r--usr/src/uts/intel/dtrace/sdt.c75
48 files changed, 1964 insertions, 83 deletions
diff --git a/usr/src/cmd/dtrace/demo/Makefile b/usr/src/cmd/dtrace/demo/Makefile
index 2e5ef38d73..6828271b06 100644
--- a/usr/src/cmd/dtrace/demo/Makefile
+++ b/usr/src/cmd/dtrace/demo/Makefile
@@ -52,6 +52,8 @@ DFILES = \
iosnoop.d \
iothrough.d \
iotime.d \
+ ipio.d \
+ ipproto.d \
iprb.d \
kstat.d \
ksyms.d \
diff --git a/usr/src/cmd/dtrace/demo/chapters b/usr/src/cmd/dtrace/demo/chapters
index a2015d2544..09a277af7e 100644
--- a/usr/src/cmd/dtrace/demo/chapters
+++ b/usr/src/cmd/dtrace/demo/chapters
@@ -1,110 +1,115 @@
name: book
title: Solaris Dynamic Tracing Guide
-number: 0
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 0
+url: http://wikis.sun.com/display/DTrace/Documentation
name: act
title: Actions and Subroutines
-number: 10
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 10
+url: http://wikis.sun.com/display/DTrace/Actions+and+Subroutines
name: agg
title: Aggregations
-number: 9
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 9
+url: http://wikis.sun.com/display/DTrace/Aggregations
name: anon
title: Anonymous Tracing
-number: 34
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 34
+url: http://wikis.sun.com/display/DTrace/Anonymous+Tracing
name: buf
title: Buffers and Buffering
-number: 11
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 11
+url: http://wikis.sun.com/display/DTrace/Buffers+and+Buffering
name: dtrace
title: dtrace Provider
-number: 17
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 17
+url: http://wikis.sun.com/display/DTrace/dtrace+Provider
name: fbt
title: fbt Provider
-number: 20
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 20
+url: http://wikis.sun.com/display/DTrace/fbt+Provider
name: intro
title: Introduction
-number: 1
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 1
+url: http://wikis.sun.com/display/DTrace/Introduction
name: io
title: io Provider
-number: 27
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 27
+url: http://wikis.sun.com/display/DTrace/io+Provider
name: lockstat
title: lockstat Provider
-number: 18
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 18
+url: http://wikis.sun.com/display/DTrace/lockstat+Provider
name: out
title: Output Formatting
-number: 12
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 12
+url: http://wikis.sun.com/display/DTrace/Output+Formatting
name: proc
title: proc Provider
-number: 25
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 25
+url: http://wikis.sun.com/display/DTrace/proc+Provider
name: profile
title: profile Provider
-number: 19
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 19
+url: http://wikis.sun.com/display/DTrace/profile+Provider
name: sched
title: sched Provider
-number: 26
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 26
+url: http://wikis.sun.com/display/DTrace/sched+Provider
name: script
title: Scripting
-number: 15
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 15
+url: http://wikis.sun.com/display/DTrace/Scripting
name: sdt
title: sdt Provider
-number: 22
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 22
+url: http://wikis.sun.com/display/DTrace/sdt+Provider
name: spec
title: Speculative Tracing
-number: 13
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 13
+url: http://wikis.sun.com/display/DTrace/Speculative+Tracing
name: struct
title: Structs and Unions
-number: 7
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 7
+url: http://wikis.sun.com/display/DTrace/Structs+and+Unions
name: sysinfo
title: sysinfo Provider
-number: 23
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 23
+url: http://wikis.sun.com/display/DTrace/sysinfo+Provider
name: user
title: User Process Tracing
-number: 32
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 32
+url: http://wikis.sun.com/display/DTrace/User+Process+Tracing
name: vars
title: Variables
-number: 3
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 3
+url: http://wikis.sun.com/display/DTrace/Variables
name: vminfo
title: vminfo Provider
-number: 24
-url: http://docs.sun.com/db/doc/817-6223?a=view
+index: 24
+url: http://wikis.sun.com/display/DTrace/vminfo+Provider
+
+name: ip
+title: ip Provider
+index: 101
+url: http://wikis.sun.com/display/DTrace/ip+Provider
diff --git a/usr/src/cmd/dtrace/demo/ip/ipio.d b/usr/src/cmd/dtrace/demo/ip/ipio.d
new file mode 100755
index 0000000000..0a7cc6f390
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/ip/ipio.d
@@ -0,0 +1,52 @@
+/*
+ * 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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma D option quiet
+#pragma D option switchrate=10hz
+
+dtrace:::BEGIN
+{
+ printf(" %3s %10s %15s %15s %8s %6s\n", "CPU", "DELTA(us)",
+ "SOURCE", "DEST", "INT", "BYTES");
+ last = timestamp;
+}
+
+ip:::send
+{
+ this->elapsed = (timestamp - last) / 1000;
+ printf(" %3d %10d %15s -> %15s %8s %6d\n", cpu, this->elapsed,
+ args[2]->ip_saddr, args[2]->ip_daddr, args[3]->if_name,
+ args[2]->ip_plength);
+ last = timestamp;
+}
+
+ip:::receive
+{
+ this->elapsed = (timestamp - last) / 1000;
+ printf(" %3d %10d %15s <- %15s %8s %6d\n", cpu, this->elapsed,
+ args[2]->ip_daddr, args[2]->ip_saddr, args[3]->if_name,
+ args[2]->ip_plength);
+ last = timestamp;
+}
diff --git a/usr/src/cmd/dtrace/demo/ip/ipproto.d b/usr/src/cmd/dtrace/demo/ip/ipproto.d
new file mode 100755
index 0000000000..f5f3656e58
--- /dev/null
+++ b/usr/src/cmd/dtrace/demo/ip/ipproto.d
@@ -0,0 +1,45 @@
+/*
+ * 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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma D option quiet
+
+dtrace:::BEGIN
+{
+ printf("Tracing... Hit Ctrl-C to end.\n");
+}
+
+ip:::send,
+ip:::receive
+{
+ this->protostr = args[2]->ip_ver == 4 ?
+ args[4]->ipv4_protostr : args[5]->ipv6_nextstr;
+ @num[args[2]->ip_saddr, args[2]->ip_daddr, this->protostr] = count();
+}
+
+dtrace:::END
+{
+ printf(" %-28s %-28s %6s %8s\n", "SADDR", "DADDR", "PROTO", "COUNT");
+ printa(" %-28s %-28s %6s %@8d\n", @num);
+}
diff --git a/usr/src/cmd/dtrace/demo/mkdemo.pl b/usr/src/cmd/dtrace/demo/mkdemo.pl
index 9c3919850b..f2bc3ec7dc 100755
--- a/usr/src/cmd/dtrace/demo/mkdemo.pl
+++ b/usr/src/cmd/dtrace/demo/mkdemo.pl
@@ -20,7 +20,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -90,7 +90,7 @@ sub chaps_read {
}
sub chaps_ascending {
- $chaps{$a}{number} <=> $chaps{$b}{number};
+ $chaps{$a}{index} <=> $chaps{$b}{index};
}
sub demo_process {
@@ -108,9 +108,9 @@ sub demo_process {
print OUT <<EOF;
*
* This D script is used as an example in the Solaris Dynamic Tracing Guide
- * in Chapter $chaps{$chap}{number}, \"$chaps{$chap}{title}\".
+ * wiki in the \"$chaps{$chap}{title}\" Chapter.
*
- * The full text of Chapter $chaps{$chap}{number} may be found here:
+ * The full text of the this chapter may be found here:
*
* $chaps{$chap}{url}
*
@@ -123,6 +123,9 @@ sub demo_process {
EOF
}
}
+
+ close (DEMO);
+ close (OUT);
}
sub demo_find {
@@ -187,7 +190,6 @@ sub chaps_process {
print HTML "<tr>\n";
print HTML "<td align=left>";
print HTML "<a href=\"$chaps{$chap}{url}\">";
- print HTML "Chapter $chaps{$chap}{number}: ";
print HTML "$chaps{$chap}{title}</a></td>\n";
print HTML "<td><table border=0>\n";
diff --git a/usr/src/cmd/dtrace/test/tst/Makefile.com b/usr/src/cmd/dtrace/test/tst/Makefile.com
index da818f4246..a23b8d65a8 100644
--- a/usr/src/cmd/dtrace/test/tst/Makefile.com
+++ b/usr/src/cmd/dtrace/test/tst/Makefile.com
@@ -42,9 +42,11 @@ DSRCS :sh= find . -name SCCS -prune -o -name *.d -print | cut -b3-
TSTS :sh= find . -name tst.*.d -o -name err.*.d -o \
-name tst.*.d.out -o -name err.*.d.out -o -name tst.*.ksh \
- -o -name err.*.ksh -o -name tst.*.ksh.out -o -name drp.*.d
+ -o -name err.*.ksh -o -name tst.*.ksh.out -o -name drp.*.d \
+ -o -name get.*.pl
-EXES :sh= find . -name SCCS -prune -o -name *.exe -print | cut -b3-
+EXES :sh= find . -name SCCS -prune -o \( -name *.exe -o -name \*.pl \) -print \
+ | cut -b3-
EXES += $(CSRCS:%.c=%.exe)
EXES += $(SSRCS:%.s=%.exe)
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl b/usr/src/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl
new file mode 100755
index 0000000000..fb41255473
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/get.ipv4remote.pl
@@ -0,0 +1,104 @@
+#!/usr/bin/perl -w
+#
+# 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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# get.ipv4remote.pl [tcpport]
+#
+# Find an IPv4 reachable remote host using both ifconfig(1M) and ping(1M).
+# If a tcpport is specified, return a host that is also listening on this
+# TCP port. Print the local address and the remote address, or an
+# error message if no suitable remote host was found. Exit status is 0 if
+# a host was found.
+#
+
+use strict;
+use IO::Socket;
+
+my $MAXHOSTS = 32; # max hosts to port scan
+my $TIMEOUT = 3; # connection timeout
+my $tcpport = @ARGV == 1 ? $ARGV[0] : 0;
+
+#
+# Determine local IP address
+#
+my $local = "";
+my $remote = "";
+my %Broadcast;
+my $up;
+open IFCONFIG, '/usr/sbin/ifconfig -a |' or die "Couldn't run ifconfig: $!\n";
+while (<IFCONFIG>) {
+ next if /^lo/;
+
+ # "UP" is always printed first (see print_flags() in ifconfig.c):
+ $up = 1 if /^[a-z].*<UP,/;
+ $up = 0 if /^[a-z].*<,/;
+
+ # assume output is "inet X ... broadcast Z":
+ if (/inet (\S+) .* broadcast (\S+)/) {
+ my ($addr, $bcast) = ($1, $2);
+ $Broadcast{$addr} = $bcast;
+ $local = $addr if $up and $local eq "";
+ $up = 0;
+ }
+}
+close IFCONFIG;
+die "Could not determine local IP address" if $local eq "";
+
+#
+# Find the first remote host that responds to an icmp echo,
+# which isn't a local address.
+#
+open PING, "/usr/sbin/ping -ns $Broadcast{$local} 56 $MAXHOSTS |" or
+ die "Couldn't run ping: $!\n";
+while (<PING>) {
+ if (/bytes from (.*): / and not defined $Broadcast{$1}) {
+ my $addr = $1;
+
+ if ($tcpport != 0) {
+ #
+ # Test TCP
+ #
+ my $socket = IO::Socket::INET->new(
+ Proto => "tcp",
+ PeerAddr => $addr,
+ PeerPort => $tcpport,
+ Timeout => $TIMEOUT,
+ );
+ next unless $socket;
+ close $socket;
+ }
+
+ $remote = $addr;
+ last;
+ }
+}
+close PING;
+die "Can't find a remote host for testing: No suitable response from " .
+ "$Broadcast{$local}\n" if $remote eq "";
+
+print "$local $remote\n";
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl b/usr/src/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl
new file mode 100755
index 0000000000..051ab8c3c3
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/get.ipv6remote.pl
@@ -0,0 +1,88 @@
+#!/usr/bin/perl -w
+#
+# 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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# get.ipv6remote.pl
+#
+# Find an IPv6 reachable remote host using both ifconfig(1M) and ping(1M).
+# Print the local address and the remote address, or print nothing if either
+# no IPv6 interfaces or remote hosts were found. (Remote IPv6 testing is
+# considered optional, and so not finding another IPv6 host is not an error
+# state we need to log.) Exit status is 0 if a host was found.
+#
+
+use strict;
+use IO::Socket;
+
+my $MAXHOSTS = 32; # max hosts to scan
+my $TIMEOUT = 3; # connection timeout
+my $MULTICAST = "FF02::1"; # IPv6 multicast address
+
+#
+# Determine local IP address
+#
+my $local = "";
+my $remote = "";
+my %Local;
+my $up;
+open IFCONFIG, '/usr/sbin/ifconfig -a inet6 |'
+ or die "Couldn't run ifconfig: $!\n";
+while (<IFCONFIG>) {
+ next if /^lo/;
+
+ # "UP" is always printed first (see print_flags() in ifconfig.c):
+ $up = 1 if /^[a-z].*<UP,/;
+ $up = 0 if /^[a-z].*<,/;
+
+ # assume output is "inet6 ...":
+ if (m:inet6 (\S+)/:) {
+ my $addr = $1;
+ $Local{$addr} = 1;
+ $local = $addr if $up and $local eq "";
+ $up = 0;
+ }
+}
+close IFCONFIG;
+exit 1 if $local eq "";
+
+#
+# Find the first remote host that responds to an icmp echo,
+# which isn't a local address.
+#
+open PING, "/usr/sbin/ping -ns -A inet6 $MULTICAST 56 $MAXHOSTS |" or
+ die "Couldn't run ping: $!\n";
+while (<PING>) {
+ if (/bytes from (.*): / and not defined $Local{$1}) {
+ $remote = $1;
+ last;
+ }
+}
+close PING;
+exit 2 if $remote eq "";
+
+print "$local $remote\n";
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh
new file mode 100755
index 0000000000..0965040e62
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh
@@ -0,0 +1,70 @@
+#!/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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv4 ICMP to a local address.
+#
+# 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. Unrelated ICMP on lo0 traced by accident.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=127.0.0.1
+
+$dtrace -c "/usr/sbin/ping $local 3" -qs /dev/stdin <<EOF | sort -n
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_ICMP/
+{
+ printf("1 ip:::send (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[4]: %d %d %d %d %d)\n",
+ args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags,
+ args[4]->ipv4_offset, args[4]->ipv4_ttl);
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_ICMP/
+{
+ printf("2 ip:::receive (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[4]: %d %d %d %d %d)\n",
+ args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags,
+ args[4]->ipv4_offset, args[4]->ipv4_ttl);
+}
+EOF
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out
new file mode 100644
index 0000000000..41d6e0c8ad
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localicmp.ksh.out
@@ -0,0 +1,6 @@
+
+1 ip:::send (args[2]: 4 64, args[4]: 4 84 0 0 255)
+1 ip:::send (args[2]: 4 64, args[4]: 4 84 0 0 255)
+2 ip:::receive (args[2]: 4 64, args[4]: 4 84 0 0 255)
+2 ip:::receive (args[2]: 4 64, args[4]: 4 84 0 0 255)
+127.0.0.1 is alive
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh
new file mode 100755
index 0000000000..32ed78b47f
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh
@@ -0,0 +1,111 @@
+#!/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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv4 TCP to a remote host.
+#
+# 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 and checks that at least the
+# following packet counts were traced:
+#
+# 3 x ip:::send (2 during the TCP handshake, then a FIN)
+# 2 x ip:::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.
+#
+# 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;
+ close \$s;
+EOPERL
+
+$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ send = receive = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ send++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ receive++;
+}
+
+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");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $status
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out
new file mode 100644
index 0000000000..18ed9477a0
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localtcp.ksh.out
@@ -0,0 +1,5 @@
+Minimum TCP events seen
+
+ip:::send - yes
+ip:::receive - yes
+
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh
new file mode 100755
index 0000000000..6ffc9bc3b2
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh
@@ -0,0 +1,82 @@
+#!/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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv4 UDP to a local address.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. No physical network interface is plumbed and up.
+# 3. No other hosts on this subnet are reachable and listening on rpcbind.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test sends a UDP message using ping and checks that at least the
+# following counts were traced:
+#
+# 1 x ip:::send (UDP sent to ping's base UDP port)
+# 1 x ip:::receive (UDP received)
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=127.0.0.1
+
+$dtrace -c "/usr/sbin/ping -U $local" -qs /dev/stdin <<EOF | grep -v 'is alive'
+BEGIN
+{
+ send = receive = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_UDP/
+{
+ send++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[4]->ipv4_protocol == IPPROTO_UDP/
+{
+ receive++;
+}
+
+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");
+}
+EOF
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out
new file mode 100644
index 0000000000..eef72522ae
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4localudp.ksh.out
@@ -0,0 +1,5 @@
+Minimum UDP events seen
+
+ip:::send - yes
+ip:::receive - yes
+
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh
new file mode 100755
index 0000000000..efe0d30fa9
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh
@@ -0,0 +1,81 @@
+#!/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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv4 ICMP to a remote host.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. No physical network interface is plumbed and up.
+# 3. No other hosts on this subnet are reachable.
+# 4. An unrelated ICMP between these hosts was traced by accident.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv4remote.pl
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr | read source dest
+if (( $? != 0 )); then
+ exit 4
+fi
+
+$dtrace -c "/usr/sbin/ping $dest 3" -qs /dev/stdin <<EOF | \
+ grep -v 'is alive' | sort -n
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->ipv4_protocol == IPPROTO_ICMP/
+{
+ printf("1 ip:::send (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[4]: %d %d %d %d %d)\n",
+ args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags,
+ args[4]->ipv4_offset, args[4]->ipv4_ttl);
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->ipv4_protocol == IPPROTO_ICMP/
+{
+ printf("2 ip:::receive (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[4]: %d %d %d %d %d)\n",
+ args[4]->ipv4_ver, args[4]->ipv4_length, args[4]->ipv4_flags,
+ args[4]->ipv4_offset, args[4]->ipv4_ttl);
+}
+EOF
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out
new file mode 100644
index 0000000000..b5915f8db4
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteicmp.ksh.out
@@ -0,0 +1,3 @@
+
+1 ip:::send (args[2]: 4 64, args[4]: 4 84 0 0 255)
+2 ip:::receive (args[2]: 4 64, args[4]: 4 84 4 0 255)
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh
new file mode 100755
index 0000000000..b55515287a
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh
@@ -0,0 +1,114 @@
+#!/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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv4 TCP to a remote host.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. No physical network interface is plumbed and up.
+# 3. No other hosts on this subnet are reachable and listening on ssh.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test performs a TCP connection and checks that at least the
+# following packet counts were traced:
+#
+# 3 x ip:::send (2 during the TCP handshake, then a FIN)
+# 2 x ip:::receive (1 during the TCP handshake, then the FIN ACK)
+#
+
+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;
+ close \$s;
+EOPERL
+
+$dtrace -c '/usr/bin/perl test.pl' -qs /dev/stdin <<EODTRACE
+BEGIN
+{
+ send = receive = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ send++;
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[4]->ipv4_protocol == IPPROTO_TCP/
+{
+ receive++;
+}
+
+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");
+}
+EODTRACE
+
+status=$?
+
+cd /
+/usr/bin/rm -rf $DIR
+
+exit $?
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out
new file mode 100644
index 0000000000..18ed9477a0
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remotetcp.ksh.out
@@ -0,0 +1,5 @@
+Minimum TCP events seen
+
+ip:::send - yes
+ip:::receive - yes
+
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh
new file mode 100755
index 0000000000..0e82fd8621
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh
@@ -0,0 +1,82 @@
+#!/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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv4 UDP to a remote host.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. No physical network interface is plumbed and up.
+# 3. No other hosts on this subnet are reachable and listening on rpcbind.
+# 4. An unlikely race causes the unlocked global send/receive
+# variables to be corrupted.
+#
+# This test sends a UDP message using ping and checks that at least the
+# following counts were traced:
+#
+# 1 x ip:::send (UDP sent to ping's base UDP port)
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv4remote.pl
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr | read source dest
+if (( $? != 0 )); then
+ exit 4
+fi
+
+$dtrace -c "/usr/sbin/ping -U $dest" -qs /dev/stdin <<EOF | grep -v 'is alive'
+BEGIN
+{
+ send = 0;
+}
+
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[4]->ipv4_protocol == IPPROTO_UDP/
+{
+ send++;
+}
+
+END
+{
+ printf("Minimum UDP events seen\n\n");
+ printf("ip:::send - %s\n", send >= 1 ? "yes" : "no");
+}
+EOF
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out
new file mode 100644
index 0000000000..71de28cebe
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv4remoteudp.ksh.out
@@ -0,0 +1,4 @@
+Minimum UDP events seen
+
+ip:::send - yes
+
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh
new file mode 100755
index 0000000000..5912ee7c8e
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh
@@ -0,0 +1,82 @@
+#!/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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv6 ICMP to a local address. This creates a
+# temporary lo0/inet6 interface if one doesn't already exist.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. Unrelated ICMPv6 on lo0 traced by accident.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+local=::1
+
+if ! ifconfig lo0 inet6 > /dev/null 2>&1; then
+ if ! ifconfig lo0 inet6 plumb up; then
+ print -u2 "could not plumb lo0 inet6 for testing"
+ exit 3
+ fi
+ removeinet6=1
+else
+ removeinet6=0
+fi
+
+$dtrace -c "/usr/sbin/ping -A inet6 $local 3" -qs /dev/stdin <<EOF | sort -n
+ip:::send
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/
+{
+ printf("1 ip:::send (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[5]: %d %d %d)\n",
+ args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen);
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$local" && args[2]->ip_daddr == "$local" &&
+ args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/
+{
+ printf("2 ip:::receive (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[5]: %d %d %d)\n",
+ args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen);
+}
+EOF
+
+if (( removeinet6 )); then
+ ifconfig lo0 inet6 unplumb
+fi
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out
new file mode 100644
index 0000000000..529d251fa0
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6localicmp.ksh.out
@@ -0,0 +1,6 @@
+
+::1 is alive
+1 ip:::send (args[2]: 6 64, args[5]: 6 0 64)
+1 ip:::send (args[2]: 6 64, args[5]: 6 0 64)
+2 ip:::receive (args[2]: 6 64, args[5]: 6 0 64)
+2 ip:::receive (args[2]: 6 64, args[5]: 6 0 64)
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh
new file mode 100755
index 0000000000..b94b784397
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh
@@ -0,0 +1,88 @@
+#!/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 2008 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#
+# Test ip:::{send,receive} of IPv6 ICMP to a remote host. This test is
+# skipped if there are no physical interfaces configured with IPv6, or no
+# other IPv6 hosts are reachable.
+#
+# This may fail due to:
+#
+# 1. A change to the ip stack breaking expected probe behavior,
+# which is the reason we are testing.
+# 2. An unrelated ICMPv6 between these hosts was traced by accident.
+#
+
+if (( $# != 1 )); then
+ print -u2 "expected one argument: <dtrace-path>"
+ exit 2
+fi
+
+dtrace=$1
+getaddr=./get.ipv6remote.pl
+
+if [[ ! -x $getaddr ]]; then
+ print -u2 "could not find or execute sub program: $getaddr"
+ exit 3
+fi
+$getaddr | read source dest
+if (( $? != 0 )); then
+ print -nu2 "Could not find a local IPv6 interface and a remote IPv6 "
+ print -u2 "host. Aborting test.\n"
+ print -nu2 "For this test to continue, a \"ping -ns -A inet6 FF02::1\" "
+ print -u2 "must respond with a\nremote IPv6 host."
+ exit 3
+fi
+
+#
+# Shake loose any ICMPv6 Neighbor advertisement messages before tracing.
+#
+/usr/sbin/ping $dest 3 > /dev/null 2>&1
+
+$dtrace -c "/usr/sbin/ping $dest 3" -qs /dev/stdin <<EOF | \
+ grep -v 'is alive' | sort -n
+ip:::send
+/args[2]->ip_saddr == "$source" && args[2]->ip_daddr == "$dest" &&
+ args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/
+{
+ printf("1 ip:::send (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[5]: %d %d %d)\n",
+ args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen);
+}
+
+ip:::receive
+/args[2]->ip_saddr == "$dest" && args[2]->ip_daddr == "$source" &&
+ args[5]->ipv6_nexthdr == IPPROTO_ICMPV6/
+{
+ printf("2 ip:::receive (");
+ printf("args[2]: %d %d, ", args[2]->ip_ver, args[2]->ip_plength);
+ printf("args[5]: %d %d %d)\n",
+ args[5]->ipv6_ver, args[5]->ipv6_tclass, args[5]->ipv6_plen);
+}
+EOF
diff --git a/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out
new file mode 100644
index 0000000000..1ddcd07b36
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/ip/tst.ipv6remoteicmp.ksh.out
@@ -0,0 +1,3 @@
+
+1 ip:::send (args[2]: 6 64, args[5]: 6 0 64)
+2 ip:::receive (args[2]: 6 64, args[5]: 6 0 64)
diff --git a/usr/src/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c b/usr/src/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c
new file mode 100644
index 0000000000..07635502a9
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.c
@@ -0,0 +1,45 @@
+/*
+ * 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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <unistd.h>
+#include <sys/uadmin.h>
+
+int
+main(int argc, char **argv)
+{
+ while (1) {
+ if (uadmin(A_SDTTEST, 0, 0) < 0) {
+ perror("uadmin");
+ return (1);
+ }
+
+ sleep(1);
+ }
+
+ return (0);
+}
diff --git a/usr/src/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d b/usr/src/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d
new file mode 100644
index 0000000000..0577ef6e0d
--- /dev/null
+++ b/usr/src/cmd/dtrace/test/tst/common/sdt/tst.sdtargs.d
@@ -0,0 +1,61 @@
+/*
+ * 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 2008 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * ASSERTION: Verify that argN (1..7) variables are properly remapped.
+ */
+
+BEGIN
+{
+ /* Timeout after 5 seconds */
+ timeout = timestamp + 5000000000;
+ ignore = $1;
+}
+
+sdt:::test
+/arg0 != 1 || arg1 != 2 || arg2 != 3 || arg3 != 4 || arg4 != 5 || arg5 != 6 ||
+ arg6 != 7/
+{
+ printf("sdt arg mismatch\n\n");
+ printf("args are : %d, %d, %d, %d, %d, %d, %d\n", arg0, arg1, arg2,
+ arg3, arg4, arg5, arg6);
+ printf("should be : 1, 2, 3, 4, 5, 6, 7\n");
+ exit(1);
+}
+
+sdt:::test
+{
+ exit(0);
+}
+
+profile:::tick-1
+/timestamp > timeout/
+{
+ trace("test timed out");
+ exit(1);
+}
diff --git a/usr/src/lib/libdtrace/Makefile.com b/usr/src/lib/libdtrace/Makefile.com
index d5bdccbf85..7e7a25f1ac 100644
--- a/usr/src/lib/libdtrace/Makefile.com
+++ b/usr/src/lib/libdtrace/Makefile.com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -97,6 +97,7 @@ CLEANFILES += dt_lex.c dt_grammar.c dt_grammar.h y.output
CLEANFILES += ../common/procfs.sed ../common/procfs.d
CLEANFILES += ../common/io.sed ../common/io.d
CLEANFILES += ../common/ip.sed ../common/ip.d
+CLEANFILES += ../common/net.sed ../common/net.d
CLEANFILES += ../common/errno.d ../common/signal.d
CLEANFILES += ../common/dt_errtags.c ../common/dt_names.c
CLEANFILES += ../common/sysevent.sed ../common/sysevent.d
@@ -172,6 +173,9 @@ pics/dt_lex.o pics/dt_grammar.o := CCVERBOSE =
../common/ip.d: ../common/ip.sed ../common/ip.d.in
sed -f ../common/ip.sed < ../common/ip.d.in > $@
+../common/net.d: ../common/net.sed ../common/net.d.in
+ sed -f ../common/net.sed < ../common/net.d.in > $@
+
../common/sysevent.d: ../common/sysevent.sed ../common/sysevent.d.in
sed -f ../common/sysevent.sed < ../common/sysevent.d.in > $@
diff --git a/usr/src/lib/libdtrace/common/ip.d.in b/usr/src/lib/libdtrace/common/ip.d.in
index da886eea66..a000607710 100644
--- a/usr/src/lib/libdtrace/common/ip.d.in
+++ b/usr/src/lib/libdtrace/common/ip.d.in
@@ -25,7 +25,282 @@
#pragma ident "%Z%%M% %I% %E% SMI"
-inline int AF_INET = @AF_INET@;
-#pragma D binding "1.0" AF_INET
-inline int AF_INET6 = @AF_INET6@;
-#pragma D binding "1.0" AF_INET6
+#pragma D depends_on module ip
+#pragma D depends_on provider ip
+
+inline int IPH_DF = @IPH_DF@;
+#pragma D binding "1.0" IPH_DF
+inline int IPH_MF = @IPH_MF@;
+#pragma D binding "1.0" IPH_MF
+
+#pragma D binding "1.0" IPPROTO_IP
+inline int IPPROTO_IP = @IPPROTO_IP@;
+#pragma D binding "1.0" IPPROTO_HOPOPTS
+inline int IPPROTO_HOPOPTS = @IPPROTO_HOPOPTS@;
+#pragma D binding "1.0" IPPROTO_ICMP
+inline int IPPROTO_ICMP = @IPPROTO_ICMP@;
+#pragma D binding "1.0" IPPROTO_IGMP
+inline int IPPROTO_IGMP = @IPPROTO_IGMP@;
+#pragma D binding "1.0" IPPROTO_GGP
+inline int IPPROTO_GGP = @IPPROTO_GGP@;
+#pragma D binding "1.0" IPPROTO_ENCAP
+inline int IPPROTO_ENCAP = @IPPROTO_ENCAP@;
+#pragma D binding "1.0" IPPROTO_TCP
+inline int IPPROTO_TCP = @IPPROTO_TCP@;
+#pragma D binding "1.0" IPPROTO_EGP
+inline int IPPROTO_EGP = @IPPROTO_EGP@;
+#pragma D binding "1.0" IPPROTO_PUP
+inline int IPPROTO_PUP = @IPPROTO_PUP@;
+#pragma D binding "1.0" IPPROTO_UDP
+inline int IPPROTO_UDP = @IPPROTO_UDP@;
+#pragma D binding "1.0" IPPROTO_IDP
+inline int IPPROTO_IDP = @IPPROTO_IDP@;
+#pragma D binding "1.0" IPPROTO_IPV6
+inline int IPPROTO_IPV6 = @IPPROTO_IPV6@;
+#pragma D binding "1.0" IPPROTO_ROUTING
+inline int IPPROTO_ROUTING = @IPPROTO_ROUTING@;
+#pragma D binding "1.0" IPPROTO_FRAGMENT
+inline int IPPROTO_FRAGMENT = @IPPROTO_FRAGMENT@;
+#pragma D binding "1.0" IPPROTO_RSVP
+inline int IPPROTO_RSVP = @IPPROTO_RSVP@;
+#pragma D binding "1.0" IPPROTO_ESP
+inline int IPPROTO_ESP = @IPPROTO_ESP@;
+#pragma D binding "1.0" IPPROTO_AH
+inline int IPPROTO_AH = @IPPROTO_AH@;
+#pragma D binding "1.0" IPPROTO_ICMPV6
+inline int IPPROTO_ICMPV6 = @IPPROTO_ICMPV6@;
+#pragma D binding "1.0" IPPROTO_NONE
+inline int IPPROTO_NONE = @IPPROTO_NONE@;
+#pragma D binding "1.0" IPPROTO_DSTOPTS
+inline int IPPROTO_DSTOPTS = @IPPROTO_DSTOPTS@;
+#pragma D binding "1.0" IPPROTO_HELLO
+inline int IPPROTO_HELLO = @IPPROTO_HELLO@;
+#pragma D binding "1.0" IPPROTO_ND
+inline int IPPROTO_ND = @IPPROTO_ND@;
+#pragma D binding "1.0" IPPROTO_EON
+inline int IPPROTO_EON = @IPPROTO_EON@;
+#pragma D binding "1.0" IPPROTO_OSPF
+inline int IPPROTO_OSPF = @IPPROTO_OSPF@;
+#pragma D binding "1.0" IPPROTO_PIM
+inline int IPPROTO_PIM = @IPPROTO_PIM@;
+#pragma D binding "1.0" IPPROTO_SCTP
+inline int IPPROTO_SCTP = @IPPROTO_SCTP@;
+#pragma D binding "1.0" IPPROTO_RAW
+inline int IPPROTO_RAW = @IPPROTO_RAW@;
+#pragma D binding "1.0" IPPROTO_MAX
+inline int IPPROTO_MAX = @IPPROTO_MAX@;
+
+/*
+ * pktinfo is where packet ID info can be made available for deeper
+ * analysis if packet IDs become supported by the kernel in the future.
+ * The pkt_addr member is currently always NULL.
+ */
+typedef struct pktinfo {
+ uintptr_t pkt_addr;
+} 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.
+ */
+typedef struct csinfo {
+ uintptr_t cs_addr;
+} csinfo_t;
+
+/*
+ * ipinfo contains common IP info for both IPv4 and IPv6.
+ */
+typedef struct ipinfo {
+ uint8_t ip_ver; /* IP version (4, 6) */
+ uint32_t ip_plength; /* payload length */
+ string ip_saddr; /* source address */
+ string ip_daddr; /* destination address */
+} ipinfo_t;
+
+/*
+ * ifinfo contains network interface info.
+ */
+typedef struct ifinfo {
+ string if_name; /* interface name */
+ int8_t if_local; /* is delivered locally */
+ netstackid_t if_ipstack; /* ipstack ID */
+ uintptr_t if_addr; /* pointer to raw ill_t */
+} ifinfo_t;
+
+/*
+ * ipv4info is a translated version of the IPv4 header (with raw pointer).
+ * These values are NULL if the packet is not IPv4.
+ */
+typedef struct ipv4info {
+ uint8_t ipv4_ver; /* IP version (4) */
+ uint8_t ipv4_ihl; /* header length, bytes */
+ uint8_t ipv4_tos; /* type of service field */
+ uint16_t ipv4_length; /* length (header + payload) */
+ uint16_t ipv4_ident; /* identification */
+ uint8_t ipv4_flags; /* IP flags */
+ uint16_t ipv4_offset; /* fragment offset */
+ uint8_t ipv4_ttl; /* time to live */
+ uint8_t ipv4_protocol; /* next level protocol */
+ string ipv4_protostr; /* next level protocol, as a string */
+ uint16_t ipv4_checksum; /* header checksum */
+ ipaddr_t ipv4_src; /* source address */
+ ipaddr_t ipv4_dst; /* destination address */
+ string ipv4_saddr; /* source address, string */
+ string ipv4_daddr; /* destination address, string */
+ ipha_t *ipv4_hdr; /* pointer to raw header */
+} ipv4info_t;
+
+/*
+ * ipv6info is a translated version of the IPv6 header (with raw pointer).
+ * These values are NULL if the packet is not IPv6.
+ */
+typedef struct ipv6info {
+ uint8_t ipv6_ver; /* IP version (6) */
+ uint8_t ipv6_tclass; /* traffic class */
+ uint32_t ipv6_flow; /* flow label */
+ uint16_t ipv6_plen; /* payload length */
+ uint8_t ipv6_nexthdr; /* next header protocol */
+ string ipv6_nextstr; /* next header protocol, as a string */
+ uint8_t ipv6_hlim; /* hop limit */
+ in6_addr_t *ipv6_src; /* source address */
+ in6_addr_t *ipv6_dst; /* destination address */
+ string ipv6_saddr; /* source address, string */
+ string ipv6_daddr; /* destination address, string */
+ ip6_t *ipv6_hdr; /* pointer to raw header */
+} ipv6info_t;
+
+/*
+ * void_ip_t is a void pointer to either an IPv4 or IPv6 header. It has
+ * its own type name so that a translator can be determined.
+ */
+typedef uintptr_t void_ip_t;
+
+/*
+ * __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
+ * them to an ifinfo_t.
+ */
+typedef ill_t __dtrace_ipsr_ill_t;
+
+#pragma D binding "1.0" translator
+translator pktinfo_t < mblk_t *M > {
+ pkt_addr = NULL;
+};
+
+#pragma D binding "1.0" translator
+translator csinfo_t < conn_t *C > {
+ cs_addr = NULL;
+};
+
+#pragma D binding "1.0" translator
+translator ipinfo_t < ipha_t *I > {
+ ip_ver = I->ipha_version_and_hdr_length >> 4;
+ ip_plength = ntohs(I->ipha_length) -
+ ((I->ipha_version_and_hdr_length & 0xf) << 2);
+ ip_saddr = inet_ntoa(&I->ipha_src);
+ ip_daddr = inet_ntoa(&I->ipha_dst);
+};
+
+#pragma D binding "1.0" translator
+translator ipinfo_t < ip6_t *I > {
+ ip_ver = *(uint8_t *)I >> 4;
+ ip_plength = ntohs(I->ip6_ctlun.ip6_un1.ip6_un1_plen);
+ ip_saddr = inet_ntoa6(&I->ip6_src);
+ ip_daddr = inet_ntoa6(&I->ip6_dst);
+};
+
+#pragma D binding "1.0" translator
+translator ipinfo_t < void_ip_t *I > {
+ ip_ver = I != NULL ? *(uint8_t *)I >> 4 : 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) :
+ *(uint8_t *)I >> 4 == 6 ?
+ ntohs(((ip6_t *)I)->ip6_ctlun.ip6_un1.ip6_un1_plen) : 0) : 0;
+ ip_saddr = I != NULL ? (*(uint8_t *)I >> 4 == 4 ?
+ inet_ntoa(&((ipha_t *)I)->ipha_src) : *(uint8_t *)I >> 4 == 6 ?
+ inet_ntoa6(&((ip6_t *)I)->ip6_src) : "<unknown>") : "<unknown>";
+ ip_daddr = I != NULL ? (*(uint8_t *)I >> 4 == 4 ?
+ inet_ntoa(&((ipha_t *)I)->ipha_dst) : *(uint8_t *)I >> 4 == 6 ?
+ inet_ntoa6(&((ip6_t *)I)->ip6_dst) : "<unknown>") : "<unknown>";
+};
+
+#pragma D binding "1.0" translator
+translator ifinfo_t < __dtrace_ipsr_ill_t *I > {
+ if_name = I != NULL ? stringof(I->ill_name) : "<null>";
+ if_ipstack = I != NULL ? I->ill_ipst->ips_netstack->netstack_stackid
+ : 0;
+ if_local = arg6; /* probe dependent */
+ if_addr = (uintptr_t)I;
+};
+
+#pragma D binding "1.0" translator
+translator ipv4info_t < ipha_t *I > {
+ ipv4_ver = I != NULL ? I->ipha_version_and_hdr_length >> 4 : 0;
+ ipv4_ihl = I != NULL ? (I->ipha_version_and_hdr_length & 0xf) << 2 : 0;
+ ipv4_tos = I != NULL ? I->ipha_type_of_service : 0;
+ ipv4_length = I != NULL ? ntohs(I->ipha_length) : 0;
+ ipv4_ident = I != NULL ? ntohs(I->ipha_ident) : 0;
+ ipv4_flags = I != NULL ? ntohs(I->ipha_fragment_offset_and_flags) >>
+ 12 : 0;
+ ipv4_offset = I != NULL ? ntohs(I->ipha_fragment_offset_and_flags) &
+ 0x0fff : 0;
+ ipv4_ttl = I != NULL ? I->ipha_ttl : 0;
+ ipv4_protocol = I != NULL ? I->ipha_protocol : 0;
+ ipv4_protostr = I == NULL ? "<null>" :
+ I->ipha_protocol == IPPROTO_TCP ? "TCP" :
+ I->ipha_protocol == IPPROTO_UDP ? "UDP" :
+ I->ipha_protocol == IPPROTO_IP ? "IP" :
+ I->ipha_protocol == IPPROTO_ICMP ? "ICMP" :
+ I->ipha_protocol == IPPROTO_IGMP ? "IGMP" :
+ I->ipha_protocol == IPPROTO_EGP ? "EGP" :
+ I->ipha_protocol == IPPROTO_IPV6 ? "IPv6" :
+ I->ipha_protocol == IPPROTO_ROUTING ? "ROUTE" :
+ I->ipha_protocol == IPPROTO_ESP ? "ESP" :
+ I->ipha_protocol == IPPROTO_AH ? "AH" :
+ I->ipha_protocol == IPPROTO_ICMPV6 ? "ICMPv6" :
+ I->ipha_protocol == IPPROTO_OSPF ? "OSPF" :
+ I->ipha_protocol == IPPROTO_SCTP ? "SCTP" :
+ I->ipha_protocol == IPPROTO_RAW ? "RAW" :
+ lltostr((uint64_t)I->ipha_protocol);
+ ipv4_checksum = I != NULL ? ntohs(I->ipha_hdr_checksum) : 0;
+ ipv4_src = I != NULL ? I->ipha_src : 0;
+ ipv4_dst = I != NULL ? I->ipha_dst : 0;
+ ipv4_saddr = I != NULL ? inet_ntoa(&I->ipha_src) : "<null>";
+ ipv4_daddr = I != NULL ? inet_ntoa(&I->ipha_dst) : "<null>";
+ ipv4_hdr = I;
+};
+
+#pragma D binding "1.0" translator
+translator ipv6info_t < ip6_t *I > {
+ ipv6_ver = I != NULL ? I->ip6_ctlun.ip6_un2_vfc >> 4 : 0;
+ ipv6_tclass = I != NULL ? ((I->ip6_ctlun.ip6_un1.ip6_un1_flow &&
+ 0x0fffffff) >> 20) : 0;
+ ipv6_flow = I != NULL ? I->ip6_ctlun.ip6_un1.ip6_un1_flow &&
+ 0x000fffff : 0;
+ ipv6_plen = I != NULL ? ntohs(I->ip6_ctlun.ip6_un1.ip6_un1_plen) : 0;
+ ipv6_nexthdr = I != NULL ? I->ip6_ctlun.ip6_un1.ip6_un1_nxt : 0;
+ ipv6_nextstr = I == NULL ? "<null>" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_TCP ? "TCP" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_UDP ? "UDP" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_IP ? "IP" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ICMP ? "ICMP" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_IGMP ? "IGMP" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_EGP ? "EGP" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_IPV6 ? "IPv6" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ROUTING ? "ROUTE" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ESP ? "ESP" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_AH ? "AH" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ICMPV6 ? "ICMPv6" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_OSPF ? "OSPF" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_SCTP ? "SCTP" :
+ I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_RAW ? "RAW" :
+ lltostr((uint64_t)I->ip6_ctlun.ip6_un1.ip6_un1_nxt);
+ ipv6_hlim = I != NULL ? I->ip6_ctlun.ip6_un1.ip6_un1_hlim : 0;
+ ipv6_src = I != NULL ? &I->ip6_src : 0;
+ ipv6_dst = I != NULL ? &I->ip6_dst : 0;
+ ipv6_saddr = I != NULL ? inet_ntoa6(&I->ip6_src) : "<null>";
+ ipv6_daddr = I != NULL ? inet_ntoa6(&I->ip6_dst) : "<null>";
+ ipv6_hdr = I;
+};
diff --git a/usr/src/lib/libdtrace/common/ip.sed.in b/usr/src/lib/libdtrace/common/ip.sed.in
index 0083edf2de..663de0344b 100644
--- a/usr/src/lib/libdtrace/common/ip.sed.in
+++ b/usr/src/lib/libdtrace/common/ip.sed.in
@@ -34,8 +34,42 @@
*/
#include <sys/socket.h>
+#include <netinet/in.h>
+#include <inet/ip.h>
#define SED_REPLACE(x) s/#x/x/g
SED_REPLACE(AF_INET)
SED_REPLACE(AF_INET6)
+
+SED_REPLACE(IPH_DF)
+SED_REPLACE(IPH_MF)
+
+SED_REPLACE(IPPROTO_IP)
+SED_REPLACE(IPPROTO_HOPOPTS)
+SED_REPLACE(IPPROTO_ICMP)
+SED_REPLACE(IPPROTO_IGMP)
+SED_REPLACE(IPPROTO_GGP)
+SED_REPLACE(IPPROTO_ENCAP)
+SED_REPLACE(IPPROTO_TCP)
+SED_REPLACE(IPPROTO_EGP)
+SED_REPLACE(IPPROTO_PUP)
+SED_REPLACE(IPPROTO_UDP)
+SED_REPLACE(IPPROTO_IDP)
+SED_REPLACE(IPPROTO_IPV6)
+SED_REPLACE(IPPROTO_ROUTING)
+SED_REPLACE(IPPROTO_FRAGMENT)
+SED_REPLACE(IPPROTO_RSVP)
+SED_REPLACE(IPPROTO_ESP)
+SED_REPLACE(IPPROTO_AH)
+SED_REPLACE(IPPROTO_ICMPV6)
+SED_REPLACE(IPPROTO_NONE)
+SED_REPLACE(IPPROTO_DSTOPTS)
+SED_REPLACE(IPPROTO_HELLO)
+SED_REPLACE(IPPROTO_ND)
+SED_REPLACE(IPPROTO_EON)
+SED_REPLACE(IPPROTO_OSPF)
+SED_REPLACE(IPPROTO_PIM)
+SED_REPLACE(IPPROTO_SCTP)
+SED_REPLACE(IPPROTO_RAW)
+SED_REPLACE(IPPROTO_MAX)
diff --git a/usr/src/lib/libdtrace/common/net.d b/usr/src/lib/libdtrace/common/net.d.in
index 7a6df86294..be7343ac20 100644
--- a/usr/src/lib/libdtrace/common/net.d
+++ b/usr/src/lib/libdtrace/common/net.d.in
@@ -26,8 +26,13 @@
#pragma ident "%Z%%M% %I% %E% SMI"
+inline int AF_INET = @AF_INET@;
+#pragma D binding "1.0" AF_INET
+inline int AF_INET6 = @AF_INET6@;
+#pragma D binding "1.0" AF_INET6
+
/*
- * The conninfo_t structure should be used by all application protocal
+ * The conninfo_t structure should be used by all application protocol
* providers as the first arguments to indicate some basic information
* about the connection. This structure may be augmented to accomodate
* the particularities of additional protocols in the future.
diff --git a/usr/src/lib/libdtrace/common/net.sed.in b/usr/src/lib/libdtrace/common/net.sed.in
new file mode 100644
index 0000000000..68c6e1c70f
--- /dev/null
+++ b/usr/src/lib/libdtrace/common/net.sed.in
@@ -0,0 +1,41 @@
+/*
+ * 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 2007 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#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
+ * values. After preprocessing, the sed script is run over net.d.in to
+ * replace the #define tokens listed below to create the finished net.d.
+ * Refer to the rules in libdtrace/Makefile.com for more information.
+ */
+
+#include <sys/socket.h>
+
+#define SED_REPLACE(x) s/#x/x/g
+
+SED_REPLACE(AF_INET)
+SED_REPLACE(AF_INET6)
diff --git a/usr/src/pkgdefs/SUNWdtrc/prototype_com b/usr/src/pkgdefs/SUNWdtrc/prototype_com
index 5065cd449c..c14b08feef 100644
--- a/usr/src/pkgdefs/SUNWdtrc/prototype_com
+++ b/usr/src/pkgdefs/SUNWdtrc/prototype_com
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -99,6 +99,8 @@ f none usr/demo/dtrace/iocpu.d 644 root bin
f none usr/demo/dtrace/iosnoop.d 644 root bin
f none usr/demo/dtrace/iothrough.d 644 root bin
f none usr/demo/dtrace/iotime.d 644 root bin
+f none usr/demo/dtrace/ipio.d 644 root bin
+f none usr/demo/dtrace/ipproto.d 644 root bin
f none usr/demo/dtrace/iprb.d 644 root bin
f none usr/demo/dtrace/kstat.d 644 root bin
f none usr/demo/dtrace/ksyms.d 644 root bin
diff --git a/usr/src/pkgdefs/SUNWdtrt/prototype_com b/usr/src/pkgdefs/SUNWdtrt/prototype_com
index ff1cb059a2..fee3c8f36f 100644
--- a/usr/src/pkgdefs/SUNWdtrt/prototype_com
+++ b/usr/src/pkgdefs/SUNWdtrt/prototype_com
@@ -585,6 +585,25 @@ d none SUNWdtrt/tst/common/io 0755 root bin
f none SUNWdtrt/tst/common/io/tst.fds.d 0444 root bin
f none SUNWdtrt/tst/common/io/tst.fds.exe 0555 root bin
f none SUNWdtrt/tst/common/io/tst.fds.d.out 0444 root bin
+d none SUNWdtrt/tst/common/ip 0755 root bin
+f none SUNWdtrt/tst/common/ip/get.ipv4remote.pl 0555 root bin
+f none SUNWdtrt/tst/common/ip/get.ipv6remote.pl 0555 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4localicmp.ksh 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4localicmp.ksh.out 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4localtcp.ksh 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4localtcp.ksh.out 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4localudp.ksh 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4localudp.ksh.out 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4remoteicmp.ksh 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4remoteicmp.ksh.out 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4remotetcp.ksh 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4remotetcp.ksh.out 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4remoteudp.ksh 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv4remoteudp.ksh.out 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv6localicmp.ksh 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv6localicmp.ksh.out 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv6remoteicmp.ksh 0444 root bin
+f none SUNWdtrt/tst/common/ip/tst.ipv6remoteicmp.ksh.out 0444 root bin
d none SUNWdtrt/tst/common/lexer 0755 root bin
f none SUNWdtrt/tst/common/lexer/err.D_CHR_NL.char.d 0444 root bin
f none SUNWdtrt/tst/common/lexer/err.D_CHR_NULL.char.d 0444 root bin
@@ -1101,6 +1120,9 @@ f none SUNWdtrt/tst/common/scripting/tst.taskid.ksh 0444 root bin
f none SUNWdtrt/tst/common/scripting/tst.trace.d 0444 root bin
f none SUNWdtrt/tst/common/scripting/tst.uid.d 0444 root bin
f none SUNWdtrt/tst/common/scripting/tst.uid.ksh 0444 root bin
+d none SUNWdtrt/tst/common/sdt 0755 root bin
+f none SUNWdtrt/tst/common/sdt/tst.sdtargs.d 0444 root bin
+f none SUNWdtrt/tst/common/sdt/tst.sdtargs.exe 0555 root bin
d none SUNWdtrt/tst/common/sizeof 0755 root bin
f none SUNWdtrt/tst/common/sizeof/err.D_IDENT_BADREF.SizeofAssoc.d 0444 root bin
f none SUNWdtrt/tst/common/sizeof/err.D_IDENT_UNDEF.UnknownSymbol.d 0444 root bin
diff --git a/usr/src/uts/common/dtrace/sdt_subr.c b/usr/src/uts/common/dtrace/sdt_subr.c
index 66ff8a92a0..20aabcc208 100644
--- a/usr/src/uts/common/dtrace/sdt_subr.c
+++ b/usr/src/uts/common/dtrace/sdt_subr.c
@@ -91,6 +91,7 @@ sdt_provider_t sdt_providers[] = {
{ "sched", "__sched_", &stab_attr, 0 },
{ "proc", "__proc_", &stab_attr, 0 },
{ "io", "__io_", &stab_attr, 0 },
+ { "ip", "__ip_", &stab_attr, 0 },
{ "mib", "__mib_", &stab_attr, 0 },
{ "fsinfo", "__fsinfo_", &fsinfo_attr, 0 },
{ "nfsv3", "__nfsv3_", &stab_attr, 0 },
@@ -788,6 +789,21 @@ sdt_argdesc_t sdt_args[] = {
"nfsv4cbinfo_t *" },
{ "nfsv4", "cb-recall-done", 2, 2, "CB_RECALL4res *" },
+ { "ip", "send", 0, 0, "mblk_t *", "pktinfo_t *" },
+ { "ip", "send", 1, 1, "conn_t *", "csinfo_t *" },
+ { "ip", "send", 2, 2, "void_ip_t *", "ipinfo_t *" },
+ { "ip", "send", 3, 3, "__dtrace_ipsr_ill_t *", "ifinfo_t *" },
+ { "ip", "send", 4, 4, "ipha_t *", "ipv4info_t *" },
+ { "ip", "send", 5, 5, "ip6_t *", "ipv6info_t *" },
+ { "ip", "send", 6, 6, "int" }, /* used by __dtrace_ipsr_ill_t */
+ { "ip", "receive", 0, 0, "mblk_t *", "pktinfo_t *" },
+ { "ip", "receive", 1, 1, "conn_t *", "csinfo_t *" },
+ { "ip", "receive", 2, 2, "void_ip_t *", "ipinfo_t *" },
+ { "ip", "receive", 3, 3, "__dtrace_ipsr_ill_t *", "ifinfo_t *" },
+ { "ip", "receive", 4, 4, "ipha_t *", "ipv4info_t *" },
+ { "ip", "receive", 5, 5, "ip6_t *", "ipv6info_t *" },
+ { "ip", "receive", 6, 6, "int" }, /* used by __dtrace_ipsr_ill_t */
+
{ "sysevent", "post", 0, 0, "evch_bind_t *", "syseventchaninfo_t *" },
{ "sysevent", "post", 1, 1, "sysevent_impl_t *", "syseventinfo_t *" },
diff --git a/usr/src/uts/common/inet/ip.h b/usr/src/uts/common/inet/ip.h
index 56b70f94f7..68b03b305c 100644
--- a/usr/src/uts/common/inet/ip.h
+++ b/usr/src/uts/common/inet/ip.h
@@ -542,6 +542,13 @@ typedef struct ipha_s {
ipaddr_t ipha_dst;
} ipha_t;
+/*
+ * IP Flags
+ *
+ * Some of these constant names are copied for the DTrace IP provider in
+ * usr/src/lib/libdtrace/common/{ip.d.in, ip.sed.in}, which should be kept
+ * in sync.
+ */
#define IPH_DF 0x4000 /* Don't fragment */
#define IPH_MF 0x2000 /* More fragments to come */
#define IPH_OFFSET 0x1FFF /* Where the offset lives */
diff --git a/usr/src/uts/common/inet/ip/ip.c b/usr/src/uts/common/inet/ip/ip.c
index e606388752..99fe3dab1d 100644
--- a/usr/src/uts/common/inet/ip/ip.c
+++ b/usr/src/uts/common/inet/ip/ip.c
@@ -605,7 +605,8 @@ static int conn_set_held_ipif(conn_t *, ipif_t **, ipif_t *);
static int ip_open(queue_t *q, dev_t *devp, int flag, int sflag,
cred_t *credp, boolean_t isv6);
-static mblk_t *ip_wput_attach_llhdr(mblk_t *, ire_t *, ip_proc_t, uint32_t);
+static mblk_t *ip_wput_attach_llhdr(mblk_t *, ire_t *, ip_proc_t, uint32_t,
+ ipha_t **);
static void icmp_frag_needed(queue_t *, mblk_t *, int, zoneid_t,
ip_stack_t *);
@@ -14038,6 +14039,11 @@ ip_fast_forward(ire_t *ire, ipaddr_t dst, ill_t *ill, mblk_t *mp)
DTRACE_PROBE1(ip4__physical__out__end, mblk_t *, mp);
if (mp == NULL)
goto drop;
+
+ DTRACE_IP7(send, mblk_t *, mp, conn_t *, NULL, void_ip_t *,
+ ipha, __dtrace_ipsr_ill_t *, stq_ill, ipha_t *, ipha,
+ ip6_t *, NULL, int, 0);
+
putnext(ire->ire_stq, mp);
}
return (ire);
@@ -15066,6 +15072,10 @@ ip_input(ill_t *ill, ill_rx_ring_t *ip_ring, mblk_t *mp_chain,
/* Obtain the dst of the current packet */
dst = ipha->ipha_dst;
+ DTRACE_IP7(receive, mblk_t *, first_mp, conn_t *, NULL,
+ void_ip_t *, ipha, __dtrace_ipsr_ill_t *, ill, ipha_t *,
+ ipha, ip6_t *, NULL, int, 0);
+
/*
* The following test for loopback is faster than
* IP_LOOPBACK_ADDR(), because it avoids any bitwise
@@ -23424,6 +23434,14 @@ nullstq:
*/
out_ill = ire_to_ill(ire);
+ /*
+ * DTrace this as ip:::send. A blocked packet will
+ * fire the send probe, but not the receive probe.
+ */
+ DTRACE_IP7(send, mblk_t *, first_mp, conn_t *, NULL,
+ void_ip_t *, ipha, __dtrace_ipsr_ill_t *, out_ill,
+ ipha_t *, ipha, ip6_t *, NULL, int, 1);
+
DTRACE_PROBE4(ip4__loopback__out__start,
ill_t *, NULL, ill_t *, out_ill,
ipha_t *, ipha, mblk_t *, first_mp);
@@ -23450,6 +23468,14 @@ nullstq:
out_ill = ire_to_ill(ire);
+ /*
+ * DTrace this as ip:::send. A blocked packet will fire the
+ * send probe, but not the receive probe.
+ */
+ DTRACE_IP7(send, mblk_t *, first_mp, conn_t *, NULL,
+ void_ip_t *, ipha, __dtrace_ipsr_ill_t *, out_ill,
+ ipha_t *, ipha, ip6_t *, NULL, int, 1);
+
DTRACE_PROBE4(ip4__loopback__out__start,
ill_t *, NULL, ill_t *, out_ill,
ipha_t *, ipha, mblk_t *, first_mp);
@@ -23982,6 +24008,10 @@ free_mmd: IP_STAT(ipst, ip_frag_mdt_discarded);
*/
ipha->ipha_hdr_checksum = ip_csum_hdr(ipha);
+ DTRACE_IP7(send, mblk_t *, md_mp, conn_t *, NULL, void_ip_t *,
+ ipha, __dtrace_ipsr_ill_t *, ill, ipha_t *, ipha, ip6_t *,
+ NULL, int, 0);
+
/*
* Record offset and size of header and data of the next packet
* in the multidata message.
@@ -24525,6 +24555,10 @@ ip_wput_frag(ire_t *ire, mblk_t *mp_orig, ip_pkt_t pkt_type, uint32_t max_frag,
DTRACE_PROBE1(ip4__physical__out__end, mblk_t *, xmit_mp);
if (xmit_mp != NULL) {
+ DTRACE_IP7(send, mblk_t *, xmit_mp, conn_t *, NULL,
+ void_ip_t *, ipha, __dtrace_ipsr_ill_t *, out_ill,
+ ipha_t *, ipha, ip6_t *, NULL, int, 0);
+
putnext(q, xmit_mp);
BUMP_MIB(out_ill->ill_ip_mib, ipIfStatsHCOutTransmits);
@@ -24830,6 +24864,11 @@ ip_wput_frag(ire_t *ire, mblk_t *mp_orig, ip_pkt_t pkt_type, uint32_t max_frag,
mp_orig = mp;
if (xmit_mp != NULL) {
+ DTRACE_IP7(send, mblk_t *, xmit_mp, conn_t *,
+ NULL, void_ip_t *, ipha,
+ __dtrace_ipsr_ill_t *, out_ill, ipha_t *,
+ ipha, ip6_t *, NULL, int, 0);
+
putnext(q, xmit_mp);
BUMP_MIB(out_ill->ill_ip_mib,
@@ -25047,6 +25086,10 @@ ip_wput_local(queue_t *q, ill_t *ill, ipha_t *ipha, mblk_t *mp, ire_t *ire,
if (first_mp == NULL)
return;
+ DTRACE_IP7(receive, mblk_t *, first_mp, conn_t *, NULL, void_ip_t *,
+ ipha, __dtrace_ipsr_ill_t *, ill, ipha_t *, ipha, ip6_t *, NULL,
+ int, 1);
+
ipst->ips_loopback_packets++;
ip2dbg(("ip_wput_local: from 0x%x to 0x%x in zone %d\n",
@@ -25474,7 +25517,8 @@ ip_wput_multicast(queue_t *q, mblk_t *mp, ipif_t *ipif, zoneid_t zoneid)
* marking, if needed.
*/
static mblk_t *
-ip_wput_attach_llhdr(mblk_t *mp, ire_t *ire, ip_proc_t proc, uint32_t ill_index)
+ip_wput_attach_llhdr(mblk_t *mp, ire_t *ire, ip_proc_t proc,
+ uint32_t ill_index, ipha_t **iphap)
{
uint_t hlen;
ipha_t *ipha;
@@ -25567,8 +25611,15 @@ unlock_err:
ip_process(proc, &mp1, ill_index);
if (mp1 == NULL)
return (NULL);
+
+ if (mp1->b_cont == NULL)
+ ipha = NULL;
+ else
+ ipha = (ipha_t *)mp1->b_cont->b_rptr;
}
}
+
+ *iphap = ipha;
return (mp1);
#undef rptr
}
@@ -25763,6 +25814,14 @@ send:
/* PFHooks: LOOPBACK_OUT */
out_ill = ire_to_ill(ire);
+ /*
+ * DTrace this as ip:::send. A blocked packet will fire the
+ * send probe, but not the receive probe.
+ */
+ DTRACE_IP7(send, mblk_t *, ipsec_mp, conn_t *, NULL,
+ void_ip_t *, ip6h, __dtrace_ipsr_ill_t *, out_ill,
+ ipha_t *, NULL, ip6_t *, ip6h, int, 1);
+
DTRACE_PROBE4(ip6__loopback__out__start,
ill_t *, NULL, ill_t *, out_ill,
ip6_t *, ip6h1, mblk_t *, ipsec_mp);
@@ -26099,6 +26158,14 @@ send:
/* PFHooks: LOOPBACK_OUT */
out_ill = ire_to_ill(ire);
+ /*
+ * DTrace this as ip:::send. A blocked packet will fire the
+ * send probe, but not the receive probe.
+ */
+ DTRACE_IP7(send, mblk_t *, ipsec_mp, conn_t *, NULL,
+ void_ip_t *, ipha, __dtrace_ipsr_ill_t *, out_ill,
+ ipha_t *, ipha, ip6_t *, NULL, int, 1);
+
DTRACE_PROBE4(ip4__loopback__out__start,
ill_t *, NULL, ill_t *, out_ill,
ipha_t *, ipha1, mblk_t *, ipsec_mp);
@@ -29839,6 +29906,7 @@ ipxmit_state_t
ip_xmit_v4(mblk_t *mp, ire_t *ire, ipsec_out_t *io, boolean_t flow_ctl_enabled)
{
nce_t *arpce;
+ ipha_t *ipha;
queue_t *q;
int ill_index;
mblk_t *nxt_mp, *first_mp;
@@ -29886,13 +29954,14 @@ ip_xmit_v4(mblk_t *mp, ire_t *ire, ipsec_out_t *io, boolean_t flow_ctl_enabled)
out_ill = ire_to_ill(ire);
ill_index = out_ill->ill_phyint->phyint_ifindex;
first_mp = ip_wput_attach_llhdr(mp, ire, proc,
- ill_index);
+ ill_index, &ipha);
if (first_mp == NULL) {
xmit_drop = B_TRUE;
BUMP_MIB(out_ill->ill_ip_mib,
ipIfStatsOutDiscards);
goto next_mp;
}
+
/* non-ipsec hw accel case */
if (io == NULL || !io->ipsec_out_accelerated) {
/* send it */
@@ -29914,6 +29983,12 @@ ip_xmit_v4(mblk_t *mp, ire_t *ire, ipsec_out_t *io, boolean_t flow_ctl_enabled)
UPDATE_IP_MIB_OB_COUNTERS(out_ill,
pkt_len);
+ DTRACE_IP7(send, mblk_t *, first_mp,
+ conn_t *, NULL, void_ip_t *, ipha,
+ __dtrace_ipsr_ill_t *, out_ill,
+ ipha_t *, ipha, ip6_t *, NULL, int,
+ 0);
+
putnext(q, first_mp);
} else {
BUMP_MIB(out_ill->ill_ip_mib,
@@ -29937,6 +30012,13 @@ ip_xmit_v4(mblk_t *mp, ire_t *ire, ipsec_out_t *io, boolean_t flow_ctl_enabled)
} else {
UPDATE_IP_MIB_OB_COUNTERS(ill1,
pkt_len);
+
+ DTRACE_IP7(send, mblk_t *, first_mp,
+ conn_t *, NULL, void_ip_t *, ipha,
+ __dtrace_ipsr_ill_t *, ill1,
+ ipha_t *, ipha, ip6_t *, NULL,
+ int, 0);
+
ipsec_hw_putnext(ire->ire_stq, mp);
}
}
diff --git a/usr/src/uts/common/inet/ip/ip6.c b/usr/src/uts/common/inet/ip/ip6.c
index 382944a369..f986a229b4 100644
--- a/usr/src/uts/common/inet/ip/ip6.c
+++ b/usr/src/uts/common/inet/ip/ip6.c
@@ -183,6 +183,10 @@ const in6_addr_t ipv6_solicited_node_mcast =
#define OK_RESOLVER_MP_V6(mp) \
((mp) && ((mp)->b_wptr - (mp)->b_rptr) >= (2 * IPV6_ADDR_LEN))
+#define IP6_MBLK_OK 0
+#define IP6_MBLK_HDR_ERR 1
+#define IP6_MBLK_LEN_ERR 2
+
static void icmp_inbound_too_big_v6(queue_t *, mblk_t *, ill_t *ill,
boolean_t, zoneid_t);
static void icmp_pkt_v6(queue_t *, mblk_t *, void *, size_t,
@@ -6572,9 +6576,11 @@ ip_process_rthdr(queue_t *q, mblk_t *mp, ip6_t *ip6h, ip6_rthdr_t *rth,
B_FALSE, B_FALSE, GLOBAL_ZONEID, ipst);
return;
}
- if (ip_check_v6_mblk(mp, ill) == 0) {
+ if (ip_check_v6_mblk(mp, ill) == IP6_MBLK_OK) {
ip6h = (ip6_t *)mp->b_rptr;
ip_rput_data_v6(q, ill, mp, ip6h, flags, hada_mp, dl_mp);
+ } else {
+ freemsg(mp);
}
return;
hada_drop:
@@ -6599,6 +6605,7 @@ ip_rput_v6(queue_t *q, mblk_t *mp)
uint_t flags = 0;
mblk_t *dl_mp;
ip_stack_t *ipst;
+ int check;
ill = (ill_t *)q->q_ptr;
ipst = ill->ill_ipst;
@@ -6792,11 +6799,26 @@ ip_rput_v6(queue_t *q, mblk_t *mp)
mp = first_mp->b_cont;
}
- if (ip_check_v6_mblk(mp, ill) == -1)
+ if ((check = ip_check_v6_mblk(mp, ill)) == IP6_MBLK_HDR_ERR) {
+ freemsg(mp);
return;
+ }
ip6h = (ip6_t *)mp->b_rptr;
+ /*
+ * ip:::receive must see ipv6 packets with a full header,
+ * and so is placed after the IP6_MBLK_HDR_ERR check.
+ */
+ DTRACE_IP7(receive, mblk_t *, first_mp, conn_t *, NULL, void_ip_t *,
+ ip6h, __dtrace_ipsr_ill_t *, ill, ipha_t *, NULL, ip6_t *, ip6h,
+ int, 0);
+
+ if (check != IP6_MBLK_OK) {
+ freemsg(mp);
+ return;
+ }
+
DTRACE_PROBE4(ip6__physical__in__start,
ill_t *, ill, ill_t *, NULL,
ip6_t *, ip6h, mblk_t *, first_mp);
@@ -7055,8 +7077,7 @@ ip_check_v6_mblk(mblk_t *mp, ill_t *ill)
if (!pullupmsg(mp, IPV6_HDR_LEN)) {
BUMP_MIB(ill->ill_ip_mib, ipIfStatsInDiscards);
ip1dbg(("ip_rput_v6: pullupmsg failed\n"));
- freemsg(mp);
- return (-1);
+ return (IP6_MBLK_HDR_ERR);
}
ip6h = (ip6_t *)mp->b_rptr;
}
@@ -7081,19 +7102,17 @@ ip_check_v6_mblk(mblk_t *mp, ill_t *ill)
ip1dbg(("ip_rput_data_v6: packet too short %d %d\n",
ip6_len, pkt_len));
BUMP_MIB(ill->ill_ip_mib, ipIfStatsInTruncatedPkts);
- freemsg(mp);
- return (-1);
+ return (IP6_MBLK_LEN_ERR);
}
diff = (ssize_t)(pkt_len - ip6_len);
if (!adjmsg(mp, -diff)) {
ip1dbg(("ip_rput_data_v6: adjmsg failed\n"));
BUMP_MIB(ill->ill_ip_mib, ipIfStatsInDiscards);
- freemsg(mp);
- return (-1);
+ return (IP6_MBLK_LEN_ERR);
}
}
- return (0);
+ return (IP6_MBLK_OK);
}
/*
@@ -10527,6 +10546,10 @@ ip_wput_local_v6(queue_t *q, ill_t *ill, ip6_t *ip6h, mblk_t *first_mp,
if (first_mp == NULL)
return;
+ DTRACE_IP7(receive, mblk_t *, first_mp, conn_t *, NULL, void_ip_t *,
+ ip6h, __dtrace_ipsr_ill_t *, ill, ipha_t *, NULL, ip6_t *, ip6h,
+ int, 1);
+
nexthdr = ip6h->ip6_nxt;
mibptr = ill->ill_ip_mib;
@@ -10941,6 +10964,17 @@ ip_wput_ire_v6(queue_t *q, mblk_t *mp, ire_t *ire, int unspec_src,
ip6__loopback__out__end,
mblk_t *, nmp);
+ /*
+ * DTrace this as ip:::send. A blocked
+ * packet will fire the send probe, but
+ * not the receive probe.
+ */
+ DTRACE_IP7(send, mblk_t *, nmp,
+ conn_t *, NULL, void_ip_t *, nip6h,
+ __dtrace_ipsr_ill_t *, ill,
+ ipha_t *, NULL, ip6_t *, nip6h,
+ int, 1);
+
if (nmp != NULL) {
/*
* Deliver locally and to
@@ -11366,6 +11400,13 @@ ip_wput_ire_v6(queue_t *q, mblk_t *mp, ire_t *ire, int unspec_src,
ASSERT(mp == first_mp);
ip_xmit_v6(mp, ire, reachable, connp, caller, NULL);
} else {
+ /*
+ * DTrace this as ip:::send. A blocked packet will fire the
+ * send probe, but not the receive probe.
+ */
+ DTRACE_IP7(send, mblk_t *, first_mp, conn_t *, NULL,
+ void_ip_t *, ip6h, __dtrace_ipsr_ill_t *, ill, ipha_t *,
+ NULL, ip6_t *, ip6h, int, 1);
DTRACE_PROBE4(ip6__loopback__out__start,
ill_t *, NULL, ill_t *, ill,
ip6_t *, ip6h, mblk_t *, first_mp);
@@ -12284,6 +12325,11 @@ ip_xmit_v6(mblk_t *mp, ire_t *ire, uint_t flags, conn_t *connp,
UPDATE_MIB(ill->ill_ip_mib,
ipIfStatsHCOutOctets,
ntohs(ip6h->ip6_plen) + IPV6_HDR_LEN);
+ DTRACE_IP7(send, mblk_t *, mp, conn_t *, NULL,
+ void_ip_t *, ip6h, __dtrace_ipsr_ill_t *,
+ out_ill, ipha_t *, NULL, ip6_t *, ip6h,
+ int, 0);
+
putnext(stq, mp);
} else {
/*
@@ -12301,6 +12347,11 @@ ip_xmit_v6(mblk_t *mp, ire_t *ire, uint_t flags, conn_t *connp,
ipIfStatsHCOutOctets,
ntohs(ip6h->ip6_plen) +
IPV6_HDR_LEN);
+ DTRACE_IP7(send, mblk_t *, mp,
+ conn_t *, NULL, void_ip_t *, ip6h,
+ __dtrace_ipsr_ill_t *, out_ill,
+ ipha_t *, NULL, ip6_t *, ip6h, int,
+ 0);
ipsec_hw_putnext(stq, mp);
}
}
diff --git a/usr/src/uts/common/inet/ip/ip_multi.c b/usr/src/uts/common/inet/ip/ip_multi.c
index abf6b93449..2a1f5c49bc 100644
--- a/usr/src/uts/common/inet/ip/ip_multi.c
+++ b/usr/src/uts/common/inet/ip/ip_multi.c
@@ -1256,6 +1256,13 @@ ip_multicast_loopback(queue_t *q, ill_t *ill, mblk_t *mp_orig, int fanout_flags,
iph = (ipha_t *)mp->b_rptr;
+ /*
+ * DTrace this as ip:::send. A blocked packet will fire the send
+ * probe, but not the receive probe.
+ */
+ DTRACE_IP7(send, mblk_t *, ipsec_mp, conn_t *, NULL, void_ip_t *, iph,
+ __dtrace_ipsr_ill_t *, ill, ipha_t *, iph, ip6_t *, NULL, int, 1);
+
DTRACE_PROBE4(ip4__loopback__out__start,
ill_t *, NULL, ill_t *, ill,
ipha_t *, iph, mblk_t *, ipsec_mp);
diff --git a/usr/src/uts/common/inet/ip/ip_netinfo.c b/usr/src/uts/common/inet/ip/ip_netinfo.c
index c70f91220e..9c073e795c 100644
--- a/usr/src/uts/common/inet/ip/ip_netinfo.c
+++ b/usr/src/uts/common/inet/ip/ip_netinfo.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -36,6 +36,7 @@
#include <sys/sunddi.h>
#include <sys/socket.h>
#include <sys/neti.h>
+#include <sys/sdt.h>
#include <netinet/in.h>
#include <inet/common.h>
@@ -871,6 +872,10 @@ ip_inject_impl(inject_t style, net_inject_t *packet, boolean_t isv6,
freemsg(mp);
return (1);
}
+ DTRACE_IP7(send, mblk_t *, mp, conn_t *, NULL,
+ void_ip_t *, ip6h, __dtrace_ipsr_ill_t *,
+ ire->ire_ipif->ipif_ill, ipha_t *, NULL, ip6_t *,
+ ip6h, int, 1);
ip_wput_local_v6(ire->ire_rfq,
ire->ire_ipif->ipif_ill, ip6h, mp, ire, 0);
ire_refrele(ire);
@@ -1311,13 +1316,13 @@ ip_ni_queue_func_impl(injection_t *inject, boolean_t out)
conn->conn_src_preferences = IPV6_PREFER_SRC_DEFAULT;
conn->conn_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
ip_output_v6(conn, packet->ni_packet, ill->ill_wq,
- IP_WPUT);
+ IP_WPUT);
} else {
conn->conn_af_isv6 = B_FALSE;
conn->conn_pkt_isv6 = B_FALSE;
conn->conn_multicast_loop = IP_DEFAULT_MULTICAST_LOOP;
ip_output(conn, packet->ni_packet, ill->ill_wq,
- IP_WPUT);
+ IP_WPUT);
}
CONN_DEC_REF(conn);
diff --git a/usr/src/uts/common/inet/ip_impl.h b/usr/src/uts/common/inet/ip_impl.h
index 30a314b8d7..8643e97b22 100644
--- a/usr/src/uts/common/inet/ip_impl.h
+++ b/usr/src/uts/common/inet/ip_impl.h
@@ -506,8 +506,12 @@ typedef struct ip_pdescinfo_s PDESCINFO_STRUCT(2) ip_pdescinfo_t;
ipst->ips_ipv4firewall_physical_out, \
NULL, ill, ipha, mp, mp, 0, ipst); \
DTRACE_PROBE1(ip4__physical__out__end, mblk_t *, mp); \
- if (mp != NULL) \
+ if (mp != NULL) { \
+ DTRACE_IP7(send, mblk_t *, mp, conn_t *, NULL, \
+ void_ip_t *, ipha, __dtrace_ipsr_ill_t *, ill, \
+ ipha_t *, ipha, ip6_t *, NULL, int, 0); \
ill_dls->ill_tx(ill_dls->ill_tx_handle, mp); \
+ } \
}
extern int ip_wput_frag_mdt_min;
diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c
index 766a7db59e..59a5117fa7 100644
--- a/usr/src/uts/common/inet/tcp/tcp.c
+++ b/usr/src/uts/common/inet/tcp/tcp.c
@@ -1464,6 +1464,11 @@ int cl_tcp_walk_list(int (*callback)(cl_tcp_info_t *, void *), void *arg);
static int cl_tcp_walk_list_stack(int (*callback)(cl_tcp_info_t *, void *),
void *arg, tcp_stack_t *tcps);
+#define DTRACE_IP_FASTPATH(mp, iph, ill, ipha, ip6h) \
+ DTRACE_IP7(send, mblk_t *, mp, conn_t *, NULL, void_ip_t *, \
+ iph, __dtrace_ipsr_ill_t *, ill, ipha_t *, ipha, \
+ ip6_t *, ip6h, int, 0);
+
/*
* Figure out the value of window scale opton. Note that the rwnd is
* ASSUMED to be rounded up to the nearest MSS before the calculation.
@@ -19661,8 +19666,11 @@ tcp_send_data(tcp_t *tcp, queue_t *q, mblk_t *mp)
ipst->ips_ipv4firewall_physical_out,
NULL, out_ill, ipha, mp, mp, 0, ipst);
DTRACE_PROBE1(ip4__physical__out__end, mblk_t *, mp);
- if (mp != NULL)
+
+ if (mp != NULL) {
+ DTRACE_IP_FASTPATH(mp, ipha, out_ill, ipha, NULL);
putnext(ire->ire_stq, mp);
+ }
}
IRE_REFRELE(ire);
}
@@ -20708,6 +20716,10 @@ legacy_send_no_md:
do {
len = seg_len;
+ /* one must remain NULL for DTRACE_IP_FASTPATH */
+ ipha = NULL;
+ ip6h = NULL;
+
ASSERT(len > 0);
ASSERT(max_pld >= 0);
ASSERT(!add_buffer || cur_pld_off == 0);
@@ -21259,6 +21271,7 @@ legacy_send_no_md:
* Need to pass it to normal path.
*/
CALL_IP_WPUT(tcp->tcp_connp, q, mp);
+ mp = NULL;
} else if (mp == NULL ||
mp->b_rptr != pkt_info->hdr_rptr ||
mp->b_wptr != pkt_info->hdr_wptr ||
@@ -21304,7 +21317,7 @@ legacy_send_no_md:
q, mp);
} while (mp1 != NULL);
- fw_mp_head = NULL;
+ fw_mp_head = mp = NULL;
} else {
if (fw_mp_head == NULL)
fw_mp_head = mp;
@@ -21314,6 +21327,11 @@ legacy_send_no_md:
}
}
+ if (mp != NULL) {
+ DTRACE_IP_FASTPATH(md_hbuf, pkt_info->hdr_rptr,
+ ill, ipha, ip6h);
+ }
+
/* advance header offset */
cur_hdr_off += hdr_frag_sz;
@@ -21612,8 +21630,11 @@ tcp_lsosend_data(tcp_t *tcp, mblk_t *mp, ire_t *ire, ill_t *ill, const int mss,
ipst->ips_ipv4firewall_physical_out,
NULL, out_ill, ipha, mp, mp, 0, ipst);
DTRACE_PROBE1(ip4__physical__out__end, mblk_t *, mp);
- if (mp != NULL)
+
+ if (mp != NULL) {
+ DTRACE_IP_FASTPATH(mp, ipha, out_ill, ipha, NULL);
putnext(ire->ire_stq, mp);
+ }
}
}
diff --git a/usr/src/uts/common/inet/udp/udp.c b/usr/src/uts/common/inet/udp/udp.c
index 9514a611c5..90bed67946 100644
--- a/usr/src/uts/common/inet/udp/udp.c
+++ b/usr/src/uts/common/inet/udp/udp.c
@@ -6352,8 +6352,12 @@ udp_xmit(queue_t *q, mblk_t *mp, ire_t *ire, conn_t *connp, zoneid_t zoneid)
ipst->ips_ipv4firewall_physical_out,
NULL, ill, ipha, mp, mp, ll_multicast, ipst);
DTRACE_PROBE1(ip4__physical__out__end, mblk_t *, mp);
- if (mp != NULL)
+ if (mp != NULL) {
+ DTRACE_IP7(send, mblk_t *, mp, conn_t *, NULL,
+ void_ip_t *, ipha, __dtrace_ipsr_ill_t *, ill,
+ ipha_t *, ipha, ip6_t *, NULL, int, 0);
putnext(ire->ire_stq, mp);
+ }
}
IRE_REFRELE(ire);
diff --git a/usr/src/uts/common/netinet/in.h b/usr/src/uts/common/netinet/in.h
index d2e33e24f7..b1f1fe8047 100644
--- a/usr/src/uts/common/netinet/in.h
+++ b/usr/src/uts/common/netinet/in.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
@@ -142,6 +142,10 @@ typedef uint16_t sa_family_t;
/*
* Protocols
+ *
+ * Some of these constant names are copied for the DTrace IP provider in
+ * usr/src/lib/libdtrace/common/{ip.d.in, ip.sed.in}, which should be kept
+ * in sync.
*/
#define IPPROTO_IP 0 /* dummy for IP */
#define IPPROTO_HOPOPTS 0 /* Hop by hop header for IPv6 */
diff --git a/usr/src/uts/common/sys/sdt.h b/usr/src/uts/common/sys/sdt.h
index 9ec47e557b..ff04802196 100644
--- a/usr/src/uts/common/sys/sdt.h
+++ b/usr/src/uts/common/sys/sdt.h
@@ -105,6 +105,32 @@ extern "C" {
(uintptr_t)(arg3), (uintptr_t)(arg4)); \
}
+#define DTRACE_PROBE5(name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5) { \
+ extern void __dtrace_probe_##name(uintptr_t, uintptr_t, \
+ uintptr_t, uintptr_t, uintptr_t); \
+ __dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2), \
+ (uintptr_t)(arg3), (uintptr_t)(arg4), (uintptr_t)(arg5)); \
+}
+
+#define DTRACE_PROBE6(name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5, type6, arg6) { \
+ extern void __dtrace_probe_##name(uintptr_t, uintptr_t, \
+ uintptr_t, uintptr_t, uintptr_t, uintptr_t); \
+ __dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2), \
+ (uintptr_t)(arg3), (uintptr_t)(arg4), (uintptr_t)(arg5), \
+ (uintptr_t)(arg6)); \
+}
+
+#define DTRACE_PROBE7(name, type1, arg1, type2, arg2, type3, arg3, \
+ type4, arg4, type5, arg5, type6, arg6, type7, arg7) { \
+ extern void __dtrace_probe_##name(uintptr_t, uintptr_t, \
+ uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t); \
+ __dtrace_probe_##name((uintptr_t)(arg1), (uintptr_t)(arg2), \
+ (uintptr_t)(arg3), (uintptr_t)(arg4), (uintptr_t)(arg5), \
+ (uintptr_t)(arg6), (uintptr_t)(arg7)); \
+}
+
#define DTRACE_SCHED(name) \
DTRACE_PROBE(__sched_##name);
@@ -180,6 +206,39 @@ extern "C" {
#define DTRACE_SMB_2(name, type1, arg1, type2, arg2) \
DTRACE_PROBE2(__smb_##name, type1, arg1, type2, arg2);
+#define DTRACE_IP(name) \
+ DTRACE_PROBE(__ip_##name);
+
+#define DTRACE_IP1(name, type1, arg1) \
+ DTRACE_PROBE1(__ip_##name, type1, arg1);
+
+#define DTRACE_IP2(name, type1, arg1, type2, arg2) \
+ DTRACE_PROBE2(__ip_##name, type1, arg1, type2, arg2);
+
+#define DTRACE_IP3(name, type1, arg1, type2, arg2, type3, arg3) \
+ DTRACE_PROBE3(__ip_##name, type1, arg1, type2, arg2, type3, arg3);
+
+#define DTRACE_IP4(name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4) \
+ DTRACE_PROBE4(__ip_##name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4);
+
+#define DTRACE_IP5(name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5) \
+ DTRACE_PROBE5(__ip_##name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5);
+
+#define DTRACE_IP6(name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5, type6, arg6) \
+ DTRACE_PROBE6(__ip_##name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5, type6, arg6);
+
+#define DTRACE_IP7(name, type1, arg1, type2, arg2, type3, arg3, \
+ type4, arg4, type5, arg5, type6, arg6, type7, arg7) \
+ DTRACE_PROBE7(__ip_##name, type1, arg1, type2, arg2, \
+ type3, arg3, type4, arg4, type5, arg5, type6, arg6, \
+ type7, arg7);
+
#define DTRACE_SYSEVENT2(name, type1, arg1, type2, arg2) \
DTRACE_PROBE2(__sysevent_##name, type1, arg1, type2, arg2);
diff --git a/usr/src/uts/common/sys/socket.h b/usr/src/uts/common/sys/socket.h
index 4183337c74..a8e1d90217 100644
--- a/usr/src/uts/common/sys/socket.h
+++ b/usr/src/uts/common/sys/socket.h
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -186,6 +186,10 @@ struct linger {
/*
* Address families.
+ *
+ * Some of these constant names are copied for the DTrace IP provider in
+ * usr/src/lib/libdtrace/common/{ip.d.in, ip.sed.in}, which should be kept
+ * in sync.
*/
#define AF_UNSPEC 0 /* unspecified */
#define AF_UNIX 1 /* local to host (pipes, portals) */
diff --git a/usr/src/uts/common/sys/uadmin.h b/usr/src/uts/common/sys/uadmin.h
index 2bf889c9b7..a23e251962 100644
--- a/usr/src/uts/common/sys/uadmin.h
+++ b/usr/src/uts/common/sys/uadmin.h
@@ -49,6 +49,7 @@ extern "C" {
#define A_FTRACE 15
#define A_SWAPCTL 16
/* 17-21 reserved for obsolete interface */
+#define A_SDTTEST 22 /* DTrace sdt:::test */
#define AD_UNKNOWN -1 /* no method */
#define AD_HALT 0 /* halt the processor */
diff --git a/usr/src/uts/common/syscall/uadmin.c b/usr/src/uts/common/syscall/uadmin.c
index a5f92268f2..9a2f01e850 100644
--- a/usr/src/uts/common/syscall/uadmin.c
+++ b/usr/src/uts/common/syscall/uadmin.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -54,6 +54,7 @@
#include <sys/zone.h>
#include <sys/condvar.h>
#include <sys/thread.h>
+#include <sys/sdt.h>
/*
* Administrivia system call. We provide this in two flavors: one for calling
@@ -147,6 +148,7 @@ kadmin(int cmd, int fcn, void *mdep, cred_t *credp)
case A_REMOUNT:
case A_FREEZE:
case A_DUMP:
+ case A_SDTTEST:
if (secpolicy_sys_config(credp, B_FALSE) != 0)
return (EPERM);
break;
@@ -356,6 +358,13 @@ kadmin(int cmd, int fcn, void *mdep, cred_t *credp)
/*NOTREACHED*/
}
+ case A_SDTTEST:
+ {
+ DTRACE_PROBE7(test, int, 1, int, 2, int, 3, int, 4, int, 5,
+ int, 6, int, 7);
+ break;
+ }
+
default:
error = EINVAL;
}
diff --git a/usr/src/uts/intel/dtrace/sdt.c b/usr/src/uts/intel/dtrace/sdt.c
index aa31d84d14..55724b3d89 100644
--- a/usr/src/uts/intel/dtrace/sdt.c
+++ b/usr/src/uts/intel/dtrace/sdt.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -33,6 +33,11 @@
#include <sys/conf.h>
#include <vm/seg_kmem.h>
#include <sys/stack.h>
+#include <sys/frame.h>
+#include <sys/dtrace_impl.h>
+#include <sys/cmn_err.h>
+#include <sys/sysmacros.h>
+#include <sys/privregs.h>
#include <sys/sdt_impl.h>
#define SDT_PATCHVAL 0xf0
@@ -289,6 +294,72 @@ err:
;
}
+/*ARGSUSED*/
+uint64_t
+sdt_getarg(void *arg, dtrace_id_t id, void *parg, int argno, int aframes)
+{
+ uintptr_t val;
+ struct frame *fp = (struct frame *)dtrace_getfp();
+ uintptr_t *stack;
+ int i;
+#if defined(__amd64)
+ /*
+ * A total of 6 arguments are passed via registers; any argument with
+ * index of 5 or lower is therefore in a register.
+ */
+ int inreg = 5;
+#endif
+
+ for (i = 1; i <= aframes; i++) {
+ fp = (struct frame *)(fp->fr_savfp);
+
+ if (fp->fr_savpc == (pc_t)dtrace_invop_callsite) {
+#if !defined(__amd64)
+ /*
+ * If we pass through the invalid op handler, we will
+ * use the pointer that it passed to the stack as the
+ * second argument to dtrace_invop() as the pointer to
+ * the stack. When using this stack, we must step
+ * beyond the EIP/RIP that was pushed when the trap was
+ * taken -- hence the "+ 1" below.
+ */
+ stack = ((uintptr_t **)&fp[1])[1];
+#else
+ /*
+ * In the case of amd64, we will use the pointer to the
+ * regs structure that was pushed when we took the
+ * trap. To get this structure, we must increment
+ * beyond the frame structure, and then again beyond
+ * the calling RIP stored in dtrace_invop(). If the
+ * argument that we're seeking is passed on the stack,
+ * we'll pull the true stack pointer out of the saved
+ * registers and decrement our argument by the number
+ * of arguments passed in registers; if the argument
+ * we're seeking is passed in regsiters, we can just
+ * load it directly.
+ */
+ struct regs *rp = (struct regs *)((uintptr_t)&fp[1] +
+ sizeof (uintptr_t));
+
+ if (argno <= inreg) {
+ stack = (uintptr_t *)&rp->r_rdi;
+ } else {
+ stack = (uintptr_t *)(rp->r_rsp);
+ argno -= inreg;
+ }
+#endif
+ goto load;
+ }
+ }
+
+load:
+ DTRACE_CPUFLAG_SET(CPU_DTRACE_NOFAULT);
+ val = stack[argno];
+ DTRACE_CPUFLAG_CLEAR(CPU_DTRACE_NOFAULT);
+
+ return (val);
+}
+
static dtrace_pops_t sdt_pops = {
NULL,
sdt_provide_module,
@@ -297,7 +368,7 @@ static dtrace_pops_t sdt_pops = {
NULL,
NULL,
sdt_getargdesc,
- NULL,
+ sdt_getarg,
NULL,
sdt_destroy
};