1289873Stuexen/*-
2289873Stuexen * Copyright (c) 2015
3289873Stuexen * The Regents of the University of California.  All rights reserved.
4289873Stuexen * Michael Tuexen.  All rights reserved.
5289873Stuexen *
6289873Stuexen * Redistribution and use in source and binary forms, with or without
7289873Stuexen * modification, are permitted provided that the following conditions
8289873Stuexen * are met:
9289873Stuexen * 1. Redistributions of source code must retain the above copyright
10289873Stuexen *    notice, this list of conditions and the following disclaimer.
11289873Stuexen * 2. Redistributions in binary form must reproduce the above copyright
12289873Stuexen *    notice, this list of conditions and the following disclaimer in the
13289873Stuexen *    documentation and/or other materials provided with the distribution.
14289873Stuexen * 4. Neither the name of the University nor the names of its contributors
15289873Stuexen *    may be used to endorse or promote products derived from this software
16289873Stuexen *    without specific prior written permission.
17289873Stuexen *
18289873Stuexen * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19289873Stuexen * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20289873Stuexen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21289873Stuexen * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22289873Stuexen * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23289873Stuexen * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24289873Stuexen * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25289873Stuexen * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26289873Stuexen * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27289873Stuexen * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28289873Stuexen * SUCH DAMAGE.
29289873Stuexen */
30289873Stuexen
31289873Stuexen#include <sys/cdefs.h>
32289873Stuexen__FBSDID("$FreeBSD: stable/11/usr.bin/systat/sctp.c 332637 2018-04-16 21:22:12Z tuexen $");
33289873Stuexen
34289873Stuexen#include <sys/param.h>
35289873Stuexen#include <sys/types.h>
36289873Stuexen#include <sys/socket.h>
37289873Stuexen#include <sys/sysctl.h>
38289873Stuexen
39289873Stuexen#include <netinet/sctp.h>
40289873Stuexen
41289873Stuexen#include <stdlib.h>
42289873Stuexen#include <string.h>
43289873Stuexen
44289873Stuexen#include "systat.h"
45289873Stuexen#include "extern.h"
46289873Stuexen#include "mode.h"
47289873Stuexen
48289873Stuexenstatic struct sctpstat curstat, initstat, oldstat;
49289873Stuexen
50289873Stuexen/*-
51289873Stuexen--0         1         2         3         4         5         6         7
52289873Stuexen--0123456789012345678901234567890123456789012345678901234567890123456789012345
53289873Stuexen00             SCTP Associations                     SCTP Packets
54289873Stuexen01999999999999 associations initiated   999999999999 packets sent
55289873Stuexen02999999999999 associations accepted    999999999999 packets received
56332637Stuexen03999999999999 associations restarted   999999999999 - out of the blue
57332637Stuexen04999999999999 associations terminated  999999999999 - bad vtag
58332637Stuexen05999999999999 associations aborted     999999999999 - bad crc32c
59332637Stuexen06
60332637Stuexen07             SCTP Timers                           SCTP Chunks
61332637Stuexen08999999999999 init timeouts            999999999999 control chunks sent
62332637Stuexen09999999999999 cookie timeouts          999999999999 data chunks sent
63332637Stuexen10999999999999 data timeouts            999999999999 - ordered
64332637Stuexen11999999999999 delayed sack timeouts    999999999999 - unordered
65332637Stuexen12999999999999 shutdown timeouts        999999999999 control chunks received
66332637Stuexen13999999999999 shutdown-ack timeouts    999999999999 data chunks received
67332637Stuexen14999999999999 shutdown guard timeouts  999999999999 - ordered
68332637Stuexen15999999999999 heartbeat timeouts       999999999999 - unordered
69332637Stuexen16999999999999 path MTU timeouts
70332637Stuexen17999999999999 autoclose timeouts                    SCTP user messages
71332637Stuexen18999999999999 asconf timeouts          999999999999 fragmented
72332637Stuexen19999999999999 stream reset timeouts    999999999999 reassembled
73289873Stuexen--0123456789012345678901234567890123456789012345678901234567890123456789012345
74289873Stuexen--0         1         2         3         4         5         6         7
75289873Stuexen*/
76289873Stuexen
77289873StuexenWINDOW *
78289873Stuexenopensctp(void)
79289873Stuexen{
80289873Stuexen	return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
81289873Stuexen}
82289873Stuexen
83289873Stuexenvoid
84289873Stuexenclosesctp(WINDOW *w)
85289873Stuexen{
86289873Stuexen	if (w != NULL) {
87289873Stuexen		wclear(w);
88289873Stuexen		wrefresh(w);
89289873Stuexen		delwin(w);
90289873Stuexen	}
91289873Stuexen}
92289873Stuexen
93289873Stuexenvoid
94289873Stuexenlabelsctp(void)
95289873Stuexen{
96289873Stuexen	wmove(wnd, 0, 0); wclrtoeol(wnd);
97289873Stuexen#define L(row, str) mvwprintw(wnd, row, 13, str)
98289873Stuexen#define R(row, str) mvwprintw(wnd, row, 51, str);
99289873Stuexen	L(0, "SCTP Associations");		R(0, "SCTP Packets");
100289873Stuexen	L(1, "associations initiated");		R(1, "packets sent");
101289873Stuexen	L(2, "associations accepted");		R(2, "packets received");
102332637Stuexen	L(3, "associations restarted");		R(3, "- out of the blue");
103332637Stuexen	L(4, "associations terminated");	R(4, "- bad vtag");
104332637Stuexen	L(5, "associations aborted");		R(5, "- bad crc32c");
105289873Stuexen
106332637Stuexen	L(7, "SCTP Timers");			R(7, "SCTP Chunks");
107332637Stuexen	L(8, "init timeouts");			R(8, "control chunks sent");
108332637Stuexen	L(9, "cookie timeouts");		R(9, "data chunks sent");
109332637Stuexen	L(10, "data timeouts");			R(10, "- ordered");
110332637Stuexen	L(11, "delayed sack timeouts");		R(11, "- unordered");
111332637Stuexen	L(12, "shutdown timeouts");		R(12, "control chunks received");
112332637Stuexen	L(13, "shutdown-ack timeouts");		R(13, "data chunks received");
113332637Stuexen	L(14, "shutdown guard timeouts");	R(14, "- ordered");
114332637Stuexen	L(15, "heartbeat timeouts");		R(15, "- unordered");
115332637Stuexen	L(16, "path MTU timeouts");
116332637Stuexen	L(17, "autoclose timeouts");		R(17, "SCTP User Messages");
117332637Stuexen	L(18, "asconf timeouts");		R(18, "fragmented");
118332637Stuexen	L(19, "stream reset timeouts");		R(19, "reassembled");
119289873Stuexen#undef L
120289873Stuexen#undef R
121289873Stuexen}
122289873Stuexen
123289873Stuexenstatic void
124289873Stuexendomode(struct sctpstat *ret)
125289873Stuexen{
126289873Stuexen	const struct sctpstat *sub;
127289873Stuexen	int divisor = 1;
128289873Stuexen
129289873Stuexen	switch(currentmode) {
130289873Stuexen	case display_RATE:
131289873Stuexen		sub = &oldstat;
132289873Stuexen		divisor = (delay > 1000000) ? delay / 1000000 : 1;
133289873Stuexen		break;
134289873Stuexen	case display_DELTA:
135289873Stuexen		sub = &oldstat;
136289873Stuexen		break;
137289873Stuexen	case display_SINCE:
138289873Stuexen		sub = &initstat;
139289873Stuexen		break;
140289873Stuexen	default:
141289873Stuexen		*ret = curstat;
142289873Stuexen		return;
143289873Stuexen	}
144289873Stuexen#define DO(stat) ret->stat = (curstat.stat - sub->stat) / divisor
145289873Stuexen	DO(sctps_currestab);
146289873Stuexen	DO(sctps_activeestab);
147289873Stuexen	DO(sctps_restartestab);
148289873Stuexen	DO(sctps_collisionestab);
149289873Stuexen	DO(sctps_passiveestab);
150289873Stuexen	DO(sctps_aborted);
151289873Stuexen	DO(sctps_shutdown);
152289873Stuexen	DO(sctps_outoftheblue);
153289873Stuexen	DO(sctps_checksumerrors);
154289873Stuexen	DO(sctps_outcontrolchunks);
155289873Stuexen	DO(sctps_outorderchunks);
156289873Stuexen	DO(sctps_outunorderchunks);
157289873Stuexen	DO(sctps_incontrolchunks);
158289873Stuexen	DO(sctps_inorderchunks);
159289873Stuexen	DO(sctps_inunorderchunks);
160289873Stuexen	DO(sctps_fragusrmsgs);
161289873Stuexen	DO(sctps_reasmusrmsgs);
162289873Stuexen	DO(sctps_outpackets);
163289873Stuexen	DO(sctps_inpackets);
164289873Stuexen
165289873Stuexen	DO(sctps_recvpackets);
166289873Stuexen	DO(sctps_recvdatagrams);
167289873Stuexen	DO(sctps_recvpktwithdata);
168289873Stuexen	DO(sctps_recvsacks);
169289873Stuexen	DO(sctps_recvdata);
170289873Stuexen	DO(sctps_recvdupdata);
171289873Stuexen	DO(sctps_recvheartbeat);
172289873Stuexen	DO(sctps_recvheartbeatack);
173289873Stuexen	DO(sctps_recvecne);
174289873Stuexen	DO(sctps_recvauth);
175289873Stuexen	DO(sctps_recvauthmissing);
176289873Stuexen	DO(sctps_recvivalhmacid);
177289873Stuexen	DO(sctps_recvivalkeyid);
178289873Stuexen	DO(sctps_recvauthfailed);
179289873Stuexen	DO(sctps_recvexpress);
180289873Stuexen	DO(sctps_recvexpressm);
181289873Stuexen	DO(sctps_recvswcrc);
182289873Stuexen	DO(sctps_recvhwcrc);
183289873Stuexen
184289873Stuexen	DO(sctps_sendpackets);
185289873Stuexen	DO(sctps_sendsacks);
186289873Stuexen	DO(sctps_senddata);
187289873Stuexen	DO(sctps_sendretransdata);
188289873Stuexen	DO(sctps_sendfastretrans);
189289873Stuexen	DO(sctps_sendmultfastretrans);
190289873Stuexen	DO(sctps_sendheartbeat);
191289873Stuexen	DO(sctps_sendecne);
192289873Stuexen	DO(sctps_sendauth);
193289873Stuexen	DO(sctps_senderrors);
194289873Stuexen	DO(sctps_sendswcrc);
195289873Stuexen	DO(sctps_sendhwcrc);
196289873Stuexen
197289873Stuexen	DO(sctps_pdrpfmbox);
198289873Stuexen	DO(sctps_pdrpfehos);
199289873Stuexen	DO(sctps_pdrpmbda);
200289873Stuexen	DO(sctps_pdrpmbct);
201289873Stuexen	DO(sctps_pdrpbwrpt);
202289873Stuexen	DO(sctps_pdrpcrupt);
203289873Stuexen	DO(sctps_pdrpnedat);
204289873Stuexen	DO(sctps_pdrppdbrk);
205289873Stuexen	DO(sctps_pdrptsnnf);
206289873Stuexen	DO(sctps_pdrpdnfnd);
207289873Stuexen	DO(sctps_pdrpdiwnp);
208289873Stuexen	DO(sctps_pdrpdizrw);
209289873Stuexen	DO(sctps_pdrpbadd);
210289873Stuexen	DO(sctps_pdrpmark);
211289873Stuexen
212289873Stuexen	DO(sctps_timoiterator);
213289873Stuexen	DO(sctps_timodata);
214289873Stuexen	DO(sctps_timowindowprobe);
215289873Stuexen	DO(sctps_timoinit);
216289873Stuexen	DO(sctps_timosack);
217289873Stuexen	DO(sctps_timoshutdown);
218289873Stuexen	DO(sctps_timoheartbeat);
219289873Stuexen	DO(sctps_timocookie);
220289873Stuexen	DO(sctps_timosecret);
221289873Stuexen	DO(sctps_timopathmtu);
222289873Stuexen	DO(sctps_timoshutdownack);
223289873Stuexen	DO(sctps_timoshutdownguard);
224289873Stuexen	DO(sctps_timostrmrst);
225289873Stuexen	DO(sctps_timoearlyfr);
226289873Stuexen	DO(sctps_timoasconf);
227289873Stuexen	DO(sctps_timodelprim);
228289873Stuexen	DO(sctps_timoautoclose);
229289873Stuexen	DO(sctps_timoassockill);
230289873Stuexen	DO(sctps_timoinpkill);
231289873Stuexen
232289873Stuexen	DO(sctps_hdrops);
233289873Stuexen	DO(sctps_badsum);
234289873Stuexen	DO(sctps_noport);
235289873Stuexen	DO(sctps_badvtag);
236289873Stuexen	DO(sctps_badsid);
237289873Stuexen	DO(sctps_nomem);
238289873Stuexen	DO(sctps_fastretransinrtt);
239289873Stuexen	DO(sctps_markedretrans);
240289873Stuexen	DO(sctps_naglesent);
241289873Stuexen	DO(sctps_naglequeued);
242289873Stuexen	DO(sctps_maxburstqueued);
243289873Stuexen	DO(sctps_ifnomemqueued);
244289873Stuexen	DO(sctps_windowprobed);
245289873Stuexen	DO(sctps_lowlevelerr);
246289873Stuexen	DO(sctps_lowlevelerrusr);
247289873Stuexen	DO(sctps_datadropchklmt);
248289873Stuexen	DO(sctps_datadroprwnd);
249289873Stuexen	DO(sctps_ecnereducedcwnd);
250289873Stuexen	DO(sctps_vtagexpress);
251289873Stuexen	DO(sctps_vtagbogus);
252289873Stuexen	DO(sctps_primary_randry);
253289873Stuexen	DO(sctps_cmt_randry);
254289873Stuexen	DO(sctps_slowpath_sack);
255289873Stuexen	DO(sctps_wu_sacks_sent);
256289873Stuexen	DO(sctps_sends_with_flags);
257289873Stuexen	DO(sctps_sends_with_unord);
258289873Stuexen	DO(sctps_sends_with_eof);
259289873Stuexen	DO(sctps_sends_with_abort);
260289873Stuexen	DO(sctps_protocol_drain_calls);
261289873Stuexen	DO(sctps_protocol_drains_done);
262289873Stuexen	DO(sctps_read_peeks);
263289873Stuexen	DO(sctps_cached_chk);
264289873Stuexen	DO(sctps_cached_strmoq);
265289873Stuexen	DO(sctps_left_abandon);
266289873Stuexen	DO(sctps_send_burst_avoid);
267289873Stuexen	DO(sctps_send_cwnd_avoid);
268289873Stuexen	DO(sctps_fwdtsn_map_over);
269289873Stuexen	DO(sctps_queue_upd_ecne);
270289873Stuexen#undef DO
271289873Stuexen}
272289873Stuexen
273289873Stuexenvoid
274289873Stuexenshowsctp(void)
275289873Stuexen{
276289873Stuexen	struct sctpstat stats;
277289873Stuexen
278289873Stuexen	memset(&stats, 0, sizeof stats);
279289873Stuexen	domode(&stats);
280289873Stuexen
281289873Stuexen#define DO(stat, row, col) \
282289873Stuexen	mvwprintw(wnd, row, col, "%12lu", stats.stat)
283289873Stuexen#define	L(row, stat) DO(stat, row, 0)
284289873Stuexen#define	R(row, stat) DO(stat, row, 38)
285289873Stuexen	L(1, sctps_activeestab);	R(1, sctps_outpackets);
286289873Stuexen	L(2, sctps_passiveestab);	R(2, sctps_inpackets);
287332637Stuexen	L(3, sctps_restartestab);	R(3, sctps_outoftheblue);
288332637Stuexen	L(4, sctps_shutdown);		R(4, sctps_badvtag);
289332637Stuexen	L(5, sctps_aborted);		R(5, sctps_checksumerrors);
290289873Stuexen
291289873Stuexen
292332637Stuexen	L(8, sctps_timoinit);		R(8, sctps_outcontrolchunks);
293332637Stuexen	L(9, sctps_timocookie);		R(9, sctps_senddata);
294332637Stuexen	L(10, sctps_timodata);		R(10, sctps_outorderchunks);
295332637Stuexen	L(11, sctps_timosack);		R(11, sctps_outunorderchunks);
296332637Stuexen	L(12, sctps_timoshutdown);	R(12, sctps_incontrolchunks);
297332637Stuexen	L(13, sctps_timoshutdownack);	R(13, sctps_recvdata);
298332637Stuexen	L(14, sctps_timoshutdownguard);	R(14, sctps_inorderchunks);
299332637Stuexen	L(15, sctps_timoheartbeat);	R(15, sctps_inunorderchunks);
300332637Stuexen	L(16, sctps_timopathmtu);
301332637Stuexen	L(17, sctps_timoautoclose);
302332637Stuexen	L(18, sctps_timoasconf);	R(18, sctps_fragusrmsgs);
303332637Stuexen	L(19, sctps_timostrmrst);	R(19, sctps_reasmusrmsgs);
304289873Stuexen#undef DO
305289873Stuexen#undef L
306289873Stuexen#undef R
307289873Stuexen}
308289873Stuexen
309289873Stuexenint
310289873Stuexeninitsctp(void)
311289873Stuexen{
312289873Stuexen	size_t len;
313289873Stuexen	const char *name = "net.inet.sctp.stats";
314289873Stuexen
315289873Stuexen	len = 0;
316289873Stuexen	if (sysctlbyname(name, NULL, &len, NULL, 0) < 0) {
317289873Stuexen		error("sysctl getting sctpstat size failed");
318289873Stuexen		return 0;
319289873Stuexen	}
320289873Stuexen	if (len > sizeof curstat) {
321289873Stuexen		error("sctpstat structure has grown--recompile systat!");
322289873Stuexen		return 0;
323289873Stuexen	}
324289873Stuexen	if (sysctlbyname(name, &initstat, &len, NULL, 0) < 0) {
325289873Stuexen		error("sysctl getting sctpstat failed");
326289873Stuexen		return 0;
327289873Stuexen	}
328289873Stuexen	oldstat = initstat;
329289873Stuexen	return 1;
330289873Stuexen}
331289873Stuexen
332289873Stuexenvoid
333289873Stuexenresetsctp(void)
334289873Stuexen{
335289873Stuexen	size_t len;
336289873Stuexen	const char *name = "net.inet.sctp.stats";
337289873Stuexen
338289873Stuexen	len = sizeof initstat;
339289873Stuexen	if (sysctlbyname(name, &initstat, &len, NULL, 0) < 0) {
340289873Stuexen		error("sysctl getting sctpstat failed");
341289873Stuexen	}
342289873Stuexen	oldstat = initstat;
343289873Stuexen}
344289873Stuexen
345289873Stuexenvoid
346289873Stuexenfetchsctp(void)
347289873Stuexen{
348289873Stuexen	size_t len;
349289873Stuexen	const char *name = "net.inet.sctp.stats";
350289873Stuexen
351289873Stuexen	oldstat = curstat;
352289873Stuexen	len = sizeof curstat;
353289873Stuexen	if (sysctlbyname(name, &curstat, &len, NULL, 0) < 0) {
354289873Stuexen		error("sysctl getting sctpstat failed");
355289873Stuexen	}
356289873Stuexen	return;
357289873Stuexen}
358