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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/stream.h> 30 #include <sys/cmn_err.h> 31 #define _SUN_TPI_VERSION 2 32 #include <sys/tihdr.h> 33 #include <sys/ddi.h> 34 #include <sys/sunddi.h> 35 #include <sys/tsol/tndb.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 mblk_t *mp_attr_ctl = NULL; 310 mblk_t *mp_attr_data; 311 mblk_t *mp_attr_tail = NULL; 312 struct opthdr *optp; 313 sctp_t *sctp, *sctp_prev = NULL; 314 sctp_faddr_t *fp; 315 mib2_sctpConnEntry_t sce; 316 mib2_sctpConnLocalEntry_t scle; 317 mib2_sctpConnRemoteEntry_t scre; 318 mib2_transportMLPEntry_t mlp; 319 int i; 320 int l; 321 int scanned = 0; 322 zoneid_t zoneid = Q_TO_CONN(q)->conn_zoneid; 323 conn_t *connp; 324 boolean_t needattr; 325 int idx; 326 327 /* 328 * Make copies of the original message. 329 * mpctl will hold SCTP counters, 330 * mp_conn_ctl will hold list of connections. 331 */ 332 mp_ret = copymsg(mpctl); 333 mp_conn_ctl = copymsg(mpctl); 334 mp_local_ctl = copymsg(mpctl); 335 mp_rem_ctl = copymsg(mpctl); 336 mp_attr_ctl = copymsg(mpctl); 337 338 mpdata = mpctl->b_cont; 339 340 if (mp_conn_ctl == NULL || mp_local_ctl == NULL || 341 mp_rem_ctl == NULL || mp_attr_ctl == NULL || mpdata == NULL) { 342 freemsg(mp_attr_ctl); 343 freemsg(mp_rem_ctl); 344 freemsg(mp_local_ctl); 345 freemsg(mp_conn_ctl); 346 freemsg(mp_ret); 347 freemsg(mpctl); 348 return (NULL); 349 } 350 mp_conn_data = mp_conn_ctl->b_cont; 351 mp_local_data = mp_local_ctl->b_cont; 352 mp_rem_data = mp_rem_ctl->b_cont; 353 mp_attr_data = mp_attr_ctl->b_cont; 354 355 /* hostname address parameters are not supported in Solaris */ 356 sce.sctpAssocRemHostName.o_length = 0; 357 sce.sctpAssocRemHostName.o_bytes[0] = 0; 358 359 /* build table of connections -- need count in fixed part */ 360 SET_MIB(sctp_mib.sctpRtoAlgorithm, MIB2_SCTP_RTOALGO_VANJ); 361 SET_MIB(sctp_mib.sctpRtoMin, sctp_rto_ming); 362 SET_MIB(sctp_mib.sctpRtoMax, sctp_rto_maxg); 363 SET_MIB(sctp_mib.sctpRtoInitial, sctp_rto_initialg); 364 SET_MIB(sctp_mib.sctpMaxAssocs, -1); 365 SET_MIB(sctp_mib.sctpValCookieLife, sctp_cookie_life); 366 SET_MIB(sctp_mib.sctpMaxInitRetr, sctp_max_init_retr); 367 SET_MIB(sctp_mib.sctpCurrEstab, 0); 368 369 idx = 0; 370 sctp = gsctp; 371 mutex_enter(&sctp_g_lock); 372 while (sctp != NULL) { 373 mutex_enter(&sctp->sctp_reflock); 374 if (sctp->sctp_condemned) { 375 mutex_exit(&sctp->sctp_reflock); 376 sctp = list_next(&sctp_g_list, sctp); 377 continue; 378 } 379 sctp->sctp_refcnt++; 380 mutex_exit(&sctp->sctp_reflock); 381 mutex_exit(&sctp_g_lock); 382 if (sctp_prev != NULL) 383 SCTP_REFRELE(sctp_prev); 384 if (sctp->sctp_connp->conn_zoneid != zoneid) 385 goto next_sctp; 386 if (sctp->sctp_state == SCTPS_ESTABLISHED || 387 sctp->sctp_state == SCTPS_SHUTDOWN_PENDING || 388 sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) { 389 BUMP_MIB(&sctp_mib, sctpCurrEstab); 390 } 391 UPDATE_MIB(&sctp_mib, sctpOutSCTPPkts, sctp->sctp_opkts); 392 sctp->sctp_opkts = 0; 393 UPDATE_MIB(&sctp_mib, sctpOutCtrlChunks, sctp->sctp_obchunks); 394 sctp->sctp_obchunks = 0; 395 UPDATE_MIB(&sctp_mib, sctpOutOrderChunks, sctp->sctp_odchunks); 396 sctp->sctp_odchunks = 0; 397 UPDATE_MIB(&sctp_mib, sctpOutUnorderChunks, 398 sctp->sctp_oudchunks); 399 sctp->sctp_oudchunks = 0; 400 UPDATE_MIB(&sctp_mib, sctpRetransChunks, sctp->sctp_rxtchunks); 401 sctp->sctp_rxtchunks = 0; 402 UPDATE_MIB(&sctp_mib, sctpInSCTPPkts, sctp->sctp_ipkts); 403 sctp->sctp_ipkts = 0; 404 UPDATE_MIB(&sctp_mib, sctpInCtrlChunks, sctp->sctp_ibchunks); 405 sctp->sctp_ibchunks = 0; 406 UPDATE_MIB(&sctp_mib, sctpInOrderChunks, sctp->sctp_idchunks); 407 sctp->sctp_idchunks = 0; 408 UPDATE_MIB(&sctp_mib, sctpInUnorderChunks, 409 sctp->sctp_iudchunks); 410 sctp->sctp_iudchunks = 0; 411 UPDATE_MIB(&sctp_mib, sctpFragUsrMsgs, sctp->sctp_fragdmsgs); 412 sctp->sctp_fragdmsgs = 0; 413 UPDATE_MIB(&sctp_mib, sctpReasmUsrMsgs, sctp->sctp_reassmsgs); 414 sctp->sctp_reassmsgs = 0; 415 416 sce.sctpAssocId = ntohl(sctp->sctp_lvtag); 417 sce.sctpAssocLocalPort = ntohs(sctp->sctp_lport); 418 sce.sctpAssocRemPort = ntohs(sctp->sctp_fport); 419 420 RUN_SCTP(sctp); 421 if (sctp->sctp_primary != NULL) { 422 fp = sctp->sctp_primary; 423 424 if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) { 425 sce.sctpAssocRemPrimAddrType = 426 MIB2_SCTP_ADDR_V4; 427 } else { 428 sce.sctpAssocRemPrimAddrType = 429 MIB2_SCTP_ADDR_V6; 430 } 431 sce.sctpAssocRemPrimAddr = fp->faddr; 432 sce.sctpAssocLocPrimAddr = fp->saddr; 433 sce.sctpAssocHeartBeatInterval = TICK_TO_MSEC( 434 fp->hb_interval); 435 } else { 436 sce.sctpAssocRemPrimAddrType = MIB2_SCTP_ADDR_V4; 437 bzero(&sce.sctpAssocRemPrimAddr, 438 sizeof (sce.sctpAssocRemPrimAddr)); 439 bzero(&sce.sctpAssocLocPrimAddr, 440 sizeof (sce.sctpAssocLocPrimAddr)); 441 sce.sctpAssocHeartBeatInterval = 442 sctp_heartbeat_interval; 443 } 444 445 /* 446 * Table for local addresses 447 */ 448 scanned = 0; 449 for (i = 0; i < SCTP_IPIF_HASH; i++) { 450 sctp_saddr_ipif_t *obj; 451 452 if (sctp->sctp_saddrs[i].ipif_count == 0) 453 continue; 454 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list); 455 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) { 456 sctp_ipif_t *sctp_ipif; 457 in6_addr_t addr; 458 459 sctp_ipif = obj->saddr_ipifp; 460 addr = sctp_ipif->sctp_ipif_saddr; 461 scanned++; 462 scle.sctpAssocId = ntohl(sctp->sctp_lvtag); 463 if (IN6_IS_ADDR_V4MAPPED(&addr)) { 464 scle.sctpAssocLocalAddrType = 465 MIB2_SCTP_ADDR_V4; 466 } else { 467 scle.sctpAssocLocalAddrType = 468 MIB2_SCTP_ADDR_V6; 469 } 470 scle.sctpAssocLocalAddr = addr; 471 (void) snmp_append_data2(mp_local_data, 472 &mp_local_tail, (char *)&scle, 473 sizeof (scle)); 474 if (scanned >= sctp->sctp_nsaddrs) 475 goto done; 476 obj = list_next(&sctp-> 477 sctp_saddrs[i].sctp_ipif_list, obj); 478 } 479 } 480 done: 481 /* 482 * Table for remote addresses 483 */ 484 for (fp = sctp->sctp_faddrs; fp; fp = fp->next) { 485 scre.sctpAssocId = ntohl(sctp->sctp_lvtag); 486 if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) { 487 scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V4; 488 } else { 489 scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V6; 490 } 491 scre.sctpAssocRemAddr = fp->faddr; 492 if (fp->state == SCTP_FADDRS_ALIVE) { 493 scre.sctpAssocRemAddrActive = 494 scre.sctpAssocRemAddrHBActive = 495 MIB2_SCTP_ACTIVE; 496 } else { 497 scre.sctpAssocRemAddrActive = 498 scre.sctpAssocRemAddrHBActive = 499 MIB2_SCTP_INACTIVE; 500 } 501 scre.sctpAssocRemAddrRTO = TICK_TO_MSEC(fp->rto); 502 scre.sctpAssocRemAddrMaxPathRtx = fp->max_retr; 503 scre.sctpAssocRemAddrRtx = fp->T3expire; 504 (void) snmp_append_data2(mp_rem_data, &mp_rem_tail, 505 (char *)&scre, sizeof (scre)); 506 } 507 connp = sctp->sctp_connp; 508 needattr = B_FALSE; 509 bzero(&mlp, sizeof (mlp)); 510 if (connp->conn_mlp_type != mlptSingle) { 511 if (connp->conn_mlp_type == mlptShared || 512 connp->conn_mlp_type == mlptBoth) 513 mlp.tme_flags |= MIB2_TMEF_SHARED; 514 if (connp->conn_mlp_type == mlptPrivate || 515 connp->conn_mlp_type == mlptBoth) 516 mlp.tme_flags |= MIB2_TMEF_PRIVATE; 517 needattr = B_TRUE; 518 } 519 if (connp->conn_peercred != NULL) { 520 ts_label_t *tsl; 521 522 tsl = crgetlabel(connp->conn_peercred); 523 mlp.tme_doi = label2doi(tsl); 524 mlp.tme_label = *label2bslabel(tsl); 525 needattr = B_TRUE; 526 } 527 WAKE_SCTP(sctp); 528 sce.sctpAssocState = sctp_snmp_state(sctp); 529 sce.sctpAssocInStreams = sctp->sctp_num_istr; 530 sce.sctpAssocOutStreams = sctp->sctp_num_ostr; 531 sce.sctpAssocMaxRetr = sctp->sctp_pa_max_rxt; 532 /* A 0 here indicates that no primary process is known */ 533 sce.sctpAssocPrimProcess = 0; 534 sce.sctpAssocT1expired = sctp->sctp_T1expire; 535 sce.sctpAssocT2expired = sctp->sctp_T2expire; 536 sce.sctpAssocRtxChunks = sctp->sctp_T3expire; 537 sce.sctpAssocStartTime = sctp->sctp_assoc_start_time; 538 sce.sctpConnEntryInfo.ce_sendq = sctp->sctp_unacked + 539 sctp->sctp_unsent; 540 sce.sctpConnEntryInfo.ce_recvq = sctp->sctp_rxqueued; 541 sce.sctpConnEntryInfo.ce_swnd = sctp->sctp_frwnd; 542 sce.sctpConnEntryInfo.ce_rwnd = sctp->sctp_rwnd; 543 sce.sctpConnEntryInfo.ce_mss = sctp->sctp_mss; 544 (void) snmp_append_data2(mp_conn_data, &mp_conn_tail, 545 (char *)&sce, sizeof (sce)); 546 mlp.tme_connidx = idx++; 547 if (needattr) 548 (void) snmp_append_data2(mp_attr_ctl->b_cont, 549 &mp_attr_tail, (char *)&mlp, sizeof (mlp)); 550 next_sctp: 551 sctp_prev = sctp; 552 mutex_enter(&sctp_g_lock); 553 sctp = list_next(&sctp_g_list, sctp); 554 } 555 mutex_exit(&sctp_g_lock); 556 if (sctp_prev != NULL) 557 SCTP_REFRELE(sctp_prev); 558 559 /* fixed length structure for IPv4 and IPv6 counters */ 560 SET_MIB(sctp_mib.sctpEntrySize, sizeof (sce)); 561 SET_MIB(sctp_mib.sctpLocalEntrySize, sizeof (scle)); 562 SET_MIB(sctp_mib.sctpRemoteEntrySize, sizeof (scre)); 563 optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)]; 564 optp->level = MIB2_SCTP; 565 optp->name = 0; 566 (void) snmp_append_data(mpdata, (char *)&sctp_mib, sizeof (sctp_mib)); 567 optp->len = msgdsize(mpdata); 568 qreply(q, mpctl); 569 570 /* table of connections... */ 571 optp = (struct opthdr *)&mp_conn_ctl->b_rptr[ 572 sizeof (struct T_optmgmt_ack)]; 573 optp->level = MIB2_SCTP; 574 optp->name = MIB2_SCTP_CONN; 575 optp->len = msgdsize(mp_conn_data); 576 qreply(q, mp_conn_ctl); 577 578 /* assoc local address table */ 579 optp = (struct opthdr *)&mp_local_ctl->b_rptr[ 580 sizeof (struct T_optmgmt_ack)]; 581 optp->level = MIB2_SCTP; 582 optp->name = MIB2_SCTP_CONN_LOCAL; 583 optp->len = msgdsize(mp_local_data); 584 qreply(q, mp_local_ctl); 585 586 /* assoc remote address table */ 587 optp = (struct opthdr *)&mp_rem_ctl->b_rptr[ 588 sizeof (struct T_optmgmt_ack)]; 589 optp->level = MIB2_SCTP; 590 optp->name = MIB2_SCTP_CONN_REMOTE; 591 optp->len = msgdsize(mp_rem_data); 592 qreply(q, mp_rem_ctl); 593 594 /* table of MLP attributes */ 595 optp = (struct opthdr *)&mp_attr_ctl->b_rptr[ 596 sizeof (struct T_optmgmt_ack)]; 597 optp->level = MIB2_SCTP; 598 optp->name = EXPER_XPORT_MLP; 599 optp->len = msgdsize(mp_attr_data); 600 if (optp->len == 0) 601 freemsg(mp_attr_ctl); 602 else 603 qreply(q, mp_attr_ctl); 604 605 return (mp_ret); 606 } 607 608 /* Translate SCTP state to MIB2 SCTP state. */ 609 static int 610 sctp_snmp_state(sctp_t *sctp) 611 { 612 if (sctp == NULL) 613 return (0); 614 615 switch (sctp->sctp_state) { 616 case SCTPS_IDLE: 617 case SCTPS_BOUND: 618 return (MIB2_SCTP_closed); 619 case SCTPS_LISTEN: 620 return (MIB2_SCTP_listen); 621 case SCTPS_COOKIE_WAIT: 622 return (MIB2_SCTP_cookieWait); 623 case SCTPS_COOKIE_ECHOED: 624 return (MIB2_SCTP_cookieEchoed); 625 case SCTPS_ESTABLISHED: 626 return (MIB2_SCTP_established); 627 case SCTPS_SHUTDOWN_PENDING: 628 return (MIB2_SCTP_shutdownPending); 629 case SCTPS_SHUTDOWN_SENT: 630 return (MIB2_SCTP_shutdownSent); 631 case SCTPS_SHUTDOWN_RECEIVED: 632 return (MIB2_SCTP_shutdownReceived); 633 case SCTPS_SHUTDOWN_ACK_SENT: 634 return (MIB2_SCTP_shutdownAckSent); 635 default: 636 return (0); 637 } 638 } 639