diff options
author | brendan <none@none> | 2008-06-13 19:06:55 -0700 |
---|---|---|
committer | brendan <none@none> | 2008-06-13 19:06:55 -0700 |
commit | 10e6dadfe63181edabc58c8f42e3c56a1cd9ec95 (patch) | |
tree | 95d4edf9068228f58a3abddd6b718c98d6f0b919 /usr/src | |
parent | 90bcde942a3919300ffc73f98ea903b58386c395 (diff) | |
download | illumos-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')
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 }; |