1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 1735 kcpoon * Common Development and Distribution License (the "License"). 6 1735 kcpoon * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 1735 kcpoon 22 0 stevel /* 23 11042 Erik * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 0 stevel * Use is subject to license terms. 25 0 stevel */ 26 0 stevel 27 0 stevel #include <sys/types.h> 28 0 stevel #include <sys/stream.h> 29 0 stevel #include <sys/mdb_modapi.h> 30 0 stevel #include <sys/socket.h> 31 0 stevel #include <sys/list.h> 32 0 stevel #include <sys/strsun.h> 33 0 stevel 34 0 stevel #include <mdb/mdb_stdlib.h> 35 0 stevel 36 0 stevel #include <netinet/in.h> 37 0 stevel #include <netinet/ip6.h> 38 0 stevel #include <netinet/sctp.h> 39 0 stevel 40 0 stevel #include <inet/common.h> 41 0 stevel #include <inet/ip.h> 42 0 stevel #include <inet/ip6.h> 43 0 stevel #include <inet/ipclassifier.h> 44 0 stevel 45 0 stevel #include <sctp/sctp_impl.h> 46 0 stevel #include <sctp/sctp_addr.h> 47 0 stevel 48 0 stevel #define MDB_SCTP_SHOW_FLAGS 0x1 49 0 stevel #define MDB_SCTP_DUMP_ADDRS 0x2 50 0 stevel #define MDB_SCTP_SHOW_HASH 0x4 51 0 stevel #define MDB_SCTP_SHOW_OUT 0x8 52 0 stevel #define MDB_SCTP_SHOW_IN 0x10 53 0 stevel #define MDB_SCTP_SHOW_MISC 0x20 54 0 stevel #define MDB_SCTP_SHOW_RTT 0x40 55 0 stevel #define MDB_SCTP_SHOW_STATS 0x80 56 0 stevel #define MDB_SCTP_SHOW_FLOW 0x100 57 0 stevel #define MDB_SCTP_SHOW_HDR 0x200 58 0 stevel #define MDB_SCTP_SHOW_PMTUD 0x400 59 0 stevel #define MDB_SCTP_SHOW_RXT 0x800 60 0 stevel #define MDB_SCTP_SHOW_CONN 0x1000 61 0 stevel #define MDB_SCTP_SHOW_CLOSE 0x2000 62 0 stevel #define MDB_SCTP_SHOW_EXT 0x4000 63 0 stevel 64 0 stevel #define MDB_SCTP_SHOW_ALL 0xffffffff 65 0 stevel 66 0 stevel /* 67 0 stevel * Copy from usr/src/uts/common/os/list.c. Should we have a generic 68 0 stevel * mdb list walker? 69 0 stevel */ 70 0 stevel #define list_object(a, node) ((void *)(((char *)node) - (a)->list_offset)) 71 3448 dh155122 72 3448 dh155122 static int 73 3448 dh155122 ns_to_stackid(uintptr_t kaddr) 74 3448 dh155122 { 75 3448 dh155122 netstack_t nss; 76 3448 dh155122 77 3448 dh155122 if (mdb_vread(&nss, sizeof (nss), kaddr) == -1) { 78 3448 dh155122 mdb_warn("failed to read netdstack info %p", kaddr); 79 3448 dh155122 return (0); 80 3448 dh155122 } 81 3448 dh155122 return (nss.netstack_stackid); 82 3448 dh155122 } 83 3448 dh155122 84 3448 dh155122 int 85 3448 dh155122 sctp_stacks_walk_init(mdb_walk_state_t *wsp) 86 3448 dh155122 { 87 3448 dh155122 if (mdb_layered_walk("netstack", wsp) == -1) { 88 3448 dh155122 mdb_warn("can't walk 'netstack'"); 89 3448 dh155122 return (WALK_ERR); 90 3448 dh155122 } 91 3448 dh155122 return (WALK_NEXT); 92 3448 dh155122 } 93 3448 dh155122 94 3448 dh155122 int 95 3448 dh155122 sctp_stacks_walk_step(mdb_walk_state_t *wsp) 96 3448 dh155122 { 97 3448 dh155122 uintptr_t kaddr; 98 3448 dh155122 netstack_t nss; 99 3448 dh155122 100 3448 dh155122 if (mdb_vread(&nss, sizeof (nss), wsp->walk_addr) == -1) { 101 3448 dh155122 mdb_warn("can't read netstack at %p", wsp->walk_addr); 102 3448 dh155122 return (WALK_ERR); 103 3448 dh155122 } 104 3448 dh155122 kaddr = (uintptr_t)nss.netstack_modules[NS_SCTP]; 105 3448 dh155122 return (wsp->walk_callback(kaddr, wsp->walk_layer, wsp->walk_cbdata)); 106 3448 dh155122 } 107 0 stevel 108 432 vi117747 static char * 109 432 vi117747 sctp_faddr_state(int state) 110 432 vi117747 { 111 432 vi117747 char *statestr; 112 432 vi117747 113 432 vi117747 switch (state) { 114 432 vi117747 case SCTP_FADDRS_UNREACH: 115 432 vi117747 statestr = "Unreachable"; 116 432 vi117747 break; 117 432 vi117747 case SCTP_FADDRS_DOWN: 118 432 vi117747 statestr = "Down"; 119 432 vi117747 break; 120 432 vi117747 case SCTP_FADDRS_ALIVE: 121 432 vi117747 statestr = "Alive"; 122 432 vi117747 break; 123 432 vi117747 case SCTP_FADDRS_UNCONFIRMED: 124 432 vi117747 statestr = "Unconfirmed"; 125 432 vi117747 break; 126 432 vi117747 default: 127 432 vi117747 statestr = "Unknown"; 128 432 vi117747 break; 129 432 vi117747 } 130 432 vi117747 return (statestr); 131 432 vi117747 } 132 432 vi117747 133 0 stevel /* ARGSUSED */ 134 0 stevel static int 135 0 stevel sctp_faddr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 136 0 stevel { 137 0 stevel sctp_faddr_t fa[1]; 138 0 stevel char *statestr; 139 0 stevel 140 0 stevel if (!(flags & DCMD_ADDRSPEC)) 141 0 stevel return (DCMD_USAGE); 142 0 stevel 143 0 stevel if (mdb_vread(fa, sizeof (*fa), addr) == -1) { 144 0 stevel mdb_warn("cannot read fadder at %p", addr); 145 0 stevel return (DCMD_ERR); 146 0 stevel } 147 0 stevel 148 432 vi117747 statestr = sctp_faddr_state(fa->state); 149 0 stevel mdb_printf("%<u>%p\t%<b>%N%</b>\t%s%</u>\n", addr, &fa->faddr, 150 0 stevel statestr); 151 0 stevel mdb_printf("next\t\t%?p\tsaddr\t%N\n", fa->next, &fa->saddr); 152 0 stevel mdb_printf("rto\t\t%?d\tsrtt\t\t%?d\n", fa->rto, fa->srtt); 153 0 stevel mdb_printf("rttvar\t\t%?d\trtt_updates\t%?u\n", fa->rttvar, 154 0 stevel fa->rtt_updates); 155 0 stevel mdb_printf("strikes\t\t%?d\tmax_retr\t%?d\n", fa->strikes, 156 0 stevel fa->max_retr); 157 0 stevel mdb_printf("hb_expiry\t%?ld\thb_interval\t%?u\n", fa->hb_expiry, 158 0 stevel fa->hb_interval); 159 0 stevel mdb_printf("pmss\t\t%?u\tcwnd\t\t%?u\n", fa->sfa_pmss, fa->cwnd); 160 0 stevel mdb_printf("ssthresh\t%?u\tsuna\t\t%?u\n", fa->ssthresh, fa->suna); 161 0 stevel mdb_printf("pba\t\t%?u\tacked\t\t%?u\n", fa->pba, fa->acked); 162 0 stevel mdb_printf("lastactive\t%?ld\thb_secret\t%?#lx\n", fa->lastactive, 163 0 stevel fa->hb_secret); 164 4818 kcpoon mdb_printf("rxt_unacked\t%?u\n", fa->rxt_unacked); 165 11042 Erik mdb_printf("timer_mp\t%?p\tixa\t\t%?p\n", fa->timer_mp, fa->ixa); 166 4818 kcpoon mdb_printf("hb_enabled\t%?d\thb_pending\t%?d\n" 167 4818 kcpoon "timer_running\t%?d\tdf\t\t%?d\n" 168 4818 kcpoon "pmtu_discovered\t%?d\tisv4\t\t%?d\n" 169 4818 kcpoon "retransmissions\t%?u\n", 170 4818 kcpoon fa->hb_enabled, fa->hb_pending, fa->timer_running, fa->df, 171 4818 kcpoon fa->pmtu_discovered, fa->isv4, fa->T3expire); 172 0 stevel 173 0 stevel return (DCMD_OK); 174 0 stevel } 175 0 stevel 176 0 stevel static void 177 0 stevel print_set(sctp_set_t *sp) 178 0 stevel { 179 0 stevel mdb_printf("\tbegin\t%<b>%?x%</b>\t\tend\t%<b>%?x%</b>\n", 180 0 stevel sp->begin, sp->end); 181 0 stevel mdb_printf("\tnext\t%?p\tprev\t%?p\n", sp->next, sp->prev); 182 0 stevel } 183 0 stevel 184 0 stevel /* ARGSUSED */ 185 0 stevel static int 186 0 stevel sctp_set(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 187 0 stevel { 188 0 stevel sctp_set_t sp[1]; 189 0 stevel 190 0 stevel if (!(flags & DCMD_ADDRSPEC)) 191 0 stevel return (DCMD_USAGE); 192 0 stevel 193 0 stevel if (mdb_vread(sp, sizeof (*sp), addr) == -1) 194 0 stevel return (DCMD_ERR); 195 0 stevel 196 0 stevel print_set(sp); 197 0 stevel 198 0 stevel return (DCMD_OK); 199 0 stevel } 200 0 stevel 201 0 stevel static void 202 0 stevel dump_sack_info(uintptr_t addr) 203 0 stevel { 204 0 stevel sctp_set_t sp[1]; 205 0 stevel 206 0 stevel while (addr != 0) { 207 0 stevel if (mdb_vread(sp, sizeof (*sp), addr) == -1) { 208 0 stevel mdb_warn("failed to read sctp_set at %p", addr); 209 0 stevel return; 210 0 stevel } 211 0 stevel 212 0 stevel addr = (uintptr_t)sp->next; 213 0 stevel print_set(sp); 214 0 stevel } 215 0 stevel } 216 0 stevel 217 0 stevel static int 218 0 stevel dump_msghdr(mblk_t *meta) 219 0 stevel { 220 0 stevel sctp_msg_hdr_t smh; 221 0 stevel 222 0 stevel if (mdb_vread(&smh, sizeof (smh), (uintptr_t)meta->b_rptr) == -1) 223 0 stevel return (-1); 224 0 stevel 225 0 stevel mdb_printf("%<u>msg_hdr_t at \t%?p\tsentto\t%?p%</u>\n", 226 0 stevel meta->b_rptr, SCTP_CHUNK_DEST(meta)); 227 0 stevel mdb_printf("\tttl\t%?ld\ttob\t%?ld\n", smh.smh_ttl, smh.smh_tob); 228 0 stevel mdb_printf("\tsid\t%?u\tssn\t%?u\n", smh.smh_sid, smh.smh_ssn); 229 0 stevel mdb_printf("\tppid\t%?u\tflags\t%?s\n", smh.smh_ppid, 230 0 stevel smh.smh_flags & MSG_UNORDERED ? "unordered" : " "); 231 0 stevel mdb_printf("\tcontext\t%?u\tmsglen\t%?d\n", smh.smh_context, 232 0 stevel smh.smh_msglen); 233 0 stevel 234 0 stevel return (0); 235 0 stevel } 236 0 stevel 237 0 stevel static int 238 0 stevel dump_datahdr(mblk_t *mp) 239 0 stevel { 240 0 stevel sctp_data_hdr_t sdc; 241 0 stevel uint16_t sdh_int16; 242 0 stevel uint32_t sdh_int32; 243 0 stevel 244 0 stevel if (mdb_vread(&sdc, sizeof (sdc), (uintptr_t)mp->b_rptr) == -1) 245 0 stevel return (-1); 246 0 stevel 247 0 stevel mdb_printf("%<u>data_chunk_t \t%?p\tsentto\t%?p%</u>\n", 248 0 stevel mp->b_rptr, SCTP_CHUNK_DEST(mp)); 249 0 stevel mdb_printf("\tsent\t%?d\t", SCTP_CHUNK_ISSENT(mp)?1:0); 250 0 stevel mdb_printf("retrans\t%?d\n", SCTP_CHUNK_WANT_REXMIT(mp)?1:0); 251 0 stevel mdb_printf("\tacked\t%?d\t", SCTP_CHUNK_ISACKED(mp)?1:0); 252 0 stevel mdb_printf("sackcnt\t%?u\n", SCTP_CHUNK_SACKCNT(mp)); 253 0 stevel 254 0 stevel mdb_nhconvert(&sdh_int16, &sdc.sdh_len, sizeof (sdc.sdh_len)); 255 0 stevel mdb_printf("\tlen\t%?d\t", sdh_int16); 256 0 stevel mdb_printf("BBIT=%d", SCTP_DATA_GET_BBIT(&sdc) == 0 ? 0 : 1); 257 0 stevel mdb_printf("EBIT=%d", SCTP_DATA_GET_EBIT(&sdc) == 0 ? 0 : 1); 258 0 stevel 259 0 stevel mdb_nhconvert(&sdh_int32, &sdc.sdh_tsn, sizeof (sdc.sdh_tsn)); 260 0 stevel mdb_nhconvert(&sdh_int16, &sdc.sdh_sid, sizeof (sdc.sdh_sid)); 261 0 stevel mdb_printf("\ttsn\t%?x\tsid\t%?hu\n", sdh_int32, sdh_int16); 262 0 stevel 263 0 stevel mdb_nhconvert(&sdh_int16, &sdc.sdh_ssn, sizeof (sdc.sdh_ssn)); 264 0 stevel mdb_nhconvert(&sdh_int32, &sdc.sdh_payload_id, 265 0 stevel sizeof (sdc.sdh_payload_id)); 266 0 stevel mdb_printf("\tssn\t%?hu\tppid\t%?d\n", sdh_int16, sdh_int32); 267 0 stevel 268 0 stevel return (0); 269 0 stevel } 270 0 stevel 271 0 stevel static int 272 0 stevel sctp_sent_list(mblk_t *addr) 273 0 stevel { 274 0 stevel mblk_t meta, mp; 275 0 stevel 276 0 stevel if (!addr) 277 0 stevel return (0); 278 0 stevel 279 0 stevel if (mdb_vread(&meta, sizeof (meta), (uintptr_t)addr) == -1) 280 0 stevel return (-1); 281 0 stevel 282 0 stevel for (;;) { 283 0 stevel dump_msghdr(&meta); 284 0 stevel 285 0 stevel if (meta.b_cont == NULL) { 286 0 stevel mdb_printf("No data chunks with message header!\n"); 287 0 stevel return (-1); 288 0 stevel } 289 0 stevel if (mdb_vread(&mp, sizeof (mp), 290 4691 kcpoon (uintptr_t)meta.b_cont) == -1) { 291 0 stevel return (-1); 292 0 stevel } 293 0 stevel for (;;) { 294 0 stevel dump_datahdr(&mp); 295 0 stevel if (!mp.b_next) 296 0 stevel break; 297 0 stevel 298 0 stevel if (mdb_vread(&mp, sizeof (mp), 299 0 stevel (uintptr_t)(mp.b_next)) == -1) 300 0 stevel return (-1); 301 0 stevel } 302 0 stevel if (meta.b_next == NULL) 303 0 stevel break; 304 0 stevel if (mdb_vread(&meta, sizeof (meta), 305 0 stevel (uintptr_t)meta.b_next) == -1) 306 0 stevel return (-1); 307 0 stevel } 308 0 stevel 309 0 stevel return (0); 310 0 stevel } 311 0 stevel 312 0 stevel static int 313 0 stevel sctp_unsent_list(mblk_t *addr) 314 0 stevel { 315 0 stevel mblk_t meta; 316 0 stevel 317 0 stevel if (!addr) 318 0 stevel return (0); 319 0 stevel 320 0 stevel if (mdb_vread(&meta, sizeof (meta), (uintptr_t)addr) == -1) 321 0 stevel return (-1); 322 0 stevel 323 0 stevel for (;;) { 324 0 stevel dump_msghdr(&meta); 325 0 stevel 326 0 stevel if (meta.b_next == NULL) 327 0 stevel break; 328 0 stevel 329 0 stevel if (mdb_vread(&meta, sizeof (meta), 330 0 stevel (uintptr_t)meta.b_next) == -1) 331 0 stevel return (-1); 332 0 stevel } 333 0 stevel 334 0 stevel return (0); 335 0 stevel } 336 0 stevel 337 0 stevel /* ARGSUSED */ 338 0 stevel static int 339 0 stevel sctp_xmit_list(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 340 0 stevel { 341 0 stevel sctp_t sctp; 342 0 stevel 343 0 stevel if (!(flags & DCMD_ADDRSPEC)) 344 0 stevel return (DCMD_USAGE); 345 0 stevel 346 0 stevel if (mdb_vread(&sctp, sizeof (sctp), addr) == -1) 347 0 stevel return (DCMD_ERR); 348 0 stevel 349 0 stevel mdb_printf("%<b>Chunkified TX list%</b>\n"); 350 0 stevel if (sctp_sent_list(sctp.sctp_xmit_head) < 0) 351 0 stevel return (DCMD_ERR); 352 0 stevel 353 0 stevel mdb_printf("%<b>Unchunkified TX list%</b>\n"); 354 0 stevel if (sctp_unsent_list(sctp.sctp_xmit_unsent) < 0) 355 0 stevel return (DCMD_ERR); 356 0 stevel 357 0 stevel return (DCMD_OK); 358 0 stevel } 359 0 stevel 360 0 stevel /* ARGSUSED */ 361 0 stevel static int 362 0 stevel sctp_mdata_chunk(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 363 0 stevel { 364 0 stevel sctp_data_hdr_t dc; 365 0 stevel mblk_t mp; 366 0 stevel 367 0 stevel if (!(flags & DCMD_ADDRSPEC)) 368 0 stevel return (DCMD_USAGE); 369 0 stevel 370 0 stevel if (mdb_vread(&mp, sizeof (mp), addr) == -1) 371 0 stevel return (DCMD_ERR); 372 0 stevel 373 0 stevel if (mdb_vread(&dc, sizeof (dc), (uintptr_t)mp.b_rptr) == -1) 374 0 stevel return (DCMD_ERR); 375 0 stevel 376 0 stevel mdb_printf("%<b>%-?p%</b>tsn\t%?x\tsid\t%?hu\n", addr, 377 0 stevel dc.sdh_tsn, dc.sdh_sid); 378 0 stevel mdb_printf("%-?sssn\t%?hu\tppid\t%?x\n", "", dc.sdh_ssn, 379 0 stevel dc.sdh_payload_id); 380 0 stevel 381 0 stevel return (DCMD_OK); 382 0 stevel } 383 0 stevel 384 0 stevel /* ARGSUSED */ 385 0 stevel static int 386 0 stevel sctp_istr_msgs(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 387 0 stevel { 388 0 stevel mblk_t istrmp; 389 0 stevel mblk_t dmp; 390 0 stevel sctp_data_hdr_t dp; 391 0 stevel uintptr_t daddr; 392 0 stevel uintptr_t chaddr; 393 0 stevel boolean_t bbit; 394 0 stevel boolean_t ebit; 395 0 stevel 396 0 stevel if (!(flags & DCMD_ADDRSPEC)) 397 0 stevel return (DCMD_USAGE); 398 0 stevel 399 0 stevel do { 400 0 stevel if (mdb_vread(&istrmp, sizeof (istrmp), addr) == -1) 401 0 stevel return (DCMD_ERR); 402 0 stevel 403 0 stevel mdb_printf("\tistr mblk at %p: next: %?p\n" 404 0 stevel "\t\tprev: %?p\tcont: %?p\n", addr, istrmp.b_next, 405 0 stevel istrmp.b_prev, istrmp.b_cont); 406 0 stevel daddr = (uintptr_t)&istrmp; 407 0 stevel do { 408 0 stevel if (mdb_vread(&dmp, sizeof (dmp), daddr) == -1) 409 0 stevel break; 410 0 stevel chaddr = (uintptr_t)dmp.b_rptr; 411 0 stevel if (mdb_vread(&dp, sizeof (dp), chaddr) == -1) 412 0 stevel break; 413 0 stevel 414 0 stevel bbit = (SCTP_DATA_GET_BBIT(&dp) != 0); 415 0 stevel ebit = (SCTP_DATA_GET_EBIT(&dp) != 0); 416 0 stevel 417 0 stevel mdb_printf("\t\t\ttsn: %x bbit: %d ebit: %d\n", 418 0 stevel dp.sdh_tsn, bbit, ebit); 419 0 stevel 420 0 stevel 421 0 stevel daddr = (uintptr_t)dmp.b_cont; 422 0 stevel } while (daddr != NULL); 423 0 stevel 424 0 stevel addr = (uintptr_t)istrmp.b_next; 425 0 stevel } while (addr != NULL); 426 0 stevel 427 0 stevel return (DCMD_OK); 428 0 stevel } 429 0 stevel 430 0 stevel /* ARGSUSED */ 431 0 stevel static int 432 0 stevel sctp_reass_list(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 433 0 stevel { 434 0 stevel sctp_reass_t srp; 435 0 stevel mblk_t srpmp; 436 0 stevel sctp_data_hdr_t dp; 437 0 stevel mblk_t dmp; 438 0 stevel uintptr_t daddr; 439 0 stevel uintptr_t chaddr; 440 0 stevel boolean_t bbit, ebit; 441 0 stevel 442 0 stevel if (!(flags & DCMD_ADDRSPEC)) 443 0 stevel return (DCMD_USAGE); 444 0 stevel 445 0 stevel do { 446 0 stevel if (mdb_vread(&srpmp, sizeof (srpmp), addr) == -1) 447 0 stevel return (DCMD_ERR); 448 0 stevel 449 0 stevel if (mdb_vread(&srp, sizeof (srp), 450 0 stevel (uintptr_t)srpmp.b_datap->db_base) == -1) 451 0 stevel return (DCMD_ERR); 452 0 stevel 453 0 stevel mdb_printf("\treassembly mblk at %p: next: %?p\n" 454 0 stevel "\t\tprev: %?p\tcont: %?p\n", addr, srpmp.b_next, 455 0 stevel srpmp.b_prev, srpmp.b_cont); 456 0 stevel mdb_printf("\t\tssn: %hu\tneeded: %hu\tgot: %hu\ttail: %?p\n" 457 0 stevel "\t\tpartial_delivered: %s\n", srp.ssn, srp.needed, 458 0 stevel srp.got, srp.tail, srp.partial_delivered ? "TRUE" : 459 0 stevel "FALSE"); 460 0 stevel 461 0 stevel /* display the contents of this ssn's reassemby list */ 462 0 stevel daddr = DB_TYPE(&srpmp) == M_CTL ? (uintptr_t)srpmp.b_cont : 463 0 stevel (uintptr_t)&srpmp; 464 0 stevel do { 465 0 stevel if (mdb_vread(&dmp, sizeof (dmp), daddr) == -1) 466 0 stevel break; 467 0 stevel chaddr = (uintptr_t)dmp.b_rptr; 468 0 stevel if (mdb_vread(&dp, sizeof (dp), chaddr) == -1) 469 0 stevel break; 470 0 stevel 471 0 stevel bbit = (SCTP_DATA_GET_BBIT(&dp) != 0); 472 0 stevel ebit = (SCTP_DATA_GET_EBIT(&dp) != 0); 473 0 stevel 474 0 stevel mdb_printf("\t\t\ttsn: %x bbit: %d ebit: %d\n", 475 0 stevel dp.sdh_tsn, bbit, ebit); 476 0 stevel 477 0 stevel daddr = (uintptr_t)dmp.b_cont; 478 0 stevel } while (daddr != NULL); 479 0 stevel 480 0 stevel addr = (uintptr_t)srpmp.b_next; 481 0 stevel } while (addr != NULL); 482 0 stevel 483 0 stevel return (DCMD_OK); 484 0 stevel } 485 0 stevel 486 0 stevel /* ARGSUSED */ 487 0 stevel static int 488 0 stevel sctp_uo_reass_list(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 489 0 stevel { 490 0 stevel sctp_data_hdr_t dp; 491 0 stevel mblk_t dmp; 492 0 stevel uintptr_t chaddr; 493 0 stevel boolean_t bbit; 494 0 stevel boolean_t ebit; 495 0 stevel boolean_t ubit; 496 0 stevel 497 0 stevel if (!(flags & DCMD_ADDRSPEC)) 498 0 stevel return (DCMD_USAGE); 499 0 stevel 500 0 stevel do { 501 0 stevel if (mdb_vread(&dmp, sizeof (dmp), addr) == -1) 502 0 stevel return (DCMD_ERR); 503 0 stevel 504 0 stevel mdb_printf("\treassembly mblk at %p: next: %?p\n" 505 0 stevel "\t\tprev: %?p\n", addr, dmp.b_next, dmp.b_prev); 506 0 stevel 507 0 stevel chaddr = (uintptr_t)dmp.b_rptr; 508 0 stevel if (mdb_vread(&dp, sizeof (dp), chaddr) == -1) 509 0 stevel break; 510 0 stevel 511 0 stevel bbit = (SCTP_DATA_GET_BBIT(&dp) != 0); 512 0 stevel ebit = (SCTP_DATA_GET_EBIT(&dp) != 0); 513 0 stevel ubit = (SCTP_DATA_GET_UBIT(&dp) != 0); 514 0 stevel 515 0 stevel mdb_printf("\t\t\tsid: %hu ssn: %hu tsn: %x " 516 0 stevel "flags: %x (U=%d B=%d E=%d)\n", dp.sdh_sid, dp.sdh_ssn, 517 0 stevel dp.sdh_tsn, dp.sdh_flags, ubit, bbit, ebit); 518 0 stevel 519 0 stevel addr = (uintptr_t)dmp.b_next; 520 0 stevel } while (addr != NULL); 521 0 stevel 522 0 stevel return (DCMD_OK); 523 0 stevel } 524 0 stevel 525 0 stevel static int 526 0 stevel sctp_instr(uintptr_t addr, uint_t flags, int ac, const mdb_arg_t *av) 527 0 stevel { 528 0 stevel sctp_instr_t sip; 529 0 stevel 530 0 stevel if (!(flags & DCMD_ADDRSPEC)) 531 0 stevel return (DCMD_USAGE); 532 0 stevel 533 0 stevel if (mdb_vread(&sip, sizeof (sip), addr) == -1) 534 0 stevel return (DCMD_ERR); 535 0 stevel 536 0 stevel mdb_printf("%<b>%-?p%</b>\n\tmsglist\t%?p\tnmsgs\t%?d\n" 537 0 stevel "\tnextseq\t%?d\treass\t%?p\n", addr, sip.istr_msgs, 538 0 stevel sip.istr_nmsgs, sip.nextseq, sip.istr_reass); 539 0 stevel mdb_set_dot(addr + sizeof (sip)); 540 0 stevel 541 0 stevel return (sctp_reass_list((uintptr_t)sip.istr_reass, flags, ac, av)); 542 0 stevel } 543 0 stevel 544 0 stevel static const char * 545 0 stevel state2str(sctp_t *sctp) 546 0 stevel { 547 0 stevel switch (sctp->sctp_state) { 548 0 stevel case SCTPS_IDLE: return ("SCTPS_IDLE"); 549 0 stevel case SCTPS_BOUND: return ("SCTPS_BOUND"); 550 0 stevel case SCTPS_LISTEN: return ("SCTPS_LISTEN"); 551 0 stevel case SCTPS_COOKIE_WAIT: return ("SCTPS_COOKIE_WAIT"); 552 0 stevel case SCTPS_COOKIE_ECHOED: return ("SCTPS_COOKIE_ECHOED"); 553 0 stevel case SCTPS_ESTABLISHED: return ("SCTPS_ESTABLISHED"); 554 0 stevel case SCTPS_SHUTDOWN_PENDING: return ("SCTPS_SHUTDOWN_PENDING"); 555 0 stevel case SCTPS_SHUTDOWN_SENT: return ("SCTPS_SHUTDOWN_SENT"); 556 0 stevel case SCTPS_SHUTDOWN_RECEIVED: return ("SCTPS_SHUTDOWN_RECEIVED"); 557 0 stevel case SCTPS_SHUTDOWN_ACK_SENT: return ("SCTPS_SHUTDOWN_ACK_SENT"); 558 0 stevel default: return ("UNKNOWN STATE"); 559 0 stevel } 560 0 stevel } 561 0 stevel 562 0 stevel static void 563 0 stevel show_sctp_flags(sctp_t *sctp) 564 0 stevel { 565 0 stevel mdb_printf("\tunderstands_asconf\t%d\n", 566 0 stevel sctp->sctp_understands_asconf); 567 11042 Erik mdb_printf("\tdebug\t\t\t%d\n", sctp->sctp_connp->conn_debug); 568 0 stevel mdb_printf("\tcchunk_pend\t\t%d\n", sctp->sctp_cchunk_pend); 569 11042 Erik mdb_printf("\tdgram_errind\t\t%d\n", 570 11042 Erik sctp->sctp_connp->conn_dgram_errind); 571 0 stevel 572 11042 Erik mdb_printf("\tlinger\t\t\t%d\n", sctp->sctp_connp->conn_linger); 573 0 stevel if (sctp->sctp_lingering) 574 0 stevel return; 575 0 stevel mdb_printf("\tlingering\t\t%d\n", sctp->sctp_lingering); 576 0 stevel mdb_printf("\tloopback\t\t%d\n", sctp->sctp_loopback); 577 0 stevel mdb_printf("\tforce_sack\t\t%d\n", sctp->sctp_force_sack); 578 0 stevel 579 0 stevel mdb_printf("\tack_timer_runing\t%d\n", sctp->sctp_ack_timer_running); 580 11042 Erik mdb_printf("\trecvdstaddr\t\t%d\n", 581 11042 Erik sctp->sctp_connp->conn_recv_ancillary.crb_recvdstaddr); 582 0 stevel mdb_printf("\thwcksum\t\t\t%d\n", sctp->sctp_hwcksum); 583 0 stevel mdb_printf("\tunderstands_addip\t%d\n", sctp->sctp_understands_addip); 584 0 stevel 585 0 stevel mdb_printf("\tbound_to_all\t\t%d\n", sctp->sctp_bound_to_all); 586 0 stevel mdb_printf("\tcansleep\t\t%d\n", sctp->sctp_cansleep); 587 0 stevel mdb_printf("\tdetached\t\t%d\n", sctp->sctp_detached); 588 5586 kcpoon mdb_printf("\tsend_adaptation\t\t%d\n", sctp->sctp_send_adaptation); 589 0 stevel 590 5586 kcpoon mdb_printf("\trecv_adaptation\t\t%d\n", sctp->sctp_recv_adaptation); 591 0 stevel mdb_printf("\tndelay\t\t\t%d\n", sctp->sctp_ndelay); 592 0 stevel mdb_printf("\tcondemned\t\t%d\n", sctp->sctp_condemned); 593 0 stevel mdb_printf("\tchk_fast_rexmit\t\t%d\n", sctp->sctp_chk_fast_rexmit); 594 1735 kcpoon 595 0 stevel mdb_printf("\tprsctp_aware\t\t%d\n", sctp->sctp_prsctp_aware); 596 432 vi117747 mdb_printf("\tlinklocal\t\t%d\n", sctp->sctp_linklocal); 597 1735 kcpoon mdb_printf("\trexmitting\t\t%d\n", sctp->sctp_rexmitting); 598 2263 sommerfe mdb_printf("\tzero_win_probe\t\t%d\n", sctp->sctp_zero_win_probe); 599 0 stevel 600 0 stevel mdb_printf("\trecvsndrcvinfo\t\t%d\n", sctp->sctp_recvsndrcvinfo); 601 0 stevel mdb_printf("\trecvassocevnt\t\t%d\n", sctp->sctp_recvassocevnt); 602 0 stevel mdb_printf("\trecvpathevnt\t\t%d\n", sctp->sctp_recvpathevnt); 603 0 stevel mdb_printf("\trecvsendfailevnt\t%d\n", sctp->sctp_recvsendfailevnt); 604 0 stevel 605 0 stevel mdb_printf("\trecvpeerevnt\t\t%d\n", sctp->sctp_recvpeererr); 606 0 stevel mdb_printf("\trecvchutdownevnt\t%d\n", sctp->sctp_recvshutdownevnt); 607 0 stevel mdb_printf("\trecvcpdnevnt\t\t%d\n", sctp->sctp_recvpdevnt); 608 0 stevel mdb_printf("\trecvcalevnt\t\t%d\n\n", sctp->sctp_recvalevnt); 609 0 stevel } 610 0 stevel 611 0 stevel /* 612 0 stevel * Given a sctp_saddr_ipif_t, print out its address. This assumes 613 0 stevel * that addr contains the sctp_addr_ipif_t structure already and this 614 0 stevel * function does not need to read it in. 615 0 stevel */ 616 0 stevel /* ARGSUSED */ 617 0 stevel static int 618 0 stevel print_saddr(uintptr_t ptr, const void *addr, void *cbdata) 619 0 stevel { 620 0 stevel sctp_saddr_ipif_t *saddr = (sctp_saddr_ipif_t *)addr; 621 0 stevel sctp_ipif_t ipif; 622 0 stevel char *statestr; 623 0 stevel 624 0 stevel /* Read in the sctp_ipif object */ 625 0 stevel if (mdb_vread(&ipif, sizeof (ipif), (uintptr_t)saddr->saddr_ipifp) == 626 0 stevel -1) { 627 0 stevel mdb_warn("cannot read ipif at %p", saddr->saddr_ipifp); 628 0 stevel return (WALK_ERR); 629 0 stevel } 630 0 stevel 631 0 stevel switch (ipif.sctp_ipif_state) { 632 0 stevel case SCTP_IPIFS_CONDEMNED: 633 432 vi117747 statestr = "Condemned"; 634 0 stevel break; 635 0 stevel case SCTP_IPIFS_INVALID: 636 432 vi117747 statestr = "Invalid"; 637 0 stevel break; 638 0 stevel case SCTP_IPIFS_DOWN: 639 432 vi117747 statestr = "Down"; 640 0 stevel break; 641 0 stevel case SCTP_IPIFS_UP: 642 432 vi117747 statestr = "Up"; 643 0 stevel break; 644 0 stevel default: 645 432 vi117747 statestr = "Unknown"; 646 0 stevel break; 647 0 stevel } 648 432 vi117747 mdb_printf("\t%p\t%N% (%s", saddr->saddr_ipifp, &ipif.sctp_ipif_saddr, 649 432 vi117747 statestr); 650 432 vi117747 if (saddr->saddr_ipif_dontsrc == 1) 651 432 vi117747 mdb_printf("/Dontsrc"); 652 432 vi117747 if (saddr->saddr_ipif_unconfirmed == 1) 653 432 vi117747 mdb_printf("/Unconfirmed"); 654 432 vi117747 if (saddr->saddr_ipif_delete_pending == 1) 655 432 vi117747 mdb_printf("/DeletePending"); 656 432 vi117747 mdb_printf(")\n"); 657 11042 Erik mdb_printf("\t\t\tid %d zoneid %d IPIF flags %x\n", 658 11042 Erik ipif.sctp_ipif_id, 659 432 vi117747 ipif.sctp_ipif_zoneid, ipif.sctp_ipif_flags); 660 0 stevel return (WALK_NEXT); 661 0 stevel } 662 0 stevel 663 0 stevel /* 664 0 stevel * Given a sctp_faddr_t, print out its address. This assumes that 665 0 stevel * addr contains the sctp_faddr_t structure already and this function 666 0 stevel * does not need to read it in. 667 0 stevel */ 668 0 stevel static int 669 0 stevel print_faddr(uintptr_t ptr, const void *addr, void *cbdata) 670 0 stevel { 671 432 vi117747 char *statestr; 672 0 stevel sctp_faddr_t *faddr = (sctp_faddr_t *)addr; 673 0 stevel int *i = cbdata; 674 0 stevel 675 432 vi117747 statestr = sctp_faddr_state(faddr->state); 676 432 vi117747 677 432 vi117747 mdb_printf("\t%d:\t%N\t%?p (%s)\n", (*i)++, &faddr->faddr, ptr, 678 432 vi117747 statestr); 679 0 stevel return (WALK_NEXT); 680 0 stevel } 681 0 stevel 682 0 stevel int 683 0 stevel sctp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 684 0 stevel { 685 11042 Erik sctp_t sctps, *sctp; 686 11042 Erik conn_t conns, *connp; 687 0 stevel int i; 688 0 stevel uint_t opts = 0; 689 0 stevel uint_t paddr = 0; 690 0 stevel in_port_t lport, fport; 691 0 stevel 692 0 stevel if (!(flags & DCMD_ADDRSPEC)) 693 0 stevel return (DCMD_USAGE); 694 0 stevel 695 11042 Erik if (mdb_vread(&sctps, sizeof (sctps), addr) == -1) { 696 0 stevel mdb_warn("failed to read sctp_t at: %p\n", addr); 697 0 stevel return (DCMD_ERR); 698 0 stevel } 699 11042 Erik sctp = &sctps; 700 11042 Erik 701 11042 Erik if (mdb_vread(&conns, sizeof (conns), 702 11042 Erik (uintptr_t)sctp->sctp_connp) == -1) { 703 11042 Erik mdb_warn("failed to read conn_t at: %p\n", sctp->sctp_connp); 704 0 stevel return (DCMD_ERR); 705 0 stevel } 706 11042 Erik 707 11042 Erik connp = &conns; 708 11042 Erik 709 11042 Erik connp->conn_sctp = sctp; 710 11042 Erik sctp->sctp_connp = connp; 711 0 stevel 712 0 stevel if (mdb_getopts(argc, argv, 713 4691 kcpoon 'a', MDB_OPT_SETBITS, MDB_SCTP_SHOW_ALL, &opts, 714 4691 kcpoon 'f', MDB_OPT_SETBITS, MDB_SCTP_SHOW_FLAGS, &opts, 715 4691 kcpoon 'h', MDB_OPT_SETBITS, MDB_SCTP_SHOW_HASH, &opts, 716 4691 kcpoon 'o', MDB_OPT_SETBITS, MDB_SCTP_SHOW_OUT, &opts, 717 4691 kcpoon 'i', MDB_OPT_SETBITS, MDB_SCTP_SHOW_IN, &opts, 718 4691 kcpoon 'm', MDB_OPT_SETBITS, MDB_SCTP_SHOW_MISC, &opts, 719 4691 kcpoon 'r', MDB_OPT_SETBITS, MDB_SCTP_SHOW_RTT, &opts, 720 4691 kcpoon 'S', MDB_OPT_SETBITS, MDB_SCTP_SHOW_STATS, &opts, 721 4691 kcpoon 'F', MDB_OPT_SETBITS, MDB_SCTP_SHOW_FLOW, &opts, 722 4691 kcpoon 'H', MDB_OPT_SETBITS, MDB_SCTP_SHOW_HDR, &opts, 723 4691 kcpoon 'p', MDB_OPT_SETBITS, MDB_SCTP_SHOW_PMTUD, &opts, 724 4691 kcpoon 'R', MDB_OPT_SETBITS, MDB_SCTP_SHOW_RXT, &opts, 725 4691 kcpoon 'C', MDB_OPT_SETBITS, MDB_SCTP_SHOW_CONN, &opts, 726 4691 kcpoon 'c', MDB_OPT_SETBITS, MDB_SCTP_SHOW_CLOSE, &opts, 727 4691 kcpoon 'e', MDB_OPT_SETBITS, MDB_SCTP_SHOW_EXT, &opts, 728 4691 kcpoon 'P', MDB_OPT_SETBITS, 1, &paddr, 729 4691 kcpoon 'd', MDB_OPT_SETBITS, MDB_SCTP_DUMP_ADDRS, &opts) != argc) { 730 0 stevel return (DCMD_USAGE); 731 0 stevel } 732 0 stevel 733 0 stevel /* non-verbose faddrs, suitable for pipelines to sctp_faddr */ 734 0 stevel if (paddr != 0) { 735 0 stevel sctp_faddr_t faddr, *fp; 736 11042 Erik for (fp = sctp->sctp_faddrs; fp != NULL; fp = faddr.next) { 737 0 stevel if (mdb_vread(&faddr, sizeof (faddr), (uintptr_t)fp) 738 0 stevel == -1) { 739 0 stevel mdb_warn("failed to read faddr at %p", 740 0 stevel fp); 741 0 stevel return (DCMD_ERR); 742 0 stevel } 743 0 stevel mdb_printf("%p\n", fp); 744 0 stevel } 745 0 stevel return (DCMD_OK); 746 0 stevel } 747 0 stevel 748 11042 Erik mdb_nhconvert(&lport, &connp->conn_lport, sizeof (lport)); 749 11042 Erik mdb_nhconvert(&fport, &connp->conn_fport, sizeof (fport)); 750 3448 dh155122 mdb_printf("%<u>%p% %22s S=%-6hu D=%-6hu% STACK=%d ZONE=%d%</u>", addr, 751 11042 Erik state2str(sctp), lport, fport, 752 11042 Erik ns_to_stackid((uintptr_t)connp->conn_netstack), connp->conn_zoneid); 753 0 stevel 754 11042 Erik if (sctp->sctp_faddrs) { 755 0 stevel sctp_faddr_t faddr; 756 0 stevel if (mdb_vread(&faddr, sizeof (faddr), 757 11042 Erik (uintptr_t)sctp->sctp_faddrs) != -1) 758 0 stevel mdb_printf("%<u> %N%</u>", &faddr.faddr); 759 0 stevel } 760 0 stevel mdb_printf("\n"); 761 0 stevel 762 0 stevel if (opts & MDB_SCTP_DUMP_ADDRS) { 763 0 stevel mdb_printf("%<b>Local and Peer Addresses%</b>\n"); 764 0 stevel 765 0 stevel /* Display source addresses */ 766 11042 Erik mdb_printf("nsaddrs\t\t%?d\n", sctp->sctp_nsaddrs); 767 0 stevel (void) mdb_pwalk("sctp_walk_saddr", print_saddr, NULL, addr); 768 0 stevel 769 0 stevel /* Display peer addresses */ 770 11042 Erik mdb_printf("nfaddrs\t\t%?d\n", sctp->sctp_nfaddrs); 771 0 stevel i = 1; 772 0 stevel (void) mdb_pwalk("sctp_walk_faddr", print_faddr, &i, addr); 773 0 stevel 774 0 stevel mdb_printf("lastfaddr\t%?p\tprimary\t\t%?p\n", 775 11042 Erik sctp->sctp_lastfaddr, sctp->sctp_primary); 776 0 stevel mdb_printf("current\t\t%?p\tlastdata\t%?p\n", 777 11042 Erik sctp->sctp_current, sctp->sctp_lastdata); 778 0 stevel } 779 0 stevel 780 0 stevel if (opts & MDB_SCTP_SHOW_OUT) { 781 0 stevel mdb_printf("%<b>Outbound Data%</b>\n"); 782 0 stevel mdb_printf("xmit_head\t%?p\txmit_tail\t%?p\n", 783 11042 Erik sctp->sctp_xmit_head, sctp->sctp_xmit_tail); 784 0 stevel mdb_printf("xmit_unsent\t%?p\txmit_unsent_tail%?p\n", 785 11042 Erik sctp->sctp_xmit_unsent, sctp->sctp_xmit_unsent_tail); 786 11042 Erik mdb_printf("xmit_unacked\t%?p\n", sctp->sctp_xmit_unacked); 787 0 stevel mdb_printf("unacked\t\t%?u\tunsent\t\t%?ld\n", 788 11042 Erik sctp->sctp_unacked, sctp->sctp_unsent); 789 0 stevel mdb_printf("ltsn\t\t%?x\tlastack_rxd\t%?x\n", 790 11042 Erik sctp->sctp_ltsn, sctp->sctp_lastack_rxd); 791 0 stevel mdb_printf("recovery_tsn\t%?x\tadv_pap\t\t%?x\n", 792 11042 Erik sctp->sctp_recovery_tsn, sctp->sctp_adv_pap); 793 0 stevel mdb_printf("num_ostr\t%?hu\tostrcntrs\t%?p\n", 794 11042 Erik sctp->sctp_num_ostr, sctp->sctp_ostrcntrs); 795 4964 kcpoon mdb_printf("pad_mp\t\t%?p\terr_chunks\t%?p\n", 796 11042 Erik sctp->sctp_pad_mp, sctp->sctp_err_chunks); 797 11042 Erik mdb_printf("err_len\t\t%?u\n", sctp->sctp_err_len); 798 0 stevel 799 0 stevel mdb_printf("%<b>Default Send Parameters%</b>\n"); 800 0 stevel mdb_printf("def_stream\t%?u\tdef_flags\t%?x\n", 801 11042 Erik sctp->sctp_def_stream, sctp->sctp_def_flags); 802 0 stevel mdb_printf("def_ppid\t%?x\tdef_context\t%?x\n", 803 11042 Erik sctp->sctp_def_ppid, sctp->sctp_def_context); 804 0 stevel mdb_printf("def_timetolive\t%?u\n", 805 11042 Erik sctp->sctp_def_timetolive); 806 0 stevel } 807 0 stevel 808 0 stevel if (opts & MDB_SCTP_SHOW_IN) { 809 0 stevel mdb_printf("%<b>Inbound Data%</b>\n"); 810 0 stevel mdb_printf("sack_info\t%?p\tsack_gaps\t%?d\n", 811 11042 Erik sctp->sctp_sack_info, sctp->sctp_sack_gaps); 812 11042 Erik dump_sack_info((uintptr_t)sctp->sctp_sack_info); 813 0 stevel mdb_printf("ftsn\t\t%?x\tlastacked\t%?x\n", 814 11042 Erik sctp->sctp_ftsn, sctp->sctp_lastacked); 815 0 stevel mdb_printf("istr_nmsgs\t%?d\tsack_toggle\t%?d\n", 816 11042 Erik sctp->sctp_istr_nmsgs, sctp->sctp_sack_toggle); 817 11042 Erik mdb_printf("ack_mp\t\t%?p\n", sctp->sctp_ack_mp); 818 0 stevel mdb_printf("num_istr\t%?hu\tinstr\t\t%?p\n", 819 11042 Erik sctp->sctp_num_istr, sctp->sctp_instr); 820 11042 Erik mdb_printf("unord_reass\t%?p\n", sctp->sctp_uo_frags); 821 0 stevel } 822 0 stevel 823 0 stevel if (opts & MDB_SCTP_SHOW_RTT) { 824 0 stevel mdb_printf("%<b>RTT Tracking%</b>\n"); 825 0 stevel mdb_printf("rtt_tsn\t\t%?x\tout_time\t%?ld\n", 826 11042 Erik sctp->sctp_rtt_tsn, sctp->sctp_out_time); 827 0 stevel } 828 0 stevel 829 0 stevel if (opts & MDB_SCTP_SHOW_FLOW) { 830 0 stevel mdb_printf("%<b>Flow Control%</b>\n"); 831 11042 Erik mdb_printf("tconn_sndbuf\t%?d\n" 832 11042 Erik "conn_sndlowat\t%?d\tfrwnd\t\t%?u\n" 833 852 vi117747 "rwnd\t\t%?u\tinitial rwnd\t%?u\n" 834 11042 Erik "rxqueued\t%?u\tcwnd_max\t%?u\n", connp->conn_sndbuf, 835 11042 Erik connp->conn_sndlowat, sctp->sctp_frwnd, 836 11042 Erik sctp->sctp_rwnd, sctp->sctp_irwnd, sctp->sctp_rxqueued, 837 11042 Erik sctp->sctp_cwnd_max); 838 0 stevel } 839 0 stevel 840 0 stevel if (opts & MDB_SCTP_SHOW_HDR) { 841 0 stevel mdb_printf("%<b>Composite Headers%</b>\n"); 842 0 stevel mdb_printf("iphc\t\t%?p\tiphc6\t\t%?p\n" 843 0 stevel "iphc_len\t%?d\tiphc6_len\t%?d\n" 844 0 stevel "hdr_len\t\t%?d\thdr6_len\t%?d\n" 845 0 stevel "ipha\t\t%?p\tip6h\t\t%?p\n" 846 0 stevel "ip_hdr_len\t%?d\tip_hdr6_len\t%?d\n" 847 0 stevel "sctph\t\t%?p\tsctph6\t\t%?p\n" 848 11042 Erik "lvtag\t\t%?x\tfvtag\t\t%?x\n", sctp->sctp_iphc, 849 11042 Erik sctp->sctp_iphc6, sctp->sctp_iphc_len, 850 11042 Erik sctp->sctp_iphc6_len, sctp->sctp_hdr_len, 851 11042 Erik sctp->sctp_hdr6_len, sctp->sctp_ipha, sctp->sctp_ip6h, 852 11042 Erik sctp->sctp_ip_hdr_len, sctp->sctp_ip_hdr6_len, 853 11042 Erik sctp->sctp_sctph, sctp->sctp_sctph6, sctp->sctp_lvtag, 854 11042 Erik sctp->sctp_fvtag); 855 0 stevel } 856 0 stevel 857 0 stevel if (opts & MDB_SCTP_SHOW_PMTUD) { 858 0 stevel mdb_printf("%<b>PMTUd%</b>\n"); 859 0 stevel mdb_printf("last_mtu_probe\t%?ld\tmtu_probe_intvl\t%?ld\n" 860 0 stevel "mss\t\t%?u\n", 861 11042 Erik sctp->sctp_last_mtu_probe, sctp->sctp_mtu_probe_intvl, 862 11042 Erik sctp->sctp_mss); 863 0 stevel } 864 0 stevel 865 0 stevel if (opts & MDB_SCTP_SHOW_RXT) { 866 0 stevel mdb_printf("%<b>Retransmit Info%</b>\n"); 867 0 stevel mdb_printf("cookie_mp\t%?p\tstrikes\t\t%?d\n" 868 0 stevel "max_init_rxt\t%?d\tpa_max_rxt\t%?d\n" 869 0 stevel "pp_max_rxt\t%?d\trto_max\t\t%?u\n" 870 0 stevel "rto_min\t\t%?u\trto_initial\t%?u\n" 871 1735 kcpoon "init_rto_max\t%?u\n" 872 11042 Erik "rxt_nxttsn\t%?u\trxt_maxtsn\t%?u\n", sctp->sctp_cookie_mp, 873 11042 Erik sctp->sctp_strikes, sctp->sctp_max_init_rxt, 874 11042 Erik sctp->sctp_pa_max_rxt, sctp->sctp_pp_max_rxt, 875 11042 Erik sctp->sctp_rto_max, sctp->sctp_rto_min, 876 11042 Erik sctp->sctp_rto_initial, sctp->sctp_init_rto_max, 877 11042 Erik sctp->sctp_rxt_nxttsn, sctp->sctp_rxt_maxtsn); 878 0 stevel } 879 0 stevel 880 0 stevel if (opts & MDB_SCTP_SHOW_CONN) { 881 0 stevel mdb_printf("%<b>Connection State%</b>\n"); 882 0 stevel mdb_printf("last_secret_update%?ld\n", 883 11042 Erik sctp->sctp_last_secret_update); 884 0 stevel 885 0 stevel mdb_printf("secret\t\t"); 886 0 stevel for (i = 0; i < SCTP_SECRET_LEN; i++) { 887 0 stevel if (i % 2 == 0) 888 11042 Erik mdb_printf("0x%02x", sctp->sctp_secret[i]); 889 0 stevel else 890 11042 Erik mdb_printf("%02x ", sctp->sctp_secret[i]); 891 0 stevel } 892 0 stevel mdb_printf("\n"); 893 0 stevel mdb_printf("old_secret\t"); 894 0 stevel for (i = 0; i < SCTP_SECRET_LEN; i++) { 895 0 stevel if (i % 2 == 0) 896 11042 Erik mdb_printf("0x%02x", sctp->sctp_old_secret[i]); 897 0 stevel else 898 11042 Erik mdb_printf("%02x ", sctp->sctp_old_secret[i]); 899 0 stevel } 900 0 stevel mdb_printf("\n"); 901 0 stevel } 902 0 stevel 903 0 stevel if (opts & MDB_SCTP_SHOW_STATS) { 904 0 stevel mdb_printf("%<b>Stats Counters%</b>\n"); 905 0 stevel mdb_printf("opkts\t\t%?llu\tobchunks\t%?llu\n" 906 0 stevel "odchunks\t%?llu\toudchunks\t%?llu\n" 907 0 stevel "rxtchunks\t%?llu\tT1expire\t%?lu\n" 908 0 stevel "T2expire\t%?lu\tT3expire\t%?lu\n" 909 0 stevel "msgcount\t%?llu\tprsctpdrop\t%?llu\n" 910 0 stevel "AssocStartTime\t%?lu\n", 911 11042 Erik sctp->sctp_opkts, sctp->sctp_obchunks, 912 11042 Erik sctp->sctp_odchunks, sctp->sctp_oudchunks, 913 11042 Erik sctp->sctp_rxtchunks, sctp->sctp_T1expire, 914 11042 Erik sctp->sctp_T2expire, sctp->sctp_T3expire, 915 11042 Erik sctp->sctp_msgcount, sctp->sctp_prsctpdrop, 916 11042 Erik sctp->sctp_assoc_start_time); 917 0 stevel mdb_printf("ipkts\t\t%?llu\tibchunks\t%?llu\n" 918 0 stevel "idchunks\t%?llu\tiudchunks\t%?llu\n" 919 0 stevel "fragdmsgs\t%?llu\treassmsgs\t%?llu\n", 920 11042 Erik sctp->sctp_ipkts, sctp->sctp_ibchunks, 921 11042 Erik sctp->sctp_idchunks, sctp->sctp_iudchunks, 922 11042 Erik sctp->sctp_fragdmsgs, sctp->sctp_reassmsgs); 923 0 stevel } 924 0 stevel 925 0 stevel if (opts & MDB_SCTP_SHOW_HASH) { 926 0 stevel mdb_printf("%<b>Hash Tables%</b>\n"); 927 11042 Erik mdb_printf("conn_hash_next\t%?p\t", sctp->sctp_conn_hash_next); 928 11042 Erik mdb_printf("conn_hash_prev\t%?p\n", sctp->sctp_conn_hash_prev); 929 0 stevel 930 0 stevel mdb_printf("listen_hash_next%?p\t", 931 11042 Erik sctp->sctp_listen_hash_next); 932 0 stevel mdb_printf("listen_hash_prev%?p\n", 933 11042 Erik sctp->sctp_listen_hash_prev); 934 11042 Erik mdb_nhconvert(&lport, &connp->conn_lport, sizeof (lport)); 935 0 stevel mdb_printf("[ listen_hash bucket\t%?d ]\n", 936 0 stevel SCTP_LISTEN_HASH(lport)); 937 0 stevel 938 11042 Erik mdb_printf("conn_tfp\t%?p\t", sctp->sctp_conn_tfp); 939 11042 Erik mdb_printf("listen_tfp\t%?p\n", sctp->sctp_listen_tfp); 940 0 stevel 941 0 stevel mdb_printf("bind_hash\t%?p\tptpbhn\t\t%?p\n", 942 11042 Erik sctp->sctp_bind_hash, sctp->sctp_ptpbhn); 943 0 stevel mdb_printf("bind_lockp\t%?p\n", 944 11042 Erik sctp->sctp_bind_lockp); 945 0 stevel mdb_printf("[ bind_hash bucket\t%?d ]\n", 946 0 stevel SCTP_BIND_HASH(lport)); 947 0 stevel } 948 0 stevel 949 0 stevel if (opts & MDB_SCTP_SHOW_CLOSE) { 950 0 stevel mdb_printf("%<b>Cleanup / Close%</b>\n"); 951 0 stevel mdb_printf("shutdown_faddr\t%?p\tclient_errno\t%?d\n" 952 0 stevel "lingertime\t%?d\trefcnt\t\t%?hu\n", 953 11042 Erik sctp->sctp_shutdown_faddr, sctp->sctp_client_errno, 954 11042 Erik connp->conn_lingertime, sctp->sctp_refcnt); 955 0 stevel } 956 0 stevel 957 0 stevel if (opts & MDB_SCTP_SHOW_MISC) { 958 0 stevel mdb_printf("%<b>Miscellaneous%</b>\n"); 959 0 stevel mdb_printf("bound_if\t%?u\theartbeat_mp\t%?p\n" 960 0 stevel "family\t\t%?u\tipversion\t%?hu\n" 961 0 stevel "hb_interval\t%?u\tautoclose\t%?d\n" 962 5586 kcpoon "active\t\t%?ld\ttx_adaptation_code%?x\n" 963 5586 kcpoon "rx_adaptation_code%?x\ttimer_mp\t%?p\n" 964 3845 vi117747 "partial_delivery_point\t%?d\n", 965 11042 Erik connp->conn_bound_if, sctp->sctp_heartbeat_mp, 966 11042 Erik connp->conn_family, 967 11042 Erik connp->conn_ipversion, 968 11042 Erik sctp->sctp_hb_interval, sctp->sctp_autoclose, 969 11042 Erik sctp->sctp_active, sctp->sctp_tx_adaptation_code, 970 11042 Erik sctp->sctp_rx_adaptation_code, sctp->sctp_timer_mp, 971 11042 Erik sctp->sctp_pd_point); 972 0 stevel } 973 0 stevel 974 0 stevel if (opts & MDB_SCTP_SHOW_EXT) { 975 0 stevel mdb_printf("%<b>Extensions and Reliable Ctl Chunks%</b>\n"); 976 0 stevel mdb_printf("cxmit_list\t%?p\tlcsn\t\t%?x\n" 977 11042 Erik "fcsn\t\t%?x\n", sctp->sctp_cxmit_list, sctp->sctp_lcsn, 978 11042 Erik sctp->sctp_fcsn); 979 0 stevel } 980 0 stevel 981 0 stevel if (opts & MDB_SCTP_SHOW_FLAGS) { 982 0 stevel mdb_printf("%<b>Flags%</b>\n"); 983 11042 Erik show_sctp_flags(sctp); 984 0 stevel } 985 0 stevel 986 0 stevel return (DCMD_OK); 987 0 stevel } 988 0 stevel 989 0 stevel typedef struct fanout_walk_data { 990 0 stevel int index; 991 0 stevel int size; 992 0 stevel uintptr_t sctp; 993 0 stevel sctp_tf_t *fanout; 994 0 stevel uintptr_t (*getnext)(sctp_t *); 995 0 stevel } fanout_walk_data_t; 996 0 stevel 997 0 stevel typedef struct fanout_init { 998 3448 dh155122 const char *nested_walker_name; 999 3448 dh155122 size_t offset; /* for what used to be a symbol */ 1000 3448 dh155122 int (*getsize)(sctp_stack_t *); 1001 0 stevel uintptr_t (*getnext)(sctp_t *); 1002 0 stevel } fanout_init_t; 1003 0 stevel 1004 0 stevel static uintptr_t 1005 0 stevel listen_next(sctp_t *sctp) 1006 0 stevel { 1007 0 stevel return ((uintptr_t)sctp->sctp_listen_hash_next); 1008 0 stevel } 1009 0 stevel 1010 3448 dh155122 /* ARGSUSED */ 1011 0 stevel static int 1012 3448 dh155122 listen_size(sctp_stack_t *sctps) 1013 0 stevel { 1014 0 stevel return (SCTP_LISTEN_FANOUT_SIZE); 1015 0 stevel } 1016 0 stevel 1017 0 stevel static uintptr_t 1018 0 stevel conn_next(sctp_t *sctp) 1019 0 stevel { 1020 0 stevel return ((uintptr_t)sctp->sctp_conn_hash_next); 1021 0 stevel } 1022 0 stevel 1023 0 stevel static int 1024 3448 dh155122 conn_size(sctp_stack_t *sctps) 1025 0 stevel { 1026 0 stevel int size; 1027 3448 dh155122 uintptr_t kaddr; 1028 0 stevel 1029 3448 dh155122 kaddr = (uintptr_t)&sctps->sctps_conn_hash_size; 1030 3448 dh155122 1031 3448 dh155122 if (mdb_vread(&size, sizeof (size), kaddr) == -1) { 1032 3448 dh155122 mdb_warn("can't read 'sctps_conn_hash_size' at %p", kaddr); 1033 0 stevel return (1); 1034 0 stevel } 1035 0 stevel return (size); 1036 0 stevel } 1037 0 stevel 1038 0 stevel static uintptr_t 1039 0 stevel bind_next(sctp_t *sctp) 1040 0 stevel { 1041 0 stevel return ((uintptr_t)sctp->sctp_bind_hash); 1042 0 stevel } 1043 0 stevel 1044 3448 dh155122 /* ARGSUSED */ 1045 0 stevel static int 1046 3448 dh155122 bind_size(sctp_stack_t *sctps) 1047 0 stevel { 1048 0 stevel return (SCTP_BIND_FANOUT_SIZE); 1049 0 stevel } 1050 0 stevel 1051 0 stevel static intptr_t 1052 0 stevel find_next_hash_item(fanout_walk_data_t *fw) 1053 0 stevel { 1054 0 stevel sctp_tf_t tf; 1055 0 stevel sctp_t sctp; 1056 0 stevel 1057 0 stevel /* first try to continue down the hash chain */ 1058 0 stevel if (fw->sctp != NULL) { 1059 0 stevel /* try to get next in hash chain */ 1060 0 stevel if (mdb_vread(&sctp, sizeof (sctp), fw->sctp) == -1) { 1061 0 stevel mdb_warn("failed to read sctp at %p", fw->sctp); 1062 0 stevel return (NULL); 1063 0 stevel } 1064 0 stevel fw->sctp = fw->getnext(&sctp); 1065 0 stevel if (fw->sctp != NULL) 1066 0 stevel return (fw->sctp); 1067 0 stevel else 1068 0 stevel /* end of chain; go to next bucket */ 1069 0 stevel fw->index++; 1070 0 stevel } 1071 0 stevel 1072 0 stevel /* find a new hash chain, traversing the buckets */ 1073 0 stevel for (; fw->index < fw->size; fw->index++) { 1074 0 stevel /* read the current hash line for an sctp */ 1075 0 stevel if (mdb_vread(&tf, sizeof (tf), 1076 4691 kcpoon (uintptr_t)(fw->fanout + fw->index)) == -1) { 1077 0 stevel mdb_warn("failed to read tf at %p", 1078 0 stevel fw->fanout + fw->index); 1079 0 stevel return (NULL); 1080 0 stevel } 1081 0 stevel if (tf.tf_sctp != NULL) { 1082 0 stevel /* start of a new chain */ 1083 0 stevel fw->sctp = (uintptr_t)tf.tf_sctp; 1084 0 stevel return (fw->sctp); 1085 0 stevel } 1086 0 stevel } 1087 0 stevel return (NULL); 1088 0 stevel } 1089 0 stevel 1090 0 stevel static int 1091 3448 dh155122 fanout_stack_walk_init(mdb_walk_state_t *wsp) 1092 0 stevel { 1093 0 stevel fanout_walk_data_t *lw; 1094 0 stevel fanout_init_t *fi = wsp->walk_arg; 1095 3448 dh155122 sctp_stack_t *sctps = (sctp_stack_t *)wsp->walk_addr; 1096 3448 dh155122 uintptr_t kaddr; 1097 0 stevel 1098 3448 dh155122 if (mdb_vread(&kaddr, sizeof (kaddr), 1099 3448 dh155122 wsp->walk_addr + fi->offset) == -1) { 1100 3448 dh155122 mdb_warn("can't read sctp fanout at %p", 1101 3448 dh155122 wsp->walk_addr + fi->offset); 1102 0 stevel return (WALK_ERR); 1103 0 stevel } 1104 0 stevel 1105 0 stevel lw = mdb_alloc(sizeof (*lw), UM_SLEEP); 1106 0 stevel lw->index = 0; 1107 3448 dh155122 lw->size = fi->getsize(sctps); 1108 0 stevel lw->sctp = NULL; 1109 3448 dh155122 lw->fanout = (sctp_tf_t *)kaddr; 1110 0 stevel lw->getnext = fi->getnext; 1111 0 stevel 1112 0 stevel if ((wsp->walk_addr = find_next_hash_item(lw)) == NULL) { 1113 0 stevel return (WALK_DONE); 1114 0 stevel } 1115 0 stevel wsp->walk_data = lw; 1116 0 stevel return (WALK_NEXT); 1117 0 stevel } 1118 0 stevel 1119 0 stevel static int 1120 3448 dh155122 fanout_stack_walk_step(mdb_walk_state_t *wsp) 1121 0 stevel { 1122 0 stevel fanout_walk_data_t *fw = wsp->walk_data; 1123 0 stevel uintptr_t addr = wsp->walk_addr; 1124 0 stevel sctp_t sctp; 1125 0 stevel int status; 1126 0 stevel 1127 0 stevel if (mdb_vread(&sctp, sizeof (sctp), addr) == -1) { 1128 0 stevel mdb_warn("failed to read sctp at %p", addr); 1129 0 stevel return (WALK_DONE); 1130 0 stevel } 1131 0 stevel 1132 0 stevel status = wsp->walk_callback(addr, &sctp, wsp->walk_cbdata); 1133 0 stevel if (status != WALK_NEXT) 1134 0 stevel return (status); 1135 0 stevel 1136 0 stevel if ((wsp->walk_addr = find_next_hash_item(fw)) == NULL) 1137 0 stevel return (WALK_DONE); 1138 0 stevel 1139 0 stevel return (WALK_NEXT); 1140 0 stevel } 1141 0 stevel 1142 0 stevel static void 1143 3448 dh155122 fanout_stack_walk_fini(mdb_walk_state_t *wsp) 1144 0 stevel { 1145 0 stevel fanout_walk_data_t *fw = wsp->walk_data; 1146 0 stevel 1147 0 stevel mdb_free(fw, sizeof (*fw)); 1148 0 stevel } 1149 0 stevel 1150 3448 dh155122 int 1151 3448 dh155122 fanout_walk_init(mdb_walk_state_t *wsp) 1152 0 stevel { 1153 3448 dh155122 if (mdb_layered_walk("sctp_stacks", wsp) == -1) { 1154 3448 dh155122 mdb_warn("can't walk 'sctp_stacks'"); 1155 3448 dh155122 return (WALK_ERR); 1156 3448 dh155122 } 1157 3448 dh155122 1158 0 stevel return (WALK_NEXT); 1159 0 stevel } 1160 0 stevel 1161 3448 dh155122 int 1162 3448 dh155122 fanout_walk_step(mdb_walk_state_t *wsp) 1163 0 stevel { 1164 3448 dh155122 fanout_init_t *fi = wsp->walk_arg; 1165 0 stevel 1166 3448 dh155122 if (mdb_pwalk(fi->nested_walker_name, wsp->walk_callback, 1167 4691 kcpoon wsp->walk_cbdata, wsp->walk_addr) == -1) { 1168 3448 dh155122 mdb_warn("couldn't walk '%s'for address %p", 1169 3448 dh155122 fi->nested_walker_name, wsp->walk_addr); 1170 0 stevel return (WALK_ERR); 1171 0 stevel } 1172 3448 dh155122 return (WALK_NEXT); 1173 3448 dh155122 } 1174 0 stevel 1175 3448 dh155122 int 1176 3448 dh155122 sctps_walk_init(mdb_walk_state_t *wsp) 1177 3448 dh155122 { 1178 3448 dh155122 1179 3448 dh155122 if (mdb_layered_walk("sctp_stacks", wsp) == -1) { 1180 3448 dh155122 mdb_warn("can't walk 'sctp_stacks'"); 1181 3448 dh155122 return (WALK_ERR); 1182 0 stevel } 1183 3448 dh155122 1184 3448 dh155122 return (WALK_NEXT); 1185 3448 dh155122 } 1186 3448 dh155122 1187 3448 dh155122 int 1188 3448 dh155122 sctps_walk_step(mdb_walk_state_t *wsp) 1189 3448 dh155122 { 1190 3448 dh155122 uintptr_t kaddr; 1191 3448 dh155122 1192 3448 dh155122 kaddr = wsp->walk_addr + OFFSETOF(sctp_stack_t, sctps_g_list); 1193 3448 dh155122 if (mdb_pwalk("list", wsp->walk_callback, 1194 4691 kcpoon wsp->walk_cbdata, kaddr) == -1) { 1195 3448 dh155122 mdb_warn("couldn't walk 'list' for address %p", kaddr); 1196 3448 dh155122 return (WALK_ERR); 1197 3448 dh155122 } 1198 3448 dh155122 return (WALK_NEXT); 1199 0 stevel } 1200 0 stevel 1201 0 stevel static int 1202 0 stevel sctp_walk_faddr_init(mdb_walk_state_t *wsp) 1203 0 stevel { 1204 0 stevel sctp_t sctp; 1205 0 stevel 1206 0 stevel if (wsp->walk_addr == NULL) 1207 0 stevel return (WALK_ERR); 1208 0 stevel 1209 0 stevel if (mdb_vread(&sctp, sizeof (sctp), wsp->walk_addr) == -1) { 1210 0 stevel mdb_warn("failed to read sctp at %p", wsp->walk_addr); 1211 0 stevel return (WALK_ERR); 1212 0 stevel } 1213 0 stevel if ((wsp->walk_addr = (uintptr_t)sctp.sctp_faddrs) != NULL) 1214 0 stevel return (WALK_NEXT); 1215 0 stevel else 1216 0 stevel return (WALK_DONE); 1217 0 stevel } 1218 0 stevel 1219 0 stevel static int 1220 0 stevel sctp_walk_faddr_step(mdb_walk_state_t *wsp) 1221 0 stevel { 1222 0 stevel uintptr_t faddr_ptr = wsp->walk_addr; 1223 0 stevel sctp_faddr_t sctp_faddr; 1224 0 stevel int status; 1225 0 stevel 1226 0 stevel if (mdb_vread(&sctp_faddr, sizeof (sctp_faddr_t), faddr_ptr) == -1) { 1227 0 stevel mdb_warn("failed to read sctp_faddr_t at %p", faddr_ptr); 1228 0 stevel return (WALK_ERR); 1229 0 stevel } 1230 0 stevel status = wsp->walk_callback(faddr_ptr, &sctp_faddr, wsp->walk_cbdata); 1231 0 stevel if (status != WALK_NEXT) 1232 0 stevel return (status); 1233 0 stevel if ((faddr_ptr = (uintptr_t)sctp_faddr.next) == NULL) { 1234 0 stevel return (WALK_DONE); 1235 0 stevel } else { 1236 0 stevel wsp->walk_addr = faddr_ptr; 1237 0 stevel return (WALK_NEXT); 1238 0 stevel } 1239 0 stevel } 1240 0 stevel 1241 0 stevel /* 1242 0 stevel * Helper structure for sctp_walk_saddr. It stores the sctp_t being walked, 1243 0 stevel * the current index to the sctp_saddrs[], and the current count of the 1244 0 stevel * sctp_saddr_ipif_t list. 1245 0 stevel */ 1246 0 stevel typedef struct { 1247 0 stevel sctp_t sctp; 1248 0 stevel int hash_index; 1249 0 stevel int cur_cnt; 1250 0 stevel } saddr_walk_t; 1251 0 stevel 1252 0 stevel static int 1253 0 stevel sctp_walk_saddr_init(mdb_walk_state_t *wsp) 1254 0 stevel { 1255 0 stevel sctp_t *sctp; 1256 0 stevel int i; 1257 0 stevel saddr_walk_t *swalker; 1258 0 stevel 1259 0 stevel if (wsp->walk_addr == NULL) 1260 0 stevel return (WALK_ERR); 1261 0 stevel 1262 0 stevel swalker = mdb_alloc(sizeof (saddr_walk_t), UM_SLEEP); 1263 0 stevel sctp = &swalker->sctp; 1264 0 stevel if (mdb_vread(sctp, sizeof (sctp_t), wsp->walk_addr) == -1) { 1265 0 stevel mdb_warn("failed to read sctp at %p", wsp->walk_addr); 1266 0 stevel mdb_free(swalker, sizeof (saddr_walk_t)); 1267 0 stevel return (WALK_ERR); 1268 0 stevel } 1269 0 stevel 1270 0 stevel /* Find the first source address. */ 1271 0 stevel for (i = 0; i < SCTP_IPIF_HASH; i++) { 1272 0 stevel if (sctp->sctp_saddrs[i].ipif_count > 0) { 1273 0 stevel list_t *addr_list; 1274 0 stevel 1275 0 stevel addr_list = &sctp->sctp_saddrs[i].sctp_ipif_list; 1276 0 stevel wsp->walk_addr = (uintptr_t)list_object(addr_list, 1277 0 stevel addr_list->list_head.list_next); 1278 0 stevel 1279 0 stevel /* Recode the current info */ 1280 0 stevel swalker->hash_index = i; 1281 0 stevel swalker->cur_cnt = 1; 1282 0 stevel wsp->walk_data = swalker; 1283 0 stevel 1284 0 stevel return (WALK_NEXT); 1285 0 stevel } 1286 0 stevel } 1287 0 stevel return (WALK_DONE); 1288 0 stevel } 1289 0 stevel 1290 0 stevel static int 1291 0 stevel sctp_walk_saddr_step(mdb_walk_state_t *wsp) 1292 0 stevel { 1293 0 stevel uintptr_t saddr_ptr = wsp->walk_addr; 1294 0 stevel sctp_saddr_ipif_t saddr; 1295 0 stevel saddr_walk_t *swalker; 1296 0 stevel sctp_t *sctp; 1297 0 stevel int status; 1298 0 stevel int i, j; 1299 0 stevel 1300 0 stevel if (mdb_vread(&saddr, sizeof (sctp_saddr_ipif_t), saddr_ptr) == -1) { 1301 0 stevel mdb_warn("failed to read sctp_saddr_ipif_t at %p", saddr_ptr); 1302 0 stevel return (WALK_ERR); 1303 0 stevel } 1304 0 stevel status = wsp->walk_callback(saddr_ptr, &saddr, wsp->walk_cbdata); 1305 0 stevel if (status != WALK_NEXT) 1306 0 stevel return (status); 1307 0 stevel 1308 0 stevel swalker = (saddr_walk_t *)wsp->walk_data; 1309 0 stevel sctp = &swalker->sctp; 1310 0 stevel i = swalker->hash_index; 1311 0 stevel j = swalker->cur_cnt; 1312 0 stevel 1313 0 stevel /* 1314 0 stevel * If there is still a source address in the current list, return it. 1315 0 stevel * Otherwise, go to the next list in the sctp_saddrs[]. 1316 0 stevel */ 1317 0 stevel if (j++ < sctp->sctp_saddrs[i].ipif_count) { 1318 0 stevel wsp->walk_addr = (uintptr_t)saddr.saddr_ipif.list_next; 1319 0 stevel swalker->cur_cnt = j; 1320 0 stevel return (WALK_NEXT); 1321 0 stevel } else { 1322 0 stevel list_t *lst; 1323 0 stevel 1324 0 stevel for (i = i + 1; i < SCTP_IPIF_HASH; i++) { 1325 0 stevel if (sctp->sctp_saddrs[i].ipif_count > 0) { 1326 0 stevel lst = &sctp->sctp_saddrs[i].sctp_ipif_list; 1327 0 stevel wsp->walk_addr = (uintptr_t)list_object( 1328 0 stevel lst, lst->list_head.list_next); 1329 0 stevel swalker->hash_index = i; 1330 0 stevel swalker->cur_cnt = 1; 1331 0 stevel return (WALK_NEXT); 1332 0 stevel } 1333 0 stevel } 1334 0 stevel } 1335 0 stevel return (WALK_DONE); 1336 0 stevel } 1337 0 stevel 1338 0 stevel static void 1339 0 stevel sctp_walk_saddr_fini(mdb_walk_state_t *wsp) 1340 0 stevel { 1341 0 stevel saddr_walk_t *swalker = (saddr_walk_t *)wsp->walk_data; 1342 0 stevel 1343 0 stevel mdb_free(swalker, sizeof (saddr_walk_t)); 1344 0 stevel } 1345 0 stevel 1346 3448 dh155122 1347 3448 dh155122 typedef struct ill_walk_data { 1348 3448 dh155122 sctp_ill_hash_t ills[SCTP_ILL_HASH]; 1349 3448 dh155122 uint32_t count; 1350 3448 dh155122 } ill_walk_data_t; 1351 3448 dh155122 1352 3448 dh155122 typedef struct ipuf_walk_data { 1353 3448 dh155122 sctp_ipif_hash_t ipifs[SCTP_IPIF_HASH]; 1354 3448 dh155122 uint32_t count; 1355 3448 dh155122 } ipif_walk_data_t; 1356 3448 dh155122 1357 3448 dh155122 1358 3448 dh155122 int 1359 3448 dh155122 sctp_ill_walk_init(mdb_walk_state_t *wsp) 1360 3448 dh155122 { 1361 3448 dh155122 if (mdb_layered_walk("sctp_stacks", wsp) == -1) { 1362 3448 dh155122 mdb_warn("can't walk 'sctp_stacks'"); 1363 3448 dh155122 return (WALK_ERR); 1364 3448 dh155122 } 1365 3448 dh155122 1366 3448 dh155122 return (WALK_NEXT); 1367 3448 dh155122 } 1368 3448 dh155122 1369 3448 dh155122 int 1370 3448 dh155122 sctp_ill_walk_step(mdb_walk_state_t *wsp) 1371 3448 dh155122 { 1372 3448 dh155122 if (mdb_pwalk("sctp_stack_walk_ill", wsp->walk_callback, 1373 4691 kcpoon wsp->walk_cbdata, wsp->walk_addr) == -1) { 1374 3448 dh155122 mdb_warn("couldn't walk 'sctp_stack_walk_ill' for addr %p", 1375 3448 dh155122 wsp->walk_addr); 1376 3448 dh155122 return (WALK_ERR); 1377 3448 dh155122 } 1378 3448 dh155122 return (WALK_NEXT); 1379 3448 dh155122 } 1380 3448 dh155122 1381 3448 dh155122 /* 1382 3448 dh155122 * wsp->walk_addr is the address of sctps_ill_list 1383 3448 dh155122 */ 1384 0 stevel static int 1385 3448 dh155122 sctp_stack_ill_walk_init(mdb_walk_state_t *wsp) 1386 0 stevel { 1387 3448 dh155122 ill_walk_data_t iw; 1388 0 stevel intptr_t i; 1389 3448 dh155122 uintptr_t kaddr, uaddr; 1390 3448 dh155122 size_t offset; 1391 3448 dh155122 1392 3448 dh155122 kaddr = wsp->walk_addr + OFFSETOF(sctp_stack_t, sctps_ills_count); 1393 3448 dh155122 if (mdb_vread(&iw.count, sizeof (iw.count), kaddr) == -1) { 1394 3448 dh155122 mdb_warn("can't read sctps_ills_count at %p", kaddr); 1395 3448 dh155122 return (WALK_ERR); 1396 3448 dh155122 } 1397 3448 dh155122 kaddr = wsp->walk_addr + OFFSETOF(sctp_stack_t, sctps_g_ills); 1398 3448 dh155122 1399 3448 dh155122 if (mdb_vread(&kaddr, sizeof (kaddr), kaddr) == -1) { 1400 3448 dh155122 mdb_warn("can't read scpts_g_ills %p", kaddr); 1401 3448 dh155122 return (WALK_ERR); 1402 3448 dh155122 } 1403 3448 dh155122 if (mdb_vread(&iw.ills, sizeof (iw.ills), kaddr) == -1) { 1404 3448 dh155122 mdb_warn("failed to read 'sctps_g_ills'"); 1405 3448 dh155122 return (NULL); 1406 3448 dh155122 } 1407 0 stevel 1408 0 stevel /* Find the first ill. */ 1409 0 stevel for (i = 0; i < SCTP_ILL_HASH; i++) { 1410 3448 dh155122 if (iw.ills[i].ill_count > 0) { 1411 3448 dh155122 uaddr = (uintptr_t)&iw.ills[i].sctp_ill_list; 1412 3448 dh155122 offset = uaddr - (uintptr_t)&iw.ills; 1413 3448 dh155122 if (mdb_pwalk("list", wsp->walk_callback, 1414 4691 kcpoon wsp->walk_cbdata, kaddr+offset) == -1) { 1415 3448 dh155122 mdb_warn("couldn't walk 'list' for address %p", 1416 3448 dh155122 kaddr); 1417 3448 dh155122 return (WALK_ERR); 1418 0 stevel } 1419 0 stevel } 1420 0 stevel } 1421 0 stevel return (WALK_DONE); 1422 0 stevel } 1423 0 stevel 1424 0 stevel static int 1425 3448 dh155122 sctp_stack_ill_walk_step(mdb_walk_state_t *wsp) 1426 0 stevel { 1427 3448 dh155122 return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, 1428 4691 kcpoon wsp->walk_cbdata)); 1429 3448 dh155122 } 1430 3448 dh155122 1431 3448 dh155122 int 1432 3448 dh155122 sctp_ipif_walk_init(mdb_walk_state_t *wsp) 1433 3448 dh155122 { 1434 3448 dh155122 if (mdb_layered_walk("sctp_stacks", wsp) == -1) { 1435 3448 dh155122 mdb_warn("can't walk 'sctp_stacks'"); 1436 3448 dh155122 return (WALK_ERR); 1437 3448 dh155122 } 1438 3448 dh155122 return (WALK_NEXT); 1439 3448 dh155122 } 1440 3448 dh155122 1441 3448 dh155122 int 1442 3448 dh155122 sctp_ipif_walk_step(mdb_walk_state_t *wsp) 1443 3448 dh155122 { 1444 3448 dh155122 if (mdb_pwalk("sctp_stack_walk_ipif", wsp->walk_callback, 1445 4691 kcpoon wsp->walk_cbdata, wsp->walk_addr) == -1) { 1446 3448 dh155122 mdb_warn("couldn't walk 'sctp_stack_walk_ipif' for addr %p", 1447 3448 dh155122 wsp->walk_addr); 1448 3448 dh155122 return (WALK_ERR); 1449 3448 dh155122 } 1450 3448 dh155122 return (WALK_NEXT); 1451 3448 dh155122 } 1452 3448 dh155122 1453 3448 dh155122 /* 1454 3448 dh155122 * wsp->walk_addr is the address of sctps_ipif_list 1455 3448 dh155122 */ 1456 3448 dh155122 static int 1457 3448 dh155122 sctp_stack_ipif_walk_init(mdb_walk_state_t *wsp) 1458 3448 dh155122 { 1459 3448 dh155122 ipif_walk_data_t iw; 1460 0 stevel intptr_t i; 1461 3448 dh155122 uintptr_t kaddr, uaddr; 1462 3448 dh155122 size_t offset; 1463 0 stevel 1464 3448 dh155122 kaddr = wsp->walk_addr + OFFSETOF(sctp_stack_t, sctps_g_ipifs_count); 1465 3448 dh155122 if (mdb_vread(&iw.count, sizeof (iw.count), kaddr) == -1) { 1466 3448 dh155122 mdb_warn("can't read sctps_g_ipifs_count at %p", kaddr); 1467 3448 dh155122 return (WALK_ERR); 1468 3448 dh155122 } 1469 3448 dh155122 kaddr = wsp->walk_addr + OFFSETOF(sctp_stack_t, sctps_g_ipifs); 1470 3448 dh155122 1471 3448 dh155122 if (mdb_vread(&kaddr, sizeof (kaddr), kaddr) == -1) { 1472 3448 dh155122 mdb_warn("can't read scpts_g_ipifs %p", kaddr); 1473 3448 dh155122 return (WALK_ERR); 1474 3448 dh155122 } 1475 3448 dh155122 if (mdb_vread(&iw.ipifs, sizeof (iw.ipifs), kaddr) == -1) { 1476 3448 dh155122 mdb_warn("failed to read 'sctps_g_ipifs'"); 1477 3448 dh155122 return (NULL); 1478 3448 dh155122 } 1479 3448 dh155122 1480 3448 dh155122 /* Find the first ipif. */ 1481 0 stevel for (i = 0; i < SCTP_IPIF_HASH; i++) { 1482 3448 dh155122 if (iw.ipifs[i].ipif_count > 0) { 1483 3448 dh155122 uaddr = (uintptr_t)&iw.ipifs[i].sctp_ipif_list; 1484 3448 dh155122 offset = uaddr - (uintptr_t)&iw.ipifs; 1485 3448 dh155122 if (mdb_pwalk("list", wsp->walk_callback, 1486 4691 kcpoon wsp->walk_cbdata, kaddr+offset) == -1) { 1487 3448 dh155122 mdb_warn("couldn't walk 'list' for address %p", 1488 3448 dh155122 kaddr); 1489 3448 dh155122 return (WALK_ERR); 1490 3448 dh155122 } 1491 0 stevel } 1492 0 stevel } 1493 0 stevel return (WALK_DONE); 1494 0 stevel } 1495 0 stevel 1496 0 stevel static int 1497 3448 dh155122 sctp_stack_ipif_walk_step(mdb_walk_state_t *wsp) 1498 0 stevel { 1499 3448 dh155122 return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, 1500 4691 kcpoon wsp->walk_cbdata)); 1501 0 stevel } 1502 0 stevel 1503 0 stevel static void 1504 0 stevel sctp_help(void) 1505 0 stevel { 1506 0 stevel mdb_printf("Print information for a given SCTP sctp_t\n\n"); 1507 0 stevel mdb_printf("Options:\n"); 1508 0 stevel mdb_printf("\t-a\t All the information\n"); 1509 0 stevel mdb_printf("\t-f\t Flags\n"); 1510 0 stevel mdb_printf("\t-h\t Hash Tables\n"); 1511 0 stevel mdb_printf("\t-o\t Outbound Data\n"); 1512 0 stevel mdb_printf("\t-i\t Inbound Data\n"); 1513 0 stevel mdb_printf("\t-m\t Miscellaneous Information\n"); 1514 0 stevel mdb_printf("\t-r\t RTT Tracking\n"); 1515 0 stevel mdb_printf("\t-S\t Stats Counters\n"); 1516 0 stevel mdb_printf("\t-F\t Flow Control\n"); 1517 0 stevel mdb_printf("\t-H\t Composite Headers\n"); 1518 0 stevel mdb_printf("\t-p\t PMTUD\n"); 1519 0 stevel mdb_printf("\t-R\t Retransmit Information\n"); 1520 0 stevel mdb_printf("\t-C\t Connection State\n"); 1521 0 stevel mdb_printf("\t-c\t Cleanup / Close\n"); 1522 0 stevel mdb_printf("\t-e\t Extensions and Reliable Control Chunks\n"); 1523 0 stevel mdb_printf("\t-d\t Local and Peer addresses\n"); 1524 0 stevel mdb_printf("\t-P\t Peer addresses\n"); 1525 0 stevel } 1526 0 stevel static const mdb_dcmd_t dcmds[] = { 1527 0 stevel { "sctp", ":[-afhoimrSFHpRCcedP]", 1528 0 stevel "display sctp control structure", sctp, sctp_help }, 1529 0 stevel { "sctp_set", ":", "display a SCTP set", sctp_set }, 1530 0 stevel { "sctp_faddr", ":", "display a faddr", sctp_faddr }, 1531 0 stevel { "sctp_istr_msgs", ":", "display msg list on an instream", 1532 0 stevel sctp_istr_msgs }, 1533 0 stevel { "sctp_mdata_chunk", ":", "display a data chunk in an mblk", 1534 0 stevel sctp_mdata_chunk }, 1535 0 stevel { "sctp_xmit_list", ":", "display sctp xmit lists", sctp_xmit_list }, 1536 0 stevel { "sctp_instr", ":", "display instr", sctp_instr }, 1537 0 stevel { "sctp_reass_list", ":", "display reass list", sctp_reass_list }, 1538 0 stevel { "sctp_uo_reass_list", ":", "display un-ordered reass list", 1539 0 stevel sctp_uo_reass_list }, 1540 0 stevel { NULL } 1541 0 stevel }; 1542 0 stevel 1543 0 stevel static const fanout_init_t listen_fanout_init = { 1544 3448 dh155122 "sctp_stack_listen_fanout", OFFSETOF(sctp_stack_t, sctps_listen_fanout), 1545 3448 dh155122 listen_size, listen_next 1546 0 stevel }; 1547 0 stevel 1548 0 stevel static const fanout_init_t conn_fanout_init = { 1549 3448 dh155122 "sctp_stack_conn_fanout", OFFSETOF(sctp_stack_t, sctps_conn_fanout), 1550 3448 dh155122 conn_size, conn_next 1551 0 stevel }; 1552 0 stevel 1553 0 stevel static const fanout_init_t bind_fanout_init = { 1554 3448 dh155122 "sctp_stack_bind_fanout", OFFSETOF(sctp_stack_t, sctps_bind_fanout), 1555 3448 dh155122 bind_size, bind_next 1556 0 stevel }; 1557 0 stevel 1558 0 stevel static const mdb_walker_t walkers[] = { 1559 3448 dh155122 { "sctps", "walk the full chain of sctps for all stacks", 1560 3448 dh155122 sctps_walk_init, sctps_walk_step, NULL }, 1561 3448 dh155122 { "sctp_listen_fanout", "walk the sctp listen fanout for all stacks", 1562 3448 dh155122 fanout_walk_init, fanout_walk_step, NULL, 1563 0 stevel (void *)&listen_fanout_init }, 1564 3448 dh155122 { "sctp_conn_fanout", "walk the sctp conn fanout for all stacks", 1565 3448 dh155122 fanout_walk_init, fanout_walk_step, NULL, 1566 0 stevel (void *)&conn_fanout_init }, 1567 3448 dh155122 { "sctp_bind_fanout", "walk the sctp bind fanout for all stacks", 1568 3448 dh155122 fanout_walk_init, fanout_walk_step, NULL, 1569 3448 dh155122 (void *)&bind_fanout_init }, 1570 3448 dh155122 { "sctp_stack_listen_fanout", 1571 3448 dh155122 "walk the sctp listen fanout for one stack", 1572 3448 dh155122 fanout_stack_walk_init, fanout_stack_walk_step, 1573 3448 dh155122 fanout_stack_walk_fini, 1574 3448 dh155122 (void *)&listen_fanout_init }, 1575 3448 dh155122 { "sctp_stack_conn_fanout", "walk the sctp conn fanout for one stack", 1576 3448 dh155122 fanout_stack_walk_init, fanout_stack_walk_step, 1577 3448 dh155122 fanout_stack_walk_fini, 1578 3448 dh155122 (void *)&conn_fanout_init }, 1579 3448 dh155122 { "sctp_stack_bind_fanout", "walk the sctp bind fanoutfor one stack", 1580 3448 dh155122 fanout_stack_walk_init, fanout_stack_walk_step, 1581 3448 dh155122 fanout_stack_walk_fini, 1582 0 stevel (void *)&bind_fanout_init }, 1583 0 stevel { "sctp_walk_faddr", "walk the peer address list of a given sctp_t", 1584 0 stevel sctp_walk_faddr_init, sctp_walk_faddr_step, NULL }, 1585 0 stevel { "sctp_walk_saddr", "walk the local address list of a given sctp_t", 1586 0 stevel sctp_walk_saddr_init, sctp_walk_saddr_step, sctp_walk_saddr_fini }, 1587 3448 dh155122 { "sctp_walk_ill", "walk the sctp_g_ills list for all stacks", 1588 3448 dh155122 sctp_ill_walk_init, sctp_ill_walk_step, NULL }, 1589 3448 dh155122 { "sctp_walk_ipif", "walk the sctp_g_ipif list for all stacks", 1590 3448 dh155122 sctp_ipif_walk_init, sctp_ipif_walk_step, NULL }, 1591 3448 dh155122 { "sctp_stack_walk_ill", "walk the sctp_g_ills list for one stack", 1592 3448 dh155122 sctp_stack_ill_walk_init, sctp_stack_ill_walk_step, NULL }, 1593 3448 dh155122 { "sctp_stack_walk_ipif", "walk the sctp_g_ipif list for one stack", 1594 3448 dh155122 sctp_stack_ipif_walk_init, sctp_stack_ipif_walk_step, NULL }, 1595 3448 dh155122 { "sctp_stacks", "walk all the sctp_stack_t", 1596 3448 dh155122 sctp_stacks_walk_init, sctp_stacks_walk_step, NULL }, 1597 0 stevel { NULL } 1598 0 stevel }; 1599 0 stevel 1600 0 stevel static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 1601 0 stevel 1602 0 stevel const mdb_modinfo_t * 1603 0 stevel _mdb_init(void) 1604 0 stevel { 1605 0 stevel return (&modinfo); 1606 0 stevel } 1607