xref: /freebsd/usr.bin/systat/sctp.c (revision 076ad2f836d5f49dc1375f1677335a48fe0d4b82)
1 /*-
2  * Copyright (c) 2015
3  * The Regents of the University of California.  All rights reserved.
4  * Michael Tuexen.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the University nor the names of its contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <sys/sysctl.h>
38 
39 #include <netinet/sctp.h>
40 
41 #include <stdlib.h>
42 #include <string.h>
43 
44 #include "systat.h"
45 #include "extern.h"
46 #include "mode.h"
47 
48 static struct sctpstat curstat, initstat, oldstat;
49 
50 /*-
51 --0         1         2         3         4         5         6         7
52 --0123456789012345678901234567890123456789012345678901234567890123456789012345
53 00             SCTP Associations                     SCTP Packets
54 01999999999999 associations initiated   999999999999 packets sent
55 02999999999999 associations accepted    999999999999 packets received
56 03999999999999 associations established 999999999999 - out of the blue
57 04999999999999 associations restarted   999999999999 - bad vtag
58 05999999999999 associations terminated  999999999999 - bad crc32c
59 06999999999999 associations aborted
60 07
61 08             SCTP Timers                           SCTP Chunks
62 09999999999999 init timeouts            999999999999 control chunks sent
63 10999999999999 cookie timeouts          999999999999 data chunks sent
64 11999999999999 data timeouts            999999999999 - ordered
65 12999999999999 delayed sack timeouts    999999999999 - unordered
66 13999999999999 shutdown timeouts        999999999999 control chunks received
67 14999999999999 shutdown-ack timeouts    999999999999 data chunks received
68 15999999999999 shutdown guard timeouts  999999999999 - ordered
69 16999999999999 heartbeat timeouts       999999999999 - unordered
70 17999999999999 path MTU timeouts
71 18999999999999 autoclose timeouts                    SCTP user messages
72 19999999999999 asconf timeouts          999999999999 fragmented
73 20999999999999 stream reset timeouts    999999999999 reassembled
74 --0123456789012345678901234567890123456789012345678901234567890123456789012345
75 --0         1         2         3         4         5         6         7
76 */
77 
78 WINDOW *
79 opensctp(void)
80 {
81 	return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
82 }
83 
84 void
85 closesctp(WINDOW *w)
86 {
87 	if (w != NULL) {
88 		wclear(w);
89 		wrefresh(w);
90 		delwin(w);
91 	}
92 }
93 
94 void
95 labelsctp(void)
96 {
97 	wmove(wnd, 0, 0); wclrtoeol(wnd);
98 #define L(row, str) mvwprintw(wnd, row, 13, str)
99 #define R(row, str) mvwprintw(wnd, row, 51, str);
100 	L(0, "SCTP Associations");		R(0, "SCTP Packets");
101 	L(1, "associations initiated");		R(1, "packets sent");
102 	L(2, "associations accepted");		R(2, "packets received");
103 	L(3, "associations established");	R(3, "- out of the blue");
104 	L(4, "associations restarted");		R(4, "- bad vtag");
105 	L(5, "associations terminated");	R(5, "- bad crc32c");
106 	L(6, "associations aborted");
107 
108 	L(8, "SCTP Timers");			R(8, "SCTP Chunks");
109 	L(9, "init timeouts");			R(9, "control chunks sent");
110 	L(10, "cookie timeouts");		R(10, "data chunks sent");
111 	L(11, "data timeouts");			R(11, "- ordered");
112 	L(12, "delayed sack timeouts");		R(12, "- unordered");
113 	L(13, "shutdown timeouts");		R(13, "control chunks received");
114 	L(14, "shutdown-ack timeouts");		R(14, "data chunks received");
115 	L(15, "shutdown guard timeouts");	R(15, "- ordered");
116 	L(16, "heartbeat timeouts");		R(16, "- unordered");
117 	L(17, "path MTU timeouts");
118 	L(18, "autoclose timeouts");		R(18, "SCTP User Messages");
119 	L(19, "asconf timeouts");		R(19, "fragmented");
120 	L(20, "stream reset timeouts");		R(20, "reassembled");
121 #undef L
122 #undef R
123 }
124 
125 static void
126 domode(struct sctpstat *ret)
127 {
128 	const struct sctpstat *sub;
129 	int divisor = 1;
130 
131 	switch(currentmode) {
132 	case display_RATE:
133 		sub = &oldstat;
134 		divisor = (delay > 1000000) ? delay / 1000000 : 1;
135 		break;
136 	case display_DELTA:
137 		sub = &oldstat;
138 		break;
139 	case display_SINCE:
140 		sub = &initstat;
141 		break;
142 	default:
143 		*ret = curstat;
144 		return;
145 	}
146 #define DO(stat) ret->stat = (curstat.stat - sub->stat) / divisor
147 	DO(sctps_currestab);
148 	DO(sctps_activeestab);
149 	DO(sctps_restartestab);
150 	DO(sctps_collisionestab);
151 	DO(sctps_passiveestab);
152 	DO(sctps_aborted);
153 	DO(sctps_shutdown);
154 	DO(sctps_outoftheblue);
155 	DO(sctps_checksumerrors);
156 	DO(sctps_outcontrolchunks);
157 	DO(sctps_outorderchunks);
158 	DO(sctps_outunorderchunks);
159 	DO(sctps_incontrolchunks);
160 	DO(sctps_inorderchunks);
161 	DO(sctps_inunorderchunks);
162 	DO(sctps_fragusrmsgs);
163 	DO(sctps_reasmusrmsgs);
164 	DO(sctps_outpackets);
165 	DO(sctps_inpackets);
166 
167 	DO(sctps_recvpackets);
168 	DO(sctps_recvdatagrams);
169 	DO(sctps_recvpktwithdata);
170 	DO(sctps_recvsacks);
171 	DO(sctps_recvdata);
172 	DO(sctps_recvdupdata);
173 	DO(sctps_recvheartbeat);
174 	DO(sctps_recvheartbeatack);
175 	DO(sctps_recvecne);
176 	DO(sctps_recvauth);
177 	DO(sctps_recvauthmissing);
178 	DO(sctps_recvivalhmacid);
179 	DO(sctps_recvivalkeyid);
180 	DO(sctps_recvauthfailed);
181 	DO(sctps_recvexpress);
182 	DO(sctps_recvexpressm);
183 	DO(sctps_recvnocrc);
184 	DO(sctps_recvswcrc);
185 	DO(sctps_recvhwcrc);
186 
187 	DO(sctps_sendpackets);
188 	DO(sctps_sendsacks);
189 	DO(sctps_senddata);
190 	DO(sctps_sendretransdata);
191 	DO(sctps_sendfastretrans);
192 	DO(sctps_sendmultfastretrans);
193 	DO(sctps_sendheartbeat);
194 	DO(sctps_sendecne);
195 	DO(sctps_sendauth);
196 	DO(sctps_senderrors);
197 	DO(sctps_sendnocrc);
198 	DO(sctps_sendswcrc);
199 	DO(sctps_sendhwcrc);
200 
201 	DO(sctps_pdrpfmbox);
202 	DO(sctps_pdrpfehos);
203 	DO(sctps_pdrpmbda);
204 	DO(sctps_pdrpmbct);
205 	DO(sctps_pdrpbwrpt);
206 	DO(sctps_pdrpcrupt);
207 	DO(sctps_pdrpnedat);
208 	DO(sctps_pdrppdbrk);
209 	DO(sctps_pdrptsnnf);
210 	DO(sctps_pdrpdnfnd);
211 	DO(sctps_pdrpdiwnp);
212 	DO(sctps_pdrpdizrw);
213 	DO(sctps_pdrpbadd);
214 	DO(sctps_pdrpmark);
215 
216 	DO(sctps_timoiterator);
217 	DO(sctps_timodata);
218 	DO(sctps_timowindowprobe);
219 	DO(sctps_timoinit);
220 	DO(sctps_timosack);
221 	DO(sctps_timoshutdown);
222 	DO(sctps_timoheartbeat);
223 	DO(sctps_timocookie);
224 	DO(sctps_timosecret);
225 	DO(sctps_timopathmtu);
226 	DO(sctps_timoshutdownack);
227 	DO(sctps_timoshutdownguard);
228 	DO(sctps_timostrmrst);
229 	DO(sctps_timoearlyfr);
230 	DO(sctps_timoasconf);
231 	DO(sctps_timodelprim);
232 	DO(sctps_timoautoclose);
233 	DO(sctps_timoassockill);
234 	DO(sctps_timoinpkill);
235 
236 	DO(sctps_hdrops);
237 	DO(sctps_badsum);
238 	DO(sctps_noport);
239 	DO(sctps_badvtag);
240 	DO(sctps_badsid);
241 	DO(sctps_nomem);
242 	DO(sctps_fastretransinrtt);
243 	DO(sctps_markedretrans);
244 	DO(sctps_naglesent);
245 	DO(sctps_naglequeued);
246 	DO(sctps_maxburstqueued);
247 	DO(sctps_ifnomemqueued);
248 	DO(sctps_windowprobed);
249 	DO(sctps_lowlevelerr);
250 	DO(sctps_lowlevelerrusr);
251 	DO(sctps_datadropchklmt);
252 	DO(sctps_datadroprwnd);
253 	DO(sctps_ecnereducedcwnd);
254 	DO(sctps_vtagexpress);
255 	DO(sctps_vtagbogus);
256 	DO(sctps_primary_randry);
257 	DO(sctps_cmt_randry);
258 	DO(sctps_slowpath_sack);
259 	DO(sctps_wu_sacks_sent);
260 	DO(sctps_sends_with_flags);
261 	DO(sctps_sends_with_unord);
262 	DO(sctps_sends_with_eof);
263 	DO(sctps_sends_with_abort);
264 	DO(sctps_protocol_drain_calls);
265 	DO(sctps_protocol_drains_done);
266 	DO(sctps_read_peeks);
267 	DO(sctps_cached_chk);
268 	DO(sctps_cached_strmoq);
269 	DO(sctps_left_abandon);
270 	DO(sctps_send_burst_avoid);
271 	DO(sctps_send_cwnd_avoid);
272 	DO(sctps_fwdtsn_map_over);
273 	DO(sctps_queue_upd_ecne);
274 #undef DO
275 }
276 
277 void
278 showsctp(void)
279 {
280 	struct sctpstat stats;
281 
282 	memset(&stats, 0, sizeof stats);
283 	domode(&stats);
284 
285 #define DO(stat, row, col) \
286 	mvwprintw(wnd, row, col, "%12lu", stats.stat)
287 #define	L(row, stat) DO(stat, row, 0)
288 #define	R(row, stat) DO(stat, row, 38)
289 	L(1, sctps_activeestab);	R(1, sctps_outpackets);
290 	L(2, sctps_passiveestab);	R(2, sctps_inpackets);
291 	L(3, sctps_currestab);		R(3, sctps_outoftheblue);
292 	L(4, sctps_restartestab);	R(4, sctps_badvtag);
293 	L(5, sctps_shutdown);		R(5, sctps_checksumerrors);
294 	L(6, sctps_aborted);
295 
296 
297 	L(9, sctps_timoinit);		R(9, sctps_outcontrolchunks);
298 	L(10, sctps_timocookie);	R(10, sctps_senddata);
299 	L(11, sctps_timodata);		R(11, sctps_outorderchunks);
300 	L(12, sctps_timosack);		R(12, sctps_outunorderchunks);
301 	L(13, sctps_timoshutdown);	R(13, sctps_incontrolchunks);
302 	L(14, sctps_timoshutdownack);	R(14, sctps_recvdata);
303 	L(15, sctps_timoshutdownguard);	R(15, sctps_inorderchunks);
304 	L(16, sctps_timoheartbeat);	R(16, sctps_inunorderchunks);
305 	L(17, sctps_timopathmtu);
306 	L(18, sctps_timoautoclose);
307 	L(19, sctps_timoasconf);	R(19, sctps_fragusrmsgs);
308 	L(20, sctps_timostrmrst);	R(20, sctps_reasmusrmsgs);
309 #undef DO
310 #undef L
311 #undef R
312 }
313 
314 int
315 initsctp(void)
316 {
317 	size_t len;
318 	const char *name = "net.inet.sctp.stats";
319 
320 	len = 0;
321 	if (sysctlbyname(name, NULL, &len, NULL, 0) < 0) {
322 		error("sysctl getting sctpstat size failed");
323 		return 0;
324 	}
325 	if (len > sizeof curstat) {
326 		error("sctpstat structure has grown--recompile systat!");
327 		return 0;
328 	}
329 	if (sysctlbyname(name, &initstat, &len, NULL, 0) < 0) {
330 		error("sysctl getting sctpstat failed");
331 		return 0;
332 	}
333 	oldstat = initstat;
334 	return 1;
335 }
336 
337 void
338 resetsctp(void)
339 {
340 	size_t len;
341 	const char *name = "net.inet.sctp.stats";
342 
343 	len = sizeof initstat;
344 	if (sysctlbyname(name, &initstat, &len, NULL, 0) < 0) {
345 		error("sysctl getting sctpstat failed");
346 	}
347 	oldstat = initstat;
348 }
349 
350 void
351 fetchsctp(void)
352 {
353 	size_t len;
354 	const char *name = "net.inet.sctp.stats";
355 
356 	oldstat = curstat;
357 	len = sizeof curstat;
358 	if (sysctlbyname(name, &curstat, &len, NULL, 0) < 0) {
359 		error("sysctl getting sctpstat failed");
360 	}
361 	return;
362 }
363