1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <sys/types.h> 30 #include <sys/stream.h> 31 #include <sys/cmn_err.h> 32 #define _SUN_TPI_VERSION 2 33 #include <sys/tihdr.h> 34 #include <sys/ddi.h> 35 #include <sys/sunddi.h> 36 37 #include <netinet/in.h> 38 39 #include <inet/common.h> 40 #include <inet/ip.h> 41 #include <inet/mib2.h> 42 #include <inet/snmpcom.h> 43 #include <inet/kstatcom.h> 44 #include <inet/ipclassifier.h> 45 #include "sctp_impl.h" 46 #include "sctp_addr.h" 47 48 mib2_sctp_t sctp_mib; 49 kstat_t *sctp_mibkp; /* kstat exporting sctp_mib data */ 50 51 static int sctp_snmp_state(sctp_t *sctp); 52 53 static int 54 sctp_kstat_update(kstat_t *kp, int rw) 55 { 56 sctp_named_kstat_t *sctpkp; 57 sctp_t *sctp, *sctp_prev; 58 zoneid_t zoneid; 59 60 if (kp == NULL|| kp->ks_data == NULL) 61 return (EIO); 62 63 if (rw == KSTAT_WRITE) 64 return (EACCES); 65 66 zoneid = getzoneid(); 67 68 /* 69 * Get the number of current associations and gather their 70 * individual set of statistics. 71 */ 72 SET_MIB(sctp_mib.sctpCurrEstab, 0); 73 sctp = gsctp; 74 sctp_prev = NULL; 75 mutex_enter(&sctp_g_lock); 76 while (sctp != NULL) { 77 mutex_enter(&sctp->sctp_reflock); 78 if (sctp->sctp_condemned) { 79 mutex_exit(&sctp->sctp_reflock); 80 sctp = list_next(&sctp_g_list, sctp); 81 continue; 82 } 83 sctp->sctp_refcnt++; 84 mutex_exit(&sctp->sctp_reflock); 85 mutex_exit(&sctp_g_lock); 86 if (sctp_prev != NULL) 87 SCTP_REFRELE(sctp_prev); 88 if (sctp->sctp_connp->conn_zoneid != zoneid) 89 goto next_sctp; 90 if (sctp->sctp_state == SCTPS_ESTABLISHED || 91 sctp->sctp_state == SCTPS_SHUTDOWN_PENDING || 92 sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) { 93 BUMP_MIB(&sctp_mib, sctpCurrEstab); 94 } 95 96 if (sctp->sctp_opkts) { 97 UPDATE_MIB(&sctp_mib, sctpOutSCTPPkts, 98 sctp->sctp_opkts); 99 sctp->sctp_opkts = 0; 100 } 101 102 if (sctp->sctp_obchunks) { 103 UPDATE_MIB(&sctp_mib, sctpOutCtrlChunks, 104 sctp->sctp_obchunks); 105 sctp->sctp_obchunks = 0; 106 } 107 108 if (sctp->sctp_odchunks) { 109 UPDATE_MIB(&sctp_mib, sctpOutOrderChunks, 110 sctp->sctp_odchunks); 111 sctp->sctp_odchunks = 0; 112 } 113 114 if (sctp->sctp_oudchunks) { 115 UPDATE_MIB(&sctp_mib, sctpOutUnorderChunks, 116 sctp->sctp_oudchunks); 117 sctp->sctp_oudchunks = 0; 118 } 119 120 if (sctp->sctp_rxtchunks) { 121 UPDATE_MIB(&sctp_mib, sctpRetransChunks, 122 sctp->sctp_rxtchunks); 123 sctp->sctp_rxtchunks = 0; 124 } 125 126 if (sctp->sctp_ipkts) { 127 UPDATE_MIB(&sctp_mib, sctpInSCTPPkts, sctp->sctp_ipkts); 128 sctp->sctp_ipkts = 0; 129 } 130 131 if (sctp->sctp_ibchunks) { 132 UPDATE_MIB(&sctp_mib, sctpInCtrlChunks, 133 sctp->sctp_ibchunks); 134 sctp->sctp_ibchunks = 0; 135 } 136 137 if (sctp->sctp_idchunks) { 138 UPDATE_MIB(&sctp_mib, sctpInOrderChunks, 139 sctp->sctp_idchunks); 140 sctp->sctp_idchunks = 0; 141 } 142 143 if (sctp->sctp_iudchunks) { 144 UPDATE_MIB(&sctp_mib, sctpInUnorderChunks, 145 sctp->sctp_iudchunks); 146 sctp->sctp_iudchunks = 0; 147 } 148 149 if (sctp->sctp_fragdmsgs) { 150 UPDATE_MIB(&sctp_mib, sctpFragUsrMsgs, 151 sctp->sctp_fragdmsgs); 152 sctp->sctp_fragdmsgs = 0; 153 } 154 155 if (sctp->sctp_reassmsgs) { 156 UPDATE_MIB(&sctp_mib, sctpReasmUsrMsgs, 157 sctp->sctp_reassmsgs); 158 sctp->sctp_reassmsgs = 0; 159 } 160 161 next_sctp: 162 sctp_prev = sctp; 163 mutex_enter(&sctp_g_lock); 164 sctp = list_next(&sctp_g_list, sctp); 165 } 166 mutex_exit(&sctp_g_lock); 167 if (sctp_prev != NULL) 168 SCTP_REFRELE(sctp_prev); 169 170 /* Copy data from the SCTP MIB */ 171 sctpkp = (sctp_named_kstat_t *)kp->ks_data; 172 173 /* These are from global ndd params. */ 174 sctpkp->sctpRtoMin.value.ui32 = sctp_rto_ming; 175 sctpkp->sctpRtoMax.value.ui32 = sctp_rto_maxg; 176 sctpkp->sctpRtoInitial.value.ui32 = sctp_rto_initialg; 177 sctpkp->sctpValCookieLife.value.ui32 = sctp_cookie_life; 178 sctpkp->sctpMaxInitRetr.value.ui32 = sctp_max_init_retr; 179 180 sctpkp->sctpCurrEstab.value.i32 = sctp_mib.sctpCurrEstab; 181 sctpkp->sctpActiveEstab.value.i32 = sctp_mib.sctpActiveEstab; 182 sctpkp->sctpPassiveEstab.value.i32 = sctp_mib.sctpPassiveEstab; 183 sctpkp->sctpAborted.value.i32 = sctp_mib.sctpAborted; 184 sctpkp->sctpShutdowns.value.i32 = sctp_mib.sctpShutdowns; 185 sctpkp->sctpOutOfBlue.value.i32 = sctp_mib.sctpOutOfBlue; 186 sctpkp->sctpChecksumError.value.i32 = sctp_mib.sctpChecksumError; 187 sctpkp->sctpOutCtrlChunks.value.i64 = sctp_mib.sctpOutCtrlChunks; 188 sctpkp->sctpOutOrderChunks.value.i64 = sctp_mib.sctpOutOrderChunks; 189 sctpkp->sctpOutUnorderChunks.value.i64 = sctp_mib.sctpOutUnorderChunks; 190 sctpkp->sctpRetransChunks.value.i64 = sctp_mib.sctpRetransChunks; 191 sctpkp->sctpOutAck.value.i32 = sctp_mib.sctpOutAck; 192 sctpkp->sctpOutAckDelayed.value.i32 = sctp_mib.sctpOutAckDelayed; 193 sctpkp->sctpOutWinUpdate.value.i32 = sctp_mib.sctpOutWinUpdate; 194 sctpkp->sctpOutFastRetrans.value.i32 = sctp_mib.sctpOutFastRetrans; 195 sctpkp->sctpOutWinProbe.value.i32 = sctp_mib.sctpOutWinProbe; 196 sctpkp->sctpInCtrlChunks.value.i64 = sctp_mib.sctpInCtrlChunks; 197 sctpkp->sctpInOrderChunks.value.i64 = sctp_mib.sctpInOrderChunks; 198 sctpkp->sctpInUnorderChunks.value.i64 = sctp_mib.sctpInUnorderChunks; 199 sctpkp->sctpInAck.value.i32 = sctp_mib.sctpInAck; 200 sctpkp->sctpInDupAck.value.i32 = sctp_mib.sctpInDupAck; 201 sctpkp->sctpInAckUnsent.value.i32 = sctp_mib.sctpInAckUnsent; 202 sctpkp->sctpFragUsrMsgs.value.i64 = sctp_mib.sctpFragUsrMsgs; 203 sctpkp->sctpReasmUsrMsgs.value.i64 = sctp_mib.sctpReasmUsrMsgs; 204 sctpkp->sctpOutSCTPPkts.value.i64 = sctp_mib.sctpOutSCTPPkts; 205 sctpkp->sctpInSCTPPkts.value.i64 = sctp_mib.sctpInSCTPPkts; 206 sctpkp->sctpInInvalidCookie.value.i32 = sctp_mib.sctpInInvalidCookie; 207 sctpkp->sctpTimRetrans.value.i32 = sctp_mib.sctpTimRetrans; 208 sctpkp->sctpTimRetransDrop.value.i32 = sctp_mib.sctpTimRetransDrop; 209 sctpkp->sctpTimHeartBeatProbe.value.i32 = 210 sctp_mib.sctpTimHeartBeatProbe; 211 sctpkp->sctpTimHeartBeatDrop.value.i32 = sctp_mib.sctpTimHeartBeatDrop; 212 sctpkp->sctpListenDrop.value.i32 = sctp_mib.sctpListenDrop; 213 sctpkp->sctpInClosed.value.i32 = sctp_mib.sctpInClosed; 214 215 return (0); 216 } 217 218 void 219 sctp_kstat_init(void) 220 { 221 sctp_named_kstat_t template = { 222 { "sctpRtoAlgorithm", KSTAT_DATA_INT32, 0 }, 223 { "sctpRtoMin", KSTAT_DATA_UINT32, 0 }, 224 { "sctpRtoMax", KSTAT_DATA_UINT32, 0 }, 225 { "sctpRtoInitial", KSTAT_DATA_UINT32, 0 }, 226 { "sctpMaxAssocs", KSTAT_DATA_INT32, 0 }, 227 { "sctpValCookieLife", KSTAT_DATA_UINT32, 0 }, 228 { "sctpMaxInitRetr", KSTAT_DATA_UINT32, 0 }, 229 { "sctpCurrEstab", KSTAT_DATA_INT32, 0 }, 230 { "sctpActiveEstab", KSTAT_DATA_INT32, 0 }, 231 { "sctpPassiveEstab", KSTAT_DATA_INT32, 0 }, 232 { "sctpAborted", KSTAT_DATA_INT32, 0 }, 233 { "sctpShutdowns", KSTAT_DATA_INT32, 0 }, 234 { "sctpOutOfBlue", KSTAT_DATA_INT32, 0 }, 235 { "sctpChecksumError", KSTAT_DATA_INT32, 0 }, 236 { "sctpOutCtrlChunks", KSTAT_DATA_INT64, 0 }, 237 { "sctpOutOrderChunks", KSTAT_DATA_INT64, 0 }, 238 { "sctpOutUnorderChunks", KSTAT_DATA_INT64, 0 }, 239 { "sctpRetransChunks", KSTAT_DATA_INT64, 0 }, 240 { "sctpOutAck", KSTAT_DATA_INT32, 0 }, 241 { "sctpOutAckDelayed", KSTAT_DATA_INT32, 0 }, 242 { "sctpOutWinUpdate", KSTAT_DATA_INT32, 0 }, 243 { "sctpOutFastRetrans", KSTAT_DATA_INT32, 0 }, 244 { "sctpOutWinProbe", KSTAT_DATA_INT32, 0 }, 245 { "sctpInCtrlChunks", KSTAT_DATA_INT64, 0 }, 246 { "sctpInOrderChunks", KSTAT_DATA_INT64, 0 }, 247 { "sctpInUnorderChunks", KSTAT_DATA_INT64, 0 }, 248 { "sctpInAck", KSTAT_DATA_INT32, 0 }, 249 { "sctpInDupAck", KSTAT_DATA_INT32, 0 }, 250 { "sctpInAckUnsent", KSTAT_DATA_INT32, 0 }, 251 { "sctpFragUsrMsgs", KSTAT_DATA_INT64, 0 }, 252 { "sctpReasmUsrMsgs", KSTAT_DATA_INT64, 0 }, 253 { "sctpOutSCTPPkts", KSTAT_DATA_INT64, 0 }, 254 { "sctpInSCTPPkts", KSTAT_DATA_INT64, 0 }, 255 { "sctpInInvalidCookie", KSTAT_DATA_INT32, 0 }, 256 { "sctpTimRetrans", KSTAT_DATA_INT32, 0 }, 257 { "sctpTimRetransDrop", KSTAT_DATA_INT32, 0 }, 258 { "sctpTimHearBeatProbe", KSTAT_DATA_INT32, 0 }, 259 { "sctpTimHearBeatDrop", KSTAT_DATA_INT32, 0 }, 260 { "sctpListenDrop", KSTAT_DATA_INT32, 0 }, 261 { "sctpInClosed", KSTAT_DATA_INT32, 0 } 262 }; 263 264 sctp_mibkp = kstat_create("sctp", 0, "sctp", "mib2", KSTAT_TYPE_NAMED, 265 NUM_OF_FIELDS(sctp_named_kstat_t), 0); 266 267 if (sctp_mibkp == NULL) 268 return; 269 270 /* These won't change. */ 271 template.sctpRtoAlgorithm.value.i32 = MIB2_SCTP_RTOALGO_VANJ; 272 template.sctpMaxAssocs.value.i32 = -1; 273 274 bcopy(&template, sctp_mibkp->ks_data, sizeof (template)); 275 276 sctp_mibkp->ks_update = sctp_kstat_update; 277 278 kstat_install(sctp_mibkp); 279 } 280 281 void 282 sctp_kstat_fini(void) 283 { 284 if (sctp_mibkp != NULL) { 285 kstat_delete(sctp_mibkp); 286 sctp_mibkp = NULL; 287 } 288 } 289 290 /* 291 * Return SNMP global stats in buffer in mpdata. 292 * Return associatiation table in mp_conn_data, 293 * local address table in mp_local_data, and 294 * remote address table in mp_rem_data. 295 */ 296 mblk_t * 297 sctp_snmp_get_mib2(queue_t *q, mblk_t *mpctl) 298 { 299 mblk_t *mpdata, *mp_ret; 300 mblk_t *mp_conn_ctl = NULL; 301 mblk_t *mp_conn_data; 302 mblk_t *mp_conn_tail = NULL; 303 mblk_t *mp_local_ctl = NULL; 304 mblk_t *mp_local_data; 305 mblk_t *mp_local_tail = NULL; 306 mblk_t *mp_rem_ctl = NULL; 307 mblk_t *mp_rem_data; 308 mblk_t *mp_rem_tail = NULL; 309 struct opthdr *optp; 310 sctp_t *sctp, *sctp_prev = NULL; 311 sctp_faddr_t *fp; 312 mib2_sctpConnEntry_t sce; 313 mib2_sctpConnLocalEntry_t scle; 314 mib2_sctpConnRemoteEntry_t scre; 315 int i; 316 int l; 317 int scanned = 0; 318 zoneid_t zoneid = Q_TO_CONN(q)->conn_zoneid; 319 320 /* 321 * Make copies of the original message. 322 * mpctl will hold SCTP counters, 323 * mp_conn_ctl will hold list of connections. 324 */ 325 mp_ret = copymsg(mpctl); 326 mp_conn_ctl = copymsg(mpctl); 327 mp_local_ctl = copymsg(mpctl); 328 mp_rem_ctl = copymsg(mpctl); 329 330 mpdata = mpctl->b_cont; 331 332 if (!mp_conn_ctl || !mp_local_ctl || !mp_rem_ctl || !mpdata) { 333 freemsg(mp_rem_ctl); 334 freemsg(mp_local_ctl); 335 freemsg(mp_conn_ctl); 336 freemsg(mp_ret); 337 freemsg(mpctl); 338 return (NULL); 339 } 340 mp_conn_data = mp_conn_ctl->b_cont; 341 mp_local_data = mp_local_ctl->b_cont; 342 mp_rem_data = mp_rem_ctl->b_cont; 343 344 /* hostname address parameters are not supported in Solaris */ 345 sce.sctpAssocRemHostName.o_length = 0; 346 sce.sctpAssocRemHostName.o_bytes[0] = 0; 347 348 /* build table of connections -- need count in fixed part */ 349 SET_MIB(sctp_mib.sctpRtoAlgorithm, MIB2_SCTP_RTOALGO_VANJ); 350 SET_MIB(sctp_mib.sctpRtoMin, sctp_rto_ming); 351 SET_MIB(sctp_mib.sctpRtoMax, sctp_rto_maxg); 352 SET_MIB(sctp_mib.sctpRtoInitial, sctp_rto_initialg); 353 SET_MIB(sctp_mib.sctpMaxAssocs, -1); 354 SET_MIB(sctp_mib.sctpValCookieLife, sctp_cookie_life); 355 SET_MIB(sctp_mib.sctpMaxInitRetr, sctp_max_init_retr); 356 SET_MIB(sctp_mib.sctpCurrEstab, 0); 357 358 sctp = gsctp; 359 mutex_enter(&sctp_g_lock); 360 while (sctp != NULL) { 361 mutex_enter(&sctp->sctp_reflock); 362 if (sctp->sctp_condemned) { 363 mutex_exit(&sctp->sctp_reflock); 364 sctp = list_next(&sctp_g_list, sctp); 365 continue; 366 } 367 sctp->sctp_refcnt++; 368 mutex_exit(&sctp->sctp_reflock); 369 mutex_exit(&sctp_g_lock); 370 if (sctp_prev != NULL) 371 SCTP_REFRELE(sctp_prev); 372 if (sctp->sctp_connp->conn_zoneid != zoneid) 373 goto next_sctp; 374 if (sctp->sctp_state == SCTPS_ESTABLISHED || 375 sctp->sctp_state == SCTPS_SHUTDOWN_PENDING || 376 sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) { 377 BUMP_MIB(&sctp_mib, sctpCurrEstab); 378 } 379 UPDATE_MIB(&sctp_mib, sctpOutSCTPPkts, sctp->sctp_opkts); 380 sctp->sctp_opkts = 0; 381 UPDATE_MIB(&sctp_mib, sctpOutCtrlChunks, sctp->sctp_obchunks); 382 sctp->sctp_obchunks = 0; 383 UPDATE_MIB(&sctp_mib, sctpOutOrderChunks, sctp->sctp_odchunks); 384 sctp->sctp_odchunks = 0; 385 UPDATE_MIB(&sctp_mib, sctpOutUnorderChunks, 386 sctp->sctp_oudchunks); 387 sctp->sctp_oudchunks = 0; 388 UPDATE_MIB(&sctp_mib, sctpRetransChunks, sctp->sctp_rxtchunks); 389 sctp->sctp_rxtchunks = 0; 390 UPDATE_MIB(&sctp_mib, sctpInSCTPPkts, sctp->sctp_ipkts); 391 sctp->sctp_ipkts = 0; 392 UPDATE_MIB(&sctp_mib, sctpInCtrlChunks, sctp->sctp_ibchunks); 393 sctp->sctp_ibchunks = 0; 394 UPDATE_MIB(&sctp_mib, sctpInOrderChunks, sctp->sctp_idchunks); 395 sctp->sctp_idchunks = 0; 396 UPDATE_MIB(&sctp_mib, sctpInUnorderChunks, 397 sctp->sctp_iudchunks); 398 sctp->sctp_iudchunks = 0; 399 UPDATE_MIB(&sctp_mib, sctpFragUsrMsgs, sctp->sctp_fragdmsgs); 400 sctp->sctp_fragdmsgs = 0; 401 UPDATE_MIB(&sctp_mib, sctpReasmUsrMsgs, sctp->sctp_reassmsgs); 402 sctp->sctp_reassmsgs = 0; 403 404 sce.sctpAssocId = ntohl(sctp->sctp_lvtag); 405 sce.sctpAssocLocalPort = ntohs(sctp->sctp_lport); 406 sce.sctpAssocRemPort = ntohs(sctp->sctp_fport); 407 408 RUN_SCTP(sctp); 409 if (sctp->sctp_primary != NULL) { 410 fp = sctp->sctp_primary; 411 412 if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) { 413 sce.sctpAssocRemPrimAddrType = 414 MIB2_SCTP_ADDR_V4; 415 } else { 416 sce.sctpAssocRemPrimAddrType = 417 MIB2_SCTP_ADDR_V6; 418 } 419 sce.sctpAssocRemPrimAddr = fp->faddr; 420 sce.sctpAssocLocPrimAddr = fp->saddr; 421 sce.sctpAssocHeartBeatInterval = TICK_TO_MSEC( 422 fp->hb_interval); 423 } else { 424 sce.sctpAssocRemPrimAddrType = MIB2_SCTP_ADDR_V4; 425 bzero(&sce.sctpAssocRemPrimAddr, 426 sizeof (sce.sctpAssocRemPrimAddr)); 427 bzero(&sce.sctpAssocLocPrimAddr, 428 sizeof (sce.sctpAssocLocPrimAddr)); 429 sce.sctpAssocHeartBeatInterval = 430 sctp_heartbeat_interval; 431 } 432 433 /* 434 * Table for local addresses 435 */ 436 scanned = 0; 437 for (i = 0; i < SCTP_IPIF_HASH; i++) { 438 sctp_saddr_ipif_t *obj; 439 440 if (sctp->sctp_saddrs[i].ipif_count == 0) 441 continue; 442 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list); 443 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) { 444 sctp_ipif_t *sctp_ipif; 445 in6_addr_t addr; 446 447 sctp_ipif = obj->saddr_ipifp; 448 addr = sctp_ipif->sctp_ipif_saddr; 449 scanned++; 450 scle.sctpAssocId = ntohl(sctp->sctp_lvtag); 451 if (IN6_IS_ADDR_V4MAPPED(&addr)) { 452 scle.sctpAssocLocalAddrType = 453 MIB2_SCTP_ADDR_V4; 454 } else { 455 scle.sctpAssocLocalAddrType = 456 MIB2_SCTP_ADDR_V6; 457 } 458 scle.sctpAssocLocalAddr = addr; 459 (void) snmp_append_data2(mp_local_data, 460 &mp_local_tail, (char *)&scle, 461 sizeof (scle)); 462 if (scanned >= sctp->sctp_nsaddrs) 463 goto done; 464 obj = list_next(&sctp-> 465 sctp_saddrs[i].sctp_ipif_list, obj); 466 } 467 } 468 done: 469 /* 470 * Table for remote addresses 471 */ 472 for (fp = sctp->sctp_faddrs; fp; fp = fp->next) { 473 scre.sctpAssocId = ntohl(sctp->sctp_lvtag); 474 if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) { 475 scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V4; 476 } else { 477 scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V6; 478 } 479 scre.sctpAssocRemAddr = fp->faddr; 480 if (fp->state == SCTP_FADDRS_ALIVE) { 481 scre.sctpAssocRemAddrActive = 482 scre.sctpAssocRemAddrHBActive = 483 MIB2_SCTP_ACTIVE; 484 } else { 485 scre.sctpAssocRemAddrActive = 486 scre.sctpAssocRemAddrHBActive = 487 MIB2_SCTP_INACTIVE; 488 } 489 scre.sctpAssocRemAddrRTO = TICK_TO_MSEC(fp->rto); 490 scre.sctpAssocRemAddrMaxPathRtx = fp->max_retr; 491 scre.sctpAssocRemAddrRtx = fp->T3expire; 492 (void) snmp_append_data2(mp_rem_data, &mp_rem_tail, 493 (char *)&scre, sizeof (scre)); 494 } 495 WAKE_SCTP(sctp); 496 sce.sctpAssocState = sctp_snmp_state(sctp); 497 sce.sctpAssocInStreams = sctp->sctp_num_istr; 498 sce.sctpAssocOutStreams = sctp->sctp_num_ostr; 499 sce.sctpAssocMaxRetr = sctp->sctp_pa_max_rxt; 500 /* A 0 here indicates that no primary process is known */ 501 sce.sctpAssocPrimProcess = 0; 502 sce.sctpAssocT1expired = sctp->sctp_T1expire; 503 sce.sctpAssocT2expired = sctp->sctp_T2expire; 504 sce.sctpAssocRtxChunks = sctp->sctp_T3expire; 505 sce.sctpAssocStartTime = sctp->sctp_assoc_start_time; 506 sce.sctpConnEntryInfo.ce_sendq = sctp->sctp_unacked + 507 sctp->sctp_unsent; 508 sce.sctpConnEntryInfo.ce_recvq = sctp->sctp_rxqueued; 509 sce.sctpConnEntryInfo.ce_swnd = sctp->sctp_frwnd; 510 sce.sctpConnEntryInfo.ce_rwnd = sctp->sctp_rwnd; 511 sce.sctpConnEntryInfo.ce_mss = sctp->sctp_mss; 512 (void) snmp_append_data2(mp_conn_data, &mp_conn_tail, 513 (char *)&sce, sizeof (sce)); 514 next_sctp: 515 sctp_prev = sctp; 516 mutex_enter(&sctp_g_lock); 517 sctp = list_next(&sctp_g_list, sctp); 518 } 519 mutex_exit(&sctp_g_lock); 520 if (sctp_prev != NULL) 521 SCTP_REFRELE(sctp_prev); 522 523 /* fixed length structure for IPv4 and IPv6 counters */ 524 SET_MIB(sctp_mib.sctpEntrySize, sizeof (sce)); 525 SET_MIB(sctp_mib.sctpLocalEntrySize, sizeof (scle)); 526 SET_MIB(sctp_mib.sctpRemoteEntrySize, sizeof (scre)); 527 optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)]; 528 optp->level = MIB2_SCTP; 529 optp->name = 0; 530 (void) snmp_append_data(mpdata, (char *)&sctp_mib, sizeof (sctp_mib)); 531 optp->len = msgdsize(mpdata); 532 qreply(q, mpctl); 533 534 /* table of connections... */ 535 optp = (struct opthdr *)&mp_conn_ctl->b_rptr[ 536 sizeof (struct T_optmgmt_ack)]; 537 optp->level = MIB2_SCTP; 538 optp->name = MIB2_SCTP_CONN; 539 optp->len = msgdsize(mp_conn_data); 540 qreply(q, mp_conn_ctl); 541 542 /* assoc local address table */ 543 optp = (struct opthdr *)&mp_local_ctl->b_rptr[ 544 sizeof (struct T_optmgmt_ack)]; 545 optp->level = MIB2_SCTP; 546 optp->name = MIB2_SCTP_CONN_LOCAL; 547 optp->len = msgdsize(mp_local_data); 548 qreply(q, mp_local_ctl); 549 550 /* assoc remote address table */ 551 optp = (struct opthdr *)&mp_rem_ctl->b_rptr[ 552 sizeof (struct T_optmgmt_ack)]; 553 optp->level = MIB2_SCTP; 554 optp->name = MIB2_SCTP_CONN_REMOTE; 555 optp->len = msgdsize(mp_rem_data); 556 qreply(q, mp_rem_ctl); 557 558 return (mp_ret); 559 } 560 561 /* Translate SCTP state to MIB2 SCTP state. */ 562 static int 563 sctp_snmp_state(sctp_t *sctp) 564 { 565 if (sctp == NULL) 566 return (0); 567 568 switch (sctp->sctp_state) { 569 case SCTPS_IDLE: 570 case SCTPS_BOUND: 571 return (MIB2_SCTP_closed); 572 case SCTPS_LISTEN: 573 return (MIB2_SCTP_listen); 574 case SCTPS_COOKIE_WAIT: 575 return (MIB2_SCTP_cookieWait); 576 case SCTPS_COOKIE_ECHOED: 577 return (MIB2_SCTP_cookieEchoed); 578 case SCTPS_ESTABLISHED: 579 return (MIB2_SCTP_established); 580 case SCTPS_SHUTDOWN_PENDING: 581 return (MIB2_SCTP_shutdownPending); 582 case SCTPS_SHUTDOWN_SENT: 583 return (MIB2_SCTP_shutdownSent); 584 case SCTPS_SHUTDOWN_RECEIVED: 585 return (MIB2_SCTP_shutdownReceived); 586 case SCTPS_SHUTDOWN_ACK_SENT: 587 return (MIB2_SCTP_shutdownAckSent); 588 default: 589 return (0); 590 } 591 } 592