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]
22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #include <mdb/mdb_modapi.h>
27 #include <mdb/mdb_ks.h>
28 #include <mdb/mdb_ctf.h>
29 #include <sys/types.h>
30 #include <sys/tihdr.h>
32 #include <inet/common.h>
33 #include <netinet/in.h>
34 #include <netinet/ip6.h>
35 #include <netinet/icmp6.h>
38 #include <inet/ipclassifier.h>
40 #include <sys/stream.h>
42 #include <sys/stropts.h>
43 #include <sys/tpicommon.h>
44 #include <sys/socket.h>
45 #include <sys/socketvar.h>
46 #include <sys/cred_impl.h>
47 #include <inet/udp_impl.h>
48 #include <inet/rawip_impl.h>
50 #include <../../../../kernel/fs/sockfs/socktpi_impl.h>
51 #include <net/bridge_impl.h>
52 #include <io/trill_impl.h>
53 #include <sys/mac_impl.h>
55 #define ADDR_V6_WIDTH 23
56 #define ADDR_V4_WIDTH 15
58 #define NETSTAT_ALL 0x01
59 #define NETSTAT_VERBOSE 0x02
60 #define NETSTAT_ROUTE 0x04
61 #define NETSTAT_V4 0x08
62 #define NETSTAT_V6 0x10
63 #define NETSTAT_UNIX 0x20
65 #define NETSTAT_FIRST 0x80000000u
67 typedef struct netstat_cb_data_s
{
74 icmp_stacks_walk_init(mdb_walk_state_t
*wsp
)
76 if (mdb_layered_walk("netstack", wsp
) == -1) {
77 mdb_warn("can't walk 'netstack'");
84 icmp_stacks_walk_step(mdb_walk_state_t
*wsp
)
89 if (mdb_vread(&nss
, sizeof (nss
), wsp
->walk_addr
) == -1) {
90 mdb_warn("can't read netstack at %p", wsp
->walk_addr
);
93 kaddr
= (uintptr_t)nss
.netstack_modules
[NS_ICMP
];
94 return (wsp
->walk_callback(kaddr
, wsp
->walk_layer
, wsp
->walk_cbdata
));
98 tcp_stacks_walk_init(mdb_walk_state_t
*wsp
)
100 if (mdb_layered_walk("netstack", wsp
) == -1) {
101 mdb_warn("can't walk 'netstack'");
108 tcp_stacks_walk_step(mdb_walk_state_t
*wsp
)
113 if (mdb_vread(&nss
, sizeof (nss
), wsp
->walk_addr
) == -1) {
114 mdb_warn("can't read netstack at %p", wsp
->walk_addr
);
117 kaddr
= (uintptr_t)nss
.netstack_modules
[NS_TCP
];
118 return (wsp
->walk_callback(kaddr
, wsp
->walk_layer
, wsp
->walk_cbdata
));
122 udp_stacks_walk_init(mdb_walk_state_t
*wsp
)
124 if (mdb_layered_walk("netstack", wsp
) == -1) {
125 mdb_warn("can't walk 'netstack'");
132 udp_stacks_walk_step(mdb_walk_state_t
*wsp
)
137 if (mdb_vread(&nss
, sizeof (nss
), wsp
->walk_addr
) == -1) {
138 mdb_warn("can't read netstack at %p", wsp
->walk_addr
);
141 kaddr
= (uintptr_t)nss
.netstack_modules
[NS_UDP
];
142 return (wsp
->walk_callback(kaddr
, wsp
->walk_layer
, wsp
->walk_cbdata
));
146 * Print an IPv4 address and port number in a compact and easy to read format
147 * The arguments are in network byte order
150 net_ipv4addrport_pr(const in6_addr_t
*nipv6addr
, in_port_t nport
)
152 uint32_t naddr
= V4_PART_OF_V6((*nipv6addr
));
154 mdb_nhconvert(&nport
, &nport
, sizeof (nport
));
155 mdb_printf("%*I.%-5hu", ADDR_V4_WIDTH
, naddr
, nport
);
159 * Print an IPv6 address and port number in a compact and easy to read format
160 * The arguments are in network byte order
163 net_ipv6addrport_pr(const in6_addr_t
*naddr
, in_port_t nport
)
165 mdb_nhconvert(&nport
, &nport
, sizeof (nport
));
166 mdb_printf("%*N.%-5hu", ADDR_V6_WIDTH
, naddr
, nport
);
170 net_tcp_active(const tcp_t
*tcp
)
172 return (tcp
->tcp_state
>= TCPS_ESTABLISHED
);
176 net_tcp_ipv4(const tcp_t
*tcp
)
178 return ((tcp
->tcp_connp
->conn_ipversion
== IPV4_VERSION
) ||
179 (IN6_IS_ADDR_UNSPECIFIED(&tcp
->tcp_connp
->conn_laddr_v6
) &&
180 (tcp
->tcp_state
<= TCPS_LISTEN
)));
184 net_tcp_ipv6(const tcp_t
*tcp
)
186 return (tcp
->tcp_connp
->conn_ipversion
== IPV6_VERSION
);
190 net_udp_active(const udp_t
*udp
)
192 return ((udp
->udp_state
== TS_IDLE
) ||
193 (udp
->udp_state
== TS_DATA_XFER
));
197 net_udp_ipv4(const udp_t
*udp
)
199 return ((udp
->udp_connp
->conn_ipversion
== IPV4_VERSION
) ||
200 (IN6_IS_ADDR_UNSPECIFIED(&udp
->udp_connp
->conn_laddr_v6
) &&
201 (udp
->udp_state
<= TS_IDLE
)));
205 net_udp_ipv6(const udp_t
*udp
)
207 return (udp
->udp_connp
->conn_ipversion
== IPV6_VERSION
);
211 sonode_walk_init(mdb_walk_state_t
*wsp
)
213 if (wsp
->walk_addr
== (uintptr_t)NULL
) {
215 struct socklist
*slp
;
217 if (mdb_lookup_by_obj("sockfs", "socklist", &sym
) == -1) {
218 mdb_warn("failed to lookup sockfs`socklist");
222 slp
= (struct socklist
*)(uintptr_t)sym
.st_value
;
224 if (mdb_vread(&wsp
->walk_addr
, sizeof (wsp
->walk_addr
),
225 (uintptr_t)&slp
->sl_list
) == -1) {
226 mdb_warn("failed to read address of initial sonode "
227 "at %p", &slp
->sl_list
);
232 wsp
->walk_data
= mdb_alloc(sizeof (struct sotpi_sonode
), UM_SLEEP
);
237 sonode_walk_step(mdb_walk_state_t
*wsp
)
240 struct sotpi_sonode
*stp
;
242 if (wsp
->walk_addr
== (uintptr_t)NULL
)
245 if (mdb_vread(wsp
->walk_data
, sizeof (struct sotpi_sonode
),
246 wsp
->walk_addr
) == -1) {
247 mdb_warn("failed to read sonode at %p", wsp
->walk_addr
);
251 status
= wsp
->walk_callback(wsp
->walk_addr
, wsp
->walk_data
,
254 stp
= wsp
->walk_data
;
256 wsp
->walk_addr
= (uintptr_t)stp
->st_info
.sti_next_so
;
261 sonode_walk_fini(mdb_walk_state_t
*wsp
)
263 mdb_free(wsp
->walk_data
, sizeof (struct sotpi_sonode
));
266 struct mi_walk_data
{
267 uintptr_t mi_wd_miofirst
;
272 mi_walk_init(mdb_walk_state_t
*wsp
)
274 struct mi_walk_data
*wdp
;
276 if (wsp
->walk_addr
== (uintptr_t)NULL
) {
277 mdb_warn("mi doesn't support global walks\n");
281 wdp
= mdb_alloc(sizeof (struct mi_walk_data
), UM_SLEEP
);
283 /* So that we do not immediately return WALK_DONE below */
284 wdp
->mi_wd_miofirst
= (uintptr_t)NULL
;
286 wsp
->walk_data
= wdp
;
291 mi_walk_step(mdb_walk_state_t
*wsp
)
293 struct mi_walk_data
*wdp
= wsp
->walk_data
;
294 MI_OP miop
= &wdp
->mi_wd_miodata
;
297 /* Always false in the first iteration */
298 if ((wsp
->walk_addr
== (uintptr_t)NULL
) ||
299 (wsp
->walk_addr
== wdp
->mi_wd_miofirst
)) {
303 if (mdb_vread(miop
, sizeof (MI_O
), wsp
->walk_addr
) == -1) {
304 mdb_warn("failed to read MI object at %p", wsp
->walk_addr
);
308 /* Only true in the first iteration */
309 if (wdp
->mi_wd_miofirst
== (uintptr_t)NULL
) {
310 wdp
->mi_wd_miofirst
= wsp
->walk_addr
;
313 status
= wsp
->walk_callback(wsp
->walk_addr
+ sizeof (MI_O
),
314 &miop
[1], wsp
->walk_cbdata
);
317 wsp
->walk_addr
= (uintptr_t)miop
->mi_o_next
;
322 mi_walk_fini(mdb_walk_state_t
*wsp
)
324 mdb_free(wsp
->walk_data
, sizeof (struct mi_walk_data
));
327 typedef struct mi_payload_walk_arg_s
{
328 const char *mi_pwa_walker
; /* Underlying walker */
329 const off_t mi_pwa_head_off
; /* Offset for mi_o_head_t * in stack */
330 const size_t mi_pwa_size
; /* size of mi payload */
331 const uint_t mi_pwa_flags
; /* device and/or module */
332 } mi_payload_walk_arg_t
;
334 #define MI_PAYLOAD_DEVICE 0x1
335 #define MI_PAYLOAD_MODULE 0x2
338 mi_payload_walk_init(mdb_walk_state_t
*wsp
)
340 const mi_payload_walk_arg_t
*arg
= wsp
->walk_arg
;
342 if (mdb_layered_walk(arg
->mi_pwa_walker
, wsp
) == -1) {
343 mdb_warn("can't walk '%s'", arg
->mi_pwa_walker
);
350 mi_payload_walk_step(mdb_walk_state_t
*wsp
)
352 const mi_payload_walk_arg_t
*arg
= wsp
->walk_arg
;
355 kaddr
= wsp
->walk_addr
+ arg
->mi_pwa_head_off
;
357 if (mdb_vread(&kaddr
, sizeof (kaddr
), kaddr
) == -1) {
358 mdb_warn("can't read address of mi head at %p for %s",
359 kaddr
, arg
->mi_pwa_walker
);
363 if (kaddr
== (uintptr_t)NULL
) {
368 if (mdb_pwalk("genunix`mi", wsp
->walk_callback
,
369 wsp
->walk_cbdata
, kaddr
) == -1) {
370 mdb_warn("failed to walk genunix`mi");
376 const mi_payload_walk_arg_t mi_icmp_arg
= {
377 "icmp_stacks", OFFSETOF(icmp_stack_t
, is_head
), sizeof (icmp_t
),
378 MI_PAYLOAD_DEVICE
| MI_PAYLOAD_MODULE
382 sonode(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
384 const char *optf
= NULL
;
385 const char *optt
= NULL
;
386 const char *optp
= NULL
;
387 int family
, type
, proto
;
391 if (!(flags
& DCMD_ADDRSPEC
)) {
392 if (mdb_walk_dcmd("genunix`sonode", "genunix`sonode", argc
,
394 mdb_warn("failed to walk sonode");
401 if (mdb_getopts(argc
, argv
,
402 'f', MDB_OPT_STR
, &optf
,
403 't', MDB_OPT_STR
, &optt
,
404 'p', MDB_OPT_STR
, &optp
,
409 if (strcmp("inet", optf
) == 0)
411 else if (strcmp("inet6", optf
) == 0)
413 else if (strcmp("unix", optf
) == 0)
416 family
= mdb_strtoull(optf
);
421 if (strcmp("stream", optt
) == 0)
423 else if (strcmp("dgram", optt
) == 0)
425 else if (strcmp("raw", optt
) == 0)
428 type
= mdb_strtoull(optt
);
433 proto
= mdb_strtoull(optp
);
437 if (DCMD_HDRSPEC(flags
) && !filter
) {
438 mdb_printf("%<u>%-?s Family Type Proto State Mode Flag "
439 "AccessVP%</u>\n", "Sonode:");
442 if (mdb_vread(&so
, sizeof (so
), addr
) == -1) {
443 mdb_warn("failed to read sonode at %p", addr
);
447 if ((optf
!= NULL
) && (so
.so_family
!= family
))
450 if ((optt
!= NULL
) && (so
.so_type
!= type
))
453 if ((optp
!= NULL
) && (so
.so_protocol
!= proto
))
457 mdb_printf("%0?p\n", addr
);
461 mdb_printf("%0?p ", addr
);
463 switch (so
.so_family
) {
471 mdb_printf("inet6 ");
474 mdb_printf("%6hi", so
.so_family
);
477 switch (so
.so_type
) {
488 mdb_printf(" %4hi", so
.so_type
);
491 mdb_printf(" %5hi %05x %04x %04hx\n",
492 so
.so_protocol
, so
.so_state
, so
.so_mode
,
498 #define MI_PAYLOAD 0x1
499 #define MI_DEVICE 0x2
500 #define MI_MODULE 0x4
503 mi(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
508 if (!(flags
& DCMD_ADDRSPEC
))
511 if (mdb_getopts(argc
, argv
,
512 'p', MDB_OPT_SETBITS
, MI_PAYLOAD
, &opts
,
513 'd', MDB_OPT_SETBITS
, MI_DEVICE
, &opts
,
514 'm', MDB_OPT_SETBITS
, MI_MODULE
, &opts
,
518 if ((opts
& (MI_DEVICE
| MI_MODULE
)) == (MI_DEVICE
| MI_MODULE
)) {
519 mdb_warn("at most one filter, d for devices or m "
520 "for modules, may be specified\n");
524 if ((opts
== 0) && (DCMD_HDRSPEC(flags
))) {
525 mdb_printf("%<u>%-?s %-?s %-?s IsDev Dev%</u>\n",
526 "MI_O", "Next", "Prev");
529 if (mdb_vread(&mio
, sizeof (mio
), addr
) == -1) {
530 mdb_warn("failed to read mi object MI_O at %p", addr
);
535 if (mio
.mi_o_isdev
== B_FALSE
) {
536 /* mio is a module */
537 if (!(opts
& MI_MODULE
) && (opts
& MI_DEVICE
))
540 /* mio is a device */
541 if (!(opts
& MI_DEVICE
) && (opts
& MI_MODULE
))
545 if (opts
& MI_PAYLOAD
)
546 mdb_printf("%p\n", addr
+ sizeof (MI_O
));
548 mdb_printf("%p\n", addr
);
552 mdb_printf("%0?p %0?p %0?p ", addr
, mio
.mi_o_next
, mio
.mi_o_prev
);
554 if (mio
.mi_o_isdev
== B_FALSE
)
559 mdb_printf(" %0?p\n", mio
.mi_o_dev
);
565 ns_to_stackid(uintptr_t kaddr
)
569 if (mdb_vread(&nss
, sizeof (nss
), kaddr
) == -1) {
570 mdb_warn("failed to read netstack_t %p", kaddr
);
573 return (nss
.netstack_stackid
);
579 netstat_tcp_verbose_pr(const tcp_t
*tcp
)
581 mdb_printf(" %5i %08x %08x %5i %08x %08x %5li %5i\n",
582 tcp
->tcp_swnd
, tcp
->tcp_snxt
, tcp
->tcp_suna
, tcp
->tcp_rwnd
,
583 tcp
->tcp_rack
, tcp
->tcp_rnxt
, tcp
->tcp_rto
, tcp
->tcp_mss
);
588 netstat_tcp_cb(uintptr_t kaddr
, const void *walk_data
, void *cb_data
)
590 netstat_cb_data_t
*ncb
= cb_data
;
591 uint_t opts
= ncb
->opts
;
594 conn_t
*connp
= &ncb
->conn
;
597 if (mdb_vread(connp
, sizeof (conn_t
), kaddr
) == -1) {
598 mdb_warn("failed to read conn_t at %p", kaddr
);
602 tcp_kaddr
= (uintptr_t)connp
->conn_tcp
;
603 if (mdb_vread(&tcps
, sizeof (tcp_t
), tcp_kaddr
) == -1) {
604 mdb_warn("failed to read tcp_t at %p", tcp_kaddr
);
609 connp
->conn_tcp
= tcp
;
610 tcp
->tcp_connp
= connp
;
612 if (!((opts
& NETSTAT_ALL
) || net_tcp_active(tcp
)) ||
613 (af
== AF_INET
&& !net_tcp_ipv4(tcp
)) ||
614 (af
== AF_INET6
&& !net_tcp_ipv6(tcp
))) {
618 mdb_printf("%0?p %2i ", tcp_kaddr
, tcp
->tcp_state
);
620 net_ipv4addrport_pr(&connp
->conn_laddr_v6
, connp
->conn_lport
);
622 net_ipv4addrport_pr(&connp
->conn_faddr_v6
, connp
->conn_fport
);
623 } else if (af
== AF_INET6
) {
624 net_ipv6addrport_pr(&connp
->conn_laddr_v6
, connp
->conn_lport
);
626 net_ipv6addrport_pr(&connp
->conn_faddr_v6
, connp
->conn_fport
);
628 mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp
->conn_netstack
));
629 mdb_printf(" %4i\n", connp
->conn_zoneid
);
630 if (opts
& NETSTAT_VERBOSE
)
631 netstat_tcp_verbose_pr(tcp
);
638 netstat_udp_cb(uintptr_t kaddr
, const void *walk_data
, void *cb_data
)
640 netstat_cb_data_t
*ncb
= cb_data
;
641 uint_t opts
= ncb
->opts
;
644 conn_t
*connp
= &ncb
->conn
;
648 if (mdb_vread(connp
, sizeof (conn_t
), kaddr
) == -1) {
649 mdb_warn("failed to read conn_t at %p", kaddr
);
653 udp_kaddr
= (uintptr_t)connp
->conn_udp
;
654 if (mdb_vread(&udp
, sizeof (udp_t
), udp_kaddr
) == -1) {
655 mdb_warn("failed to read conn_udp at %p", udp_kaddr
);
659 /* Need to do these reassignments for the net_udp_*() routines below. */
660 connp
->conn_udp
= &udp
;
661 udp
.udp_connp
= connp
;
663 if (!((opts
& NETSTAT_ALL
) || net_udp_active(&udp
)) ||
664 (af
== AF_INET
&& !net_udp_ipv4(&udp
)) ||
665 (af
== AF_INET6
&& !net_udp_ipv6(&udp
))) {
669 if (udp
.udp_state
== TS_UNBND
)
671 else if (udp
.udp_state
== TS_IDLE
)
673 else if (udp
.udp_state
== TS_DATA_XFER
)
678 mdb_printf("%0?p %10s ", udp_kaddr
, state
);
680 net_ipv4addrport_pr(&connp
->conn_laddr_v6
, connp
->conn_lport
);
682 net_ipv4addrport_pr(&connp
->conn_faddr_v6
, connp
->conn_fport
);
683 } else if (af
== AF_INET6
) {
684 net_ipv6addrport_pr(&connp
->conn_laddr_v6
, connp
->conn_lport
);
686 net_ipv6addrport_pr(&connp
->conn_faddr_v6
, connp
->conn_fport
);
688 mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp
->conn_netstack
));
689 mdb_printf(" %4i\n", connp
->conn_zoneid
);
696 netstat_icmp_cb(uintptr_t kaddr
, const void *walk_data
, void *cb_data
)
698 netstat_cb_data_t
*ncb
= cb_data
;
701 conn_t
*connp
= &ncb
->conn
;
704 if (mdb_vread(connp
, sizeof (conn_t
), kaddr
) == -1) {
705 mdb_warn("failed to read conn_t at %p", kaddr
);
709 if (mdb_vread(&icmp
, sizeof (icmp_t
),
710 (uintptr_t)connp
->conn_icmp
) == -1) {
711 mdb_warn("failed to read conn_icmp at %p",
712 (uintptr_t)connp
->conn_icmp
);
716 connp
->conn_icmp
= &icmp
;
717 icmp
.icmp_connp
= connp
;
719 if ((af
== AF_INET
&& connp
->conn_ipversion
!= IPV4_VERSION
) ||
720 (af
== AF_INET6
&& connp
->conn_ipversion
!= IPV6_VERSION
)) {
724 if (icmp
.icmp_state
== TS_UNBND
)
726 else if (icmp
.icmp_state
== TS_IDLE
)
728 else if (icmp
.icmp_state
== TS_DATA_XFER
)
733 mdb_printf("%0?p %10s ", (uintptr_t)connp
->conn_icmp
, state
);
735 net_ipv4addrport_pr(&connp
->conn_laddr_v6
, connp
->conn_lport
);
737 net_ipv4addrport_pr(&connp
->conn_faddr_v6
, connp
->conn_fport
);
738 } else if (af
== AF_INET6
) {
739 net_ipv6addrport_pr(&connp
->conn_laddr_v6
, connp
->conn_lport
);
741 net_ipv6addrport_pr(&connp
->conn_faddr_v6
, connp
->conn_fport
);
743 mdb_printf(" %5i", ns_to_stackid((uintptr_t)connp
->conn_netstack
));
744 mdb_printf(" %4i\n", connp
->conn_zoneid
);
750 * print the address of a unix domain socket
752 * so is the address of a AF_UNIX struct sonode in mdb's address space
753 * soa is the address of the struct soaddr to print
755 * returns 0 on success, -1 otherwise
758 netstat_unix_name_pr(const struct sotpi_sonode
*st
, const struct soaddr
*soa
)
760 const struct sonode
*so
= &st
->st_sonode
;
761 const char none
[] = " (none)";
763 if ((so
->so_state
& SS_ISBOUND
) && (soa
->soa_len
!= 0)) {
764 if (st
->st_info
.sti_faddr_noxlate
) {
765 mdb_printf("%-14s ", " (socketpair)");
767 if (soa
->soa_len
> sizeof (sa_family_t
)) {
768 char addr
[MAXPATHLEN
+ 1];
770 if (mdb_readstr(addr
, sizeof (addr
),
771 (uintptr_t)&soa
->soa_sa
->sa_data
) == -1) {
772 mdb_warn("failed to read unix address "
773 "at %p", &soa
->soa_sa
->sa_data
);
777 mdb_printf("%-14s ", addr
);
779 mdb_printf("%-14s ", none
);
783 mdb_printf("%-14s ", none
);
789 /* based on sockfs_snapshot */
792 netstat_unix_cb(uintptr_t kaddr
, const void *walk_data
, void *cb_data
)
794 const struct sotpi_sonode
*st
= walk_data
;
795 const struct sonode
*so
= &st
->st_sonode
;
796 const struct sotpi_info
*sti
= &st
->st_info
;
798 if (so
->so_count
== 0)
801 if (so
->so_family
!= AF_UNIX
) {
802 mdb_warn("sonode of family %hi at %p\n", so
->so_family
, kaddr
);
806 mdb_printf("%-?p ", kaddr
);
808 switch (sti
->sti_serv_type
) {
810 mdb_printf("%-10s ", "dgram");
813 mdb_printf("%-10s ", "stream");
816 mdb_printf("%-10s ", "stream-ord");
819 mdb_printf("%-10i ", sti
->sti_serv_type
);
822 if ((so
->so_state
& SS_ISBOUND
) &&
823 (sti
->sti_ux_laddr
.soua_magic
== SOU_MAGIC_EXPLICIT
)) {
824 mdb_printf("%0?p ", sti
->sti_ux_laddr
.soua_vp
);
826 mdb_printf("%0?p ", NULL
);
829 if ((so
->so_state
& SS_ISCONNECTED
) &&
830 (sti
->sti_ux_faddr
.soua_magic
== SOU_MAGIC_EXPLICIT
)) {
831 mdb_printf("%0?p ", sti
->sti_ux_faddr
.soua_vp
);
833 mdb_printf("%0?p ", NULL
);
836 if (netstat_unix_name_pr(st
, &sti
->sti_laddr
) == -1)
839 if (netstat_unix_name_pr(st
, &sti
->sti_faddr
) == -1)
842 mdb_printf("%4i\n", so
->so_zoneid
);
848 netstat_tcp_verbose_header_pr(void)
850 mdb_printf(" %<u>%-5s %-8s %-8s %-5s %-8s %-8s %5s %5s%</u>\n",
851 "Swind", "Snext", "Suna", "Rwind", "Rack", "Rnext", "Rto", "Mss");
855 get_ifname(const ire_t
*ire
, char *intf
)
860 if (ire
->ire_ill
!= NULL
) {
861 if (mdb_vread(&ill
, sizeof (ill
),
862 (uintptr_t)ire
->ire_ill
) == -1)
864 (void) mdb_readstr(intf
, MIN(LIFNAMSIZ
, ill
.ill_name_length
),
865 (uintptr_t)ill
.ill_name
);
869 const in6_addr_t ipv6_all_ones
=
870 IN6ADDR_INITIALIZER(0xffffffffu
, 0xffffffffu
, 0xffffffffu
, 0xffffffffu
);
873 get_ireflags(const ire_t
*ire
, char *flags
)
875 (void) strcpy(flags
, "U");
876 /* RTF_INDIRECT wins over RTF_GATEWAY - don't display both */
877 if (ire
->ire_flags
& RTF_INDIRECT
)
878 (void) strcat(flags
, "I");
879 else if (ire
->ire_type
& IRE_OFFLINK
)
880 (void) strcat(flags
, "G");
882 /* IRE_IF_CLONE wins over RTF_HOST - don't display both */
883 if (ire
->ire_type
& IRE_IF_CLONE
)
884 (void) strcat(flags
, "C");
885 else if (ire
->ire_ipversion
== IPV4_VERSION
) {
886 if (ire
->ire_mask
== IP_HOST_MASK
)
887 (void) strcat(flags
, "H");
889 if (IN6_ARE_ADDR_EQUAL(&ire
->ire_mask_v6
, &ipv6_all_ones
))
890 (void) strcat(flags
, "H");
893 if (ire
->ire_flags
& RTF_DYNAMIC
)
894 (void) strcat(flags
, "D");
895 if (ire
->ire_type
== IRE_BROADCAST
)
896 (void) strcat(flags
, "b");
897 if (ire
->ire_type
== IRE_MULTICAST
)
898 (void) strcat(flags
, "m");
899 if (ire
->ire_type
== IRE_LOCAL
)
900 (void) strcat(flags
, "L");
901 if (ire
->ire_type
== IRE_NOROUTE
)
902 (void) strcat(flags
, "N");
903 if (ire
->ire_flags
& RTF_SETSRC
)
904 (void) strcat(flags
, "S");
905 if (ire
->ire_flags
& RTF_REJECT
)
906 (void) strcat(flags
, "R");
907 if (ire
->ire_flags
& RTF_BLACKHOLE
)
908 (void) strcat(flags
, "B");
912 netstat_irev4_cb(uintptr_t kaddr
, const void *walk_data
, void *cb_data
)
914 const ire_t
*ire
= walk_data
;
915 uint_t
*opts
= cb_data
;
917 char flags
[10], intf
[LIFNAMSIZ
+ 1];
919 if (ire
->ire_ipversion
!= IPV4_VERSION
)
922 /* Skip certain IREs by default */
923 if (!(*opts
& NETSTAT_ALL
) &&
925 (IRE_BROADCAST
|IRE_LOCAL
|IRE_MULTICAST
|IRE_NOROUTE
|IRE_IF_CLONE
)))
928 if (*opts
& NETSTAT_FIRST
) {
929 *opts
&= ~NETSTAT_FIRST
;
930 mdb_printf("%<u>%s Table: IPv4%</u>\n",
931 (*opts
& NETSTAT_VERBOSE
) ? "IRE" : "Routing");
932 if (*opts
& NETSTAT_VERBOSE
) {
933 mdb_printf("%<u>%-?s %-*s %-*s %-*s Device Mxfrg Rtt "
934 " Ref Flg Out In/Fwd%</u>\n",
935 "Address", ADDR_V4_WIDTH
, "Destination",
936 ADDR_V4_WIDTH
, "Mask", ADDR_V4_WIDTH
, "Gateway");
938 mdb_printf("%<u>%-?s %-*s %-*s Flags Ref Use "
940 "Address", ADDR_V4_WIDTH
, "Destination",
941 ADDR_V4_WIDTH
, "Gateway");
945 gate
= ire
->ire_gateway_addr
;
947 get_ireflags(ire
, flags
);
949 get_ifname(ire
, intf
);
951 if (*opts
& NETSTAT_VERBOSE
) {
952 mdb_printf("%?p %-*I %-*I %-*I %-6s %5u%c %4u %3u %-3s %5u "
953 "%u\n", kaddr
, ADDR_V4_WIDTH
, ire
->ire_addr
, ADDR_V4_WIDTH
,
954 ire
->ire_mask
, ADDR_V4_WIDTH
, gate
, intf
,
956 ire
->ire_metrics
.iulp_rtt
, ire
->ire_refcnt
, flags
,
957 ire
->ire_ob_pkt_count
, ire
->ire_ib_pkt_count
);
959 mdb_printf("%?p %-*I %-*I %-5s %4u %5u %s\n", kaddr
,
960 ADDR_V4_WIDTH
, ire
->ire_addr
, ADDR_V4_WIDTH
, gate
, flags
,
962 ire
->ire_ob_pkt_count
+ ire
->ire_ib_pkt_count
, intf
);
969 ip_mask_to_plen_v6(const in6_addr_t
*v6mask
)
975 for (i
= 3; i
>= 0; i
--)
976 if (v6mask
->s6_addr32
[i
] != 0)
981 val
= v6mask
->s6_addr32
[i
];
991 netstat_irev6_cb(uintptr_t kaddr
, const void *walk_data
, void *cb_data
)
993 const ire_t
*ire
= walk_data
;
994 uint_t
*opts
= cb_data
;
995 const in6_addr_t
*gatep
;
996 char deststr
[ADDR_V6_WIDTH
+ 5];
997 char flags
[10], intf
[LIFNAMSIZ
+ 1];
1000 if (ire
->ire_ipversion
!= IPV6_VERSION
)
1003 /* Skip certain IREs by default */
1004 if (!(*opts
& NETSTAT_ALL
) &&
1006 (IRE_BROADCAST
|IRE_LOCAL
|IRE_MULTICAST
|IRE_NOROUTE
|IRE_IF_CLONE
)))
1009 if (*opts
& NETSTAT_FIRST
) {
1010 *opts
&= ~NETSTAT_FIRST
;
1011 mdb_printf("\n%<u>%s Table: IPv6%</u>\n",
1012 (*opts
& NETSTAT_VERBOSE
) ? "IRE" : "Routing");
1013 if (*opts
& NETSTAT_VERBOSE
) {
1014 mdb_printf("%<u>%-?s %-*s %-*s If PMTU Rtt Ref "
1015 "Flags Out In/Fwd%</u>\n",
1016 "Address", ADDR_V6_WIDTH
+4, "Destination/Mask",
1017 ADDR_V6_WIDTH
, "Gateway");
1019 mdb_printf("%<u>%-?s %-*s %-*s Flags Ref Use If"
1021 "Address", ADDR_V6_WIDTH
+4, "Destination/Mask",
1022 ADDR_V6_WIDTH
, "Gateway");
1026 gatep
= &ire
->ire_gateway_addr_v6
;
1028 masklen
= ip_mask_to_plen_v6(&ire
->ire_mask_v6
);
1029 (void) mdb_snprintf(deststr
, sizeof (deststr
), "%N/%d",
1030 &ire
->ire_addr_v6
, masklen
);
1032 get_ireflags(ire
, flags
);
1034 get_ifname(ire
, intf
);
1036 if (*opts
& NETSTAT_VERBOSE
) {
1037 mdb_printf("%?p %-*s %-*N %-5s %5u%c %5u %3u %-5s %6u %u\n",
1038 kaddr
, ADDR_V6_WIDTH
+4, deststr
, ADDR_V6_WIDTH
, gatep
,
1040 ire
->ire_metrics
.iulp_rtt
, ire
->ire_refcnt
,
1041 flags
, ire
->ire_ob_pkt_count
, ire
->ire_ib_pkt_count
);
1043 mdb_printf("%?p %-*s %-*N %-5s %3u %6u %s\n", kaddr
,
1044 ADDR_V6_WIDTH
+4, deststr
, ADDR_V6_WIDTH
, gatep
, flags
,
1046 ire
->ire_ob_pkt_count
+ ire
->ire_ib_pkt_count
, intf
);
1053 netstat_header_v4(int proto
)
1055 if (proto
== IPPROTO_TCP
)
1056 mdb_printf("%<u>%-?s ", "TCPv4");
1057 else if (proto
== IPPROTO_UDP
)
1058 mdb_printf("%<u>%-?s ", "UDPv4");
1059 else if (proto
== IPPROTO_ICMP
)
1060 mdb_printf("%<u>%-?s ", "ICMPv4");
1061 mdb_printf("State %6s%*s %6s%*s %-5s %-4s%</u>\n",
1062 "", ADDR_V4_WIDTH
, "Local Address",
1063 "", ADDR_V4_WIDTH
, "Remote Address", "Stack", "Zone");
1067 netstat_header_v6(int proto
)
1069 if (proto
== IPPROTO_TCP
)
1070 mdb_printf("%<u>%-?s ", "TCPv6");
1071 else if (proto
== IPPROTO_UDP
)
1072 mdb_printf("%<u>%-?s ", "UDPv6");
1073 else if (proto
== IPPROTO_ICMP
)
1074 mdb_printf("%<u>%-?s ", "ICMPv6");
1075 mdb_printf("State %6s%*s %6s%*s %-5s %-4s%</u>\n",
1076 "", ADDR_V6_WIDTH
, "Local Address",
1077 "", ADDR_V6_WIDTH
, "Remote Address", "Stack", "Zone");
1081 netstat_print_conn(const char *cache
, int proto
, mdb_walk_cb_t cbfunc
,
1084 netstat_cb_data_t
*ncb
= cbdata
;
1086 if ((ncb
->opts
& NETSTAT_VERBOSE
) && proto
== IPPROTO_TCP
)
1087 netstat_tcp_verbose_header_pr();
1088 if (mdb_walk(cache
, cbfunc
, cbdata
) == -1) {
1089 mdb_warn("failed to walk %s", cache
);
1096 netstat_print_common(const char *cache
, int proto
, mdb_walk_cb_t cbfunc
,
1099 netstat_cb_data_t
*ncb
= cbdata
;
1101 int status
= DCMD_OK
;
1103 if (af
!= AF_INET6
) {
1105 netstat_header_v4(proto
);
1106 status
= netstat_print_conn(cache
, proto
, cbfunc
, cbdata
);
1108 if (status
== DCMD_OK
&& af
!= AF_INET
) {
1110 netstat_header_v6(proto
);
1111 status
= netstat_print_conn(cache
, proto
, cbfunc
, cbdata
);
1119 netstat(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1122 const char *optf
= NULL
;
1123 const char *optP
= NULL
;
1124 netstat_cb_data_t
*cbdata
;
1128 if (mdb_getopts(argc
, argv
,
1129 'a', MDB_OPT_SETBITS
, NETSTAT_ALL
, &opts
,
1130 'f', MDB_OPT_STR
, &optf
,
1131 'P', MDB_OPT_STR
, &optP
,
1132 'r', MDB_OPT_SETBITS
, NETSTAT_ROUTE
, &opts
,
1133 'v', MDB_OPT_SETBITS
, NETSTAT_VERBOSE
, &opts
,
1135 return (DCMD_USAGE
);
1138 if ((strcmp("tcp", optP
) != 0) && (strcmp("udp", optP
) != 0) &&
1139 (strcmp("icmp", optP
) != 0))
1140 return (DCMD_USAGE
);
1141 if (opts
& NETSTAT_ROUTE
)
1142 return (DCMD_USAGE
);
1146 opts
|= NETSTAT_V4
| NETSTAT_V6
| NETSTAT_UNIX
;
1147 else if (strcmp("inet", optf
) == 0)
1149 else if (strcmp("inet6", optf
) == 0)
1151 else if (strcmp("unix", optf
) == 0)
1152 opts
|= NETSTAT_UNIX
;
1154 return (DCMD_USAGE
);
1156 if (opts
& NETSTAT_ROUTE
) {
1157 if (!(opts
& (NETSTAT_V4
|NETSTAT_V6
)))
1158 return (DCMD_USAGE
);
1159 if (opts
& NETSTAT_V4
) {
1160 opts
|= NETSTAT_FIRST
;
1161 if (mdb_walk("ip`ire", netstat_irev4_cb
, &opts
) == -1) {
1162 mdb_warn("failed to walk ip`ire");
1166 if (opts
& NETSTAT_V6
) {
1167 opts
|= NETSTAT_FIRST
;
1168 if (mdb_walk("ip`ire", netstat_irev6_cb
, &opts
) == -1) {
1169 mdb_warn("failed to walk ip`ire");
1176 if ((opts
& NETSTAT_UNIX
) && (optP
== NULL
)) {
1177 /* Print Unix Domain Sockets */
1178 mdb_printf("%<u>%-?s %-10s %-?s %-?s %-14s %-14s %s%</u>\n",
1179 "AF_UNIX", "Type", "Vnode", "Conn", "Local Addr",
1180 "Remote Addr", "Zone");
1182 if (mdb_walk("genunix`sonode", netstat_unix_cb
, NULL
) == -1) {
1183 mdb_warn("failed to walk genunix`sonode");
1186 if (!(opts
& (NETSTAT_V4
| NETSTAT_V6
)))
1190 cbdata
= mdb_alloc(sizeof (netstat_cb_data_t
), UM_SLEEP
);
1191 cbdata
->opts
= opts
;
1192 if ((optf
!= NULL
) && (opts
& NETSTAT_V4
))
1194 else if ((optf
!= NULL
) && (opts
& NETSTAT_V6
))
1198 if ((optP
== NULL
) || (strcmp("tcp", optP
) == 0)) {
1199 status
= netstat_print_common("tcp_conn_cache", IPPROTO_TCP
,
1200 netstat_tcp_cb
, cbdata
);
1201 if (status
!= DCMD_OK
)
1205 if ((optP
== NULL
) || (strcmp("udp", optP
) == 0)) {
1206 status
= netstat_print_common("udp_conn_cache", IPPROTO_UDP
,
1207 netstat_udp_cb
, cbdata
);
1208 if (status
!= DCMD_OK
)
1212 if ((optP
== NULL
) || (strcmp("icmp", optP
) == 0)) {
1213 status
= netstat_print_common("rawip_conn_cache", IPPROTO_ICMP
,
1214 netstat_icmp_cb
, cbdata
);
1215 if (status
!= DCMD_OK
)
1219 mdb_free(cbdata
, sizeof (netstat_cb_data_t
));
1224 * "::dladm show-bridge" support
1237 * These structures are kept inside the 'args' for allocation reasons.
1238 * They're all large data structures (over 1K), and may cause the stack
1239 * to explode. mdb and kmdb will fail in these cases, and thus we
1240 * allocate them from the heap.
1245 } show_bridge_args_t
;
1248 show_vlans(const uint8_t *vlans
)
1252 int rstart
= -1, rnext
= -1;
1254 for (i
= 0; i
< BRIDGE_VLAN_ARR_SIZE
; i
++) {
1258 while ((bit
= mdb_ffs(val
)) != 0) {
1261 bit
+= i
* sizeof (*vlans
) * NBBY
;
1263 if (rnext
!= -1 && rstart
+ 1 != rnext
)
1264 mdb_printf("-%d", rnext
- 1);
1267 mdb_printf("%d", bit
);
1273 if (rnext
!= -1 && rstart
+ 1 != rnext
)
1274 mdb_printf("-%d", rnext
- 1);
1279 * This callback is invoked by a walk of the links attached to a bridge. If
1280 * we're showing link details, then they're printed here. If not, then we just
1281 * count up the links for the bridge summary.
1284 do_bridge_links(uintptr_t addr
, const void *data
, void *ptr
)
1286 show_bridge_args_t
*args
= ptr
;
1287 const bridge_link_t
*blp
= data
;
1288 char macaddr
[ETHERADDRL
* 3];
1296 if (mdb_vread(&args
->mi
, sizeof (args
->mi
),
1297 (uintptr_t)blp
->bl_mh
) == -1) {
1298 mdb_warn("cannot read mac data at %p", blp
->bl_mh
);
1301 name
= args
->mi
.mi_name
;
1304 mdb_mac_addr(blp
->bl_local_mac
, ETHERADDRL
, macaddr
,
1307 mdb_printf("%-?p %-16s %-17s %03X %-4d ", addr
, name
, macaddr
,
1308 blp
->bl_flags
, blp
->bl_pvid
);
1310 if (blp
->bl_trilldata
== NULL
) {
1311 switch (blp
->bl_state
) {
1312 case BLS_BLOCKLISTEN
:
1318 case BLS_FORWARDING
:
1324 mdb_printf("%-5s ", name
);
1325 show_vlans(blp
->bl_vlans
);
1327 show_vlans(blp
->bl_afs
);
1334 * It seems a shame to duplicate this code, but merging it with the link
1335 * printing code above is more trouble than it would be worth.
1338 print_link_name(show_bridge_args_t
*args
, uintptr_t addr
, char sep
)
1342 if (mdb_vread(&args
->bl
, sizeof (args
->bl
), addr
) == -1) {
1343 mdb_warn("cannot read bridge link at %p", addr
);
1347 if (mdb_vread(&args
->mi
, sizeof (args
->mi
),
1348 (uintptr_t)args
->bl
.bl_mh
) == -1) {
1351 name
= args
->mi
.mi_name
;
1354 mdb_printf("%s%c", name
, sep
);
1358 do_bridge_fwd(uintptr_t addr
, const void *data
, void *ptr
)
1360 show_bridge_args_t
*args
= ptr
;
1361 const bridge_fwd_t
*bfp
= data
;
1362 char macaddr
[ETHERADDRL
* 3];
1364 #define MAX_FWD_LINKS 16
1365 bridge_link_t
*links
[MAX_FWD_LINKS
];
1373 if ((nlinks
= bfp
->bf_nlinks
) > MAX_FWD_LINKS
)
1374 nlinks
= MAX_FWD_LINKS
;
1376 if (mdb_vread(links
, sizeof (links
[0]) * nlinks
,
1377 (uintptr_t)bfp
->bf_links
) == -1) {
1378 mdb_warn("cannot read bridge forwarding links at %p",
1383 mdb_mac_addr(bfp
->bf_dest
, ETHERADDRL
, macaddr
, sizeof (macaddr
));
1385 mdb_printf("%-?p %-17s ", addr
, macaddr
);
1386 if (bfp
->bf_flags
& BFF_LOCALADDR
)
1387 mdb_printf("%-7s", "[self]");
1389 mdb_printf("t-%-5d", args
->lbolt
- bfp
->bf_lastheard
);
1390 mdb_printf(" %-7u ", bfp
->bf_refs
);
1392 if (bfp
->bf_trill_nick
!= 0) {
1393 mdb_printf("%d\n", bfp
->bf_trill_nick
);
1395 for (i
= 0; i
< bfp
->bf_nlinks
; i
++) {
1396 print_link_name(args
, (uintptr_t)links
[i
],
1397 i
== bfp
->bf_nlinks
- 1 ? '\n' : ' ');
1405 do_show_bridge(uintptr_t addr
, const void *data
, void *ptr
)
1407 show_bridge_args_t
*args
= ptr
;
1409 const bridge_inst_t
*bip
;
1412 trill_nickinfo_t tni
;
1413 char bname
[MAXLINKNAMELEN
];
1414 char macaddr
[ETHERADDRL
* 3];
1422 if (mdb_vread(&bi
, sizeof (bi
), addr
) == -1) {
1423 mdb_warn("cannot read bridge instance at %p", addr
);
1429 (void) strncpy(bname
, bip
->bi_name
, sizeof (bname
) - 1);
1430 bname
[MAXLINKNAMELEN
- 1] = '\0';
1431 cp
= bname
+ strlen(bname
);
1432 if (cp
> bname
&& cp
[-1] == '0')
1435 if (args
->name
!= NULL
&& strcmp(args
->name
, bname
) != 0)
1438 args
->found
= B_TRUE
;
1439 args
->nlinks
= args
->nfwd
= 0;
1442 mdb_printf("%-?s %-16s %-17s %3s %-4s ", "ADDR", "LINK",
1443 "MAC-ADDR", "FLG", "PVID");
1444 if (bip
->bi_trilldata
== NULL
)
1445 mdb_printf("%-5s %s\n", "STATE", "VLANS");
1447 mdb_printf("%s\n", "FWD-VLANS");
1450 if (!args
->opt_f
&& !args
->opt_t
&&
1451 mdb_pwalk("list", do_bridge_links
, args
,
1452 addr
+ offsetof(bridge_inst_t
, bi_links
)) != DCMD_OK
)
1456 mdb_printf("%-?s %-17s %-7s %-7s %s\n", "ADDR", "DEST", "TIME",
1459 if (!args
->opt_l
&& !args
->opt_t
&&
1460 mdb_pwalk("avl", do_bridge_fwd
, args
,
1461 addr
+ offsetof(bridge_inst_t
, bi_fwd
)) != DCMD_OK
)
1465 if (bip
->bi_trilldata
!= NULL
&& !args
->opt_l
&& !args
->opt_f
) {
1466 if (mdb_vread(&args
->ti
, sizeof (args
->ti
),
1467 (uintptr_t)bip
->bi_trilldata
) == -1) {
1468 mdb_warn("cannot read trill instance at %p",
1473 mdb_printf("%-?s %-5s %-17s %s\n", "ADDR",
1474 "NICK", "NEXT-HOP", "LINK");
1475 for (i
= 0; i
< RBRIDGE_NICKNAME_MAX
; i
++) {
1476 if (args
->ti
.ti_nodes
[i
] == NULL
)
1479 if (mdb_vread(&tn
, sizeof (tn
),
1480 (uintptr_t)args
->ti
.ti_nodes
[i
]) == -1) {
1481 mdb_warn("cannot read trill node %d at "
1482 "%p", i
, args
->ti
.ti_nodes
[i
]);
1485 if (mdb_vread(&tni
, sizeof (tni
),
1486 (uintptr_t)tn
.tn_ni
) == -1) {
1487 mdb_warn("cannot read trill node info "
1488 "%d at %p", i
, tn
.tn_ni
);
1491 mdb_mac_addr(tni
.tni_adjsnpa
, ETHERADDRL
,
1492 macaddr
, sizeof (macaddr
));
1493 if (tni
.tni_nick
== args
->ti
.ti_nick
) {
1494 (void) strcpy(macaddr
, "[self]");
1496 mdb_printf("%-?p %-5u %-17s ",
1497 args
->ti
.ti_nodes
[i
], tni
.tni_nick
,
1499 if (tn
.tn_tsp
!= NULL
) {
1500 if (mdb_vread(&tsp
, sizeof (tsp
),
1501 (uintptr_t)tn
.tn_tsp
) == -1) {
1502 mdb_warn("cannot read trill "
1503 "socket info at %p",
1507 if (tsp
.ts_link
!= NULL
) {
1508 print_link_name(args
,
1509 (uintptr_t)tsp
.ts_link
,
1521 mdb_printf("bridge is not running TRILL\n");
1524 if (!args
->opt_l
&& !args
->opt_f
&& !args
->opt_t
) {
1525 mdb_printf("%-?p %-7s %-16s %-7u %-7u", addr
,
1526 bip
->bi_trilldata
== NULL
? "stp" : "trill", bname
,
1527 args
->nlinks
, args
->nfwd
);
1528 if (bip
->bi_trilldata
!= NULL
)
1529 mdb_printf(" %-7u %u\n", nnicks
, args
->ti
.ti_nick
);
1531 mdb_printf(" %-7s %s\n", "--", "--");
1537 dladm_show_bridge(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1539 show_bridge_args_t
*args
;
1543 args
= mdb_zalloc(sizeof (*args
), UM_SLEEP
);
1545 i
= mdb_getopts(argc
, argv
,
1546 'l', MDB_OPT_SETBITS
, 1, &args
->opt_l
,
1547 'f', MDB_OPT_SETBITS
, 1, &args
->opt_f
,
1548 't', MDB_OPT_SETBITS
, 1, &args
->opt_t
,
1554 if (argc
> 1 || (argc
== 1 && argv
[0].a_type
!= MDB_TYPE_STRING
)) {
1555 mdb_free(args
, sizeof (*args
));
1556 return (DCMD_USAGE
);
1559 args
->name
= argv
[0].a_un
.a_str
;
1561 if ((args
->lbolt
= mdb_get_lbolt()) == -1) {
1562 mdb_warn("failed to read lbolt");
1566 if (flags
& DCMD_ADDRSPEC
) {
1567 if (args
->name
!= NULL
) {
1568 mdb_printf("bridge name and address are mutually "
1572 if (!args
->opt_l
&& !args
->opt_f
&& !args
->opt_t
)
1573 mdb_printf("%-?s %-7s %-16s %-7s %-7s\n", "ADDR",
1574 "PROTECT", "NAME", "NLINKS", "NFWD");
1575 if (do_show_bridge(addr
, NULL
, args
) != WALK_NEXT
)
1577 mdb_free(args
, sizeof (*args
));
1580 if ((args
->opt_l
|| args
->opt_f
|| args
->opt_t
) &&
1581 args
->name
== NULL
) {
1582 mdb_printf("need bridge name or address with -[lft]\n");
1585 if (mdb_lookup_by_obj("bridge", "inst_list", &sym
) == -1) {
1586 mdb_warn("failed to find 'bridge`inst_list'");
1589 if (!args
->opt_l
&& !args
->opt_f
&& !args
->opt_t
)
1590 mdb_printf("%-?s %-7s %-16s %-7s %-7s %-7s %s\n",
1591 "ADDR", "PROTECT", "NAME", "NLINKS", "NFWD",
1593 if (mdb_pwalk("list", do_show_bridge
, args
,
1594 (uintptr_t)sym
.st_value
) != DCMD_OK
)
1596 if (!args
->found
&& args
->name
!= NULL
) {
1597 mdb_printf("bridge instance %s not found\n",
1601 mdb_free(args
, sizeof (*args
));
1606 mdb_free(args
, sizeof (*args
));
1611 * Support for the "::dladm" dcmd
1614 dladm(uintptr_t addr
, uint_t flags
, int argc
, const mdb_arg_t
*argv
)
1616 if (argc
< 1 || argv
[0].a_type
!= MDB_TYPE_STRING
)
1617 return (DCMD_USAGE
);
1620 * This could be a bit more elaborate, once we support more of the
1621 * dladm show-* subcommands.
1625 if (strcmp(argv
[-1].a_un
.a_str
, "show-bridge") == 0)
1626 return (dladm_show_bridge(addr
, flags
, argc
, argv
));
1628 return (DCMD_USAGE
);
1634 mdb_printf("Subcommands:\n"
1635 " show-bridge [-flt] [<name>]\n"
1636 "\t Show bridge information; -l for links and -f for "
1638 "\t entries, and -t for TRILL nicknames. Address is required "
1640 "\t is not specified.\n");