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 restarted 999999999999 - out of the blue 57 04999999999999 associations terminated 999999999999 - bad vtag 58 05999999999999 associations aborted 999999999999 - bad crc32c 59 06 60 07 SCTP Timers SCTP Chunks 61 08999999999999 init timeouts 999999999999 control chunks sent 62 09999999999999 cookie timeouts 999999999999 data chunks sent 63 10999999999999 data timeouts 999999999999 - ordered 64 11999999999999 delayed sack timeouts 999999999999 - unordered 65 12999999999999 shutdown timeouts 999999999999 control chunks received 66 13999999999999 shutdown-ack timeouts 999999999999 data chunks received 67 14999999999999 shutdown guard timeouts 999999999999 - ordered 68 15999999999999 heartbeat timeouts 999999999999 - unordered 69 16999999999999 path MTU timeouts 70 17999999999999 autoclose timeouts SCTP user messages 71 18999999999999 asconf timeouts 999999999999 fragmented 72 19999999999999 stream reset timeouts 999999999999 reassembled 73 --0123456789012345678901234567890123456789012345678901234567890123456789012345 74 --0 1 2 3 4 5 6 7 75 */ 76 77 WINDOW * 78 opensctp(void) 79 { 80 return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); 81 } 82 83 void 84 closesctp(WINDOW *w) 85 { 86 if (w != NULL) { 87 wclear(w); 88 wrefresh(w); 89 delwin(w); 90 } 91 } 92 93 void 94 labelsctp(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 123 static void 124 domode(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 273 void 274 showsctp(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 309 int 310 initsctp(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 332 void 333 resetsctp(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 345 void 346 fetchsctp(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