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