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