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 /* 23 * Copyright 2006 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 #include <sys/tsol/tndb.h> 37 38 #include <netinet/in.h> 39 40 #include <inet/common.h> 41 #include <inet/ip.h> 42 #include <inet/mib2.h> 43 #include <inet/snmpcom.h> 44 #include <inet/kstatcom.h> 45 #include <inet/ipclassifier.h> 46 #include "sctp_impl.h" 47 #include "sctp_addr.h" 48 49 mib2_sctp_t sctp_mib; 50 static kstat_t *sctp_mibkp; /* kstat exporting sctp_mib data */ 51 static kstat_t *sctp_kstat; /* kstat exporting general sctp stats */ 52 53 static int sctp_snmp_state(sctp_t *sctp); 54 55 /* 56 * The following kstats are for debugging purposes. They keep 57 * track of problems which should not happen normally. But in 58 * those cases which they do happen, these kstats would be handy 59 * for engineers to diagnose the problems. They are not intended 60 * to be consumed by customers. 61 */ 62 sctp_kstat_t sctp_statistics = { 63 { "sctp_add_faddr", KSTAT_DATA_UINT64 }, 64 { "sctp_add_timer", KSTAT_DATA_UINT64 }, 65 { "sctp_conn_create", KSTAT_DATA_UINT64 }, 66 { "sctp_find_next_tq", KSTAT_DATA_UINT64 }, 67 { "sctp_fr_add_hdr", KSTAT_DATA_UINT64 }, 68 { "sctp_fr_not_found", KSTAT_DATA_UINT64 }, 69 { "sctp_output_failed", KSTAT_DATA_UINT64 }, 70 { "sctp_rexmit_failed", KSTAT_DATA_UINT64 }, 71 { "sctp_send_init_failed", KSTAT_DATA_UINT64 }, 72 { "sctp_send_cookie_failed", KSTAT_DATA_UINT64 }, 73 { "sctp_send_cookie_ack_failed", KSTAT_DATA_UINT64 }, 74 { "sctp_send_err_failed", KSTAT_DATA_UINT64 }, 75 { "sctp_send_sack_failed", KSTAT_DATA_UINT64 }, 76 { "sctp_send_shutdown_failed", KSTAT_DATA_UINT64 }, 77 { "sctp_send_shutdown_ack_failed", KSTAT_DATA_UINT64 }, 78 { "sctp_send_shutdown_comp_failed", KSTAT_DATA_UINT64 }, 79 { "sctp_send_user_abort_failed", KSTAT_DATA_UINT64 }, 80 { "sctp_send_asconf_failed", KSTAT_DATA_UINT64 }, 81 { "sctp_send_asconf_ack_failed", KSTAT_DATA_UINT64 }, 82 { "sctp_send_ftsn_failed", KSTAT_DATA_UINT64 }, 83 { "sctp_send_hb_failed", KSTAT_DATA_UINT64 }, 84 { "sctp_return_hb_failed", KSTAT_DATA_UINT64 }, 85 { "sctp_ss_rexmit_failed", KSTAT_DATA_UINT64 }, 86 { "sctp_cl_connect", KSTAT_DATA_UINT64 }, 87 { "sctp_cl_assoc_change", KSTAT_DATA_UINT64 }, 88 { "sctp_cl_check_addrs", KSTAT_DATA_UINT64 }, 89 }; 90 91 static int 92 sctp_kstat_update(kstat_t *kp, int rw) 93 { 94 sctp_named_kstat_t *sctpkp; 95 sctp_t *sctp, *sctp_prev; 96 zoneid_t zoneid; 97 98 if (kp == NULL|| kp->ks_data == NULL) 99 return (EIO); 100 101 if (rw == KSTAT_WRITE) 102 return (EACCES); 103 104 zoneid = getzoneid(); 105 106 /* 107 * Get the number of current associations and gather their 108 * individual set of statistics. 109 */ 110 SET_MIB(sctp_mib.sctpCurrEstab, 0); 111 sctp = gsctp; 112 sctp_prev = NULL; 113 mutex_enter(&sctp_g_lock); 114 while (sctp != NULL) { 115 mutex_enter(&sctp->sctp_reflock); 116 if (sctp->sctp_condemned) { 117 mutex_exit(&sctp->sctp_reflock); 118 sctp = list_next(&sctp_g_list, sctp); 119 continue; 120 } 121 sctp->sctp_refcnt++; 122 mutex_exit(&sctp->sctp_reflock); 123 mutex_exit(&sctp_g_lock); 124 if (sctp_prev != NULL) 125 SCTP_REFRELE(sctp_prev); 126 if (sctp->sctp_connp->conn_zoneid != zoneid) 127 goto next_sctp; 128 if (sctp->sctp_state == SCTPS_ESTABLISHED || 129 sctp->sctp_state == SCTPS_SHUTDOWN_PENDING || 130 sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) { 131 BUMP_MIB(&sctp_mib, sctpCurrEstab); 132 } 133 134 if (sctp->sctp_opkts) { 135 UPDATE_MIB(&sctp_mib, sctpOutSCTPPkts, 136 sctp->sctp_opkts); 137 sctp->sctp_opkts = 0; 138 } 139 140 if (sctp->sctp_obchunks) { 141 UPDATE_MIB(&sctp_mib, sctpOutCtrlChunks, 142 sctp->sctp_obchunks); 143 sctp->sctp_obchunks = 0; 144 } 145 146 if (sctp->sctp_odchunks) { 147 UPDATE_MIB(&sctp_mib, sctpOutOrderChunks, 148 sctp->sctp_odchunks); 149 sctp->sctp_odchunks = 0; 150 } 151 152 if (sctp->sctp_oudchunks) { 153 UPDATE_MIB(&sctp_mib, sctpOutUnorderChunks, 154 sctp->sctp_oudchunks); 155 sctp->sctp_oudchunks = 0; 156 } 157 158 if (sctp->sctp_rxtchunks) { 159 UPDATE_MIB(&sctp_mib, sctpRetransChunks, 160 sctp->sctp_rxtchunks); 161 sctp->sctp_rxtchunks = 0; 162 } 163 164 if (sctp->sctp_ipkts) { 165 UPDATE_MIB(&sctp_mib, sctpInSCTPPkts, sctp->sctp_ipkts); 166 sctp->sctp_ipkts = 0; 167 } 168 169 if (sctp->sctp_ibchunks) { 170 UPDATE_MIB(&sctp_mib, sctpInCtrlChunks, 171 sctp->sctp_ibchunks); 172 sctp->sctp_ibchunks = 0; 173 } 174 175 if (sctp->sctp_idchunks) { 176 UPDATE_MIB(&sctp_mib, sctpInOrderChunks, 177 sctp->sctp_idchunks); 178 sctp->sctp_idchunks = 0; 179 } 180 181 if (sctp->sctp_iudchunks) { 182 UPDATE_MIB(&sctp_mib, sctpInUnorderChunks, 183 sctp->sctp_iudchunks); 184 sctp->sctp_iudchunks = 0; 185 } 186 187 if (sctp->sctp_fragdmsgs) { 188 UPDATE_MIB(&sctp_mib, sctpFragUsrMsgs, 189 sctp->sctp_fragdmsgs); 190 sctp->sctp_fragdmsgs = 0; 191 } 192 193 if (sctp->sctp_reassmsgs) { 194 UPDATE_MIB(&sctp_mib, sctpReasmUsrMsgs, 195 sctp->sctp_reassmsgs); 196 sctp->sctp_reassmsgs = 0; 197 } 198 199 next_sctp: 200 sctp_prev = sctp; 201 mutex_enter(&sctp_g_lock); 202 sctp = list_next(&sctp_g_list, sctp); 203 } 204 mutex_exit(&sctp_g_lock); 205 if (sctp_prev != NULL) 206 SCTP_REFRELE(sctp_prev); 207 208 /* Copy data from the SCTP MIB */ 209 sctpkp = (sctp_named_kstat_t *)kp->ks_data; 210 211 /* These are from global ndd params. */ 212 sctpkp->sctpRtoMin.value.ui32 = sctp_rto_ming; 213 sctpkp->sctpRtoMax.value.ui32 = sctp_rto_maxg; 214 sctpkp->sctpRtoInitial.value.ui32 = sctp_rto_initialg; 215 sctpkp->sctpValCookieLife.value.ui32 = sctp_cookie_life; 216 sctpkp->sctpMaxInitRetr.value.ui32 = sctp_max_init_retr; 217 218 sctpkp->sctpCurrEstab.value.i32 = sctp_mib.sctpCurrEstab; 219 sctpkp->sctpActiveEstab.value.i32 = sctp_mib.sctpActiveEstab; 220 sctpkp->sctpPassiveEstab.value.i32 = sctp_mib.sctpPassiveEstab; 221 sctpkp->sctpAborted.value.i32 = sctp_mib.sctpAborted; 222 sctpkp->sctpShutdowns.value.i32 = sctp_mib.sctpShutdowns; 223 sctpkp->sctpOutOfBlue.value.i32 = sctp_mib.sctpOutOfBlue; 224 sctpkp->sctpChecksumError.value.i32 = sctp_mib.sctpChecksumError; 225 sctpkp->sctpOutCtrlChunks.value.i64 = sctp_mib.sctpOutCtrlChunks; 226 sctpkp->sctpOutOrderChunks.value.i64 = sctp_mib.sctpOutOrderChunks; 227 sctpkp->sctpOutUnorderChunks.value.i64 = sctp_mib.sctpOutUnorderChunks; 228 sctpkp->sctpRetransChunks.value.i64 = sctp_mib.sctpRetransChunks; 229 sctpkp->sctpOutAck.value.i32 = sctp_mib.sctpOutAck; 230 sctpkp->sctpOutAckDelayed.value.i32 = sctp_mib.sctpOutAckDelayed; 231 sctpkp->sctpOutWinUpdate.value.i32 = sctp_mib.sctpOutWinUpdate; 232 sctpkp->sctpOutFastRetrans.value.i32 = sctp_mib.sctpOutFastRetrans; 233 sctpkp->sctpOutWinProbe.value.i32 = sctp_mib.sctpOutWinProbe; 234 sctpkp->sctpInCtrlChunks.value.i64 = sctp_mib.sctpInCtrlChunks; 235 sctpkp->sctpInOrderChunks.value.i64 = sctp_mib.sctpInOrderChunks; 236 sctpkp->sctpInUnorderChunks.value.i64 = sctp_mib.sctpInUnorderChunks; 237 sctpkp->sctpInAck.value.i32 = sctp_mib.sctpInAck; 238 sctpkp->sctpInDupAck.value.i32 = sctp_mib.sctpInDupAck; 239 sctpkp->sctpInAckUnsent.value.i32 = sctp_mib.sctpInAckUnsent; 240 sctpkp->sctpFragUsrMsgs.value.i64 = sctp_mib.sctpFragUsrMsgs; 241 sctpkp->sctpReasmUsrMsgs.value.i64 = sctp_mib.sctpReasmUsrMsgs; 242 sctpkp->sctpOutSCTPPkts.value.i64 = sctp_mib.sctpOutSCTPPkts; 243 sctpkp->sctpInSCTPPkts.value.i64 = sctp_mib.sctpInSCTPPkts; 244 sctpkp->sctpInInvalidCookie.value.i32 = sctp_mib.sctpInInvalidCookie; 245 sctpkp->sctpTimRetrans.value.i32 = sctp_mib.sctpTimRetrans; 246 sctpkp->sctpTimRetransDrop.value.i32 = sctp_mib.sctpTimRetransDrop; 247 sctpkp->sctpTimHeartBeatProbe.value.i32 = 248 sctp_mib.sctpTimHeartBeatProbe; 249 sctpkp->sctpTimHeartBeatDrop.value.i32 = sctp_mib.sctpTimHeartBeatDrop; 250 sctpkp->sctpListenDrop.value.i32 = sctp_mib.sctpListenDrop; 251 sctpkp->sctpInClosed.value.i32 = sctp_mib.sctpInClosed; 252 253 return (0); 254 } 255 256 void 257 sctp_kstat_init(void) 258 { 259 sctp_named_kstat_t template = { 260 { "sctpRtoAlgorithm", KSTAT_DATA_INT32, 0 }, 261 { "sctpRtoMin", KSTAT_DATA_UINT32, 0 }, 262 { "sctpRtoMax", KSTAT_DATA_UINT32, 0 }, 263 { "sctpRtoInitial", KSTAT_DATA_UINT32, 0 }, 264 { "sctpMaxAssocs", KSTAT_DATA_INT32, 0 }, 265 { "sctpValCookieLife", KSTAT_DATA_UINT32, 0 }, 266 { "sctpMaxInitRetr", KSTAT_DATA_UINT32, 0 }, 267 { "sctpCurrEstab", KSTAT_DATA_INT32, 0 }, 268 { "sctpActiveEstab", KSTAT_DATA_INT32, 0 }, 269 { "sctpPassiveEstab", KSTAT_DATA_INT32, 0 }, 270 { "sctpAborted", KSTAT_DATA_INT32, 0 }, 271 { "sctpShutdowns", KSTAT_DATA_INT32, 0 }, 272 { "sctpOutOfBlue", KSTAT_DATA_INT32, 0 }, 273 { "sctpChecksumError", KSTAT_DATA_INT32, 0 }, 274 { "sctpOutCtrlChunks", KSTAT_DATA_INT64, 0 }, 275 { "sctpOutOrderChunks", KSTAT_DATA_INT64, 0 }, 276 { "sctpOutUnorderChunks", KSTAT_DATA_INT64, 0 }, 277 { "sctpRetransChunks", KSTAT_DATA_INT64, 0 }, 278 { "sctpOutAck", KSTAT_DATA_INT32, 0 }, 279 { "sctpOutAckDelayed", KSTAT_DATA_INT32, 0 }, 280 { "sctpOutWinUpdate", KSTAT_DATA_INT32, 0 }, 281 { "sctpOutFastRetrans", KSTAT_DATA_INT32, 0 }, 282 { "sctpOutWinProbe", KSTAT_DATA_INT32, 0 }, 283 { "sctpInCtrlChunks", KSTAT_DATA_INT64, 0 }, 284 { "sctpInOrderChunks", KSTAT_DATA_INT64, 0 }, 285 { "sctpInUnorderChunks", KSTAT_DATA_INT64, 0 }, 286 { "sctpInAck", KSTAT_DATA_INT32, 0 }, 287 { "sctpInDupAck", KSTAT_DATA_INT32, 0 }, 288 { "sctpInAckUnsent", KSTAT_DATA_INT32, 0 }, 289 { "sctpFragUsrMsgs", KSTAT_DATA_INT64, 0 }, 290 { "sctpReasmUsrMsgs", KSTAT_DATA_INT64, 0 }, 291 { "sctpOutSCTPPkts", KSTAT_DATA_INT64, 0 }, 292 { "sctpInSCTPPkts", KSTAT_DATA_INT64, 0 }, 293 { "sctpInInvalidCookie", KSTAT_DATA_INT32, 0 }, 294 { "sctpTimRetrans", KSTAT_DATA_INT32, 0 }, 295 { "sctpTimRetransDrop", KSTAT_DATA_INT32, 0 }, 296 { "sctpTimHearBeatProbe", KSTAT_DATA_INT32, 0 }, 297 { "sctpTimHearBeatDrop", KSTAT_DATA_INT32, 0 }, 298 { "sctpListenDrop", KSTAT_DATA_INT32, 0 }, 299 { "sctpInClosed", KSTAT_DATA_INT32, 0 } 300 }; 301 302 sctp_mibkp = kstat_create(SCTP_MOD_NAME, 0, "sctp", "mib2", 303 KSTAT_TYPE_NAMED, NUM_OF_FIELDS(sctp_named_kstat_t), 0); 304 305 if (sctp_mibkp == NULL) 306 return; 307 308 /* These won't change. */ 309 template.sctpRtoAlgorithm.value.i32 = MIB2_SCTP_RTOALGO_VANJ; 310 template.sctpMaxAssocs.value.i32 = -1; 311 312 bcopy(&template, sctp_mibkp->ks_data, sizeof (template)); 313 314 sctp_mibkp->ks_update = sctp_kstat_update; 315 316 kstat_install(sctp_mibkp); 317 318 if ((sctp_kstat = kstat_create(SCTP_MOD_NAME, 0, "sctpstat", 319 "net", KSTAT_TYPE_NAMED, NUM_OF_FIELDS(sctp_statistics), 320 KSTAT_FLAG_VIRTUAL)) != NULL) { 321 sctp_kstat->ks_data = &sctp_statistics; 322 kstat_install(sctp_kstat); 323 } 324 } 325 326 void 327 sctp_kstat_fini(void) 328 { 329 if (sctp_mibkp != NULL) { 330 kstat_delete(sctp_mibkp); 331 sctp_mibkp = NULL; 332 } 333 if (sctp_kstat != NULL) { 334 kstat_delete(sctp_kstat); 335 sctp_kstat = NULL; 336 } 337 } 338 339 /* 340 * Return SNMP global stats in buffer in mpdata. 341 * Return associatiation table in mp_conn_data, 342 * local address table in mp_local_data, and 343 * remote address table in mp_rem_data. 344 */ 345 mblk_t * 346 sctp_snmp_get_mib2(queue_t *q, mblk_t *mpctl) 347 { 348 mblk_t *mpdata, *mp_ret; 349 mblk_t *mp_conn_ctl = NULL; 350 mblk_t *mp_conn_data; 351 mblk_t *mp_conn_tail = NULL; 352 mblk_t *mp_local_ctl = NULL; 353 mblk_t *mp_local_data; 354 mblk_t *mp_local_tail = NULL; 355 mblk_t *mp_rem_ctl = NULL; 356 mblk_t *mp_rem_data; 357 mblk_t *mp_rem_tail = NULL; 358 mblk_t *mp_attr_ctl = NULL; 359 mblk_t *mp_attr_data; 360 mblk_t *mp_attr_tail = NULL; 361 struct opthdr *optp; 362 sctp_t *sctp, *sctp_prev = NULL; 363 sctp_faddr_t *fp; 364 mib2_sctpConnEntry_t sce; 365 mib2_sctpConnLocalEntry_t scle; 366 mib2_sctpConnRemoteEntry_t scre; 367 mib2_transportMLPEntry_t mlp; 368 int i; 369 int l; 370 int scanned = 0; 371 zoneid_t zoneid = Q_TO_CONN(q)->conn_zoneid; 372 conn_t *connp; 373 boolean_t needattr; 374 int idx; 375 376 /* 377 * Make copies of the original message. 378 * mpctl will hold SCTP counters, 379 * mp_conn_ctl will hold list of connections. 380 */ 381 mp_ret = copymsg(mpctl); 382 mp_conn_ctl = copymsg(mpctl); 383 mp_local_ctl = copymsg(mpctl); 384 mp_rem_ctl = copymsg(mpctl); 385 mp_attr_ctl = copymsg(mpctl); 386 387 mpdata = mpctl->b_cont; 388 389 if (mp_conn_ctl == NULL || mp_local_ctl == NULL || 390 mp_rem_ctl == NULL || mp_attr_ctl == NULL || mpdata == NULL) { 391 freemsg(mp_attr_ctl); 392 freemsg(mp_rem_ctl); 393 freemsg(mp_local_ctl); 394 freemsg(mp_conn_ctl); 395 freemsg(mp_ret); 396 freemsg(mpctl); 397 return (NULL); 398 } 399 mp_conn_data = mp_conn_ctl->b_cont; 400 mp_local_data = mp_local_ctl->b_cont; 401 mp_rem_data = mp_rem_ctl->b_cont; 402 mp_attr_data = mp_attr_ctl->b_cont; 403 404 /* hostname address parameters are not supported in Solaris */ 405 sce.sctpAssocRemHostName.o_length = 0; 406 sce.sctpAssocRemHostName.o_bytes[0] = 0; 407 408 /* build table of connections -- need count in fixed part */ 409 SET_MIB(sctp_mib.sctpRtoAlgorithm, MIB2_SCTP_RTOALGO_VANJ); 410 SET_MIB(sctp_mib.sctpRtoMin, sctp_rto_ming); 411 SET_MIB(sctp_mib.sctpRtoMax, sctp_rto_maxg); 412 SET_MIB(sctp_mib.sctpRtoInitial, sctp_rto_initialg); 413 SET_MIB(sctp_mib.sctpMaxAssocs, -1); 414 SET_MIB(sctp_mib.sctpValCookieLife, sctp_cookie_life); 415 SET_MIB(sctp_mib.sctpMaxInitRetr, sctp_max_init_retr); 416 SET_MIB(sctp_mib.sctpCurrEstab, 0); 417 418 idx = 0; 419 sctp = gsctp; 420 mutex_enter(&sctp_g_lock); 421 while (sctp != NULL) { 422 mutex_enter(&sctp->sctp_reflock); 423 if (sctp->sctp_condemned) { 424 mutex_exit(&sctp->sctp_reflock); 425 sctp = list_next(&sctp_g_list, sctp); 426 continue; 427 } 428 sctp->sctp_refcnt++; 429 mutex_exit(&sctp->sctp_reflock); 430 mutex_exit(&sctp_g_lock); 431 if (sctp_prev != NULL) 432 SCTP_REFRELE(sctp_prev); 433 if (sctp->sctp_connp->conn_zoneid != zoneid) 434 goto next_sctp; 435 if (sctp->sctp_state == SCTPS_ESTABLISHED || 436 sctp->sctp_state == SCTPS_SHUTDOWN_PENDING || 437 sctp->sctp_state == SCTPS_SHUTDOWN_RECEIVED) { 438 BUMP_MIB(&sctp_mib, sctpCurrEstab); 439 } 440 UPDATE_MIB(&sctp_mib, sctpOutSCTPPkts, sctp->sctp_opkts); 441 sctp->sctp_opkts = 0; 442 UPDATE_MIB(&sctp_mib, sctpOutCtrlChunks, sctp->sctp_obchunks); 443 sctp->sctp_obchunks = 0; 444 UPDATE_MIB(&sctp_mib, sctpOutOrderChunks, sctp->sctp_odchunks); 445 sctp->sctp_odchunks = 0; 446 UPDATE_MIB(&sctp_mib, sctpOutUnorderChunks, 447 sctp->sctp_oudchunks); 448 sctp->sctp_oudchunks = 0; 449 UPDATE_MIB(&sctp_mib, sctpRetransChunks, sctp->sctp_rxtchunks); 450 sctp->sctp_rxtchunks = 0; 451 UPDATE_MIB(&sctp_mib, sctpInSCTPPkts, sctp->sctp_ipkts); 452 sctp->sctp_ipkts = 0; 453 UPDATE_MIB(&sctp_mib, sctpInCtrlChunks, sctp->sctp_ibchunks); 454 sctp->sctp_ibchunks = 0; 455 UPDATE_MIB(&sctp_mib, sctpInOrderChunks, sctp->sctp_idchunks); 456 sctp->sctp_idchunks = 0; 457 UPDATE_MIB(&sctp_mib, sctpInUnorderChunks, 458 sctp->sctp_iudchunks); 459 sctp->sctp_iudchunks = 0; 460 UPDATE_MIB(&sctp_mib, sctpFragUsrMsgs, sctp->sctp_fragdmsgs); 461 sctp->sctp_fragdmsgs = 0; 462 UPDATE_MIB(&sctp_mib, sctpReasmUsrMsgs, sctp->sctp_reassmsgs); 463 sctp->sctp_reassmsgs = 0; 464 465 sce.sctpAssocId = ntohl(sctp->sctp_lvtag); 466 sce.sctpAssocLocalPort = ntohs(sctp->sctp_lport); 467 sce.sctpAssocRemPort = ntohs(sctp->sctp_fport); 468 469 RUN_SCTP(sctp); 470 if (sctp->sctp_primary != NULL) { 471 fp = sctp->sctp_primary; 472 473 if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) { 474 sce.sctpAssocRemPrimAddrType = 475 MIB2_SCTP_ADDR_V4; 476 } else { 477 sce.sctpAssocRemPrimAddrType = 478 MIB2_SCTP_ADDR_V6; 479 } 480 sce.sctpAssocRemPrimAddr = fp->faddr; 481 sce.sctpAssocLocPrimAddr = fp->saddr; 482 sce.sctpAssocHeartBeatInterval = TICK_TO_MSEC( 483 fp->hb_interval); 484 } else { 485 sce.sctpAssocRemPrimAddrType = MIB2_SCTP_ADDR_V4; 486 bzero(&sce.sctpAssocRemPrimAddr, 487 sizeof (sce.sctpAssocRemPrimAddr)); 488 bzero(&sce.sctpAssocLocPrimAddr, 489 sizeof (sce.sctpAssocLocPrimAddr)); 490 sce.sctpAssocHeartBeatInterval = 491 sctp_heartbeat_interval; 492 } 493 494 /* 495 * Table for local addresses 496 */ 497 scanned = 0; 498 for (i = 0; i < SCTP_IPIF_HASH; i++) { 499 sctp_saddr_ipif_t *obj; 500 501 if (sctp->sctp_saddrs[i].ipif_count == 0) 502 continue; 503 obj = list_head(&sctp->sctp_saddrs[i].sctp_ipif_list); 504 for (l = 0; l < sctp->sctp_saddrs[i].ipif_count; l++) { 505 sctp_ipif_t *sctp_ipif; 506 in6_addr_t addr; 507 508 sctp_ipif = obj->saddr_ipifp; 509 addr = sctp_ipif->sctp_ipif_saddr; 510 scanned++; 511 scle.sctpAssocId = ntohl(sctp->sctp_lvtag); 512 if (IN6_IS_ADDR_V4MAPPED(&addr)) { 513 scle.sctpAssocLocalAddrType = 514 MIB2_SCTP_ADDR_V4; 515 } else { 516 scle.sctpAssocLocalAddrType = 517 MIB2_SCTP_ADDR_V6; 518 } 519 scle.sctpAssocLocalAddr = addr; 520 (void) snmp_append_data2(mp_local_data, 521 &mp_local_tail, (char *)&scle, 522 sizeof (scle)); 523 if (scanned >= sctp->sctp_nsaddrs) 524 goto done; 525 obj = list_next(&sctp-> 526 sctp_saddrs[i].sctp_ipif_list, obj); 527 } 528 } 529 done: 530 /* 531 * Table for remote addresses 532 */ 533 for (fp = sctp->sctp_faddrs; fp; fp = fp->next) { 534 scre.sctpAssocId = ntohl(sctp->sctp_lvtag); 535 if (IN6_IS_ADDR_V4MAPPED(&fp->faddr)) { 536 scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V4; 537 } else { 538 scre.sctpAssocRemAddrType = MIB2_SCTP_ADDR_V6; 539 } 540 scre.sctpAssocRemAddr = fp->faddr; 541 if (fp->state == SCTP_FADDRS_ALIVE) { 542 scre.sctpAssocRemAddrActive = 543 scre.sctpAssocRemAddrHBActive = 544 MIB2_SCTP_ACTIVE; 545 } else { 546 scre.sctpAssocRemAddrActive = 547 scre.sctpAssocRemAddrHBActive = 548 MIB2_SCTP_INACTIVE; 549 } 550 scre.sctpAssocRemAddrRTO = TICK_TO_MSEC(fp->rto); 551 scre.sctpAssocRemAddrMaxPathRtx = fp->max_retr; 552 scre.sctpAssocRemAddrRtx = fp->T3expire; 553 (void) snmp_append_data2(mp_rem_data, &mp_rem_tail, 554 (char *)&scre, sizeof (scre)); 555 } 556 connp = sctp->sctp_connp; 557 needattr = B_FALSE; 558 bzero(&mlp, sizeof (mlp)); 559 if (connp->conn_mlp_type != mlptSingle) { 560 if (connp->conn_mlp_type == mlptShared || 561 connp->conn_mlp_type == mlptBoth) 562 mlp.tme_flags |= MIB2_TMEF_SHARED; 563 if (connp->conn_mlp_type == mlptPrivate || 564 connp->conn_mlp_type == mlptBoth) 565 mlp.tme_flags |= MIB2_TMEF_PRIVATE; 566 needattr = B_TRUE; 567 } 568 if (connp->conn_peercred != NULL) { 569 ts_label_t *tsl; 570 571 tsl = crgetlabel(connp->conn_peercred); 572 mlp.tme_doi = label2doi(tsl); 573 mlp.tme_label = *label2bslabel(tsl); 574 needattr = B_TRUE; 575 } 576 WAKE_SCTP(sctp); 577 sce.sctpAssocState = sctp_snmp_state(sctp); 578 sce.sctpAssocInStreams = sctp->sctp_num_istr; 579 sce.sctpAssocOutStreams = sctp->sctp_num_ostr; 580 sce.sctpAssocMaxRetr = sctp->sctp_pa_max_rxt; 581 /* A 0 here indicates that no primary process is known */ 582 sce.sctpAssocPrimProcess = 0; 583 sce.sctpAssocT1expired = sctp->sctp_T1expire; 584 sce.sctpAssocT2expired = sctp->sctp_T2expire; 585 sce.sctpAssocRtxChunks = sctp->sctp_T3expire; 586 sce.sctpAssocStartTime = sctp->sctp_assoc_start_time; 587 sce.sctpConnEntryInfo.ce_sendq = sctp->sctp_unacked + 588 sctp->sctp_unsent; 589 sce.sctpConnEntryInfo.ce_recvq = sctp->sctp_rxqueued; 590 sce.sctpConnEntryInfo.ce_swnd = sctp->sctp_frwnd; 591 sce.sctpConnEntryInfo.ce_rwnd = sctp->sctp_rwnd; 592 sce.sctpConnEntryInfo.ce_mss = sctp->sctp_mss; 593 (void) snmp_append_data2(mp_conn_data, &mp_conn_tail, 594 (char *)&sce, sizeof (sce)); 595 mlp.tme_connidx = idx++; 596 if (needattr) 597 (void) snmp_append_data2(mp_attr_ctl->b_cont, 598 &mp_attr_tail, (char *)&mlp, sizeof (mlp)); 599 next_sctp: 600 sctp_prev = sctp; 601 mutex_enter(&sctp_g_lock); 602 sctp = list_next(&sctp_g_list, sctp); 603 } 604 mutex_exit(&sctp_g_lock); 605 if (sctp_prev != NULL) 606 SCTP_REFRELE(sctp_prev); 607 608 /* fixed length structure for IPv4 and IPv6 counters */ 609 SET_MIB(sctp_mib.sctpEntrySize, sizeof (sce)); 610 SET_MIB(sctp_mib.sctpLocalEntrySize, sizeof (scle)); 611 SET_MIB(sctp_mib.sctpRemoteEntrySize, sizeof (scre)); 612 optp = (struct opthdr *)&mpctl->b_rptr[sizeof (struct T_optmgmt_ack)]; 613 optp->level = MIB2_SCTP; 614 optp->name = 0; 615 (void) snmp_append_data(mpdata, (char *)&sctp_mib, sizeof (sctp_mib)); 616 optp->len = msgdsize(mpdata); 617 qreply(q, mpctl); 618 619 /* table of connections... */ 620 optp = (struct opthdr *)&mp_conn_ctl->b_rptr[ 621 sizeof (struct T_optmgmt_ack)]; 622 optp->level = MIB2_SCTP; 623 optp->name = MIB2_SCTP_CONN; 624 optp->len = msgdsize(mp_conn_data); 625 qreply(q, mp_conn_ctl); 626 627 /* assoc local address table */ 628 optp = (struct opthdr *)&mp_local_ctl->b_rptr[ 629 sizeof (struct T_optmgmt_ack)]; 630 optp->level = MIB2_SCTP; 631 optp->name = MIB2_SCTP_CONN_LOCAL; 632 optp->len = msgdsize(mp_local_data); 633 qreply(q, mp_local_ctl); 634 635 /* assoc remote address table */ 636 optp = (struct opthdr *)&mp_rem_ctl->b_rptr[ 637 sizeof (struct T_optmgmt_ack)]; 638 optp->level = MIB2_SCTP; 639 optp->name = MIB2_SCTP_CONN_REMOTE; 640 optp->len = msgdsize(mp_rem_data); 641 qreply(q, mp_rem_ctl); 642 643 /* table of MLP attributes */ 644 optp = (struct opthdr *)&mp_attr_ctl->b_rptr[ 645 sizeof (struct T_optmgmt_ack)]; 646 optp->level = MIB2_SCTP; 647 optp->name = EXPER_XPORT_MLP; 648 optp->len = msgdsize(mp_attr_data); 649 if (optp->len == 0) 650 freemsg(mp_attr_ctl); 651 else 652 qreply(q, mp_attr_ctl); 653 654 return (mp_ret); 655 } 656 657 /* Translate SCTP state to MIB2 SCTP state. */ 658 static int 659 sctp_snmp_state(sctp_t *sctp) 660 { 661 if (sctp == NULL) 662 return (0); 663 664 switch (sctp->sctp_state) { 665 case SCTPS_IDLE: 666 case SCTPS_BOUND: 667 return (MIB2_SCTP_closed); 668 case SCTPS_LISTEN: 669 return (MIB2_SCTP_listen); 670 case SCTPS_COOKIE_WAIT: 671 return (MIB2_SCTP_cookieWait); 672 case SCTPS_COOKIE_ECHOED: 673 return (MIB2_SCTP_cookieEchoed); 674 case SCTPS_ESTABLISHED: 675 return (MIB2_SCTP_established); 676 case SCTPS_SHUTDOWN_PENDING: 677 return (MIB2_SCTP_shutdownPending); 678 case SCTPS_SHUTDOWN_SENT: 679 return (MIB2_SCTP_shutdownSent); 680 case SCTPS_SHUTDOWN_RECEIVED: 681 return (MIB2_SCTP_shutdownReceived); 682 case SCTPS_SHUTDOWN_ACK_SENT: 683 return (MIB2_SCTP_shutdownAckSent); 684 default: 685 return (0); 686 } 687 } 688