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$"); 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 established 999999999999 - out of the blue 5704999999999999 associations restarted 999999999999 - bad vtag 5805999999999999 associations terminated 999999999999 - bad crc32c 5906999999999999 associations aborted 6007 6108 SCTP Timers SCTP Chunks 6209999999999999 init timeouts 999999999999 control chunks sent 6310999999999999 cookie timeouts 999999999999 data chunks sent 6411999999999999 data timeouts 999999999999 - ordered 6512999999999999 delayed sack timeouts 999999999999 - unordered 6613999999999999 shutdown timeouts 999999999999 control chunks received 6714999999999999 shutdown-ack timeouts 999999999999 data chunks received 6815999999999999 shutdown guard timeouts 999999999999 - ordered 6916999999999999 heartbeat timeouts 999999999999 - unordered 7017999999999999 path MTU timeouts 7118999999999999 autoclose timeouts SCTP user messages 7219999999999999 asconf timeouts 999999999999 fragmented 7320999999999999 stream reset timeouts 999999999999 reassembled 74--0123456789012345678901234567890123456789012345678901234567890123456789012345 75--0 1 2 3 4 5 6 7 76*/ 77 78WINDOW * 79opensctp(void) 80{ 81 return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0)); 82} 83 84void 85closesctp(WINDOW *w) 86{ 87 if (w != NULL) { 88 wclear(w); 89 wrefresh(w); 90 delwin(w); 91 } 92} 93 94void 95labelsctp(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 125static void 126domode(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 277void 278showsctp(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 314int 315initsctp(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 337void 338resetsctp(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 350void 351fetchsctp(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