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) 2018 Michael Tuexen <tuexen@FreeBSD.org>
23 */
24
25#pragma D depends_on library ip.d
26#pragma D depends_on library socket.d
27#pragma D depends_on module kernel
28#pragma D depends_on provider sctp
29
30#pragma D binding "1.13" SCTP_STATE_MASK
31inline int32_t SCTP_STATE_MASK =		0x0000007f;
32#pragma D binding "1.13" SCTP_STATE_SHUTDOWN_PENDING
33inline int32_t SCTP_STATE_SHUTDOWN_PENDING =	0x00000080;
34#pragma D binding "1.13" SCTP_STATE_CLOSED_SOCKET
35inline int32_t SCTP_STATE_CLOSED_SOCKET =	0x00000100;
36#pragma D binding "1.13" SCTP_STATE_ABOUT_TO_BE_FREED
37inline int32_t SCTP_STATE_ABOUT_TO_BE_FREED =	0x00000200;
38#pragma D binding "1.13" SCTP_STATE_ABOUT_TO_BE_FREED
39inline int32_t SCTP_STATE_PARTIAL_MSG_LEFT =	0x00000400;
40#pragma D binding "1.13" SCTP_STATE_PARTIAL_MSG_LEFT
41inline int32_t SCTP_STATE_WAS_ABORTED =		0x00000800;
42#pragma D binding "1.13" SCTP_STATE_IN_ACCEPT_QUEUE
43inline int32_t SCTP_STATE_IN_ACCEPT_QUEUE =	0x00001000;
44#pragma D binding "1.13" SCTP_STATE_BOUND
45inline int32_t SCTP_STATE_BOUND =		0x00001000;
46#pragma D binding "1.13" SCTP_STATE_EMPTY
47inline int32_t SCTP_STATE_EMPTY =		0x00000000;
48#pragma D binding "1.13" SCTP_STATE_CLOSED
49inline int32_t SCTP_STATE_CLOSED =		0x00000000;
50#pragma D binding "1.13" SCTP_STATE_INUSE
51inline int32_t SCTP_STATE_INUSE =		0x00000001;
52#pragma D binding "1.13" SCTP_STATE_COOKIE_WAIT
53inline int32_t SCTP_STATE_COOKIE_WAIT =		0x00000002;
54#pragma D binding "1.13" SCTP_STATE_COOKIE_ECHOED
55inline int32_t SCTP_STATE_COOKIE_ECHOED =	0x00000004;
56#pragma D binding "1.13" SCTP_STATE_ESTABLISHED
57inline int32_t SCTP_STATE_ESTABLISHED =		0x00000008;
58#pragma D binding "1.13" SCTP_STATE_OPEN
59inline int32_t SCTP_STATE_OPEN =		0x00000008;
60#pragma D binding "1.13" SCTP_STATE_SHUTDOWN_SENT
61inline int32_t SCTP_STATE_SHUTDOWN_SENT =	0x00000010;
62#pragma D binding "1.13" SCTP_STATE_SHUTDOWN_RECEIVED
63inline int32_t SCTP_STATE_SHUTDOWN_RECEIVED =	0x00000020;
64#pragma D binding "1.13" SCTP_STATE_SHUTDOWN_ACK_SENT
65inline int32_t SCTP_STATE_SHUTDOWN_ACK_SENT =	0x00000040;
66
67/* SCTP association state strings. */
68#pragma D binding "1.13" sctp_state_string
69inline string sctp_state_string[int32_t state] =
70	state & SCTP_STATE_ABOUT_TO_BE_FREED ?				"state-closed" :
71	state & SCTP_STATE_SHUTDOWN_PENDING ?				"state-shutdown-pending" :
72	(state & SCTP_STATE_MASK) == SCTP_STATE_EMPTY ?			"state-closed" :
73	(state & SCTP_STATE_MASK) == SCTP_STATE_INUSE ?			"state-closed" :
74	(state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_WAIT ?		"state-cookie-wait" :
75	(state & SCTP_STATE_MASK) == SCTP_STATE_COOKIE_ECHOED ?		"state-cookie-echoed" :
76	(state & SCTP_STATE_MASK) == SCTP_STATE_OPEN ?			"state-established" :
77	(state & SCTP_STATE_MASK) == SCTP_STATE_SHUTDOWN_SENT ?		"state-shutdown-sent" :
78	(state & SCTP_STATE_MASK) == SCTP_STATE_SHUTDOWN_RECEIVED ?	"state-shutdown-received" :
79	(state & SCTP_STATE_MASK) == SCTP_STATE_SHUTDOWN_ACK_SENT ?	"state-shutdown-ack-sent" :
80	"<unknown>";
81
82/*
83 * sctpsinfo contains stable SCTP details.
84 */
85typedef struct sctpsinfo {
86	uintptr_t sctps_addr;			/* pointer to struct sctp_tcb */
87	int sctps_num_raddrs;			/* number of remote addresses */
88	uintptr_t sctps_raddrs;			/* pointer to struct sctp_nets */
89	int sctps_num_laddrs;			/* number of local addresses */
90	uintptr_t sctps_laddrs;			/* pointer to struct sctp_laddr */
91	uint16_t sctps_lport;			/* local port */
92	uint16_t sctps_rport;			/* remote port */
93	string sctps_laddr;			/* local address, as a string */
94	string sctps_raddr;			/* remote address, as a string */
95	int32_t sctps_state;
96} sctpsinfo_t;
97
98/*
99 * sctplsinfo provides the old SCTP state for state changes.
100 */
101typedef struct sctplsinfo {
102	int32_t sctps_state;			/* previous SCTP state */
103} sctplsinfo_t;
104
105/*
106 * sctpinfo is the SCTP header fields.
107 */
108typedef struct sctpinfo {
109	uint16_t sctp_sport;			/* source port */
110	uint16_t sctp_dport;			/* destination port */
111	uint32_t sctp_verify;			/* verification tag */
112	uint32_t sctp_checksum;			/* CRC32C of the SCTP packet */
113	struct sctphdr *sctp_hdr;		/* raw SCTP header */
114} sctpinfo_t;
115
116#pragma D binding "1.13" translator
117translator csinfo_t < struct sctp_tcb *p > {
118	cs_addr =	NULL;
119	cs_cid =	(uint64_t)p;
120	cs_pid =	0;
121	cs_zoneid =	0;
122};
123
124#pragma D binding "1.13" translator
125translator sctpsinfo_t < struct sctp_tcb *p > {
126	sctps_addr =		(uintptr_t)p;
127	sctps_num_raddrs =	p == NULL ? -1 : p->asoc.numnets;
128	sctps_raddrs =		p == NULL ? NULL : (uintptr_t)(p->asoc.nets.tqh_first);
129	sctps_num_laddrs =	p == NULL ? -1 :
130	    p->sctp_ep == NULL ? -1 :
131	    p->sctp_ep->laddr_count;
132	sctps_laddrs =		p == NULL ? NULL :
133	    p->sctp_ep == NULL ? NULL :
134	    (uintptr_t)(p->sctp_ep->sctp_addr_list.lh_first);
135	sctps_lport =		p == NULL ? 0 :
136	    p->sctp_ep == NULL ? 0 :
137	    ntohs(p->sctp_ep->ip_inp.inp.inp_inc.inc_ie.ie_lport);
138	sctps_rport =		p == NULL ? 0 : ntohs(p->rport);
139	sctps_laddr =		p == NULL ? "<unknown>" :
140	    p->asoc.primary_destination == NULL ? "<unknown>" :
141	    p->asoc.primary_destination->ro._s_addr == NULL ? "<unknown>" :
142	    p->asoc.primary_destination->ro._s_addr->address.sa.sa_family == AF_INET ?
143	    inet_ntoa(&p->asoc.primary_destination->ro._s_addr->address.sin.sin_addr.s_addr) :
144	    p->asoc.primary_destination->ro._s_addr->address.sa.sa_family == AF_INET6 ?
145	    inet_ntoa6(&p->asoc.primary_destination->ro._s_addr->address.sin6.sin6_addr) :
146	    "<unknown>";
147	sctps_raddr =		p == NULL ? "<unknown>" :
148	    p->asoc.primary_destination == NULL ? "<unknown>" :
149	    p->asoc.primary_destination->ro._l_addr.sa.sa_family == AF_INET ?
150	    inet_ntoa(&p->asoc.primary_destination->ro._l_addr.sin.sin_addr.s_addr) :
151	    p->asoc.primary_destination->ro._l_addr.sa.sa_family == AF_INET6 ?
152	    inet_ntoa6(&p->asoc.primary_destination->ro._l_addr.sin6.sin6_addr) :
153	    "<unknown>";
154	sctps_state =		p == NULL ? SCTP_STATE_CLOSED : p->asoc.state;
155};
156
157#pragma D binding "1.13" translator
158translator sctpinfo_t < struct sctphdr *p > {
159	sctp_sport =		p == NULL ? 0 : ntohs(p->src_port);
160	sctp_dport =		p == NULL ? 0 : ntohs(p->dest_port);
161	sctp_verify =		p == NULL ? 0 : ntohl(p->v_tag);
162	sctp_checksum =		p == NULL ? 0 : ntohl(p->checksum);
163	sctp_hdr =		p;
164};
165
166#pragma D binding "1.13" translator
167translator sctplsinfo_t < int state > {
168	sctps_state = state;
169};
170