xref: /illumos-gate/usr/src/cmd/mdb/common/modules/sppp/sppp.c (revision 0c1b95bef39aa56a594619ae1fa17557c8a8b8ab)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5f53eecf5SJames Carlson  * Common Development and Distribution License (the "License").
6f53eecf5SJames Carlson  *  You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22f53eecf5SJames Carlson  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <sys/types.h>
277c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
287c478bd9Sstevel@tonic-gate #include <sys/stream.h>
297c478bd9Sstevel@tonic-gate #include <sys/socket.h>
307c478bd9Sstevel@tonic-gate #include <net/if.h>
317c478bd9Sstevel@tonic-gate #define	SOL2
327c478bd9Sstevel@tonic-gate #include <net/ppp_defs.h>
337c478bd9Sstevel@tonic-gate #include <net/pppio.h>
347c478bd9Sstevel@tonic-gate #include <net/sppptun.h>
357c478bd9Sstevel@tonic-gate #include <netinet/in.h>
367c478bd9Sstevel@tonic-gate #include <netinet/ip6.h>
377c478bd9Sstevel@tonic-gate #include <inet/common.h>
387c478bd9Sstevel@tonic-gate #include <inet/mib2.h>
397c478bd9Sstevel@tonic-gate #include <inet/ip.h>
407c478bd9Sstevel@tonic-gate #include <inet/ip6.h>
417c478bd9Sstevel@tonic-gate #include <sppp/sppp.h>
427c478bd9Sstevel@tonic-gate #include <sppptun/sppptun_impl.h>
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
457c478bd9Sstevel@tonic-gate #include <mdb/mdb_ks.h>
467c478bd9Sstevel@tonic-gate #include <stdio.h>
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate /* ****************** sppp ****************** */
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate static int
sppp_walk_init(mdb_walk_state_t * wsp)517c478bd9Sstevel@tonic-gate sppp_walk_init(mdb_walk_state_t *wsp)
527c478bd9Sstevel@tonic-gate {
537c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&wsp->walk_addr, "sps_list") == -1) {
547c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read sps_list");
557c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
567c478bd9Sstevel@tonic-gate 	}
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
597c478bd9Sstevel@tonic-gate }
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate static int
sppp_walk_step(mdb_walk_state_t * wsp)627c478bd9Sstevel@tonic-gate sppp_walk_step(mdb_walk_state_t *wsp)
637c478bd9Sstevel@tonic-gate {
647c478bd9Sstevel@tonic-gate 	spppstr_t sps;
657c478bd9Sstevel@tonic-gate 	int status;
667c478bd9Sstevel@tonic-gate 
67892ad162SToomas Soome 	if (wsp->walk_addr == 0)
687c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 	if (mdb_vread(&sps, sizeof (sps), wsp->walk_addr) == -1) {
717c478bd9Sstevel@tonic-gate 		mdb_warn("can't read spppstr_t at %p", wsp->walk_addr);
727c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
737c478bd9Sstevel@tonic-gate 	}
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	status = (wsp->walk_callback(wsp->walk_addr, &sps, wsp->walk_cbdata));
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)sps.sps_nextmn;
787c478bd9Sstevel@tonic-gate 	return (status);
797c478bd9Sstevel@tonic-gate }
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate static int
sps_format(uintptr_t addr,const spppstr_t * sps,uint_t * qfmt)827c478bd9Sstevel@tonic-gate sps_format(uintptr_t addr, const spppstr_t *sps, uint_t *qfmt)
837c478bd9Sstevel@tonic-gate {
847c478bd9Sstevel@tonic-gate 	sppa_t ppa;
857c478bd9Sstevel@tonic-gate 	queue_t upq;
867c478bd9Sstevel@tonic-gate 	uintptr_t upaddr, illaddr;
877c478bd9Sstevel@tonic-gate 	ill_t ill;
887c478bd9Sstevel@tonic-gate 	ipif_t ipif;
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 	mdb_printf("%?p ", addr);
917c478bd9Sstevel@tonic-gate 	if (*qfmt)
927c478bd9Sstevel@tonic-gate 		mdb_printf("%?p ", sps->sps_rq);
937c478bd9Sstevel@tonic-gate 	if (sps->sps_ppa == NULL) {
94f53eecf5SJames Carlson 		mdb_printf("?       unset     ");
957c478bd9Sstevel@tonic-gate 	} else if (mdb_vread(&ppa, sizeof (ppa), (uintptr_t)sps->sps_ppa) ==
967c478bd9Sstevel@tonic-gate 	    -1) {
97f53eecf5SJames Carlson 		mdb_printf("?      ?%p ", sps->sps_ppa);
987c478bd9Sstevel@tonic-gate 	} else {
99f53eecf5SJames Carlson 		mdb_printf("%-6d sppp%-5d ", ppa.ppa_zoneid, ppa.ppa_ppa_id);
1007c478bd9Sstevel@tonic-gate 	}
1017c478bd9Sstevel@tonic-gate 	if (IS_SPS_CONTROL(sps)) {
1027c478bd9Sstevel@tonic-gate 		mdb_printf("Control\n");
1037c478bd9Sstevel@tonic-gate 	} else if (IS_SPS_PIOATTACH(sps)) {
1047c478bd9Sstevel@tonic-gate 		mdb_printf("Stats\n");
1057c478bd9Sstevel@tonic-gate 	} else if (sps->sps_dlstate == DL_UNATTACHED) {
1067c478bd9Sstevel@tonic-gate 		mdb_printf("Unknown\n");
1077c478bd9Sstevel@tonic-gate 	} else if (sps->sps_dlstate != DL_IDLE) {
1087c478bd9Sstevel@tonic-gate 		mdb_printf("DLPI Unbound\n");
1097c478bd9Sstevel@tonic-gate 	} else {
1107c478bd9Sstevel@tonic-gate 		upaddr = (uintptr_t)sps->sps_rq;
1117c478bd9Sstevel@tonic-gate 		upq.q_ptr = NULL;
1127c478bd9Sstevel@tonic-gate 		illaddr = 0;
113892ad162SToomas Soome 		while (upaddr != 0) {
1147c478bd9Sstevel@tonic-gate 			if (mdb_vread(&upq, sizeof (upq), upaddr) == -1) {
1157c478bd9Sstevel@tonic-gate 				upq.q_ptr = NULL;
1167c478bd9Sstevel@tonic-gate 				break;
1177c478bd9Sstevel@tonic-gate 			}
1187c478bd9Sstevel@tonic-gate 			if ((upaddr = (uintptr_t)upq.q_next) != 0)
1197c478bd9Sstevel@tonic-gate 				illaddr = (uintptr_t)upq.q_ptr;
1207c478bd9Sstevel@tonic-gate 		}
1217c478bd9Sstevel@tonic-gate 		if (illaddr != 0) {
1227c478bd9Sstevel@tonic-gate 			if (mdb_vread(&ill, sizeof (ill), illaddr) == -1 ||
1237c478bd9Sstevel@tonic-gate 			    mdb_vread(&ipif, sizeof (ipif),
1247c478bd9Sstevel@tonic-gate 			    (uintptr_t)ill.ill_ipif) == -1) {
1257c478bd9Sstevel@tonic-gate 				illaddr = 0;
1267c478bd9Sstevel@tonic-gate 			}
1277c478bd9Sstevel@tonic-gate 		}
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 		switch (sps->sps_req_sap) {
1307c478bd9Sstevel@tonic-gate 		case ETHERTYPE_IP:
1317c478bd9Sstevel@tonic-gate 			mdb_printf("DLPI IPv4 ");
1327c478bd9Sstevel@tonic-gate 			if (*qfmt) {
1337c478bd9Sstevel@tonic-gate 				mdb_printf("\n");
1347c478bd9Sstevel@tonic-gate 			} else if (illaddr == 0) {
1357c478bd9Sstevel@tonic-gate 				mdb_printf("(no addresses)\n");
1367c478bd9Sstevel@tonic-gate 			} else {
1377c478bd9Sstevel@tonic-gate 				/*
1387c478bd9Sstevel@tonic-gate 				 * SCCS oddity here -- % <capital> %
1397c478bd9Sstevel@tonic-gate 				 * suffers from keyword replacement.
1407c478bd9Sstevel@tonic-gate 				 * Avoid that by using ANSI string
1417c478bd9Sstevel@tonic-gate 				 * pasting.
1427c478bd9Sstevel@tonic-gate 				 */
1437c478bd9Sstevel@tonic-gate 				mdb_printf("%I:%I" "%s\n",
1447c478bd9Sstevel@tonic-gate 				    ipif.ipif_lcl_addr, ipif.ipif_pp_dst_addr,
1457c478bd9Sstevel@tonic-gate 				    (ipif.ipif_next ? " ..." : ""));
1467c478bd9Sstevel@tonic-gate 			}
1477c478bd9Sstevel@tonic-gate 			break;
1487c478bd9Sstevel@tonic-gate 		case ETHERTYPE_IPV6:
1497c478bd9Sstevel@tonic-gate 			mdb_printf("DLPI IPv6 ");
1507c478bd9Sstevel@tonic-gate 			if (*qfmt) {
1517c478bd9Sstevel@tonic-gate 				mdb_printf("\n");
1527c478bd9Sstevel@tonic-gate 				break;
1537c478bd9Sstevel@tonic-gate 			}
1547c478bd9Sstevel@tonic-gate 			if (illaddr == 0) {
1557c478bd9Sstevel@tonic-gate 				mdb_printf("(no addresses)\n");
1567c478bd9Sstevel@tonic-gate 				break;
1577c478bd9Sstevel@tonic-gate 			}
1587c478bd9Sstevel@tonic-gate 			mdb_printf("%N\n%?s%21s", &ipif.ipif_v6lcl_addr,
1597c478bd9Sstevel@tonic-gate 			    "", "");
1607c478bd9Sstevel@tonic-gate 			mdb_printf("%N\n", &ipif.ipif_v6pp_dst_addr);
1617c478bd9Sstevel@tonic-gate 			break;
1627c478bd9Sstevel@tonic-gate 		case ETHERTYPE_ALLSAP:
1637c478bd9Sstevel@tonic-gate 			mdb_printf("DLPI Snoop\n");
1647c478bd9Sstevel@tonic-gate 			break;
1657c478bd9Sstevel@tonic-gate 		default:
1667c478bd9Sstevel@tonic-gate 			mdb_printf("DLPI SAP 0x%04X\n", sps->sps_req_sap);
1677c478bd9Sstevel@tonic-gate 			break;
1687c478bd9Sstevel@tonic-gate 		}
1697c478bd9Sstevel@tonic-gate 	}
1707c478bd9Sstevel@tonic-gate 
1717c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate static int
sppp(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1757c478bd9Sstevel@tonic-gate sppp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1767c478bd9Sstevel@tonic-gate {
1777c478bd9Sstevel@tonic-gate 	uint_t qfmt = FALSE;
1787c478bd9Sstevel@tonic-gate 	spppstr_t sps;
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate 	if (mdb_getopts(argc, argv, 'q', MDB_OPT_SETBITS, TRUE, &qfmt, NULL) !=
1817c478bd9Sstevel@tonic-gate 	    argc)
1827c478bd9Sstevel@tonic-gate 		return (DCMD_USAGE);
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
1857c478bd9Sstevel@tonic-gate 		if (qfmt) {
186f53eecf5SJames Carlson 			mdb_printf("%<u>%?s %?s %-6s %-9s %s%</u>\n", "Address",
187f53eecf5SJames Carlson 			    "RecvQ", "ZoneID", "Interface", "Type");
1887c478bd9Sstevel@tonic-gate 		} else {
189f53eecf5SJames Carlson 			mdb_printf("%<u>%?s %-6s %-9s %s%</u>\n", "Address",
190f53eecf5SJames Carlson 			    "ZoneID", "Interface", "Type");
1917c478bd9Sstevel@tonic-gate 		}
1927c478bd9Sstevel@tonic-gate 	}
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC) {
1957c478bd9Sstevel@tonic-gate 		(void) mdb_vread(&sps, sizeof (sps), addr);
1967c478bd9Sstevel@tonic-gate 		(void) sps_format(addr, &sps, &qfmt);
1977c478bd9Sstevel@tonic-gate 	} else if (mdb_walk("sppp", (mdb_walk_cb_t)sps_format, &qfmt) == -1) {
1987c478bd9Sstevel@tonic-gate 		mdb_warn("failed to walk sps_list");
1997c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
2007c478bd9Sstevel@tonic-gate 	}
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate static int
sppa_walk_init(mdb_walk_state_t * wsp)2067c478bd9Sstevel@tonic-gate sppa_walk_init(mdb_walk_state_t *wsp)
2077c478bd9Sstevel@tonic-gate {
2087c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&wsp->walk_addr, "ppa_list") == -1) {
2097c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read ppa_list");
2107c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
2117c478bd9Sstevel@tonic-gate 	}
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
2147c478bd9Sstevel@tonic-gate }
2157c478bd9Sstevel@tonic-gate 
2167c478bd9Sstevel@tonic-gate static int
sppa_walk_step(mdb_walk_state_t * wsp)2177c478bd9Sstevel@tonic-gate sppa_walk_step(mdb_walk_state_t *wsp)
2187c478bd9Sstevel@tonic-gate {
2197c478bd9Sstevel@tonic-gate 	sppa_t ppa;
2207c478bd9Sstevel@tonic-gate 	int status;
2217c478bd9Sstevel@tonic-gate 
222892ad162SToomas Soome 	if (wsp->walk_addr == 0)
2237c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ppa, sizeof (ppa), wsp->walk_addr) == -1) {
2267c478bd9Sstevel@tonic-gate 		mdb_warn("can't read spppstr_t at %p", wsp->walk_addr);
2277c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
2287c478bd9Sstevel@tonic-gate 	}
2297c478bd9Sstevel@tonic-gate 
2307c478bd9Sstevel@tonic-gate 	status = (wsp->walk_callback(wsp->walk_addr, &ppa, wsp->walk_cbdata));
2317c478bd9Sstevel@tonic-gate 
2327c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)ppa.ppa_nextppa;
2337c478bd9Sstevel@tonic-gate 	return (status);
2347c478bd9Sstevel@tonic-gate }
2357c478bd9Sstevel@tonic-gate 
2367c478bd9Sstevel@tonic-gate /* ARGSUSED */
2377c478bd9Sstevel@tonic-gate static int
ppa_format(uintptr_t addr,const sppa_t * ppa,uint_t * qfmt)2387c478bd9Sstevel@tonic-gate ppa_format(uintptr_t addr, const sppa_t *ppa, uint_t *qfmt)
2397c478bd9Sstevel@tonic-gate {
240f53eecf5SJames Carlson 	mdb_printf("%?p %-6d sppp%-5d %?p %?p\n", addr, ppa->ppa_zoneid,
241f53eecf5SJames Carlson 	    ppa->ppa_ppa_id, ppa->ppa_ctl, ppa->ppa_lower_wq);
2427c478bd9Sstevel@tonic-gate 
2437c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
2447c478bd9Sstevel@tonic-gate }
2457c478bd9Sstevel@tonic-gate 
2467c478bd9Sstevel@tonic-gate /* ARGSUSED */
2477c478bd9Sstevel@tonic-gate static int
sppa(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)2487c478bd9Sstevel@tonic-gate sppa(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2497c478bd9Sstevel@tonic-gate {
2507c478bd9Sstevel@tonic-gate 	uint_t qfmt = FALSE;
2517c478bd9Sstevel@tonic-gate 	sppa_t ppa;
2527c478bd9Sstevel@tonic-gate 
2537c478bd9Sstevel@tonic-gate 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
254f53eecf5SJames Carlson 		mdb_printf("%<u>%?s %-6s %-9s %?s %?s%</u>\n", "Address",
255f53eecf5SJames Carlson 		    "ZoneID", "Interface", "Control", "LowerQ");
2567c478bd9Sstevel@tonic-gate 	}
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC) {
2597c478bd9Sstevel@tonic-gate 		(void) mdb_vread(&ppa, sizeof (ppa), addr);
2607c478bd9Sstevel@tonic-gate 		(void) ppa_format(addr, &ppa, &qfmt);
2617c478bd9Sstevel@tonic-gate 	} else if (mdb_walk("sppa", (mdb_walk_cb_t)ppa_format, &qfmt) == -1) {
2627c478bd9Sstevel@tonic-gate 		mdb_warn("failed to walk ppa_list");
2637c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
2647c478bd9Sstevel@tonic-gate 	}
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate 
2697c478bd9Sstevel@tonic-gate static void
sppp_qinfo(const queue_t * q,char * buf,size_t nbytes)2707c478bd9Sstevel@tonic-gate sppp_qinfo(const queue_t *q, char *buf, size_t nbytes)
2717c478bd9Sstevel@tonic-gate {
2727c478bd9Sstevel@tonic-gate 	spppstr_t sps;
2737c478bd9Sstevel@tonic-gate 	sppa_t ppa;
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 	if (mdb_vread(&sps, sizeof (sps), (uintptr_t)q->q_ptr) ==
2767c478bd9Sstevel@tonic-gate 	    sizeof (sps)) {
2777c478bd9Sstevel@tonic-gate 		if (sps.sps_ppa == NULL ||
2787c478bd9Sstevel@tonic-gate 		    mdb_vread(&ppa, sizeof (ppa), (uintptr_t)sps.sps_ppa) ==
2797c478bd9Sstevel@tonic-gate 		    -1) {
2807c478bd9Sstevel@tonic-gate 			(void) mdb_snprintf(buf, nbytes, "minor %d",
2817c478bd9Sstevel@tonic-gate 			    sps.sps_mn_id);
2827c478bd9Sstevel@tonic-gate 		} else {
2837c478bd9Sstevel@tonic-gate 			(void) mdb_snprintf(buf, nbytes, "sppp%d",
2847c478bd9Sstevel@tonic-gate 			    ppa.ppa_ppa_id);
2857c478bd9Sstevel@tonic-gate 		}
2867c478bd9Sstevel@tonic-gate 	}
2877c478bd9Sstevel@tonic-gate }
2887c478bd9Sstevel@tonic-gate 
2897c478bd9Sstevel@tonic-gate static uintptr_t
sppp_rnext(const queue_t * q)2907c478bd9Sstevel@tonic-gate sppp_rnext(const queue_t *q)
2917c478bd9Sstevel@tonic-gate {
2927c478bd9Sstevel@tonic-gate 	spppstr_t sps;
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate 	if (mdb_vread(&sps, sizeof (sps), (uintptr_t)q->q_ptr) == sizeof (sps))
2957c478bd9Sstevel@tonic-gate 		return ((uintptr_t)sps.sps_rq);
2967c478bd9Sstevel@tonic-gate 
297892ad162SToomas Soome 	return (0);
2987c478bd9Sstevel@tonic-gate }
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate static uintptr_t
sppp_wnext(const queue_t * q)3017c478bd9Sstevel@tonic-gate sppp_wnext(const queue_t *q)
3027c478bd9Sstevel@tonic-gate {
3037c478bd9Sstevel@tonic-gate 	spppstr_t sps;
3047c478bd9Sstevel@tonic-gate 	sppa_t ppa;
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 	if (mdb_vread(&sps, sizeof (sps), (uintptr_t)q->q_ptr) != sizeof (sps))
307892ad162SToomas Soome 		return (0);
3087c478bd9Sstevel@tonic-gate 
3097c478bd9Sstevel@tonic-gate 	if (sps.sps_ppa != NULL &&
3107c478bd9Sstevel@tonic-gate 	    mdb_vread(&ppa, sizeof (ppa), (uintptr_t)sps.sps_ppa) ==
3117c478bd9Sstevel@tonic-gate 	    sizeof (ppa))
3127c478bd9Sstevel@tonic-gate 		return ((uintptr_t)ppa.ppa_lower_wq);
3137c478bd9Sstevel@tonic-gate 
314892ad162SToomas Soome 	return (0);
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate /* ****************** sppptun ****************** */
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate struct tcl_walk_data {
3207c478bd9Sstevel@tonic-gate 	size_t tcl_nslots;
3217c478bd9Sstevel@tonic-gate 	size_t walkpos;
3227c478bd9Sstevel@tonic-gate 	tuncl_t *tcl_slots[1];
3237c478bd9Sstevel@tonic-gate };
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate static void
tuncl_walk_fini(mdb_walk_state_t * wsp)3267c478bd9Sstevel@tonic-gate tuncl_walk_fini(mdb_walk_state_t *wsp)
3277c478bd9Sstevel@tonic-gate {
3287c478bd9Sstevel@tonic-gate 	struct tcl_walk_data *twd;
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 	if (wsp != NULL && wsp->walk_addr != 0) {
3317c478bd9Sstevel@tonic-gate 		twd = (struct tcl_walk_data *)wsp->walk_addr;
3327c478bd9Sstevel@tonic-gate 		mdb_free(twd, sizeof (*twd) + ((twd->tcl_nslots - 1) *
3337c478bd9Sstevel@tonic-gate 		    sizeof (twd->tcl_slots[0])));
3347c478bd9Sstevel@tonic-gate 		wsp->walk_addr = 0;
3357c478bd9Sstevel@tonic-gate 	}
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate 
3387c478bd9Sstevel@tonic-gate static int
tuncl_walk_init(mdb_walk_state_t * wsp)3397c478bd9Sstevel@tonic-gate tuncl_walk_init(mdb_walk_state_t *wsp)
3407c478bd9Sstevel@tonic-gate {
3417c478bd9Sstevel@tonic-gate 	size_t tcl_nslots;
3427c478bd9Sstevel@tonic-gate 	tuncl_t **tcl_slots;
3437c478bd9Sstevel@tonic-gate 	struct tcl_walk_data *twd;
3447c478bd9Sstevel@tonic-gate 
3457c478bd9Sstevel@tonic-gate 	if (wsp == NULL)
3467c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr != 0)
3497c478bd9Sstevel@tonic-gate 		tuncl_walk_fini(wsp);
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&tcl_nslots, "tcl_nslots") == -1) {
3527c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read tcl_nslots");
3537c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
3547c478bd9Sstevel@tonic-gate 	}
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate 	if (tcl_nslots == 0)
3577c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
3587c478bd9Sstevel@tonic-gate 
3597c478bd9Sstevel@tonic-gate 	if (mdb_readvar(&tcl_slots, "tcl_slots") == -1) {
3607c478bd9Sstevel@tonic-gate 		mdb_warn("failed to read tcl_slots");
3617c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
3627c478bd9Sstevel@tonic-gate 	}
3637c478bd9Sstevel@tonic-gate 
3647c478bd9Sstevel@tonic-gate 	twd = (struct tcl_walk_data *)mdb_alloc(sizeof (*twd) +
3657c478bd9Sstevel@tonic-gate 	    (tcl_nslots - 1) * sizeof (*tcl_slots), UM_NOSLEEP);
3667c478bd9Sstevel@tonic-gate 	if (twd == NULL)
3677c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
3687c478bd9Sstevel@tonic-gate 	twd->tcl_nslots = tcl_nslots;
3697c478bd9Sstevel@tonic-gate 	twd->walkpos = 0;
3707c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)twd;
3717c478bd9Sstevel@tonic-gate 
3727c478bd9Sstevel@tonic-gate 	if (mdb_vread(twd->tcl_slots, tcl_nslots * sizeof (twd->tcl_slots[0]),
3737c478bd9Sstevel@tonic-gate 	    (uintptr_t)tcl_slots) == -1) {
3747c478bd9Sstevel@tonic-gate 		mdb_warn("can't read tcl_slots at %p", tcl_slots);
3757c478bd9Sstevel@tonic-gate 		tuncl_walk_fini(wsp);
3767c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
3777c478bd9Sstevel@tonic-gate 	}
3787c478bd9Sstevel@tonic-gate 
3797c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate 
3827c478bd9Sstevel@tonic-gate static int
tuncl_walk_step(mdb_walk_state_t * wsp)3837c478bd9Sstevel@tonic-gate tuncl_walk_step(mdb_walk_state_t *wsp)
3847c478bd9Sstevel@tonic-gate {
3857c478bd9Sstevel@tonic-gate 	tuncl_t tcl;
3867c478bd9Sstevel@tonic-gate 	int status;
3877c478bd9Sstevel@tonic-gate 	struct tcl_walk_data *twd;
3887c478bd9Sstevel@tonic-gate 	uintptr_t addr;
3897c478bd9Sstevel@tonic-gate 
390892ad162SToomas Soome 	if (wsp == NULL || wsp->walk_addr == 0)
3917c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	twd = (struct tcl_walk_data *)wsp->walk_addr;
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate 	while (twd->walkpos < twd->tcl_nslots &&
3967c478bd9Sstevel@tonic-gate 	    twd->tcl_slots[twd->walkpos] == NULL)
3977c478bd9Sstevel@tonic-gate 		twd->walkpos++;
3987c478bd9Sstevel@tonic-gate 	if (twd->walkpos >= twd->tcl_nslots)
3997c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate 	addr = (uintptr_t)twd->tcl_slots[twd->walkpos];
4027c478bd9Sstevel@tonic-gate 	if (mdb_vread(&tcl, sizeof (tcl), addr) == -1) {
4037c478bd9Sstevel@tonic-gate 		mdb_warn("can't read tuncl_t at %p", addr);
4047c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
4057c478bd9Sstevel@tonic-gate 	}
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 	status = wsp->walk_callback(addr, &tcl, wsp->walk_cbdata);
4087c478bd9Sstevel@tonic-gate 
4097c478bd9Sstevel@tonic-gate 	twd->walkpos++;
4107c478bd9Sstevel@tonic-gate 	return (status);
4117c478bd9Sstevel@tonic-gate }
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate /* ARGSUSED */
4147c478bd9Sstevel@tonic-gate static int
tuncl_format(uintptr_t addr,const tuncl_t * tcl,uint_t * qfmt)4157c478bd9Sstevel@tonic-gate tuncl_format(uintptr_t addr, const tuncl_t *tcl, uint_t *qfmt)
4167c478bd9Sstevel@tonic-gate {
417f53eecf5SJames Carlson 	mdb_printf("%?p %-6d %?p %?p", addr, tcl->tcl_zoneid, tcl->tcl_data_tll,
418f53eecf5SJames Carlson 	    tcl->tcl_ctrl_tll);
4197c478bd9Sstevel@tonic-gate 	mdb_printf(" %-2d %04X %04X ", tcl->tcl_style,
4207c478bd9Sstevel@tonic-gate 	    tcl->tcl_lsessid, tcl->tcl_rsessid);
4217c478bd9Sstevel@tonic-gate 	if (tcl->tcl_flags & TCLF_DAEMON) {
4227c478bd9Sstevel@tonic-gate 		mdb_printf("<daemon>\n");
4237c478bd9Sstevel@tonic-gate 	} else {
4247c478bd9Sstevel@tonic-gate 		mdb_printf("sppp%d\n", tcl->tcl_unit);
4257c478bd9Sstevel@tonic-gate 	}
4267c478bd9Sstevel@tonic-gate 
4277c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
4287c478bd9Sstevel@tonic-gate }
4297c478bd9Sstevel@tonic-gate 
4307c478bd9Sstevel@tonic-gate /* ARGSUSED */
4317c478bd9Sstevel@tonic-gate static int
tuncl(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)4327c478bd9Sstevel@tonic-gate tuncl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
4337c478bd9Sstevel@tonic-gate {
4347c478bd9Sstevel@tonic-gate 	uint_t qfmt = FALSE;
4357c478bd9Sstevel@tonic-gate 	tuncl_t tcl;
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
438f53eecf5SJames Carlson 		mdb_printf("%<u>%?s %-6s %?s %?s Ty LSes RSes %s%</u>\n",
439f53eecf5SJames Carlson 		    "Address", "ZoneID", "Data", "Control", "Interface");
4407c478bd9Sstevel@tonic-gate 	}
4417c478bd9Sstevel@tonic-gate 
4427c478bd9Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC) {
4437c478bd9Sstevel@tonic-gate 		if (mdb_vread(&tcl, sizeof (tcl), addr) == -1)
4447c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read tuncl_t at %p", addr);
4457c478bd9Sstevel@tonic-gate 		else
4467c478bd9Sstevel@tonic-gate 			tuncl_format(addr, &tcl, &qfmt);
4477c478bd9Sstevel@tonic-gate 	} else if (mdb_walk("tuncl", (mdb_walk_cb_t)tuncl_format, &qfmt) ==
4487c478bd9Sstevel@tonic-gate 	    -1) {
4497c478bd9Sstevel@tonic-gate 		mdb_warn("failed to walk tcl_slots");
4507c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
4517c478bd9Sstevel@tonic-gate 	}
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
4547c478bd9Sstevel@tonic-gate }
4557c478bd9Sstevel@tonic-gate 
4567c478bd9Sstevel@tonic-gate struct tll_walk_data {
4577c478bd9Sstevel@tonic-gate 	void *listhead;
4587c478bd9Sstevel@tonic-gate 	void *next;
4597c478bd9Sstevel@tonic-gate };
4607c478bd9Sstevel@tonic-gate 
4617c478bd9Sstevel@tonic-gate static void
tunll_walk_fini(mdb_walk_state_t * wsp)4627c478bd9Sstevel@tonic-gate tunll_walk_fini(mdb_walk_state_t *wsp)
4637c478bd9Sstevel@tonic-gate {
4647c478bd9Sstevel@tonic-gate 	struct tll_walk_data *twd;
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 	if (wsp != NULL && wsp->walk_addr != 0) {
4677c478bd9Sstevel@tonic-gate 		twd = (struct tll_walk_data *)wsp->walk_addr;
4687c478bd9Sstevel@tonic-gate 		mdb_free(twd, sizeof (*twd));
4697c478bd9Sstevel@tonic-gate 		wsp->walk_addr = 0;
4707c478bd9Sstevel@tonic-gate 	}
4717c478bd9Sstevel@tonic-gate }
4727c478bd9Sstevel@tonic-gate 
4737c478bd9Sstevel@tonic-gate static int
tunll_walk_init(mdb_walk_state_t * wsp)4747c478bd9Sstevel@tonic-gate tunll_walk_init(mdb_walk_state_t *wsp)
4757c478bd9Sstevel@tonic-gate {
4767c478bd9Sstevel@tonic-gate 	GElf_Sym sym;
4777c478bd9Sstevel@tonic-gate 	struct tll_walk_data *twd;
4787c478bd9Sstevel@tonic-gate 	struct qelem tunll_list;
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate 	if (wsp->walk_addr != 0)
4817c478bd9Sstevel@tonic-gate 		tunll_walk_fini(wsp);
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_obj("sppptun", "tunll_list", &sym) != 0) {
4847c478bd9Sstevel@tonic-gate 		mdb_warn("failed to find tunll_list");
4857c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
4867c478bd9Sstevel@tonic-gate 	}
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate 	if (mdb_vread(&tunll_list, sizeof (tunll_list),
4897c478bd9Sstevel@tonic-gate 	    (uintptr_t)sym.st_value) == -1) {
4907c478bd9Sstevel@tonic-gate 		mdb_warn("can't read tunll_list at %p",
4917c478bd9Sstevel@tonic-gate 		    (uintptr_t)sym.st_value);
4927c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
4937c478bd9Sstevel@tonic-gate 	}
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate 	twd = (struct tll_walk_data *)mdb_alloc(sizeof (*twd), UM_NOSLEEP);
4967c478bd9Sstevel@tonic-gate 	if (twd == NULL)
4977c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
4987c478bd9Sstevel@tonic-gate 	twd->listhead = (void *)(uintptr_t)sym.st_value;
4997c478bd9Sstevel@tonic-gate 	twd->next = (void *)tunll_list.q_forw;
5007c478bd9Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)twd;
5017c478bd9Sstevel@tonic-gate 
5027c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
5037c478bd9Sstevel@tonic-gate }
5047c478bd9Sstevel@tonic-gate 
5057c478bd9Sstevel@tonic-gate static int
tunll_walk_step(mdb_walk_state_t * wsp)5067c478bd9Sstevel@tonic-gate tunll_walk_step(mdb_walk_state_t *wsp)
5077c478bd9Sstevel@tonic-gate {
5087c478bd9Sstevel@tonic-gate 	struct tll_walk_data *twd;
5097c478bd9Sstevel@tonic-gate 	tunll_t tll;
5107c478bd9Sstevel@tonic-gate 	int status;
5117c478bd9Sstevel@tonic-gate 	uintptr_t addr;
5127c478bd9Sstevel@tonic-gate 
5137c478bd9Sstevel@tonic-gate 	if (wsp == NULL || wsp->walk_addr == 0)
5147c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate 	twd = (struct tll_walk_data *)wsp->walk_addr;
5177c478bd9Sstevel@tonic-gate 	if (twd->next == NULL || twd->next == twd->listhead)
5187c478bd9Sstevel@tonic-gate 		return (WALK_DONE);
5197c478bd9Sstevel@tonic-gate 
5207c478bd9Sstevel@tonic-gate 	/* LINTED */
5217c478bd9Sstevel@tonic-gate 	addr = (uintptr_t)TO_TLL(twd->next);
5227c478bd9Sstevel@tonic-gate 	if (mdb_vread(&tll, sizeof (tll), addr) == -1) {
5237c478bd9Sstevel@tonic-gate 		mdb_warn("can't read tunll_t at %p", addr);
5247c478bd9Sstevel@tonic-gate 		return (WALK_ERR);
5257c478bd9Sstevel@tonic-gate 	}
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 	status = wsp->walk_callback(addr, &tll, wsp->walk_cbdata);
5287c478bd9Sstevel@tonic-gate 
5297c478bd9Sstevel@tonic-gate 	twd->next = (void *)tll.tll_next;
5307c478bd9Sstevel@tonic-gate 	return (status);
5317c478bd9Sstevel@tonic-gate }
5327c478bd9Sstevel@tonic-gate 
5337c478bd9Sstevel@tonic-gate /* ARGSUSED */
5347c478bd9Sstevel@tonic-gate static int
tunll_format(uintptr_t addr,const tunll_t * tll,uint_t * qfmt)5357c478bd9Sstevel@tonic-gate tunll_format(uintptr_t addr, const tunll_t *tll, uint_t *qfmt)
5367c478bd9Sstevel@tonic-gate {
537f53eecf5SJames Carlson 	mdb_printf("%?p %-6d %-14s %?p", addr, tll->tll_zoneid, tll->tll_name,
538f53eecf5SJames Carlson 	    tll->tll_defcl);
5397c478bd9Sstevel@tonic-gate 	if (tll->tll_style == PTS_PPPOE) {
5407c478bd9Sstevel@tonic-gate 		mdb_printf(" %x:%x:%x:%x:%x:%x",
5417c478bd9Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[0],
5427c478bd9Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[1],
5437c478bd9Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[2],
5447c478bd9Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[3],
5457c478bd9Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[4],
5467c478bd9Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[5]);
5477c478bd9Sstevel@tonic-gate 	}
5487c478bd9Sstevel@tonic-gate 	mdb_printf("\n");
5497c478bd9Sstevel@tonic-gate 
5507c478bd9Sstevel@tonic-gate 	return (WALK_NEXT);
5517c478bd9Sstevel@tonic-gate }
5527c478bd9Sstevel@tonic-gate 
5537c478bd9Sstevel@tonic-gate /* ARGSUSED */
5547c478bd9Sstevel@tonic-gate static int
tunll(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)5557c478bd9Sstevel@tonic-gate tunll(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
5567c478bd9Sstevel@tonic-gate {
5577c478bd9Sstevel@tonic-gate 	uint_t qfmt = FALSE;
5587c478bd9Sstevel@tonic-gate 	tunll_t tll;
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
561f53eecf5SJames Carlson 		mdb_printf("%<u>%?s %-6s %-14s %?s %s%</u>\n", "Address",
562f53eecf5SJames Carlson 		    "ZoneID", "Interface Name", "Daemon", "Local Address");
5637c478bd9Sstevel@tonic-gate 	}
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC) {
5667c478bd9Sstevel@tonic-gate 		if (mdb_vread(&tll, sizeof (tll), addr) == -1)
5677c478bd9Sstevel@tonic-gate 			mdb_warn("failed to read tunll_t at %p", addr);
5687c478bd9Sstevel@tonic-gate 		else
5697c478bd9Sstevel@tonic-gate 			tunll_format(addr, &tll, &qfmt);
5707c478bd9Sstevel@tonic-gate 	} else if (mdb_walk("tunll", (mdb_walk_cb_t)tunll_format, &qfmt) ==
5717c478bd9Sstevel@tonic-gate 	    -1) {
5727c478bd9Sstevel@tonic-gate 		mdb_warn("failed to walk tunll_list");
5737c478bd9Sstevel@tonic-gate 		return (DCMD_ERR);
5747c478bd9Sstevel@tonic-gate 	}
5757c478bd9Sstevel@tonic-gate 
5767c478bd9Sstevel@tonic-gate 	return (DCMD_OK);
5777c478bd9Sstevel@tonic-gate }
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate union tun_state {
5807c478bd9Sstevel@tonic-gate 	uint32_t tunflags;
5817c478bd9Sstevel@tonic-gate 	tuncl_t tcl;
5827c478bd9Sstevel@tonic-gate 	tunll_t tll;
5837c478bd9Sstevel@tonic-gate };
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate static int
tun_state_read(void * ptr,union tun_state * ts)5867c478bd9Sstevel@tonic-gate tun_state_read(void *ptr, union tun_state *ts)
5877c478bd9Sstevel@tonic-gate {
5887c478bd9Sstevel@tonic-gate 	/*
5897c478bd9Sstevel@tonic-gate 	 * First, get the flags on this structure.  This is either a
5907c478bd9Sstevel@tonic-gate 	 * tuncl_t or a tunll_t.
5917c478bd9Sstevel@tonic-gate 	 */
5927c478bd9Sstevel@tonic-gate 	if (mdb_vread(&ts->tunflags, sizeof (ts->tunflags), (uintptr_t)ptr) ==
5937c478bd9Sstevel@tonic-gate 	    sizeof (ts->tunflags)) {
5947c478bd9Sstevel@tonic-gate 		if (ts->tunflags & TCLF_ISCLIENT) {
5957c478bd9Sstevel@tonic-gate 			if (mdb_vread(&ts->tcl, sizeof (ts->tcl),
5967c478bd9Sstevel@tonic-gate 			    (uintptr_t)ptr) == sizeof (ts->tcl)) {
5977c478bd9Sstevel@tonic-gate 				return (0);
5987c478bd9Sstevel@tonic-gate 			}
5997c478bd9Sstevel@tonic-gate 		} else {
6007c478bd9Sstevel@tonic-gate 			if (mdb_vread(&ts->tll, sizeof (ts->tll),
6017c478bd9Sstevel@tonic-gate 			    (uintptr_t)ptr) == sizeof (ts->tll)) {
6027c478bd9Sstevel@tonic-gate 				return (0);
6037c478bd9Sstevel@tonic-gate 			}
6047c478bd9Sstevel@tonic-gate 		}
6057c478bd9Sstevel@tonic-gate 	}
6067c478bd9Sstevel@tonic-gate 	return (-1);
6077c478bd9Sstevel@tonic-gate }
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate static void
sppptun_qinfo(const queue_t * q,char * buf,size_t nbytes)6107c478bd9Sstevel@tonic-gate sppptun_qinfo(const queue_t *q, char *buf, size_t nbytes)
6117c478bd9Sstevel@tonic-gate {
6127c478bd9Sstevel@tonic-gate 	union tun_state ts;
6137c478bd9Sstevel@tonic-gate 
6147c478bd9Sstevel@tonic-gate 	if (tun_state_read(q->q_ptr, &ts) == -1)
6157c478bd9Sstevel@tonic-gate 		return;
6167c478bd9Sstevel@tonic-gate 
6177c478bd9Sstevel@tonic-gate 	if (ts.tcl.tcl_flags & TCLF_ISCLIENT)
6187c478bd9Sstevel@tonic-gate 		mdb_snprintf(buf, nbytes, "sppp%d client %04X",
6197c478bd9Sstevel@tonic-gate 		    ts.tcl.tcl_unit, ts.tcl.tcl_lsessid);
6207c478bd9Sstevel@tonic-gate 	else
6217c478bd9Sstevel@tonic-gate 		mdb_snprintf(buf, nbytes, "%s", ts.tll.tll_name);
6227c478bd9Sstevel@tonic-gate }
6237c478bd9Sstevel@tonic-gate 
6247c478bd9Sstevel@tonic-gate static uintptr_t
sppptun_rnext(const queue_t * q)6257c478bd9Sstevel@tonic-gate sppptun_rnext(const queue_t *q)
6267c478bd9Sstevel@tonic-gate {
6277c478bd9Sstevel@tonic-gate 	union tun_state ts;
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate 	if (tun_state_read(q->q_ptr, &ts) == -1)
630892ad162SToomas Soome 		return (0);
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate 	if (ts.tcl.tcl_flags & TCLF_ISCLIENT) {
6337c478bd9Sstevel@tonic-gate 		return ((uintptr_t)ts.tcl.tcl_rq);
6347c478bd9Sstevel@tonic-gate 	} else {
6357c478bd9Sstevel@tonic-gate 		/* Not quite right, but ... */
6367c478bd9Sstevel@tonic-gate 		return ((uintptr_t)ts.tll.tll_defcl);
6377c478bd9Sstevel@tonic-gate 	}
6387c478bd9Sstevel@tonic-gate }
6397c478bd9Sstevel@tonic-gate 
6407c478bd9Sstevel@tonic-gate static uintptr_t
sppptun_wnext(const queue_t * q)6417c478bd9Sstevel@tonic-gate sppptun_wnext(const queue_t *q)
6427c478bd9Sstevel@tonic-gate {
6437c478bd9Sstevel@tonic-gate 	union tun_state ts;
6447c478bd9Sstevel@tonic-gate 
6457c478bd9Sstevel@tonic-gate 	if (tun_state_read(q->q_ptr, &ts) == -1)
646892ad162SToomas Soome 		return (0);
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate 	if (ts.tcl.tcl_flags & TCLF_ISCLIENT) {
6497c478bd9Sstevel@tonic-gate 		if (ts.tcl.tcl_data_tll == NULL)
650892ad162SToomas Soome 			return (0);
6517c478bd9Sstevel@tonic-gate 		if (mdb_vread(&ts.tll, sizeof (ts.tll),
6527c478bd9Sstevel@tonic-gate 		    (uintptr_t)ts.tcl.tcl_data_tll) != sizeof (ts.tll)) {
653892ad162SToomas Soome 			return (0);
6547c478bd9Sstevel@tonic-gate 		}
6557c478bd9Sstevel@tonic-gate 	}
6567c478bd9Sstevel@tonic-gate 	return ((uintptr_t)ts.tll.tll_wq);
6577c478bd9Sstevel@tonic-gate }
6587c478bd9Sstevel@tonic-gate 
6597c478bd9Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
6607c478bd9Sstevel@tonic-gate 	{ "sppp", "[-q]", "display PPP stream state structures", sppp },
6617c478bd9Sstevel@tonic-gate 	{ "sppa", "", "display PPP attachment state structures", sppa },
6627c478bd9Sstevel@tonic-gate 	{ "tuncl", "", "display sppptun client stream state structures",
6637c478bd9Sstevel@tonic-gate 	    tuncl },
6647c478bd9Sstevel@tonic-gate 	{ "tunll", "", "display sppptun lower stream state structures",
6657c478bd9Sstevel@tonic-gate 	    tunll },
6667c478bd9Sstevel@tonic-gate 	{ NULL }
6677c478bd9Sstevel@tonic-gate };
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
6707c478bd9Sstevel@tonic-gate 	{ "sppp", "walk active spppstr_t structures",
6717c478bd9Sstevel@tonic-gate 	    sppp_walk_init, sppp_walk_step, NULL },
6727c478bd9Sstevel@tonic-gate 	{ "sppa", "walk active sppa_t structures",
6737c478bd9Sstevel@tonic-gate 	    sppa_walk_init, sppa_walk_step, NULL },
6747c478bd9Sstevel@tonic-gate 	{ "tuncl", "walk active tuncl_t structures",
6757c478bd9Sstevel@tonic-gate 	    tuncl_walk_init, tuncl_walk_step, tuncl_walk_fini },
6767c478bd9Sstevel@tonic-gate 	{ "tunll", "walk active tunll_t structures",
6777c478bd9Sstevel@tonic-gate 	    tunll_walk_init, tunll_walk_step, tunll_walk_fini },
6787c478bd9Sstevel@tonic-gate 	{ NULL }
6797c478bd9Sstevel@tonic-gate };
6807c478bd9Sstevel@tonic-gate 
681*0c1b95beSRichard Lowe static const mdb_qops_t sppp_qops = {
682*0c1b95beSRichard Lowe 	.q_info = sppp_qinfo,
683*0c1b95beSRichard Lowe 	.q_rnext = sppp_rnext,
684*0c1b95beSRichard Lowe 	.q_wnext = sppp_wnext,
6857c478bd9Sstevel@tonic-gate };
686*0c1b95beSRichard Lowe 
687*0c1b95beSRichard Lowe static const mdb_qops_t sppptun_qops = {
688*0c1b95beSRichard Lowe 	.q_info = sppptun_qinfo,
689*0c1b95beSRichard Lowe 	.q_rnext = sppptun_rnext,
690*0c1b95beSRichard Lowe 	.q_wnext = sppptun_wnext,
691*0c1b95beSRichard Lowe };
692*0c1b95beSRichard Lowe 
6937c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
6947c478bd9Sstevel@tonic-gate 
6957c478bd9Sstevel@tonic-gate const mdb_modinfo_t *
_mdb_init(void)6967c478bd9Sstevel@tonic-gate _mdb_init(void)
6977c478bd9Sstevel@tonic-gate {
6987c478bd9Sstevel@tonic-gate 	GElf_Sym sym;
6997c478bd9Sstevel@tonic-gate 
7007c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_obj("sppp", "sppp_uwinit", &sym) == 0)
7017c478bd9Sstevel@tonic-gate 		mdb_qops_install(&sppp_qops, (uintptr_t)sym.st_value);
7027c478bd9Sstevel@tonic-gate 
7037c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_obj("sppptun", "sppptun_uwinit", &sym) == 0)
7047c478bd9Sstevel@tonic-gate 		mdb_qops_install(&sppptun_qops, (uintptr_t)sym.st_value);
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate 	return (&modinfo);
7077c478bd9Sstevel@tonic-gate }
7087c478bd9Sstevel@tonic-gate 
7097c478bd9Sstevel@tonic-gate void
_mdb_fini(void)7107c478bd9Sstevel@tonic-gate _mdb_fini(void)
7117c478bd9Sstevel@tonic-gate {
7127c478bd9Sstevel@tonic-gate 	GElf_Sym sym;
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_obj("sppptun", "sppptun_uwinit", &sym) == 0)
7157c478bd9Sstevel@tonic-gate 		mdb_qops_remove(&sppptun_qops, (uintptr_t)sym.st_value);
7167c478bd9Sstevel@tonic-gate 
7177c478bd9Sstevel@tonic-gate 	if (mdb_lookup_by_obj("sppp", "sppp_uwinit", &sym) == 0)
7187c478bd9Sstevel@tonic-gate 		mdb_qops_remove(&sppp_qops, (uintptr_t)sym.st_value);
7197c478bd9Sstevel@tonic-gate }
720