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 * 4. 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: stable/11/usr.bin/systat/sctp.c 332637 2018-04-16 21:22:12Z tuexen $"); 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 48static struct sctpstat curstat, initstat, oldstat; 49 50/*- 51--0 1 2 3 4 5 6 7 52--0123456789012345678901234567890123456789012345678901234567890123456789012345 5300 SCTP Associations SCTP Packets 5401999999999999 associations initiated 999999999999 packets sent 5502999999999999 associations accepted 999999999999 packets received 5603999999999999 associations restarted 999999999999 - out of the blue 5704999999999999 associations terminated 999999999999 - bad vtag 5805999999999999 associations aborted 999999999999 - bad crc32c 5906 6007 SCTP Timers SCTP Chunks 6108999999999999 init timeouts 999999999999 control chunks sent 6209999999999999 cookie timeouts 999999999999 data chunks sent 6310999999999999 data timeouts 999999999999 - ordered 6411999999999999 delayed sack timeouts 999999999999 - unordered 6512999999999999 shutdown timeouts 999999999999 control chunks received 6613999999999999 shutdown-ack timeouts 999999999999 data chunks received 6714999999999999 shutdown guard timeouts 999999999999 - ordered 6815999999999999 heartbeat timeouts 999999999999 - unordered 6916999999999999 path MTU timeouts 7017999999999999 autoclose timeouts SCTP user messages 7118999999999999 asconf timeouts 999999999999 fragmented 7219999999999999 stream reset timeouts 999999999999 reassembled 73--0123456789012345678901234567890123456789012345678901234567890123456789012345 74--0 1 2 3 4 5 6 7 75*/ 76 77WINDOW * 78opensctp(void) 79{ 80 return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); 81} 82 83void 84closesctp(WINDOW *w) 85{ 86 if (w != NULL) { 87 wclear(w); 88 wrefresh(w); 89 delwin(w); 90 } 91} 92 93void 94labelsctp(void) 95{ 96 wmove(wnd, 0, 0); wclrtoeol(wnd); 97#define L(row, str) mvwprintw(wnd, row, 13, str) 98#define R(row, str) mvwprintw(wnd, row, 51, str); 99 L(0, "SCTP Associations"); R(0, "SCTP Packets"); 100 L(1, "associations initiated"); R(1, "packets sent"); 101 L(2, "associations accepted"); R(2, "packets received"); 102 L(3, "associations restarted"); R(3, "- out of the blue"); 103 L(4, "associations terminated"); R(4, "- bad vtag"); 104 L(5, "associations aborted"); R(5, "- bad crc32c"); 105 106 L(7, "SCTP Timers"); R(7, "SCTP Chunks"); 107 L(8, "init timeouts"); R(8, "control chunks sent"); 108 L(9, "cookie timeouts"); R(9, "data chunks sent"); 109 L(10, "data timeouts"); R(10, "- ordered"); 110 L(11, "delayed sack timeouts"); R(11, "- unordered"); 111 L(12, "shutdown timeouts"); R(12, "control chunks received"); 112 L(13, "shutdown-ack timeouts"); R(13, "data chunks received"); 113 L(14, "shutdown guard timeouts"); R(14, "- ordered"); 114 L(15, "heartbeat timeouts"); R(15, "- unordered"); 115 L(16, "path MTU timeouts"); 116 L(17, "autoclose timeouts"); R(17, "SCTP User Messages"); 117 L(18, "asconf timeouts"); R(18, "fragmented"); 118 L(19, "stream reset timeouts"); R(19, "reassembled"); 119#undef L 120#undef R 121} 122 123static void 124domode(struct sctpstat *ret) 125{ 126 const struct sctpstat *sub; 127 int divisor = 1; 128 129 switch(currentmode) { 130 case display_RATE: 131 sub = &oldstat; 132 divisor = (delay > 1000000) ? delay / 1000000 : 1; 133 break; 134 case display_DELTA: 135 sub = &oldstat; 136 break; 137 case display_SINCE: 138 sub = &initstat; 139 break; 140 default: 141 *ret = curstat; 142 return; 143 } 144#define DO(stat) ret->stat = (curstat.stat - sub->stat) / divisor 145 DO(sctps_currestab); 146 DO(sctps_activeestab); 147 DO(sctps_restartestab); 148 DO(sctps_collisionestab); 149 DO(sctps_passiveestab); 150 DO(sctps_aborted); 151 DO(sctps_shutdown); 152 DO(sctps_outoftheblue); 153 DO(sctps_checksumerrors); 154 DO(sctps_outcontrolchunks); 155 DO(sctps_outorderchunks); 156 DO(sctps_outunorderchunks); 157 DO(sctps_incontrolchunks); 158 DO(sctps_inorderchunks); 159 DO(sctps_inunorderchunks); 160 DO(sctps_fragusrmsgs); 161 DO(sctps_reasmusrmsgs); 162 DO(sctps_outpackets); 163 DO(sctps_inpackets); 164 165 DO(sctps_recvpackets); 166 DO(sctps_recvdatagrams); 167 DO(sctps_recvpktwithdata); 168 DO(sctps_recvsacks); 169 DO(sctps_recvdata); 170 DO(sctps_recvdupdata); 171 DO(sctps_recvheartbeat); 172 DO(sctps_recvheartbeatack); 173 DO(sctps_recvecne); 174 DO(sctps_recvauth); 175 DO(sctps_recvauthmissing); 176 DO(sctps_recvivalhmacid); 177 DO(sctps_recvivalkeyid); 178 DO(sctps_recvauthfailed); 179 DO(sctps_recvexpress); 180 DO(sctps_recvexpressm); 181 DO(sctps_recvswcrc); 182 DO(sctps_recvhwcrc); 183 184 DO(sctps_sendpackets); 185 DO(sctps_sendsacks); 186 DO(sctps_senddata); 187 DO(sctps_sendretransdata); 188 DO(sctps_sendfastretrans); 189 DO(sctps_sendmultfastretrans); 190 DO(sctps_sendheartbeat); 191 DO(sctps_sendecne); 192 DO(sctps_sendauth); 193 DO(sctps_senderrors); 194 DO(sctps_sendswcrc); 195 DO(sctps_sendhwcrc); 196 197 DO(sctps_pdrpfmbox); 198 DO(sctps_pdrpfehos); 199 DO(sctps_pdrpmbda); 200 DO(sctps_pdrpmbct); 201 DO(sctps_pdrpbwrpt); 202 DO(sctps_pdrpcrupt); 203 DO(sctps_pdrpnedat); 204 DO(sctps_pdrppdbrk); 205 DO(sctps_pdrptsnnf); 206 DO(sctps_pdrpdnfnd); 207 DO(sctps_pdrpdiwnp); 208 DO(sctps_pdrpdizrw); 209 DO(sctps_pdrpbadd); 210 DO(sctps_pdrpmark); 211 212 DO(sctps_timoiterator); 213 DO(sctps_timodata); 214 DO(sctps_timowindowprobe); 215 DO(sctps_timoinit); 216 DO(sctps_timosack); 217 DO(sctps_timoshutdown); 218 DO(sctps_timoheartbeat); 219 DO(sctps_timocookie); 220 DO(sctps_timosecret); 221 DO(sctps_timopathmtu); 222 DO(sctps_timoshutdownack); 223 DO(sctps_timoshutdownguard); 224 DO(sctps_timostrmrst); 225 DO(sctps_timoearlyfr); 226 DO(sctps_timoasconf); 227 DO(sctps_timodelprim); 228 DO(sctps_timoautoclose); 229 DO(sctps_timoassockill); 230 DO(sctps_timoinpkill); 231 232 DO(sctps_hdrops); 233 DO(sctps_badsum); 234 DO(sctps_noport); 235 DO(sctps_badvtag); 236 DO(sctps_badsid); 237 DO(sctps_nomem); 238 DO(sctps_fastretransinrtt); 239 DO(sctps_markedretrans); 240 DO(sctps_naglesent); 241 DO(sctps_naglequeued); 242 DO(sctps_maxburstqueued); 243 DO(sctps_ifnomemqueued); 244 DO(sctps_windowprobed); 245 DO(sctps_lowlevelerr); 246 DO(sctps_lowlevelerrusr); 247 DO(sctps_datadropchklmt); 248 DO(sctps_datadroprwnd); 249 DO(sctps_ecnereducedcwnd); 250 DO(sctps_vtagexpress); 251 DO(sctps_vtagbogus); 252 DO(sctps_primary_randry); 253 DO(sctps_cmt_randry); 254 DO(sctps_slowpath_sack); 255 DO(sctps_wu_sacks_sent); 256 DO(sctps_sends_with_flags); 257 DO(sctps_sends_with_unord); 258 DO(sctps_sends_with_eof); 259 DO(sctps_sends_with_abort); 260 DO(sctps_protocol_drain_calls); 261 DO(sctps_protocol_drains_done); 262 DO(sctps_read_peeks); 263 DO(sctps_cached_chk); 264 DO(sctps_cached_strmoq); 265 DO(sctps_left_abandon); 266 DO(sctps_send_burst_avoid); 267 DO(sctps_send_cwnd_avoid); 268 DO(sctps_fwdtsn_map_over); 269 DO(sctps_queue_upd_ecne); 270#undef DO 271} 272 273void 274showsctp(void) 275{ 276 struct sctpstat stats; 277 278 memset(&stats, 0, sizeof stats); 279 domode(&stats); 280 281#define DO(stat, row, col) \ 282 mvwprintw(wnd, row, col, "%12lu", stats.stat) 283#define L(row, stat) DO(stat, row, 0) 284#define R(row, stat) DO(stat, row, 38) 285 L(1, sctps_activeestab); R(1, sctps_outpackets); 286 L(2, sctps_passiveestab); R(2, sctps_inpackets); 287 L(3, sctps_restartestab); R(3, sctps_outoftheblue); 288 L(4, sctps_shutdown); R(4, sctps_badvtag); 289 L(5, sctps_aborted); R(5, sctps_checksumerrors); 290 291 292 L(8, sctps_timoinit); R(8, sctps_outcontrolchunks); 293 L(9, sctps_timocookie); R(9, sctps_senddata); 294 L(10, sctps_timodata); R(10, sctps_outorderchunks); 295 L(11, sctps_timosack); R(11, sctps_outunorderchunks); 296 L(12, sctps_timoshutdown); R(12, sctps_incontrolchunks); 297 L(13, sctps_timoshutdownack); R(13, sctps_recvdata); 298 L(14, sctps_timoshutdownguard); R(14, sctps_inorderchunks); 299 L(15, sctps_timoheartbeat); R(15, sctps_inunorderchunks); 300 L(16, sctps_timopathmtu); 301 L(17, sctps_timoautoclose); 302 L(18, sctps_timoasconf); R(18, sctps_fragusrmsgs); 303 L(19, sctps_timostrmrst); R(19, sctps_reasmusrmsgs); 304#undef DO 305#undef L 306#undef R 307} 308 309int 310initsctp(void) 311{ 312 size_t len; 313 const char *name = "net.inet.sctp.stats"; 314 315 len = 0; 316 if (sysctlbyname(name, NULL, &len, NULL, 0) < 0) { 317 error("sysctl getting sctpstat size failed"); 318 return 0; 319 } 320 if (len > sizeof curstat) { 321 error("sctpstat structure has grown--recompile systat!"); 322 return 0; 323 } 324 if (sysctlbyname(name, &initstat, &len, NULL, 0) < 0) { 325 error("sysctl getting sctpstat failed"); 326 return 0; 327 } 328 oldstat = initstat; 329 return 1; 330} 331 332void 333resetsctp(void) 334{ 335 size_t len; 336 const char *name = "net.inet.sctp.stats"; 337 338 len = sizeof initstat; 339 if (sysctlbyname(name, &initstat, &len, NULL, 0) < 0) { 340 error("sysctl getting sctpstat failed"); 341 } 342 oldstat = initstat; 343} 344 345void 346fetchsctp(void) 347{ 348 size_t len; 349 const char *name = "net.inet.sctp.stats"; 350 351 oldstat = curstat; 352 len = sizeof curstat; 353 if (sysctlbyname(name, &curstat, &len, NULL, 0) < 0) { 354 error("sysctl getting sctpstat failed"); 355 } 356 return; 357} 358