1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25#pragma D depends_on module ip
26#pragma D depends_on provider ip
27
28inline int IPH_DF = @IPH_DF@;
29#pragma D binding "1.5" IPH_DF
30inline int IPH_MF = @IPH_MF@;
31#pragma D binding "1.5" IPH_MF
32
33#pragma D binding "1.5" IPPROTO_IP
34inline int IPPROTO_IP = @IPPROTO_IP@;
35#pragma D binding "1.5" IPPROTO_HOPOPTS
36inline int IPPROTO_HOPOPTS = @IPPROTO_HOPOPTS@;
37#pragma D binding "1.5" IPPROTO_ICMP
38inline int IPPROTO_ICMP = @IPPROTO_ICMP@;
39#pragma D binding "1.5" IPPROTO_IGMP
40inline int IPPROTO_IGMP = @IPPROTO_IGMP@;
41#pragma D binding "1.5" IPPROTO_GGP
42inline int IPPROTO_GGP = @IPPROTO_GGP@;
43#pragma D binding "1.5" IPPROTO_ENCAP
44inline int IPPROTO_ENCAP = @IPPROTO_ENCAP@;
45#pragma D binding "1.5" IPPROTO_TCP
46inline int IPPROTO_TCP = @IPPROTO_TCP@;
47#pragma D binding "1.5" IPPROTO_EGP
48inline int IPPROTO_EGP = @IPPROTO_EGP@;
49#pragma D binding "1.5" IPPROTO_PUP
50inline int IPPROTO_PUP = @IPPROTO_PUP@;
51#pragma D binding "1.5" IPPROTO_UDP
52inline int IPPROTO_UDP = @IPPROTO_UDP@;
53#pragma D binding "1.5" IPPROTO_IDP
54inline int IPPROTO_IDP = @IPPROTO_IDP@;
55#pragma D binding "1.5" IPPROTO_IPV6
56inline int IPPROTO_IPV6 = @IPPROTO_IPV6@;
57#pragma D binding "1.5" IPPROTO_ROUTING
58inline int IPPROTO_ROUTING = @IPPROTO_ROUTING@;
59#pragma D binding "1.5" IPPROTO_FRAGMENT
60inline int IPPROTO_FRAGMENT = @IPPROTO_FRAGMENT@;
61#pragma D binding "1.5" IPPROTO_RSVP
62inline int IPPROTO_RSVP = @IPPROTO_RSVP@;
63#pragma D binding "1.5" IPPROTO_ESP
64inline int IPPROTO_ESP = @IPPROTO_ESP@;
65#pragma D binding "1.5" IPPROTO_AH
66inline int IPPROTO_AH = @IPPROTO_AH@;
67#pragma D binding "1.5" IPPROTO_ICMPV6
68inline int IPPROTO_ICMPV6 = @IPPROTO_ICMPV6@;
69#pragma D binding "1.5" IPPROTO_NONE
70inline int IPPROTO_NONE = @IPPROTO_NONE@;
71#pragma D binding "1.5" IPPROTO_DSTOPTS
72inline int IPPROTO_DSTOPTS = @IPPROTO_DSTOPTS@;
73#pragma D binding "1.5" IPPROTO_HELLO
74inline int IPPROTO_HELLO = @IPPROTO_HELLO@;
75#pragma D binding "1.5" IPPROTO_ND
76inline int IPPROTO_ND = @IPPROTO_ND@;
77#pragma D binding "1.5" IPPROTO_EON
78inline int IPPROTO_EON = @IPPROTO_EON@;
79#pragma D binding "1.5" IPPROTO_OSPF
80inline int IPPROTO_OSPF = @IPPROTO_OSPF@;
81#pragma D binding "1.5" IPPROTO_PIM
82inline int IPPROTO_PIM = @IPPROTO_PIM@;
83#pragma D binding "1.5" IPPROTO_SCTP
84inline int IPPROTO_SCTP = @IPPROTO_SCTP@;
85#pragma D binding "1.5" IPPROTO_RAW
86inline int IPPROTO_RAW = @IPPROTO_RAW@;
87#pragma D binding "1.5" IPPROTO_MAX
88inline int IPPROTO_MAX = @IPPROTO_MAX@;
89
90/*
91 * pktinfo is where packet ID info can be made available for deeper
92 * analysis if packet IDs become supported by the kernel in the future.
93 * The pkt_addr member is currently always NULL.
94 */
95typedef struct pktinfo {
96	uintptr_t pkt_addr;
97} pktinfo_t;
98
99/*
100 * csinfo is where connection state info is made available.
101 */
102typedef struct csinfo {
103	uintptr_t cs_addr;
104	uint64_t cs_cid;
105	pid_t cs_pid;
106	zoneid_t cs_zoneid;
107} csinfo_t;
108
109/*
110 * ipinfo contains common IP info for both IPv4 and IPv6.
111 */
112typedef struct ipinfo {
113	uint8_t ip_ver;			/* IP version (4, 6) */
114	uint32_t ip_plength;		/* payload length */
115	string ip_saddr;		/* source address */
116	string ip_daddr;		/* destination address */
117} ipinfo_t;
118
119/*
120 * ifinfo contains network interface info.
121 */
122typedef struct ifinfo {
123	string if_name;			/* interface name */
124	int8_t if_local;		/* is delivered locally */
125	netstackid_t if_ipstack;	/* ipstack ID */
126	uintptr_t if_addr;		/* pointer to raw ill_t */
127} ifinfo_t;
128
129/*
130 * ipv4info is a translated version of the IPv4 header (with raw pointer).
131 * These values are NULL if the packet is not IPv4.
132 */
133typedef struct ipv4info {
134	uint8_t ipv4_ver;		/* IP version (4) */
135	uint8_t ipv4_ihl;		/* header length, bytes */
136	uint8_t ipv4_tos;		/* type of service field */
137	uint16_t ipv4_length;		/* length (header + payload) */
138	uint16_t ipv4_ident;		/* identification */
139	uint8_t ipv4_flags;		/* IP flags */
140	uint16_t ipv4_offset;		/* fragment offset */
141	uint8_t ipv4_ttl;		/* time to live */
142	uint8_t ipv4_protocol;		/* next level protocol */
143	string ipv4_protostr;		/* next level protocol, as a string */
144	uint16_t ipv4_checksum;		/* header checksum */
145	ipaddr_t ipv4_src;		/* source address */
146	ipaddr_t ipv4_dst;		/* destination address */
147	string ipv4_saddr;		/* source address, string */
148	string ipv4_daddr;		/* destination address, string */
149	ipha_t *ipv4_hdr;		/* pointer to raw header */
150} ipv4info_t;
151
152/*
153 * ipv6info is a translated version of the IPv6 header (with raw pointer).
154 * These values are NULL if the packet is not IPv6.
155 */
156typedef struct ipv6info {
157	uint8_t ipv6_ver;		/* IP version (6) */
158	uint8_t ipv6_tclass;		/* traffic class */
159	uint32_t ipv6_flow;		/* flow label */
160	uint16_t ipv6_plen;		/* payload length */
161	uint8_t ipv6_nexthdr;		/* next header protocol */
162	string ipv6_nextstr;		/* next header protocol, as a string */
163	uint8_t ipv6_hlim;		/* hop limit */
164	in6_addr_t *ipv6_src;		/* source address */
165	in6_addr_t *ipv6_dst;		/* destination address */
166	string ipv6_saddr;		/* source address, string */
167	string ipv6_daddr;		/* destination address, string */
168	ip6_t *ipv6_hdr;		/* pointer to raw header */
169} ipv6info_t;
170
171/*
172 * void_ip_t is a void pointer to either an IPv4 or IPv6 header.  It has
173 * its own type name so that a translator can be determined.
174 */
175typedef uintptr_t void_ip_t;
176
177/*
178 * __dtrace_ipsr_ill_t is used by the translator to take an ill_t plus an
179 * additional arg6 from the ip:::send and ip:::recieve probes, and translate
180 * them to an ifinfo_t.
181 */
182typedef ill_t __dtrace_ipsr_ill_t;
183
184/*
185 * __dtrace_tcp_void_ip_t is used by the translator to take either the
186 * non-NULL void_ip_t * passed in or, if it is NULL, uses arg3 (tcp_t *)
187 * from the tcp:::send and tcp:::recieve probes to translate to an ipinfo_t.
188 * When no headers are available in the TCP fusion case for tcp:::send
189 * and tcp:::receive case, this allows us to present the consumer with header
190 * data based on the tcp_t * content in order to hide the implementation
191 * details of TCP fusion.
192 */
193typedef void * __dtrace_tcp_void_ip_t;
194
195#pragma D binding "1.5" translator
196translator pktinfo_t < mblk_t *M > {
197	pkt_addr = NULL;
198};
199
200#pragma D binding "1.5" translator
201translator csinfo_t < conn_t *C > {
202	cs_addr = NULL;
203};
204
205#pragma D binding "1.6.3" translator
206translator csinfo_t < ip_xmit_attr_t *C > {
207	cs_addr = (uintptr_t)C;
208	cs_cid = C ? C->ixa_conn_id : NULL;
209	cs_pid = C ? C->ixa_cpid : -1;
210	cs_zoneid = C ?
211	    (C->ixa_ipst == NULL || C->ixa_ipst->ips_netstack == NULL ||
212	    C->ixa_ipst->ips_netstack->netstack_stackid ==
213	    @GLOBAL_NETSTACKID@ ||
214	    C->ixa_cred == NULL ||
215	    C->ixa_cred->cr_zone == NULL ||
216	    C->ixa_cred->cr_uid == -1 ?
217	    C->ixa_zoneid : C->ixa_cred->cr_zone->zone_id) : -1;
218};
219
220#pragma D binding "1.5" translator
221translator ipinfo_t < ipha_t *I > {
222	ip_ver = I->ipha_version_and_hdr_length >> 4;
223	ip_plength = ntohs(I->ipha_length) -
224	    ((I->ipha_version_and_hdr_length & 0xf) << 2);
225	ip_saddr = inet_ntoa(&I->ipha_src);
226	ip_daddr = inet_ntoa(&I->ipha_dst);
227};
228
229#pragma D binding "1.5" translator
230translator ipinfo_t < ip6_t *I > {
231	ip_ver = *(uint8_t *)I >> 4;
232	ip_plength = ntohs(I->ip6_ctlun.ip6_un1.ip6_un1_plen);
233	ip_saddr = inet_ntoa6(&I->ip6_src);
234	ip_daddr = inet_ntoa6(&I->ip6_dst);
235};
236
237#pragma D binding "1.5" translator
238translator ipinfo_t < void_ip_t *I > {
239	ip_ver = I != NULL ? *(uint8_t *)I >> 4 : 0;
240	ip_plength = I != NULL ? (*(uint8_t *)I >> 4 == 4 ?
241	    ntohs(((ipha_t *)I)->ipha_length) -
242	    ((((ipha_t *)I)->ipha_version_and_hdr_length & 0xf) << 2) :
243	    *(uint8_t *)I >> 4 == 6 ?
244	    ntohs(((ip6_t *)I)->ip6_ctlun.ip6_un1.ip6_un1_plen) : 0) : 0;
245	ip_saddr = I != NULL ? (*(uint8_t *)I >> 4 == 4 ?
246	    inet_ntoa(&((ipha_t *)I)->ipha_src) : *(uint8_t *)I >> 4 == 6 ?
247	    inet_ntoa6(&((ip6_t *)I)->ip6_src) : "<unknown>") : "<unknown>";
248	ip_daddr = I != NULL ? (*(uint8_t *)I >> 4 == 4 ?
249	    inet_ntoa(&((ipha_t *)I)->ipha_dst) : *(uint8_t *)I >> 4 == 6 ?
250	    inet_ntoa6(&((ip6_t *)I)->ip6_dst) : "<unknown>") : "<unknown>";
251};
252
253#pragma D binding "1.5" translator
254translator ifinfo_t < __dtrace_ipsr_ill_t *I > {
255	if_name = I != NULL ? stringof(I->ill_name) : "<null>";
256	if_ipstack = I != NULL ? I->ill_ipst->ips_netstack->netstack_stackid
257	    : 0;
258	if_local = arg6;		/* probe dependent */
259	if_addr = (uintptr_t)I;
260};
261
262/*
263 * Translate to an ipinfo_t * from either the non-NULL void_ip_t * passed in,
264 * or use arg3 (tcp_t *) to fabricate ip header info.
265 */
266#pragma D binding "1.6.3" translator
267translator ipinfo_t < __dtrace_tcp_void_ip_t *I > {
268	ip_ver = I != NULL ? *(uint8_t *)I >> 4 :
269	    arg3 != NULL ? ((tcp_t *)arg3)->tcp_connp->conn_ipversion : 0;
270	ip_plength =
271	    I != NULL && *(uint8_t *)I >> 4 == 4 ?
272	    ntohs(((ipha_t *)I)->ipha_length) -
273	    ((((ipha_t *)I)->ipha_version_and_hdr_length & 0xf) << 2) :
274	    I != NULL && *(uint8_t *)I >> 4 == 6 ?
275	    ntohs(((ip6_t *)I)->ip6_ctlun.ip6_un1.ip6_un1_plen) :
276	    I != NULL ? 0 :
277	    arg3 != NULL && probename == "send" ?
278	    ((tcp_t *)arg3)->tcp_last_sent_len + @TCP_MIN_HEADER_LENGTH@ :
279	    arg3 != NULL && probename == "receive" ?
280	    ((tcp_t *)arg3)->tcp_last_recv_len + @TCP_MIN_HEADER_LENGTH@ :
281	    0;
282	ip_saddr =
283	    I != NULL && *(uint8_t *)I >> 4 == 4 ?
284	    inet_ntoa(&((ipha_t *)I)->ipha_src) :
285	    I != NULL && *(uint8_t *)I >> 4 == 6 ?
286	    inet_ntoa6(&((ip6_t *)I)->ip6_src) :
287	    I != NULL ? "<unknown>" :
288	    arg3 != NULL && probename == "send" ?
289	    inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_laddr):
290	    arg3 != NULL && probename == "receive" ?
291	    inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_faddr):
292	    "<unknown>";
293	ip_daddr =
294	    I != NULL && *(uint8_t *)I >> 4 == 4 ?
295	    inet_ntoa(&((ipha_t *)I)->ipha_dst) :
296	    I != NULL && *(uint8_t *)I >> 4 == 6 ?
297	    inet_ntoa6(&((ip6_t *)I)->ip6_dst) :
298	    I != NULL ? "<unknown>" :
299	    arg3 != NULL && probename == "send" ?
300	    inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_faddr):
301	    arg3 != NULL && probename == "receive" ?
302	    inet_ntoa6(&((tcp_t *)arg3)->tcp_connp->connua_v6addr.connua_laddr):
303	    "<unknown>";
304};
305
306#pragma D binding "1.5" translator
307translator ipv4info_t < ipha_t *I > {
308	ipv4_ver = I != NULL ? I->ipha_version_and_hdr_length >> 4 : 0;
309	ipv4_ihl = I != NULL ? (I->ipha_version_and_hdr_length & 0xf) << 2 : 0;
310	ipv4_tos = I != NULL ? I->ipha_type_of_service : 0;
311	ipv4_length = I != NULL ? ntohs(I->ipha_length) : 0;
312	ipv4_ident = I != NULL ? ntohs(I->ipha_ident) : 0;
313	ipv4_flags = I != NULL ? ntohs(I->ipha_fragment_offset_and_flags) >>
314	    13 : 0;
315	ipv4_offset = I != NULL ? ntohs(I->ipha_fragment_offset_and_flags) &
316	    0x1fff : 0;
317	ipv4_ttl = I != NULL ? I->ipha_ttl : 0;
318	ipv4_protocol = I != NULL ? I->ipha_protocol : 0;
319	ipv4_protostr = I == NULL ? "<null>" :
320	    I->ipha_protocol == IPPROTO_TCP     ? "TCP"    :
321	    I->ipha_protocol == IPPROTO_UDP     ? "UDP"    :
322	    I->ipha_protocol == IPPROTO_IP      ? "IP"     :
323	    I->ipha_protocol == IPPROTO_ICMP    ? "ICMP"   :
324	    I->ipha_protocol == IPPROTO_IGMP    ? "IGMP"   :
325	    I->ipha_protocol == IPPROTO_EGP     ? "EGP"    :
326	    I->ipha_protocol == IPPROTO_IPV6    ? "IPv6"   :
327	    I->ipha_protocol == IPPROTO_ROUTING ? "ROUTE"  :
328	    I->ipha_protocol == IPPROTO_ESP     ? "ESP"    :
329	    I->ipha_protocol == IPPROTO_AH      ? "AH"     :
330	    I->ipha_protocol == IPPROTO_ICMPV6  ? "ICMPv6" :
331	    I->ipha_protocol == IPPROTO_OSPF    ? "OSPF"   :
332	    I->ipha_protocol == IPPROTO_SCTP    ? "SCTP"   :
333	    I->ipha_protocol == IPPROTO_RAW     ? "RAW"    :
334	    lltostr((uint64_t)I->ipha_protocol);
335	ipv4_checksum = I != NULL ? ntohs(I->ipha_hdr_checksum) : 0;
336	ipv4_src = I != NULL ? I->ipha_src : 0;
337	ipv4_dst = I != NULL ? I->ipha_dst : 0;
338	ipv4_saddr = I != NULL ? inet_ntoa(&I->ipha_src) : "<null>";
339	ipv4_daddr = I != NULL ? inet_ntoa(&I->ipha_dst) : "<null>";
340	ipv4_hdr = I;
341};
342
343#pragma D binding "1.5" translator
344translator ipv6info_t < ip6_t *I > {
345	ipv6_ver = I != NULL ? I->ip6_ctlun.ip6_un2_vfc >> 4 : 0;
346	ipv6_tclass = I != NULL ? ((I->ip6_ctlun.ip6_un1.ip6_un1_flow &&
347	    0x0fffffff) >> 20) : 0;
348	ipv6_flow = I != NULL ? I->ip6_ctlun.ip6_un1.ip6_un1_flow &&
349	    0x000fffff : 0;
350	ipv6_plen = I != NULL ? ntohs(I->ip6_ctlun.ip6_un1.ip6_un1_plen) : 0;
351	ipv6_nexthdr = I != NULL ? I->ip6_ctlun.ip6_un1.ip6_un1_nxt : 0;
352	ipv6_nextstr = I == NULL ? "<null>" :
353	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_TCP     ? "TCP"    :
354	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_UDP     ? "UDP"    :
355	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_IP      ? "IP"     :
356	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ICMP    ? "ICMP"   :
357	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_IGMP    ? "IGMP"   :
358	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_EGP     ? "EGP"    :
359	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_IPV6    ? "IPv6"   :
360	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ROUTING ? "ROUTE"  :
361	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ESP     ? "ESP"    :
362	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_AH      ? "AH"     :
363	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ICMPV6  ? "ICMPv6" :
364	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_OSPF    ? "OSPF"   :
365	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_SCTP    ? "SCTP"   :
366	    I->ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_RAW     ? "RAW"    :
367	    lltostr((uint64_t)I->ip6_ctlun.ip6_un1.ip6_un1_nxt);
368	ipv6_hlim = I != NULL ? I->ip6_ctlun.ip6_un1.ip6_un1_hlim : 0;
369	ipv6_src = I != NULL ? &I->ip6_src : 0;
370	ipv6_dst = I != NULL ? &I->ip6_dst : 0;
371	ipv6_saddr = I != NULL ? inet_ntoa6(&I->ip6_src) : "<null>";
372	ipv6_daddr = I != NULL ? inet_ntoa6(&I->ip6_dst) : "<null>";
373	ipv6_hdr = I;
374};
375