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.
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.
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]
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/types.h>
27 #include <sys/stream.h>
28 #include <sys/mdb_modapi.h>
29 #include <sys/socket.h>
31 #include <sys/strsun.h>
33 #include <mdb/mdb_stdlib.h>
35 #include <netinet/in.h>
36 #include <netinet/ip6.h>
37 #include <netinet/sctp.h>
39 #include <inet/common.h>
42 #include <inet/ipclassifier.h>
44 #include <sctp/sctp_impl.h>
45 #include <sctp/sctp_addr.h>
47 #define MDB_SCTP_SHOW_FLAGS 0x1
48 #define MDB_SCTP_DUMP_ADDRS 0x2
49 #define MDB_SCTP_SHOW_HASH 0x4
50 #define MDB_SCTP_SHOW_OUT 0x8
51 #define MDB_SCTP_SHOW_IN 0x10
52 #define MDB_SCTP_SHOW_MISC 0x20
53 #define MDB_SCTP_SHOW_RTT 0x40
54 #define MDB_SCTP_SHOW_STATS 0x80
55 #define MDB_SCTP_SHOW_FLOW 0x100
56 #define MDB_SCTP_SHOW_HDR 0x200
57 #define MDB_SCTP_SHOW_PMTUD 0x400
58 #define MDB_SCTP_SHOW_RXT 0x800
59 #define MDB_SCTP_SHOW_CONN 0x1000
60 #define MDB_SCTP_SHOW_CLOSE 0x2000
61 #define MDB_SCTP_SHOW_EXT 0x4000
63 #define MDB_SCTP_SHOW_ALL 0xffffffff
66 * Copy from kernel/os/list.c. Should we have a generic
69 #define list_object(a, node) ((void *)(((char *)node) - (a)->list_offset))
72 ns_to_stackid(uintptr_t kaddr
)
76 if (mdb_vread(&nss
, sizeof (nss
), kaddr
) == -1) {
77 mdb_warn("failed to read netdstack info %p", kaddr
);
80 return (nss
.netstack_stackid
);
84 sctp_stacks_walk_init(mdb_walk_state_t
*wsp
)
86 if (mdb_layered_walk("netstack", wsp
) == -1) {
87 mdb_warn("can't walk 'netstack'");
94 sctp_stacks_walk_step(mdb_walk_state_t
*wsp
)
99 if (mdb_vread(&nss
, sizeof (nss
), wsp
->walk_addr
) == -1) {
100 mdb_warn("can't read netstack at %p", wsp
->walk_addr
);
103 kaddr
= (uintptr_t)nss
.netstack_modules
[NS_SCTP
];
104 return (wsp
->walk_callback(kaddr
, wsp
->walk_layer
, wsp
->walk_cbdata
));
108 sctp_faddr_state(int state
)
113 case SCTP_FADDRS_UNREACH
:
114 statestr
= "Unreachable";
116 case SCTP_FADDRS_DOWN
:
119 case SCTP_FADDRS_ALIVE
:
122 case SCTP_FADDRS_UNCONFIRMED
:
123 statestr
= "Unconfirmed";
126 statestr
= "Unknown";
134 sctp_faddr(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
139 if (!(flags
& DCMD_ADDRSPEC
))
142 if (mdb_vread(fa
, sizeof (*fa
), addr
) == -1) {
143 mdb_warn("cannot read fadder at %p", addr
);
147 statestr
= sctp_faddr_state(fa
->sf_state
);
148 mdb_printf("%<u>%p\t%<b>%N%</b>\t%s%</u>\n", addr
, &fa
->sf_faddr
,
150 mdb_printf("next\t\t%?p\tsaddr\t%N\n", fa
->sf_next
, &fa
->sf_saddr
);
151 mdb_printf("rto\t\t%?d\tsrtt\t\t%?d\n", fa
->sf_rto
, fa
->sf_srtt
);
152 mdb_printf("rttvar\t\t%?d\trtt_updates\t%?u\n", fa
->sf_rttvar
,
154 mdb_printf("strikes\t\t%?d\tmax_retr\t%?d\n", fa
->sf_strikes
,
156 mdb_printf("hb_expiry\t%?ld\thb_interval\t%?u\n", fa
->sf_hb_expiry
,
158 mdb_printf("pmss\t\t%?u\tcwnd\t\t%?u\n", fa
->sf_pmss
, fa
->sf_cwnd
);
159 mdb_printf("ssthresh\t%?u\tsuna\t\t%?u\n", fa
->sf_ssthresh
,
161 mdb_printf("pba\t\t%?u\tacked\t\t%?u\n", fa
->sf_pba
, fa
->sf_acked
);
162 mdb_printf("lastactive\t%?ld\thb_secret\t%?#lx\n", fa
->sf_lastactive
,
164 mdb_printf("rxt_unacked\t%?u\n", fa
->sf_rxt_unacked
);
165 mdb_printf("timer_mp\t%?p\tixa\t\t%?p\n", fa
->sf_timer_mp
, fa
->sf_ixa
);
166 mdb_printf("hb_enabled\t%?d\thb_pending\t%?d\n"
167 "timer_running\t%?d\tdf\t\t%?d\n"
168 "pmtu_discovered\t%?d\tisv4\t\t%?d\n"
169 "retransmissions\t%?u\n",
170 fa
->sf_hb_enabled
, fa
->sf_hb_pending
, fa
->sf_timer_running
,
171 fa
->sf_df
, fa
->sf_pmtu_discovered
, fa
->sf_isv4
, fa
->sf_T3expire
);
177 print_set(sctp_set_t
*sp
)
179 mdb_printf("\tbegin\t%<b>%?x%</b>\t\tend\t%<b>%?x%</b>\n",
181 mdb_printf("\tnext\t%?p\tprev\t%?p\n", sp
->next
, sp
->prev
);
186 sctp_set(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
190 if (!(flags
& DCMD_ADDRSPEC
))
193 if (mdb_vread(sp
, sizeof (*sp
), addr
) == -1)
202 dump_sack_info(uintptr_t addr
)
206 while (addr
!= (uintptr_t)NULL
) {
207 if (mdb_vread(sp
, sizeof (*sp
), addr
) == -1) {
208 mdb_warn("failed to read sctp_set at %p", addr
);
212 addr
= (uintptr_t)sp
->next
;
218 dump_msghdr(mblk_t
*meta
)
222 if (mdb_vread(&smh
, sizeof (smh
), (uintptr_t)meta
->b_rptr
) == -1)
225 mdb_printf("%<u>msg_hdr_t at \t%?p\tsentto\t%?p%</u>\n",
226 meta
->b_rptr
, SCTP_CHUNK_DEST(meta
));
227 mdb_printf("\tttl\t%?ld\ttob\t%?ld\n", smh
.smh_ttl
, smh
.smh_tob
);
228 mdb_printf("\tsid\t%?u\tssn\t%?u\n", smh
.smh_sid
, smh
.smh_ssn
);
229 mdb_printf("\tppid\t%?u\tflags\t%?s\n", smh
.smh_ppid
,
230 smh
.smh_flags
& MSG_UNORDERED
? "unordered" : " ");
231 mdb_printf("\tcontext\t%?u\tmsglen\t%?d\n", smh
.smh_context
,
238 dump_datahdr(mblk_t
*mp
)
244 if (mdb_vread(&sdc
, sizeof (sdc
), (uintptr_t)mp
->b_rptr
) == -1)
247 mdb_printf("%<u>data_chunk_t \t%?p\tsentto\t%?p%</u>\n",
248 mp
->b_rptr
, SCTP_CHUNK_DEST(mp
));
249 mdb_printf("\tsent\t%?d\t", SCTP_CHUNK_ISSENT(mp
)?1:0);
250 mdb_printf("retrans\t%?d\n", SCTP_CHUNK_WANT_REXMIT(mp
)?1:0);
251 mdb_printf("\tacked\t%?d\t", SCTP_CHUNK_ISACKED(mp
)?1:0);
252 mdb_printf("sackcnt\t%?u\n", SCTP_CHUNK_SACKCNT(mp
));
254 mdb_nhconvert(&sdh_int16
, &sdc
.sdh_len
, sizeof (sdc
.sdh_len
));
255 mdb_printf("\tlen\t%?d\t", sdh_int16
);
256 mdb_printf("BBIT=%d", SCTP_DATA_GET_BBIT(&sdc
) == 0 ? 0 : 1);
257 mdb_printf("EBIT=%d", SCTP_DATA_GET_EBIT(&sdc
) == 0 ? 0 : 1);
259 mdb_nhconvert(&sdh_int32
, &sdc
.sdh_tsn
, sizeof (sdc
.sdh_tsn
));
260 mdb_nhconvert(&sdh_int16
, &sdc
.sdh_sid
, sizeof (sdc
.sdh_sid
));
261 mdb_printf("\ttsn\t%?x\tsid\t%?hu\n", sdh_int32
, sdh_int16
);
263 mdb_nhconvert(&sdh_int16
, &sdc
.sdh_ssn
, sizeof (sdc
.sdh_ssn
));
264 mdb_nhconvert(&sdh_int32
, &sdc
.sdh_payload_id
,
265 sizeof (sdc
.sdh_payload_id
));
266 mdb_printf("\tssn\t%?hu\tppid\t%?d\n", sdh_int16
, sdh_int32
);
272 sctp_sent_list(mblk_t
*addr
)
279 if (mdb_vread(&meta
, sizeof (meta
), (uintptr_t)addr
) == -1)
285 if (meta
.b_cont
== NULL
) {
286 mdb_printf("No data chunks with message header!\n");
289 if (mdb_vread(&mp
, sizeof (mp
),
290 (uintptr_t)meta
.b_cont
) == -1) {
298 if (mdb_vread(&mp
, sizeof (mp
),
299 (uintptr_t)(mp
.b_next
)) == -1)
302 if (meta
.b_next
== NULL
)
304 if (mdb_vread(&meta
, sizeof (meta
),
305 (uintptr_t)meta
.b_next
) == -1)
313 sctp_unsent_list(mblk_t
*addr
)
320 if (mdb_vread(&meta
, sizeof (meta
), (uintptr_t)addr
) == -1)
326 if (meta
.b_next
== NULL
)
329 if (mdb_vread(&meta
, sizeof (meta
),
330 (uintptr_t)meta
.b_next
) == -1)
339 sctp_xmit_list(uintptr_t addr
, uint_t flags
, int ac
, const mdb_arg_t
*av
)
343 if (!(flags
& DCMD_ADDRSPEC
))
346 if (mdb_vread(&sctp
, sizeof (sctp
), addr
) == -1)
349 mdb_printf("%<b>Chunkified TX list%</b>\n");
350 if (sctp_sent_list(sctp
.sctp_xmit_head
) < 0)
353 mdb_printf("%<b>Unchunkified TX list%</b>\n");
354 if (sctp_unsent_list(sctp
.sctp_xmit_unsent
) < 0)
362 sctp_mdata_chunk(uintptr_t addr
, uint_t flags
, int ac
, const mdb_arg_t
*av
)
367 if (!(flags
& DCMD_ADDRSPEC
))
370 if (mdb_vread(&mp
, sizeof (mp
), addr
) == -1)
373 if (mdb_vread(&dc
, sizeof (dc
), (uintptr_t)mp
.b_rptr
) == -1)
376 mdb_printf("%<b>%-?p%</b>tsn\t%?x\tsid\t%?hu\n", addr
,
377 dc
.sdh_tsn
, dc
.sdh_sid
);
378 mdb_printf("%-?sssn\t%?hu\tppid\t%?x\n", "", dc
.sdh_ssn
,
386 sctp_istr_msgs(uintptr_t addr
, uint_t flags
, int ac
, const mdb_arg_t
*av
)
396 if (!(flags
& DCMD_ADDRSPEC
))
400 if (mdb_vread(&istrmp
, sizeof (istrmp
), addr
) == -1)
403 mdb_printf("\tistr mblk at %p: next: %?p\n"
404 "\t\tprev: %?p\tcont: %?p\n", addr
, istrmp
.b_next
,
405 istrmp
.b_prev
, istrmp
.b_cont
);
406 daddr
= (uintptr_t)&istrmp
;
408 if (mdb_vread(&dmp
, sizeof (dmp
), daddr
) == -1)
410 chaddr
= (uintptr_t)dmp
.b_rptr
;
411 if (mdb_vread(&dp
, sizeof (dp
), chaddr
) == -1)
414 bbit
= (SCTP_DATA_GET_BBIT(&dp
) != 0);
415 ebit
= (SCTP_DATA_GET_EBIT(&dp
) != 0);
417 mdb_printf("\t\t\ttsn: %x bbit: %d ebit: %d\n",
418 dp
.sdh_tsn
, bbit
, ebit
);
421 daddr
= (uintptr_t)dmp
.b_cont
;
422 } while (daddr
!= (uintptr_t)NULL
);
424 addr
= (uintptr_t)istrmp
.b_next
;
425 } while (addr
!= (uintptr_t)NULL
);
432 sctp_reass_list(uintptr_t addr
, uint_t flags
, int ac
, const mdb_arg_t
*av
)
440 boolean_t bbit
, ebit
;
442 if (!(flags
& DCMD_ADDRSPEC
))
446 if (mdb_vread(&srpmp
, sizeof (srpmp
), addr
) == -1)
449 if (mdb_vread(&srp
, sizeof (srp
),
450 (uintptr_t)srpmp
.b_datap
->db_base
) == -1)
453 mdb_printf("\treassembly mblk at %p: next: %?p\n"
454 "\t\tprev: %?p\tcont: %?p\n", addr
, srpmp
.b_next
,
455 srpmp
.b_prev
, srpmp
.b_cont
);
456 mdb_printf("\t\tssn: %hu\tneeded: %hu\tgot: %hu\ttail: %?p\n"
457 "\t\tpartial_delivered: %s\n", srp
.sr_ssn
, srp
.sr_needed
,
458 srp
.sr_got
, srp
.sr_tail
, srp
.sr_partial_delivered
? "TRUE" :
461 /* display the contents of this ssn's reassemby list */
462 daddr
= DB_TYPE(&srpmp
) == M_CTL
? (uintptr_t)srpmp
.b_cont
:
465 if (mdb_vread(&dmp
, sizeof (dmp
), daddr
) == -1)
467 chaddr
= (uintptr_t)dmp
.b_rptr
;
468 if (mdb_vread(&dp
, sizeof (dp
), chaddr
) == -1)
471 bbit
= (SCTP_DATA_GET_BBIT(&dp
) != 0);
472 ebit
= (SCTP_DATA_GET_EBIT(&dp
) != 0);
474 mdb_printf("\t\t\ttsn: %x bbit: %d ebit: %d\n",
475 dp
.sdh_tsn
, bbit
, ebit
);
477 daddr
= (uintptr_t)dmp
.b_cont
;
478 } while (daddr
!= (uintptr_t)NULL
);
480 addr
= (uintptr_t)srpmp
.b_next
;
481 } while (addr
!= (uintptr_t)NULL
);
488 sctp_uo_reass_list(uintptr_t addr
, uint_t flags
, int ac
, const mdb_arg_t
*av
)
497 if (!(flags
& DCMD_ADDRSPEC
))
501 if (mdb_vread(&dmp
, sizeof (dmp
), addr
) == -1)
504 mdb_printf("\treassembly mblk at %p: next: %?p\n"
505 "\t\tprev: %?p\n", addr
, dmp
.b_next
, dmp
.b_prev
);
507 chaddr
= (uintptr_t)dmp
.b_rptr
;
508 if (mdb_vread(&dp
, sizeof (dp
), chaddr
) == -1)
511 bbit
= (SCTP_DATA_GET_BBIT(&dp
) != 0);
512 ebit
= (SCTP_DATA_GET_EBIT(&dp
) != 0);
513 ubit
= (SCTP_DATA_GET_UBIT(&dp
) != 0);
515 mdb_printf("\t\t\tsid: %hu ssn: %hu tsn: %x "
516 "flags: %x (U=%d B=%d E=%d)\n", dp
.sdh_sid
, dp
.sdh_ssn
,
517 dp
.sdh_tsn
, dp
.sdh_flags
, ubit
, bbit
, ebit
);
519 addr
= (uintptr_t)dmp
.b_next
;
520 } while (addr
!= (uintptr_t)NULL
);
526 sctp_instr(uintptr_t addr
, uint_t flags
, int ac
, const mdb_arg_t
*av
)
530 if (!(flags
& DCMD_ADDRSPEC
))
533 if (mdb_vread(&sip
, sizeof (sip
), addr
) == -1)
536 mdb_printf("%<b>%-?p%</b>\n\tmsglist\t%?p\tnmsgs\t%?d\n"
537 "\tnextseq\t%?d\treass\t%?p\n", addr
, sip
.istr_msgs
,
538 sip
.istr_nmsgs
, sip
.nextseq
, sip
.istr_reass
);
539 mdb_set_dot(addr
+ sizeof (sip
));
541 return (sctp_reass_list((uintptr_t)sip
.istr_reass
, flags
, ac
, av
));
545 state2str(sctp_t
*sctp
)
547 switch (sctp
->sctp_state
) {
548 case SCTPS_IDLE
: return ("SCTPS_IDLE");
549 case SCTPS_BOUND
: return ("SCTPS_BOUND");
550 case SCTPS_LISTEN
: return ("SCTPS_LISTEN");
551 case SCTPS_COOKIE_WAIT
: return ("SCTPS_COOKIE_WAIT");
552 case SCTPS_COOKIE_ECHOED
: return ("SCTPS_COOKIE_ECHOED");
553 case SCTPS_ESTABLISHED
: return ("SCTPS_ESTABLISHED");
554 case SCTPS_SHUTDOWN_PENDING
: return ("SCTPS_SHUTDOWN_PENDING");
555 case SCTPS_SHUTDOWN_SENT
: return ("SCTPS_SHUTDOWN_SENT");
556 case SCTPS_SHUTDOWN_RECEIVED
: return ("SCTPS_SHUTDOWN_RECEIVED");
557 case SCTPS_SHUTDOWN_ACK_SENT
: return ("SCTPS_SHUTDOWN_ACK_SENT");
558 default: return ("UNKNOWN STATE");
563 show_sctp_flags(sctp_t
*sctp
)
565 mdb_printf("\tunderstands_asconf\t%d\n",
566 sctp
->sctp_understands_asconf
);
567 mdb_printf("\tdebug\t\t\t%d\n", sctp
->sctp_connp
->conn_debug
);
568 mdb_printf("\tcchunk_pend\t\t%d\n", sctp
->sctp_cchunk_pend
);
569 mdb_printf("\tdgram_errind\t\t%d\n",
570 sctp
->sctp_connp
->conn_dgram_errind
);
572 mdb_printf("\tlinger\t\t\t%d\n", sctp
->sctp_connp
->conn_linger
);
573 if (sctp
->sctp_lingering
)
575 mdb_printf("\tlingering\t\t%d\n", sctp
->sctp_lingering
);
576 mdb_printf("\tloopback\t\t%d\n", sctp
->sctp_loopback
);
577 mdb_printf("\tforce_sack\t\t%d\n", sctp
->sctp_force_sack
);
579 mdb_printf("\tack_timer_runing\t%d\n", sctp
->sctp_ack_timer_running
);
580 mdb_printf("\trecvdstaddr\t\t%d\n",
581 sctp
->sctp_connp
->conn_recv_ancillary
.crb_recvdstaddr
);
582 mdb_printf("\thwcksum\t\t\t%d\n", sctp
->sctp_hwcksum
);
583 mdb_printf("\tunderstands_addip\t%d\n", sctp
->sctp_understands_addip
);
585 mdb_printf("\tbound_to_all\t\t%d\n", sctp
->sctp_bound_to_all
);
586 mdb_printf("\tcansleep\t\t%d\n", sctp
->sctp_cansleep
);
587 mdb_printf("\tdetached\t\t%d\n", sctp
->sctp_detached
);
588 mdb_printf("\tsend_adaptation\t\t%d\n", sctp
->sctp_send_adaptation
);
590 mdb_printf("\trecv_adaptation\t\t%d\n", sctp
->sctp_recv_adaptation
);
591 mdb_printf("\tndelay\t\t\t%d\n", sctp
->sctp_ndelay
);
592 mdb_printf("\tcondemned\t\t%d\n", sctp
->sctp_condemned
);
593 mdb_printf("\tchk_fast_rexmit\t\t%d\n", sctp
->sctp_chk_fast_rexmit
);
595 mdb_printf("\tprsctp_aware\t\t%d\n", sctp
->sctp_prsctp_aware
);
596 mdb_printf("\tlinklocal\t\t%d\n", sctp
->sctp_linklocal
);
597 mdb_printf("\trexmitting\t\t%d\n", sctp
->sctp_rexmitting
);
598 mdb_printf("\tzero_win_probe\t\t%d\n", sctp
->sctp_zero_win_probe
);
600 mdb_printf("\trecvsndrcvinfo\t\t%d\n", sctp
->sctp_recvsndrcvinfo
);
601 mdb_printf("\trecvassocevnt\t\t%d\n", sctp
->sctp_recvassocevnt
);
602 mdb_printf("\trecvpathevnt\t\t%d\n", sctp
->sctp_recvpathevnt
);
603 mdb_printf("\trecvsendfailevnt\t%d\n", sctp
->sctp_recvsendfailevnt
);
605 mdb_printf("\trecvpeerevnt\t\t%d\n", sctp
->sctp_recvpeererr
);
606 mdb_printf("\trecvchutdownevnt\t%d\n", sctp
->sctp_recvshutdownevnt
);
607 mdb_printf("\trecvcpdnevnt\t\t%d\n", sctp
->sctp_recvpdevnt
);
608 mdb_printf("\trecvcalevnt\t\t%d\n\n", sctp
->sctp_recvalevnt
);
612 * Given a sctp_saddr_ipif_t, print out its address. This assumes
613 * that addr contains the sctp_addr_ipif_t structure already and this
614 * function does not need to read it in.
618 print_saddr(uintptr_t ptr
, const void *addr
, void *cbdata
)
620 sctp_saddr_ipif_t
*saddr
= (sctp_saddr_ipif_t
*)addr
;
624 /* Read in the sctp_ipif object */
625 if (mdb_vread(&ipif
, sizeof (ipif
), (uintptr_t)saddr
->saddr_ipifp
) ==
627 mdb_warn("cannot read ipif at %p", saddr
->saddr_ipifp
);
631 switch (ipif
.sctp_ipif_state
) {
632 case SCTP_IPIFS_CONDEMNED
:
633 statestr
= "Condemned";
635 case SCTP_IPIFS_INVALID
:
636 statestr
= "Invalid";
638 case SCTP_IPIFS_DOWN
:
645 statestr
= "Unknown";
648 mdb_printf("\t%p\t%N% (%s", saddr
->saddr_ipifp
, &ipif
.sctp_ipif_saddr
,
650 if (saddr
->saddr_ipif_dontsrc
== 1)
651 mdb_printf("/Dontsrc");
652 if (saddr
->saddr_ipif_unconfirmed
== 1)
653 mdb_printf("/Unconfirmed");
654 if (saddr
->saddr_ipif_delete_pending
== 1)
655 mdb_printf("/DeletePending");
657 mdb_printf("\t\t\tid %d zoneid %d IPIF flags %x\n",
659 ipif
.sctp_ipif_zoneid
, ipif
.sctp_ipif_flags
);
664 * Given a sctp_faddr_t, print out its address. This assumes that
665 * addr contains the sctp_faddr_t structure already and this function
666 * does not need to read it in.
669 print_faddr(uintptr_t ptr
, const void *addr
, void *cbdata
)
672 sctp_faddr_t
*faddr
= (sctp_faddr_t
*)addr
;
675 statestr
= sctp_faddr_state(faddr
->sf_state
);
677 mdb_printf("\t%d:\t%N\t%?p (%s)\n", (*i
)++, &faddr
->sf_faddr
, ptr
,
683 sctp(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
686 conn_t conns
, *connp
;
690 in_port_t lport
, fport
;
692 if (!(flags
& DCMD_ADDRSPEC
))
695 if (mdb_vread(&sctps
, sizeof (sctps
), addr
) == -1) {
696 mdb_warn("failed to read sctp_t at: %p\n", addr
);
701 if (mdb_vread(&conns
, sizeof (conns
),
702 (uintptr_t)sctp
->sctp_connp
) == -1) {
703 mdb_warn("failed to read conn_t at: %p\n", sctp
->sctp_connp
);
709 connp
->conn_sctp
= sctp
;
710 sctp
->sctp_connp
= connp
;
712 if (mdb_getopts(argc
, argv
,
713 'a', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_ALL
, &opts
,
714 'f', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_FLAGS
, &opts
,
715 'h', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_HASH
, &opts
,
716 'o', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_OUT
, &opts
,
717 'i', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_IN
, &opts
,
718 'm', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_MISC
, &opts
,
719 'r', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_RTT
, &opts
,
720 'S', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_STATS
, &opts
,
721 'F', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_FLOW
, &opts
,
722 'H', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_HDR
, &opts
,
723 'p', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_PMTUD
, &opts
,
724 'R', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_RXT
, &opts
,
725 'C', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_CONN
, &opts
,
726 'c', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_CLOSE
, &opts
,
727 'e', MDB_OPT_SETBITS
, MDB_SCTP_SHOW_EXT
, &opts
,
728 'P', MDB_OPT_SETBITS
, 1, &paddr
,
729 'd', MDB_OPT_SETBITS
, MDB_SCTP_DUMP_ADDRS
, &opts
) != argc
) {
733 /* non-verbose faddrs, suitable for pipelines to sctp_faddr */
734 if (paddr
!= (uintptr_t)NULL
) {
735 sctp_faddr_t faddr
, *fp
;
736 for (fp
= sctp
->sctp_faddrs
; fp
!= NULL
; fp
= faddr
.sf_next
) {
737 if (mdb_vread(&faddr
, sizeof (faddr
), (uintptr_t)fp
)
739 mdb_warn("failed to read faddr at %p",
743 mdb_printf("%p\n", fp
);
748 mdb_nhconvert(&lport
, &connp
->conn_lport
, sizeof (lport
));
749 mdb_nhconvert(&fport
, &connp
->conn_fport
, sizeof (fport
));
750 mdb_printf("%<u>%p% %22s S=%-6hu D=%-6hu% STACK=%d ZONE=%d%</u>", addr
,
751 state2str(sctp
), lport
, fport
,
752 ns_to_stackid((uintptr_t)connp
->conn_netstack
), connp
->conn_zoneid
);
754 if (sctp
->sctp_faddrs
) {
756 if (mdb_vread(&faddr
, sizeof (faddr
),
757 (uintptr_t)sctp
->sctp_faddrs
) != -1)
758 mdb_printf("%<u> %N%</u>", &faddr
.sf_faddr
);
762 if (opts
& MDB_SCTP_DUMP_ADDRS
) {
763 mdb_printf("%<b>Local and Peer Addresses%</b>\n");
765 /* Display source addresses */
766 mdb_printf("nsaddrs\t\t%?d\n", sctp
->sctp_nsaddrs
);
767 (void) mdb_pwalk("sctp_walk_saddr", print_saddr
, NULL
, addr
);
769 /* Display peer addresses */
770 mdb_printf("nfaddrs\t\t%?d\n", sctp
->sctp_nfaddrs
);
772 (void) mdb_pwalk("sctp_walk_faddr", print_faddr
, &i
, addr
);
774 mdb_printf("lastfaddr\t%?p\tprimary\t\t%?p\n",
775 sctp
->sctp_lastfaddr
, sctp
->sctp_primary
);
776 mdb_printf("current\t\t%?p\tlastdata\t%?p\n",
777 sctp
->sctp_current
, sctp
->sctp_lastdata
);
780 if (opts
& MDB_SCTP_SHOW_OUT
) {
781 mdb_printf("%<b>Outbound Data%</b>\n");
782 mdb_printf("xmit_head\t%?p\txmit_tail\t%?p\n",
783 sctp
->sctp_xmit_head
, sctp
->sctp_xmit_tail
);
784 mdb_printf("xmit_unsent\t%?p\txmit_unsent_tail%?p\n",
785 sctp
->sctp_xmit_unsent
, sctp
->sctp_xmit_unsent_tail
);
786 mdb_printf("xmit_unacked\t%?p\n", sctp
->sctp_xmit_unacked
);
787 mdb_printf("unacked\t\t%?u\tunsent\t\t%?ld\n",
788 sctp
->sctp_unacked
, sctp
->sctp_unsent
);
789 mdb_printf("ltsn\t\t%?x\tlastack_rxd\t%?x\n",
790 sctp
->sctp_ltsn
, sctp
->sctp_lastack_rxd
);
791 mdb_printf("recovery_tsn\t%?x\tadv_pap\t\t%?x\n",
792 sctp
->sctp_recovery_tsn
, sctp
->sctp_adv_pap
);
793 mdb_printf("num_ostr\t%?hu\tostrcntrs\t%?p\n",
794 sctp
->sctp_num_ostr
, sctp
->sctp_ostrcntrs
);
795 mdb_printf("pad_mp\t\t%?p\terr_chunks\t%?p\n",
796 sctp
->sctp_pad_mp
, sctp
->sctp_err_chunks
);
797 mdb_printf("err_len\t\t%?u\n", sctp
->sctp_err_len
);
799 mdb_printf("%<b>Default Send Parameters%</b>\n");
800 mdb_printf("def_stream\t%?u\tdef_flags\t%?x\n",
801 sctp
->sctp_def_stream
, sctp
->sctp_def_flags
);
802 mdb_printf("def_ppid\t%?x\tdef_context\t%?x\n",
803 sctp
->sctp_def_ppid
, sctp
->sctp_def_context
);
804 mdb_printf("def_timetolive\t%?u\n",
805 sctp
->sctp_def_timetolive
);
808 if (opts
& MDB_SCTP_SHOW_IN
) {
809 mdb_printf("%<b>Inbound Data%</b>\n");
810 mdb_printf("sack_info\t%?p\tsack_gaps\t%?d\n",
811 sctp
->sctp_sack_info
, sctp
->sctp_sack_gaps
);
812 dump_sack_info((uintptr_t)sctp
->sctp_sack_info
);
813 mdb_printf("ftsn\t\t%?x\tlastacked\t%?x\n",
814 sctp
->sctp_ftsn
, sctp
->sctp_lastacked
);
815 mdb_printf("istr_nmsgs\t%?d\tsack_toggle\t%?d\n",
816 sctp
->sctp_istr_nmsgs
, sctp
->sctp_sack_toggle
);
817 mdb_printf("ack_mp\t\t%?p\n", sctp
->sctp_ack_mp
);
818 mdb_printf("num_istr\t%?hu\tinstr\t\t%?p\n",
819 sctp
->sctp_num_istr
, sctp
->sctp_instr
);
820 mdb_printf("unord_reass\t%?p\n", sctp
->sctp_uo_frags
);
823 if (opts
& MDB_SCTP_SHOW_RTT
) {
824 mdb_printf("%<b>RTT Tracking%</b>\n");
825 mdb_printf("rtt_tsn\t\t%?x\tout_time\t%?ld\n",
826 sctp
->sctp_rtt_tsn
, sctp
->sctp_out_time
);
829 if (opts
& MDB_SCTP_SHOW_FLOW
) {
830 mdb_printf("%<b>Flow Control%</b>\n");
831 mdb_printf("tconn_sndbuf\t%?d\n"
832 "conn_sndlowat\t%?d\tfrwnd\t\t%?u\n"
833 "rwnd\t\t%?u\tlast advertised rwnd\t%?u\n"
834 "rxqueued\t%?u\tcwnd_max\t%?u\n", connp
->conn_sndbuf
,
835 connp
->conn_sndlowat
, sctp
->sctp_frwnd
,
836 sctp
->sctp_rwnd
, sctp
->sctp_arwnd
, sctp
->sctp_rxqueued
,
837 sctp
->sctp_cwnd_max
);
840 if (opts
& MDB_SCTP_SHOW_HDR
) {
841 mdb_printf("%<b>Composite Headers%</b>\n");
842 mdb_printf("iphc\t\t%?p\tiphc6\t\t%?p\n"
843 "iphc_len\t%?d\tiphc6_len\t%?d\n"
844 "hdr_len\t\t%?d\thdr6_len\t%?d\n"
845 "ipha\t\t%?p\tip6h\t\t%?p\n"
846 "ip_hdr_len\t%?d\tip_hdr6_len\t%?d\n"
847 "sctph\t\t%?p\tsctph6\t\t%?p\n"
848 "lvtag\t\t%?x\tfvtag\t\t%?x\n", sctp
->sctp_iphc
,
849 sctp
->sctp_iphc6
, sctp
->sctp_iphc_len
,
850 sctp
->sctp_iphc6_len
, sctp
->sctp_hdr_len
,
851 sctp
->sctp_hdr6_len
, sctp
->sctp_ipha
, sctp
->sctp_ip6h
,
852 sctp
->sctp_ip_hdr_len
, sctp
->sctp_ip_hdr6_len
,
853 sctp
->sctp_sctph
, sctp
->sctp_sctph6
, sctp
->sctp_lvtag
,
857 if (opts
& MDB_SCTP_SHOW_PMTUD
) {
858 mdb_printf("%<b>PMTUd%</b>\n");
859 mdb_printf("last_mtu_probe\t%?ld\tmtu_probe_intvl\t%?ld\n"
861 sctp
->sctp_last_mtu_probe
, sctp
->sctp_mtu_probe_intvl
,
865 if (opts
& MDB_SCTP_SHOW_RXT
) {
866 mdb_printf("%<b>Retransmit Info%</b>\n");
867 mdb_printf("cookie_mp\t%?p\tstrikes\t\t%?d\n"
868 "max_init_rxt\t%?d\tpa_max_rxt\t%?d\n"
869 "pp_max_rxt\t%?d\trto_max\t\t%?u\n"
870 "rto_min\t\t%?u\trto_initial\t%?u\n"
871 "init_rto_max\t%?u\n"
872 "rxt_nxttsn\t%?u\trxt_maxtsn\t%?u\n", sctp
->sctp_cookie_mp
,
873 sctp
->sctp_strikes
, sctp
->sctp_max_init_rxt
,
874 sctp
->sctp_pa_max_rxt
, sctp
->sctp_pp_max_rxt
,
875 sctp
->sctp_rto_max
, sctp
->sctp_rto_min
,
876 sctp
->sctp_rto_initial
, sctp
->sctp_rto_max_init
,
877 sctp
->sctp_rxt_nxttsn
, sctp
->sctp_rxt_maxtsn
);
880 if (opts
& MDB_SCTP_SHOW_CONN
) {
881 mdb_printf("%<b>Connection State%</b>\n");
882 mdb_printf("last_secret_update%?ld\n",
883 sctp
->sctp_last_secret_update
);
885 mdb_printf("secret\t\t");
886 for (i
= 0; i
< SCTP_SECRET_LEN
; i
++) {
888 mdb_printf("0x%02x", sctp
->sctp_secret
[i
]);
890 mdb_printf("%02x ", sctp
->sctp_secret
[i
]);
893 mdb_printf("old_secret\t");
894 for (i
= 0; i
< SCTP_SECRET_LEN
; i
++) {
896 mdb_printf("0x%02x", sctp
->sctp_old_secret
[i
]);
898 mdb_printf("%02x ", sctp
->sctp_old_secret
[i
]);
903 if (opts
& MDB_SCTP_SHOW_STATS
) {
904 mdb_printf("%<b>Stats Counters%</b>\n");
905 mdb_printf("opkts\t\t%?llu\tobchunks\t%?llu\n"
906 "odchunks\t%?llu\toudchunks\t%?llu\n"
907 "rxtchunks\t%?llu\tT1expire\t%?lu\n"
908 "T2expire\t%?lu\tT3expire\t%?lu\n"
909 "msgcount\t%?llu\tprsctpdrop\t%?llu\n"
910 "AssocStartTime\t%?lu\n",
911 sctp
->sctp_opkts
, sctp
->sctp_obchunks
,
912 sctp
->sctp_odchunks
, sctp
->sctp_oudchunks
,
913 sctp
->sctp_rxtchunks
, sctp
->sctp_T1expire
,
914 sctp
->sctp_T2expire
, sctp
->sctp_T3expire
,
915 sctp
->sctp_msgcount
, sctp
->sctp_prsctpdrop
,
916 sctp
->sctp_assoc_start_time
);
917 mdb_printf("ipkts\t\t%?llu\tibchunks\t%?llu\n"
918 "idchunks\t%?llu\tiudchunks\t%?llu\n"
919 "fragdmsgs\t%?llu\treassmsgs\t%?llu\n",
920 sctp
->sctp_ipkts
, sctp
->sctp_ibchunks
,
921 sctp
->sctp_idchunks
, sctp
->sctp_iudchunks
,
922 sctp
->sctp_fragdmsgs
, sctp
->sctp_reassmsgs
);
925 if (opts
& MDB_SCTP_SHOW_HASH
) {
926 mdb_printf("%<b>Hash Tables%</b>\n");
927 mdb_printf("conn_hash_next\t%?p\t", sctp
->sctp_conn_hash_next
);
928 mdb_printf("conn_hash_prev\t%?p\n", sctp
->sctp_conn_hash_prev
);
930 mdb_printf("listen_hash_next%?p\t",
931 sctp
->sctp_listen_hash_next
);
932 mdb_printf("listen_hash_prev%?p\n",
933 sctp
->sctp_listen_hash_prev
);
934 mdb_nhconvert(&lport
, &connp
->conn_lport
, sizeof (lport
));
935 mdb_printf("[ listen_hash bucket\t%?d ]\n",
936 SCTP_LISTEN_HASH(lport
));
938 mdb_printf("conn_tfp\t%?p\t", sctp
->sctp_conn_tfp
);
939 mdb_printf("listen_tfp\t%?p\n", sctp
->sctp_listen_tfp
);
941 mdb_printf("bind_hash\t%?p\tptpbhn\t\t%?p\n",
942 sctp
->sctp_bind_hash
, sctp
->sctp_ptpbhn
);
943 mdb_printf("bind_lockp\t%?p\n",
944 sctp
->sctp_bind_lockp
);
945 mdb_printf("[ bind_hash bucket\t%?d ]\n",
946 SCTP_BIND_HASH(lport
));
949 if (opts
& MDB_SCTP_SHOW_CLOSE
) {
950 mdb_printf("%<b>Cleanup / Close%</b>\n");
951 mdb_printf("shutdown_faddr\t%?p\tclient_errno\t%?d\n"
952 "lingertime\t%?d\trefcnt\t\t%?hu\n",
953 sctp
->sctp_shutdown_faddr
, sctp
->sctp_client_errno
,
954 connp
->conn_lingertime
, sctp
->sctp_refcnt
);
957 if (opts
& MDB_SCTP_SHOW_MISC
) {
958 mdb_printf("%<b>Miscellaneous%</b>\n");
959 mdb_printf("bound_if\t%?u\theartbeat_mp\t%?p\n"
960 "family\t\t%?u\tipversion\t%?hu\n"
961 "hb_interval\t%?u\tautoclose\t%?d\n"
962 "active\t\t%?ld\ttx_adaptation_code%?x\n"
963 "rx_adaptation_code%?x\ttimer_mp\t%?p\n"
964 "partial_delivery_point\t%?d\n",
965 connp
->conn_bound_if
, sctp
->sctp_heartbeat_mp
,
967 connp
->conn_ipversion
,
968 sctp
->sctp_hb_interval
, sctp
->sctp_autoclose
,
969 sctp
->sctp_active
, sctp
->sctp_tx_adaptation_code
,
970 sctp
->sctp_rx_adaptation_code
, sctp
->sctp_timer_mp
,
971 sctp
->sctp_pd_point
);
974 if (opts
& MDB_SCTP_SHOW_EXT
) {
975 mdb_printf("%<b>Extensions and Reliable Ctl Chunks%</b>\n");
976 mdb_printf("cxmit_list\t%?p\tlcsn\t\t%?x\n"
977 "fcsn\t\t%?x\n", sctp
->sctp_cxmit_list
, sctp
->sctp_lcsn
,
981 if (opts
& MDB_SCTP_SHOW_FLAGS
) {
982 mdb_printf("%<b>Flags%</b>\n");
983 show_sctp_flags(sctp
);
989 typedef struct fanout_walk_data
{
994 uintptr_t (*getnext
)(sctp_t
*);
995 } fanout_walk_data_t
;
997 typedef struct fanout_init
{
998 const char *nested_walker_name
;
999 size_t offset
; /* for what used to be a symbol */
1000 int (*getsize
)(sctp_stack_t
*);
1001 uintptr_t (*getnext
)(sctp_t
*);
1005 listen_next(sctp_t
*sctp
)
1007 return ((uintptr_t)sctp
->sctp_listen_hash_next
);
1012 listen_size(sctp_stack_t
*sctps
)
1014 return (SCTP_LISTEN_FANOUT_SIZE
);
1018 conn_next(sctp_t
*sctp
)
1020 return ((uintptr_t)sctp
->sctp_conn_hash_next
);
1024 conn_size(sctp_stack_t
*sctps
)
1029 kaddr
= (uintptr_t)&sctps
->sctps_conn_hash_size
;
1031 if (mdb_vread(&size
, sizeof (size
), kaddr
) == -1) {
1032 mdb_warn("can't read 'sctps_conn_hash_size' at %p", kaddr
);
1039 bind_next(sctp_t
*sctp
)
1041 return ((uintptr_t)sctp
->sctp_bind_hash
);
1046 bind_size(sctp_stack_t
*sctps
)
1048 return (SCTP_BIND_FANOUT_SIZE
);
1052 find_next_hash_item(fanout_walk_data_t
*fw
)
1057 /* first try to continue down the hash chain */
1058 if (fw
->sctp
!= (uintptr_t)NULL
) {
1059 /* try to get next in hash chain */
1060 if (mdb_vread(&sctp
, sizeof (sctp
), fw
->sctp
) == -1) {
1061 mdb_warn("failed to read sctp at %p", fw
->sctp
);
1062 return ((uintptr_t)NULL
);
1064 fw
->sctp
= fw
->getnext(&sctp
);
1065 if (fw
->sctp
!= (uintptr_t)NULL
)
1068 /* end of chain; go to next bucket */
1072 /* find a new hash chain, traversing the buckets */
1073 for (; fw
->index
< fw
->size
; fw
->index
++) {
1074 /* read the current hash line for an sctp */
1075 if (mdb_vread(&tf
, sizeof (tf
),
1076 (uintptr_t)(fw
->fanout
+ fw
->index
)) == -1) {
1077 mdb_warn("failed to read tf at %p",
1078 fw
->fanout
+ fw
->index
);
1079 return ((uintptr_t)NULL
);
1081 if (tf
.tf_sctp
!= NULL
) {
1082 /* start of a new chain */
1083 fw
->sctp
= (uintptr_t)tf
.tf_sctp
;
1087 return ((uintptr_t)NULL
);
1091 fanout_stack_walk_init(mdb_walk_state_t
*wsp
)
1093 fanout_walk_data_t
*lw
;
1094 fanout_init_t
*fi
= wsp
->walk_arg
;
1095 sctp_stack_t
*sctps
= (sctp_stack_t
*)wsp
->walk_addr
;
1098 if (mdb_vread(&kaddr
, sizeof (kaddr
),
1099 wsp
->walk_addr
+ fi
->offset
) == -1) {
1100 mdb_warn("can't read sctp fanout at %p",
1101 wsp
->walk_addr
+ fi
->offset
);
1105 lw
= mdb_alloc(sizeof (*lw
), UM_SLEEP
);
1107 lw
->size
= fi
->getsize(sctps
);
1108 lw
->sctp
= (uintptr_t)NULL
;
1109 lw
->fanout
= (sctp_tf_t
*)kaddr
;
1110 lw
->getnext
= fi
->getnext
;
1112 if ((wsp
->walk_addr
= find_next_hash_item(lw
)) == (uintptr_t)NULL
) {
1115 wsp
->walk_data
= lw
;
1120 fanout_stack_walk_step(mdb_walk_state_t
*wsp
)
1122 fanout_walk_data_t
*fw
= wsp
->walk_data
;
1123 uintptr_t addr
= wsp
->walk_addr
;
1127 if (mdb_vread(&sctp
, sizeof (sctp
), addr
) == -1) {
1128 mdb_warn("failed to read sctp at %p", addr
);
1132 status
= wsp
->walk_callback(addr
, &sctp
, wsp
->walk_cbdata
);
1133 if (status
!= WALK_NEXT
)
1136 if ((wsp
->walk_addr
= find_next_hash_item(fw
)) == (uintptr_t)NULL
)
1143 fanout_stack_walk_fini(mdb_walk_state_t
*wsp
)
1145 fanout_walk_data_t
*fw
= wsp
->walk_data
;
1147 mdb_free(fw
, sizeof (*fw
));
1151 fanout_walk_init(mdb_walk_state_t
*wsp
)
1153 if (mdb_layered_walk("sctp_stacks", wsp
) == -1) {
1154 mdb_warn("can't walk 'sctp_stacks'");
1162 fanout_walk_step(mdb_walk_state_t
*wsp
)
1164 fanout_init_t
*fi
= wsp
->walk_arg
;
1166 if (mdb_pwalk(fi
->nested_walker_name
, wsp
->walk_callback
,
1167 wsp
->walk_cbdata
, wsp
->walk_addr
) == -1) {
1168 mdb_warn("couldn't walk '%s'for address %p",
1169 fi
->nested_walker_name
, wsp
->walk_addr
);
1176 sctps_walk_init(mdb_walk_state_t
*wsp
)
1179 if (mdb_layered_walk("sctp_stacks", wsp
) == -1) {
1180 mdb_warn("can't walk 'sctp_stacks'");
1188 sctps_walk_step(mdb_walk_state_t
*wsp
)
1192 kaddr
= wsp
->walk_addr
+ OFFSETOF(sctp_stack_t
, sctps_g_list
);
1193 if (mdb_pwalk("list", wsp
->walk_callback
,
1194 wsp
->walk_cbdata
, kaddr
) == -1) {
1195 mdb_warn("couldn't walk 'list' for address %p", kaddr
);
1202 sctp_walk_faddr_init(mdb_walk_state_t
*wsp
)
1206 if (wsp
->walk_addr
== (uintptr_t)NULL
)
1209 if (mdb_vread(&sctp
, sizeof (sctp
), wsp
->walk_addr
) == -1) {
1210 mdb_warn("failed to read sctp at %p", wsp
->walk_addr
);
1213 if ((wsp
->walk_addr
= (uintptr_t)sctp
.sctp_faddrs
) != (uintptr_t)NULL
)
1220 sctp_walk_faddr_step(mdb_walk_state_t
*wsp
)
1222 uintptr_t faddr_ptr
= wsp
->walk_addr
;
1223 sctp_faddr_t sctp_faddr
;
1226 if (mdb_vread(&sctp_faddr
, sizeof (sctp_faddr_t
), faddr_ptr
) == -1) {
1227 mdb_warn("failed to read sctp_faddr_t at %p", faddr_ptr
);
1230 status
= wsp
->walk_callback(faddr_ptr
, &sctp_faddr
, wsp
->walk_cbdata
);
1231 if (status
!= WALK_NEXT
)
1233 if ((faddr_ptr
= (uintptr_t)sctp_faddr
.sf_next
) == (uintptr_t)NULL
) {
1236 wsp
->walk_addr
= faddr_ptr
;
1242 * Helper structure for sctp_walk_saddr. It stores the sctp_t being walked,
1243 * the current index to the sctp_saddrs[], and the current count of the
1244 * sctp_saddr_ipif_t list.
1253 sctp_walk_saddr_init(mdb_walk_state_t
*wsp
)
1257 saddr_walk_t
*swalker
;
1259 if (wsp
->walk_addr
== (uintptr_t)NULL
)
1262 swalker
= mdb_alloc(sizeof (saddr_walk_t
), UM_SLEEP
);
1263 sctp
= &swalker
->sctp
;
1264 if (mdb_vread(sctp
, sizeof (sctp_t
), wsp
->walk_addr
) == -1) {
1265 mdb_warn("failed to read sctp at %p", wsp
->walk_addr
);
1266 mdb_free(swalker
, sizeof (saddr_walk_t
));
1270 /* Find the first source address. */
1271 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++) {
1272 if (sctp
->sctp_saddrs
[i
].ipif_count
> 0) {
1275 addr_list
= &sctp
->sctp_saddrs
[i
].sctp_ipif_list
;
1276 wsp
->walk_addr
= (uintptr_t)list_object(addr_list
,
1277 addr_list
->list_head
.list_next
);
1279 /* Recode the current info */
1280 swalker
->hash_index
= i
;
1281 swalker
->cur_cnt
= 1;
1282 wsp
->walk_data
= swalker
;
1291 sctp_walk_saddr_step(mdb_walk_state_t
*wsp
)
1293 uintptr_t saddr_ptr
= wsp
->walk_addr
;
1294 sctp_saddr_ipif_t saddr
;
1295 saddr_walk_t
*swalker
;
1300 if (mdb_vread(&saddr
, sizeof (sctp_saddr_ipif_t
), saddr_ptr
) == -1) {
1301 mdb_warn("failed to read sctp_saddr_ipif_t at %p", saddr_ptr
);
1304 status
= wsp
->walk_callback(saddr_ptr
, &saddr
, wsp
->walk_cbdata
);
1305 if (status
!= WALK_NEXT
)
1308 swalker
= (saddr_walk_t
*)wsp
->walk_data
;
1309 sctp
= &swalker
->sctp
;
1310 i
= swalker
->hash_index
;
1311 j
= swalker
->cur_cnt
;
1314 * If there is still a source address in the current list, return it.
1315 * Otherwise, go to the next list in the sctp_saddrs[].
1317 if (j
++ < sctp
->sctp_saddrs
[i
].ipif_count
) {
1318 wsp
->walk_addr
= (uintptr_t)saddr
.saddr_ipif
.list_next
;
1319 swalker
->cur_cnt
= j
;
1324 for (i
= i
+ 1; i
< SCTP_IPIF_HASH
; i
++) {
1325 if (sctp
->sctp_saddrs
[i
].ipif_count
> 0) {
1326 lst
= &sctp
->sctp_saddrs
[i
].sctp_ipif_list
;
1327 wsp
->walk_addr
= (uintptr_t)list_object(
1328 lst
, lst
->list_head
.list_next
);
1329 swalker
->hash_index
= i
;
1330 swalker
->cur_cnt
= 1;
1339 sctp_walk_saddr_fini(mdb_walk_state_t
*wsp
)
1341 saddr_walk_t
*swalker
= (saddr_walk_t
*)wsp
->walk_data
;
1343 mdb_free(swalker
, sizeof (saddr_walk_t
));
1347 typedef struct ill_walk_data
{
1348 sctp_ill_hash_t ills
[SCTP_ILL_HASH
];
1352 typedef struct ipuf_walk_data
{
1353 sctp_ipif_hash_t ipifs
[SCTP_IPIF_HASH
];
1359 sctp_ill_walk_init(mdb_walk_state_t
*wsp
)
1361 if (mdb_layered_walk("sctp_stacks", wsp
) == -1) {
1362 mdb_warn("can't walk 'sctp_stacks'");
1370 sctp_ill_walk_step(mdb_walk_state_t
*wsp
)
1372 if (mdb_pwalk("sctp_stack_walk_ill", wsp
->walk_callback
,
1373 wsp
->walk_cbdata
, wsp
->walk_addr
) == -1) {
1374 mdb_warn("couldn't walk 'sctp_stack_walk_ill' for addr %p",
1382 * wsp->walk_addr is the address of sctps_ill_list
1385 sctp_stack_ill_walk_init(mdb_walk_state_t
*wsp
)
1389 uintptr_t kaddr
, uaddr
;
1392 kaddr
= wsp
->walk_addr
+ OFFSETOF(sctp_stack_t
, sctps_ills_count
);
1393 if (mdb_vread(&iw
.count
, sizeof (iw
.count
), kaddr
) == -1) {
1394 mdb_warn("can't read sctps_ills_count at %p", kaddr
);
1397 kaddr
= wsp
->walk_addr
+ OFFSETOF(sctp_stack_t
, sctps_g_ills
);
1399 if (mdb_vread(&kaddr
, sizeof (kaddr
), kaddr
) == -1) {
1400 mdb_warn("can't read scpts_g_ills %p", kaddr
);
1403 if (mdb_vread(&iw
.ills
, sizeof (iw
.ills
), kaddr
) == -1) {
1404 mdb_warn("failed to read 'sctps_g_ills'");
1408 /* Find the first ill. */
1409 for (i
= 0; i
< SCTP_ILL_HASH
; i
++) {
1410 if (iw
.ills
[i
].ill_count
> 0) {
1411 uaddr
= (uintptr_t)&iw
.ills
[i
].sctp_ill_list
;
1412 offset
= uaddr
- (uintptr_t)&iw
.ills
;
1413 if (mdb_pwalk("list", wsp
->walk_callback
,
1414 wsp
->walk_cbdata
, kaddr
+offset
) == -1) {
1415 mdb_warn("couldn't walk 'list' for address %p",
1425 sctp_stack_ill_walk_step(mdb_walk_state_t
*wsp
)
1427 return (wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_layer
,
1432 sctp_ipif_walk_init(mdb_walk_state_t
*wsp
)
1434 if (mdb_layered_walk("sctp_stacks", wsp
) == -1) {
1435 mdb_warn("can't walk 'sctp_stacks'");
1442 sctp_ipif_walk_step(mdb_walk_state_t
*wsp
)
1444 if (mdb_pwalk("sctp_stack_walk_ipif", wsp
->walk_callback
,
1445 wsp
->walk_cbdata
, wsp
->walk_addr
) == -1) {
1446 mdb_warn("couldn't walk 'sctp_stack_walk_ipif' for addr %p",
1454 * wsp->walk_addr is the address of sctps_ipif_list
1457 sctp_stack_ipif_walk_init(mdb_walk_state_t
*wsp
)
1459 ipif_walk_data_t iw
;
1461 uintptr_t kaddr
, uaddr
;
1464 kaddr
= wsp
->walk_addr
+ OFFSETOF(sctp_stack_t
, sctps_g_ipifs_count
);
1465 if (mdb_vread(&iw
.count
, sizeof (iw
.count
), kaddr
) == -1) {
1466 mdb_warn("can't read sctps_g_ipifs_count at %p", kaddr
);
1469 kaddr
= wsp
->walk_addr
+ OFFSETOF(sctp_stack_t
, sctps_g_ipifs
);
1471 if (mdb_vread(&kaddr
, sizeof (kaddr
), kaddr
) == -1) {
1472 mdb_warn("can't read scpts_g_ipifs %p", kaddr
);
1475 if (mdb_vread(&iw
.ipifs
, sizeof (iw
.ipifs
), kaddr
) == -1) {
1476 mdb_warn("failed to read 'sctps_g_ipifs'");
1480 /* Find the first ipif. */
1481 for (i
= 0; i
< SCTP_IPIF_HASH
; i
++) {
1482 if (iw
.ipifs
[i
].ipif_count
> 0) {
1483 uaddr
= (uintptr_t)&iw
.ipifs
[i
].sctp_ipif_list
;
1484 offset
= uaddr
- (uintptr_t)&iw
.ipifs
;
1485 if (mdb_pwalk("list", wsp
->walk_callback
,
1486 wsp
->walk_cbdata
, kaddr
+offset
) == -1) {
1487 mdb_warn("couldn't walk 'list' for address %p",
1497 sctp_stack_ipif_walk_step(mdb_walk_state_t
*wsp
)
1499 return (wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_layer
,
1504 * Initialization function for the per CPU SCTP stats counter walker of a given
1508 sctps_sc_walk_init(mdb_walk_state_t
*wsp
)
1512 if (wsp
->walk_addr
== (uintptr_t)NULL
)
1515 if (mdb_vread(&sctps
, sizeof (sctps
), wsp
->walk_addr
) == -1) {
1516 mdb_warn("failed to read sctp_stack_t at %p", wsp
->walk_addr
);
1519 if (sctps
.sctps_sc_cnt
== 0)
1523 * Store the sctp_stack_t pointer in walk_data. The stepping function
1524 * used it to calculate if the end of the counter has reached.
1526 wsp
->walk_data
= (void *)wsp
->walk_addr
;
1527 wsp
->walk_addr
= (uintptr_t)sctps
.sctps_sc
;
1532 * Stepping function for the per CPU SCTP stats counterwalker.
1535 sctps_sc_walk_step(mdb_walk_state_t
*wsp
)
1539 sctp_stats_cpu_t
*stats
;
1542 if (mdb_vread(&sctps
, sizeof (sctps
), (uintptr_t)wsp
->walk_data
) ==
1544 mdb_warn("failed to read sctp_stack_t at %p", wsp
->walk_addr
);
1547 if (mdb_vread(&stats
, sizeof (stats
), wsp
->walk_addr
) == -1) {
1548 mdb_warn("failed ot read sctp_stats_cpu_t at %p",
1552 status
= wsp
->walk_callback((uintptr_t)stats
, &stats
, wsp
->walk_cbdata
);
1553 if (status
!= WALK_NEXT
)
1556 next
= (char *)wsp
->walk_addr
+ sizeof (sctp_stats_cpu_t
*);
1557 end
= (char *)sctps
.sctps_sc
+ sctps
.sctps_sc_cnt
*
1558 sizeof (sctp_stats_cpu_t
*);
1561 wsp
->walk_addr
= (uintptr_t)next
;
1568 mdb_printf("Print information for a given SCTP sctp_t\n\n");
1569 mdb_printf("Options:\n");
1570 mdb_printf("\t-a\t All the information\n");
1571 mdb_printf("\t-f\t Flags\n");
1572 mdb_printf("\t-h\t Hash Tables\n");
1573 mdb_printf("\t-o\t Outbound Data\n");
1574 mdb_printf("\t-i\t Inbound Data\n");
1575 mdb_printf("\t-m\t Miscellaneous Information\n");
1576 mdb_printf("\t-r\t RTT Tracking\n");
1577 mdb_printf("\t-S\t Stats Counters\n");
1578 mdb_printf("\t-F\t Flow Control\n");
1579 mdb_printf("\t-H\t Composite Headers\n");
1580 mdb_printf("\t-p\t PMTUD\n");
1581 mdb_printf("\t-R\t Retransmit Information\n");
1582 mdb_printf("\t-C\t Connection State\n");
1583 mdb_printf("\t-c\t Cleanup / Close\n");
1584 mdb_printf("\t-e\t Extensions and Reliable Control Chunks\n");
1585 mdb_printf("\t-d\t Local and Peer addresses\n");
1586 mdb_printf("\t-P\t Peer addresses\n");
1589 static const mdb_dcmd_t dcmds
[] = {
1590 { "sctp", ":[-afhoimrSFHpRCcedP]",
1591 "display sctp control structure", sctp
, sctp_help
},
1592 { "sctp_set", ":", "display a SCTP set", sctp_set
},
1593 { "sctp_faddr", ":", "display a faddr", sctp_faddr
},
1594 { "sctp_istr_msgs", ":", "display msg list on an instream",
1596 { "sctp_mdata_chunk", ":", "display a data chunk in an mblk",
1598 { "sctp_xmit_list", ":", "display sctp xmit lists", sctp_xmit_list
},
1599 { "sctp_instr", ":", "display instr", sctp_instr
},
1600 { "sctp_reass_list", ":", "display reass list", sctp_reass_list
},
1601 { "sctp_uo_reass_list", ":", "display un-ordered reass list",
1602 sctp_uo_reass_list
},
1606 static const fanout_init_t listen_fanout_init
= {
1607 "sctp_stack_listen_fanout", OFFSETOF(sctp_stack_t
, sctps_listen_fanout
),
1608 listen_size
, listen_next
1611 static const fanout_init_t conn_fanout_init
= {
1612 "sctp_stack_conn_fanout", OFFSETOF(sctp_stack_t
, sctps_conn_fanout
),
1613 conn_size
, conn_next
1616 static const fanout_init_t bind_fanout_init
= {
1617 "sctp_stack_bind_fanout", OFFSETOF(sctp_stack_t
, sctps_bind_fanout
),
1618 bind_size
, bind_next
1621 static const mdb_walker_t walkers
[] = {
1622 { "sctps", "walk the full chain of sctps for all stacks",
1623 sctps_walk_init
, sctps_walk_step
, NULL
},
1624 { "sctp_listen_fanout", "walk the sctp listen fanout for all stacks",
1625 fanout_walk_init
, fanout_walk_step
, NULL
,
1626 (void *)&listen_fanout_init
},
1627 { "sctp_conn_fanout", "walk the sctp conn fanout for all stacks",
1628 fanout_walk_init
, fanout_walk_step
, NULL
,
1629 (void *)&conn_fanout_init
},
1630 { "sctp_bind_fanout", "walk the sctp bind fanout for all stacks",
1631 fanout_walk_init
, fanout_walk_step
, NULL
,
1632 (void *)&bind_fanout_init
},
1633 { "sctp_stack_listen_fanout",
1634 "walk the sctp listen fanout for one stack",
1635 fanout_stack_walk_init
, fanout_stack_walk_step
,
1636 fanout_stack_walk_fini
,
1637 (void *)&listen_fanout_init
},
1638 { "sctp_stack_conn_fanout", "walk the sctp conn fanout for one stack",
1639 fanout_stack_walk_init
, fanout_stack_walk_step
,
1640 fanout_stack_walk_fini
,
1641 (void *)&conn_fanout_init
},
1642 { "sctp_stack_bind_fanout", "walk the sctp bind fanoutfor one stack",
1643 fanout_stack_walk_init
, fanout_stack_walk_step
,
1644 fanout_stack_walk_fini
,
1645 (void *)&bind_fanout_init
},
1646 { "sctp_walk_faddr", "walk the peer address list of a given sctp_t",
1647 sctp_walk_faddr_init
, sctp_walk_faddr_step
, NULL
},
1648 { "sctp_walk_saddr", "walk the local address list of a given sctp_t",
1649 sctp_walk_saddr_init
, sctp_walk_saddr_step
, sctp_walk_saddr_fini
},
1650 { "sctp_walk_ill", "walk the sctp_g_ills list for all stacks",
1651 sctp_ill_walk_init
, sctp_ill_walk_step
, NULL
},
1652 { "sctp_walk_ipif", "walk the sctp_g_ipif list for all stacks",
1653 sctp_ipif_walk_init
, sctp_ipif_walk_step
, NULL
},
1654 { "sctp_stack_walk_ill", "walk the sctp_g_ills list for one stack",
1655 sctp_stack_ill_walk_init
, sctp_stack_ill_walk_step
, NULL
},
1656 { "sctp_stack_walk_ipif", "walk the sctp_g_ipif list for one stack",
1657 sctp_stack_ipif_walk_init
, sctp_stack_ipif_walk_step
, NULL
},
1658 { "sctps_sc", "walk all the per CPU stats counters of a sctp_stack_t",
1659 sctps_sc_walk_init
, sctps_sc_walk_step
, NULL
},
1663 static const mdb_modinfo_t modinfo
= { MDB_API_VERSION
, dcmds
, walkers
};
1665 const mdb_modinfo_t
*