1#!/usr/bin/ksh
2#
3# connections - print inbound TCP connections by process.
4#               Written in DTrace (Solaris 10 3/05).
5#
6# This displays the PID and command name of the processes accepting 
7# connections, along with the source IP address and destination port number.
8#
9# 20-Apr-2006, ver 0.86			(check for newer versions)
10#
11# USAGE:	connections [-htvZ]
12#
13#		-t		# print timestamps, us
14#		-v		# print timestamps, string
15#		-Z		# print zonename
16#	eg,
17#		connections -v	# snoop connections with times
18#
19# FIELDS:
20#		UID		user ID of the server
21#		PID		process ID for the server
22#		CMD		server command name
23#		TIME		timestamp, us
24#		TIMESTR		timestamp, string
25#		PORT		server port
26#		IP_SOURCE	source IP of the client, written in IPv4 style
27#		ZONE		zonename
28#
29# SEE ALSO:	snoop 'tcp[13:1] = 0x02'	# snoop new connections
30#
31# COPYRIGHT: Copyright (c) 2005 Brendan Gregg.
32#
33# CDDL HEADER START
34#
35#  The contents of this file are subject to the terms of the
36#  Common Development and Distribution License, Version 1.0 only
37#  (the "License").  You may not use this file except in compliance
38#  with the License.
39#
40#  You can obtain a copy of the license at Docs/cddl1.txt
41#  or http://www.opensolaris.org/os/licensing.
42#  See the License for the specific language governing permissions
43#  and limitations under the License.
44#
45# CDDL HEADER END
46#
47# TODO: IPv6
48#
49# 10-Apr-2004	Brendan Gregg	Created this.
50# 23-May-2004	   "      "  	Fixed issues on SPARC.
51# 08-May-2005	   "      "  	Updated for newer Solaris 10.
52# 17-Jun-2005	   "      "	Rewrote, changed probes, wrapped in sh.
53# 04-Dec-2005	   "	  "	Changed tcp_accept_finish -> sotpi_accept
54# 20-Apr-2006	   "	  "	Fixed SS_TCP_FAST_ACCEPT bug in build 31+.
55#
56
57
58##############################
59# --- Process Arguments ---
60#
61
62### Default variables
63opt_time=0; opt_timestr=0; opt_zone=0
64
65### Process options
66while getopts htvZ name
67do
68	case $name in
69	t)      opt_time=1 ;;
70	v)      opt_timestr=1 ;;
71	Z)      opt_zone=1 ;;
72	h|?)    cat <<-END >&2
73		USAGE: connections [-htvZ]
74			   -t              # print timestamps, us
75			   -v              # print timestamps, string
76			   -Z              # print zonename
77		  eg,
78		       connections -v      # snoop connections with times
79		END
80		exit 1
81	esac
82done
83
84
85#################################
86# --- Main Program, DTrace ---
87#
88/usr/sbin/dtrace -C -s <( print -r '
89#include <sys/file.h>
90#include <sys/types.h>
91#include <sys/byteorder.h>
92#include <sys/socket.h>
93#include <sys/socketvar.h>
94
95 #pragma D option quiet
96 #pragma D option switchrate=10hz
97
98 inline int OPT_time    = '$opt_time';
99 inline int OPT_timestr = '$opt_timestr';
100 inline int OPT_zone    = '$opt_zone';
101
102 /*
103  * Print header
104  */
105 dtrace:::BEGIN 
106 {
107        /* print optional headers */
108        OPT_time    ? printf("%-14s ", "TIME") : 1;
109        OPT_timestr ? printf("%-20s ", "TIMESTR") : 1;
110	OPT_zone    ? printf("%-10s ", "ZONE") : 1;
111
112	/* print header */
113	printf("%5s %5s %-12s %4s %5s %s\n",
114	    "UID", "PID", "CMD", "TYPE", "PORT", "IP_SOURCE");
115 }
116
117 /*
118  * TCP Process inbound connections
119  *
120  * 0x00200000 has been hardcoded. It was SS_TCP_FAST_ACCEPT, but was
121  * renamed to SS_DIRECT around build 31.
122  */
123 fbt:sockfs:sotpi_accept:entry
124 /(arg1 & FREAD) && (arg1 & FWRITE) && (args[0]->so_state & 0x00200000)/
125 {
126	self->sop = args[0];
127 }
128
129 fbt:sockfs:sotpi_create:return
130 /self->sop/
131 {
132	self->nsop = (struct sonode *)arg1;
133 }
134
135
136 /*
137  * Probe TCP connections
138  */
139 fbt:sockfs:sotpi_accept:return
140 /self->nsop/
141 {
142	/* fetch connection details */
143	this->tcpp = (tcp_t *)self->nsop->so_priv;
144	this->connp = (conn_t *)this->tcpp->tcp_connp;
145
146#if defined(_BIG_ENDIAN)
147	this->port0 = this->connp->u_port.tcpu_ports.tcpu_lport;
148#else
149	this->port0 = BSWAP_16(this->connp->u_port.tcpu_ports.tcpu_lport);
150#endif
151	this->rem12 = 
152	    (uint8_t)this->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[12];
153	this->rem13 =
154	    (uint8_t)this->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[13];
155	this->rem14 =
156	    (uint8_t)this->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[14];
157	this->rem15 =
158	    (uint8_t)this->connp->connua_v6addr.connua_faddr._S6_un._S6_u8[15];
159
160        /* print optional fields */
161        OPT_time    ? printf("%-14d ", timestamp/1000) : 1;
162        OPT_timestr ? printf("%-20Y ", walltimestamp) : 1;
163	OPT_zone    ? printf("%-10s ", zonename) : 1;
164
165	/* print output line */
166	printf("%5d %5d %-12s %4s %5d %d.%d.%d.%d\n",
167	    uid, pid, execname, "tcp", this->port0, 
168	    this->rem12, this->rem13, this->rem14, this->rem15);
169 }
170
171 fbt:sockfs:sotpi_accept:return
172 {
173	self->nsop = 0;
174	self->sop = 0;
175 }
176')
177
178