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