xref: /onnv-gate/usr/src/cmd/mdb/common/modules/sppp/sppp.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #include <sys/types.h>
30*0Sstevel@tonic-gate #include <sys/stropts.h>
31*0Sstevel@tonic-gate #include <sys/stream.h>
32*0Sstevel@tonic-gate #include <sys/socket.h>
33*0Sstevel@tonic-gate #include <net/if.h>
34*0Sstevel@tonic-gate #define	SOL2
35*0Sstevel@tonic-gate #include <net/ppp_defs.h>
36*0Sstevel@tonic-gate #include <net/pppio.h>
37*0Sstevel@tonic-gate #include <net/sppptun.h>
38*0Sstevel@tonic-gate #include <netinet/in.h>
39*0Sstevel@tonic-gate #include <netinet/ip6.h>
40*0Sstevel@tonic-gate #include <inet/common.h>
41*0Sstevel@tonic-gate #include <inet/mib2.h>
42*0Sstevel@tonic-gate #include <inet/ip.h>
43*0Sstevel@tonic-gate #include <inet/ip6.h>
44*0Sstevel@tonic-gate #include <sppp/sppp.h>
45*0Sstevel@tonic-gate #include <sppptun/sppptun_impl.h>
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate #include <mdb/mdb_modapi.h>
48*0Sstevel@tonic-gate #include <mdb/mdb_ks.h>
49*0Sstevel@tonic-gate #include <stdio.h>
50*0Sstevel@tonic-gate 
51*0Sstevel@tonic-gate /* ****************** sppp ****************** */
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate static int
54*0Sstevel@tonic-gate sppp_walk_init(mdb_walk_state_t *wsp)
55*0Sstevel@tonic-gate {
56*0Sstevel@tonic-gate 	if (mdb_readvar(&wsp->walk_addr, "sps_list") == -1) {
57*0Sstevel@tonic-gate 		mdb_warn("failed to read sps_list");
58*0Sstevel@tonic-gate 		return (WALK_ERR);
59*0Sstevel@tonic-gate 	}
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate 	return (WALK_NEXT);
62*0Sstevel@tonic-gate }
63*0Sstevel@tonic-gate 
64*0Sstevel@tonic-gate static int
65*0Sstevel@tonic-gate sppp_walk_step(mdb_walk_state_t *wsp)
66*0Sstevel@tonic-gate {
67*0Sstevel@tonic-gate 	spppstr_t sps;
68*0Sstevel@tonic-gate 	int status;
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate 	if (wsp->walk_addr == NULL)
71*0Sstevel@tonic-gate 		return (WALK_DONE);
72*0Sstevel@tonic-gate 
73*0Sstevel@tonic-gate 	if (mdb_vread(&sps, sizeof (sps), wsp->walk_addr) == -1) {
74*0Sstevel@tonic-gate 		mdb_warn("can't read spppstr_t at %p", wsp->walk_addr);
75*0Sstevel@tonic-gate 		return (WALK_ERR);
76*0Sstevel@tonic-gate 	}
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate 	status = (wsp->walk_callback(wsp->walk_addr, &sps, wsp->walk_cbdata));
79*0Sstevel@tonic-gate 
80*0Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)sps.sps_nextmn;
81*0Sstevel@tonic-gate 	return (status);
82*0Sstevel@tonic-gate }
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate static int
85*0Sstevel@tonic-gate sps_format(uintptr_t addr, const spppstr_t *sps, uint_t *qfmt)
86*0Sstevel@tonic-gate {
87*0Sstevel@tonic-gate 	sppa_t ppa;
88*0Sstevel@tonic-gate 	queue_t upq;
89*0Sstevel@tonic-gate 	uintptr_t upaddr, illaddr;
90*0Sstevel@tonic-gate 	ill_t ill;
91*0Sstevel@tonic-gate 	ipif_t ipif;
92*0Sstevel@tonic-gate 
93*0Sstevel@tonic-gate 	mdb_printf("%?p ", addr);
94*0Sstevel@tonic-gate 	if (*qfmt)
95*0Sstevel@tonic-gate 		mdb_printf("%?p ", sps->sps_rq);
96*0Sstevel@tonic-gate 	if (sps->sps_ppa == NULL) {
97*0Sstevel@tonic-gate 		mdb_printf("unset    ");
98*0Sstevel@tonic-gate 	} else if (mdb_vread(&ppa, sizeof (ppa), (uintptr_t)sps->sps_ppa) ==
99*0Sstevel@tonic-gate 	    -1) {
100*0Sstevel@tonic-gate 		mdb_printf("?%p ", sps->sps_ppa);
101*0Sstevel@tonic-gate 	} else {
102*0Sstevel@tonic-gate 		mdb_printf("sppp%-5d ", ppa.ppa_ppa_id);
103*0Sstevel@tonic-gate 	}
104*0Sstevel@tonic-gate 	if (IS_SPS_CONTROL(sps)) {
105*0Sstevel@tonic-gate 		mdb_printf("Control\n");
106*0Sstevel@tonic-gate 	} else if (IS_SPS_PIOATTACH(sps)) {
107*0Sstevel@tonic-gate 		mdb_printf("Stats\n");
108*0Sstevel@tonic-gate 	} else if (sps->sps_dlstate == DL_UNATTACHED) {
109*0Sstevel@tonic-gate 		mdb_printf("Unknown\n");
110*0Sstevel@tonic-gate 	} else if (sps->sps_dlstate != DL_IDLE) {
111*0Sstevel@tonic-gate 		mdb_printf("DLPI Unbound\n");
112*0Sstevel@tonic-gate 	} else {
113*0Sstevel@tonic-gate 		upaddr = (uintptr_t)sps->sps_rq;
114*0Sstevel@tonic-gate 		upq.q_ptr = NULL;
115*0Sstevel@tonic-gate 		illaddr = 0;
116*0Sstevel@tonic-gate 		while (upaddr != NULL) {
117*0Sstevel@tonic-gate 			if (mdb_vread(&upq, sizeof (upq), upaddr) == -1) {
118*0Sstevel@tonic-gate 				upq.q_ptr = NULL;
119*0Sstevel@tonic-gate 				break;
120*0Sstevel@tonic-gate 			}
121*0Sstevel@tonic-gate 			if ((upaddr = (uintptr_t)upq.q_next) != 0)
122*0Sstevel@tonic-gate 				illaddr = (uintptr_t)upq.q_ptr;
123*0Sstevel@tonic-gate 		}
124*0Sstevel@tonic-gate 		if (illaddr != 0) {
125*0Sstevel@tonic-gate 			if (mdb_vread(&ill, sizeof (ill), illaddr) == -1 ||
126*0Sstevel@tonic-gate 			    mdb_vread(&ipif, sizeof (ipif),
127*0Sstevel@tonic-gate 				(uintptr_t)ill.ill_ipif) == -1) {
128*0Sstevel@tonic-gate 				illaddr = 0;
129*0Sstevel@tonic-gate 			}
130*0Sstevel@tonic-gate 		}
131*0Sstevel@tonic-gate 
132*0Sstevel@tonic-gate 		switch (sps->sps_req_sap) {
133*0Sstevel@tonic-gate 		case ETHERTYPE_IP:
134*0Sstevel@tonic-gate 			mdb_printf("DLPI IPv4 ");
135*0Sstevel@tonic-gate 			if (*qfmt) {
136*0Sstevel@tonic-gate 				mdb_printf("\n");
137*0Sstevel@tonic-gate 			} else if (illaddr == 0) {
138*0Sstevel@tonic-gate 				mdb_printf("(no addresses)\n");
139*0Sstevel@tonic-gate 			} else {
140*0Sstevel@tonic-gate 				/*
141*0Sstevel@tonic-gate 				 * SCCS oddity here -- % <capital> %
142*0Sstevel@tonic-gate 				 * suffers from keyword replacement.
143*0Sstevel@tonic-gate 				 * Avoid that by using ANSI string
144*0Sstevel@tonic-gate 				 * pasting.
145*0Sstevel@tonic-gate 				 */
146*0Sstevel@tonic-gate 				mdb_printf("%I:%I" "%s\n",
147*0Sstevel@tonic-gate 				    ipif.ipif_lcl_addr, ipif.ipif_pp_dst_addr,
148*0Sstevel@tonic-gate 				    (ipif.ipif_next ? " ..." : ""));
149*0Sstevel@tonic-gate 			}
150*0Sstevel@tonic-gate 			break;
151*0Sstevel@tonic-gate 		case ETHERTYPE_IPV6:
152*0Sstevel@tonic-gate 			mdb_printf("DLPI IPv6 ");
153*0Sstevel@tonic-gate 			if (*qfmt) {
154*0Sstevel@tonic-gate 				mdb_printf("\n");
155*0Sstevel@tonic-gate 				break;
156*0Sstevel@tonic-gate 			}
157*0Sstevel@tonic-gate 			if (illaddr == 0) {
158*0Sstevel@tonic-gate 				mdb_printf("(no addresses)\n");
159*0Sstevel@tonic-gate 				break;
160*0Sstevel@tonic-gate 			}
161*0Sstevel@tonic-gate 			mdb_printf("%N\n%?s%21s", &ipif.ipif_v6lcl_addr,
162*0Sstevel@tonic-gate 			    "", "");
163*0Sstevel@tonic-gate 			mdb_printf("%N\n", &ipif.ipif_v6pp_dst_addr);
164*0Sstevel@tonic-gate 			break;
165*0Sstevel@tonic-gate 		case ETHERTYPE_ALLSAP:
166*0Sstevel@tonic-gate 			mdb_printf("DLPI Snoop\n");
167*0Sstevel@tonic-gate 			break;
168*0Sstevel@tonic-gate 		default:
169*0Sstevel@tonic-gate 			mdb_printf("DLPI SAP 0x%04X\n", sps->sps_req_sap);
170*0Sstevel@tonic-gate 			break;
171*0Sstevel@tonic-gate 		}
172*0Sstevel@tonic-gate 	}
173*0Sstevel@tonic-gate 
174*0Sstevel@tonic-gate 	return (WALK_NEXT);
175*0Sstevel@tonic-gate }
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate static int
178*0Sstevel@tonic-gate sppp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
179*0Sstevel@tonic-gate {
180*0Sstevel@tonic-gate 	uint_t qfmt = FALSE;
181*0Sstevel@tonic-gate 	spppstr_t sps;
182*0Sstevel@tonic-gate 
183*0Sstevel@tonic-gate 	if (mdb_getopts(argc, argv, 'q', MDB_OPT_SETBITS, TRUE, &qfmt, NULL) !=
184*0Sstevel@tonic-gate 	    argc)
185*0Sstevel@tonic-gate 		return (DCMD_USAGE);
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
188*0Sstevel@tonic-gate 		if (qfmt) {
189*0Sstevel@tonic-gate 			mdb_printf("%<u>%?s %?s %9s %s%</u>\n", "Address",
190*0Sstevel@tonic-gate 			    "RecvQ", "Interface", "Type");
191*0Sstevel@tonic-gate 		} else {
192*0Sstevel@tonic-gate 			mdb_printf("%<u>%?s %9s %s%</u>\n", "Address",
193*0Sstevel@tonic-gate 			    "Interface", "Type");
194*0Sstevel@tonic-gate 		}
195*0Sstevel@tonic-gate 	}
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC) {
198*0Sstevel@tonic-gate 		(void) mdb_vread(&sps, sizeof (sps), addr);
199*0Sstevel@tonic-gate 		(void) sps_format(addr, &sps, &qfmt);
200*0Sstevel@tonic-gate 	} else if (mdb_walk("sppp", (mdb_walk_cb_t)sps_format, &qfmt) == -1) {
201*0Sstevel@tonic-gate 		mdb_warn("failed to walk sps_list");
202*0Sstevel@tonic-gate 		return (DCMD_ERR);
203*0Sstevel@tonic-gate 	}
204*0Sstevel@tonic-gate 
205*0Sstevel@tonic-gate 	return (DCMD_OK);
206*0Sstevel@tonic-gate }
207*0Sstevel@tonic-gate 
208*0Sstevel@tonic-gate static int
209*0Sstevel@tonic-gate sppa_walk_init(mdb_walk_state_t *wsp)
210*0Sstevel@tonic-gate {
211*0Sstevel@tonic-gate 	if (mdb_readvar(&wsp->walk_addr, "ppa_list") == -1) {
212*0Sstevel@tonic-gate 		mdb_warn("failed to read ppa_list");
213*0Sstevel@tonic-gate 		return (WALK_ERR);
214*0Sstevel@tonic-gate 	}
215*0Sstevel@tonic-gate 
216*0Sstevel@tonic-gate 	return (WALK_NEXT);
217*0Sstevel@tonic-gate }
218*0Sstevel@tonic-gate 
219*0Sstevel@tonic-gate static int
220*0Sstevel@tonic-gate sppa_walk_step(mdb_walk_state_t *wsp)
221*0Sstevel@tonic-gate {
222*0Sstevel@tonic-gate 	sppa_t ppa;
223*0Sstevel@tonic-gate 	int status;
224*0Sstevel@tonic-gate 
225*0Sstevel@tonic-gate 	if (wsp->walk_addr == NULL)
226*0Sstevel@tonic-gate 		return (WALK_DONE);
227*0Sstevel@tonic-gate 
228*0Sstevel@tonic-gate 	if (mdb_vread(&ppa, sizeof (ppa), wsp->walk_addr) == -1) {
229*0Sstevel@tonic-gate 		mdb_warn("can't read spppstr_t at %p", wsp->walk_addr);
230*0Sstevel@tonic-gate 		return (WALK_ERR);
231*0Sstevel@tonic-gate 	}
232*0Sstevel@tonic-gate 
233*0Sstevel@tonic-gate 	status = (wsp->walk_callback(wsp->walk_addr, &ppa, wsp->walk_cbdata));
234*0Sstevel@tonic-gate 
235*0Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)ppa.ppa_nextppa;
236*0Sstevel@tonic-gate 	return (status);
237*0Sstevel@tonic-gate }
238*0Sstevel@tonic-gate 
239*0Sstevel@tonic-gate /* ARGSUSED */
240*0Sstevel@tonic-gate static int
241*0Sstevel@tonic-gate ppa_format(uintptr_t addr, const sppa_t *ppa, uint_t *qfmt)
242*0Sstevel@tonic-gate {
243*0Sstevel@tonic-gate 	mdb_printf("%?p sppp%-5d %?p %?p\n", addr, ppa->ppa_ppa_id,
244*0Sstevel@tonic-gate 	    ppa->ppa_ctl, ppa->ppa_lower_wq);
245*0Sstevel@tonic-gate 
246*0Sstevel@tonic-gate 	return (WALK_NEXT);
247*0Sstevel@tonic-gate }
248*0Sstevel@tonic-gate 
249*0Sstevel@tonic-gate /* ARGSUSED */
250*0Sstevel@tonic-gate static int
251*0Sstevel@tonic-gate sppa(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
252*0Sstevel@tonic-gate {
253*0Sstevel@tonic-gate 	uint_t qfmt = FALSE;
254*0Sstevel@tonic-gate 	sppa_t ppa;
255*0Sstevel@tonic-gate 
256*0Sstevel@tonic-gate 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
257*0Sstevel@tonic-gate 		mdb_printf("%<u>%?s %9s %?s %?s%</u>\n", "Address",
258*0Sstevel@tonic-gate 		    "Interface", "Control", "LowerQ");
259*0Sstevel@tonic-gate 	}
260*0Sstevel@tonic-gate 
261*0Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC) {
262*0Sstevel@tonic-gate 		(void) mdb_vread(&ppa, sizeof (ppa), addr);
263*0Sstevel@tonic-gate 		(void) ppa_format(addr, &ppa, &qfmt);
264*0Sstevel@tonic-gate 	} else if (mdb_walk("sppa", (mdb_walk_cb_t)ppa_format, &qfmt) == -1) {
265*0Sstevel@tonic-gate 		mdb_warn("failed to walk ppa_list");
266*0Sstevel@tonic-gate 		return (DCMD_ERR);
267*0Sstevel@tonic-gate 	}
268*0Sstevel@tonic-gate 
269*0Sstevel@tonic-gate 	return (DCMD_OK);
270*0Sstevel@tonic-gate }
271*0Sstevel@tonic-gate 
272*0Sstevel@tonic-gate static void
273*0Sstevel@tonic-gate sppp_qinfo(const queue_t *q, char *buf, size_t nbytes)
274*0Sstevel@tonic-gate {
275*0Sstevel@tonic-gate 	spppstr_t sps;
276*0Sstevel@tonic-gate 	sppa_t ppa;
277*0Sstevel@tonic-gate 
278*0Sstevel@tonic-gate 	if (mdb_vread(&sps, sizeof (sps), (uintptr_t)q->q_ptr) ==
279*0Sstevel@tonic-gate 	    sizeof (sps)) {
280*0Sstevel@tonic-gate 		if (sps.sps_ppa == NULL ||
281*0Sstevel@tonic-gate 		    mdb_vread(&ppa, sizeof (ppa), (uintptr_t)sps.sps_ppa) ==
282*0Sstevel@tonic-gate 		    -1) {
283*0Sstevel@tonic-gate 			(void) mdb_snprintf(buf, nbytes, "minor %d",
284*0Sstevel@tonic-gate 			    sps.sps_mn_id);
285*0Sstevel@tonic-gate 		} else {
286*0Sstevel@tonic-gate 			(void) mdb_snprintf(buf, nbytes, "sppp%d",
287*0Sstevel@tonic-gate 			    ppa.ppa_ppa_id);
288*0Sstevel@tonic-gate 		}
289*0Sstevel@tonic-gate 	}
290*0Sstevel@tonic-gate }
291*0Sstevel@tonic-gate 
292*0Sstevel@tonic-gate static uintptr_t
293*0Sstevel@tonic-gate sppp_rnext(const queue_t *q)
294*0Sstevel@tonic-gate {
295*0Sstevel@tonic-gate 	spppstr_t sps;
296*0Sstevel@tonic-gate 
297*0Sstevel@tonic-gate 	if (mdb_vread(&sps, sizeof (sps), (uintptr_t)q->q_ptr) == sizeof (sps))
298*0Sstevel@tonic-gate 		return ((uintptr_t)sps.sps_rq);
299*0Sstevel@tonic-gate 
300*0Sstevel@tonic-gate 	return (NULL);
301*0Sstevel@tonic-gate }
302*0Sstevel@tonic-gate 
303*0Sstevel@tonic-gate static uintptr_t
304*0Sstevel@tonic-gate sppp_wnext(const queue_t *q)
305*0Sstevel@tonic-gate {
306*0Sstevel@tonic-gate 	spppstr_t sps;
307*0Sstevel@tonic-gate 	sppa_t ppa;
308*0Sstevel@tonic-gate 
309*0Sstevel@tonic-gate 	if (mdb_vread(&sps, sizeof (sps), (uintptr_t)q->q_ptr) != sizeof (sps))
310*0Sstevel@tonic-gate 		return (NULL);
311*0Sstevel@tonic-gate 
312*0Sstevel@tonic-gate 	if (sps.sps_ppa != NULL &&
313*0Sstevel@tonic-gate 	    mdb_vread(&ppa, sizeof (ppa), (uintptr_t)sps.sps_ppa) ==
314*0Sstevel@tonic-gate 	    sizeof (ppa))
315*0Sstevel@tonic-gate 		return ((uintptr_t)ppa.ppa_lower_wq);
316*0Sstevel@tonic-gate 
317*0Sstevel@tonic-gate 	return (NULL);
318*0Sstevel@tonic-gate }
319*0Sstevel@tonic-gate 
320*0Sstevel@tonic-gate /* ****************** sppptun ****************** */
321*0Sstevel@tonic-gate 
322*0Sstevel@tonic-gate struct tcl_walk_data {
323*0Sstevel@tonic-gate 	size_t tcl_nslots;
324*0Sstevel@tonic-gate 	size_t walkpos;
325*0Sstevel@tonic-gate 	tuncl_t *tcl_slots[1];
326*0Sstevel@tonic-gate };
327*0Sstevel@tonic-gate 
328*0Sstevel@tonic-gate static void
329*0Sstevel@tonic-gate tuncl_walk_fini(mdb_walk_state_t *wsp)
330*0Sstevel@tonic-gate {
331*0Sstevel@tonic-gate 	struct tcl_walk_data *twd;
332*0Sstevel@tonic-gate 
333*0Sstevel@tonic-gate 	if (wsp != NULL && wsp->walk_addr != 0) {
334*0Sstevel@tonic-gate 		twd = (struct tcl_walk_data *)wsp->walk_addr;
335*0Sstevel@tonic-gate 		mdb_free(twd, sizeof (*twd) + ((twd->tcl_nslots - 1) *
336*0Sstevel@tonic-gate 		    sizeof (twd->tcl_slots[0])));
337*0Sstevel@tonic-gate 		wsp->walk_addr = 0;
338*0Sstevel@tonic-gate 	}
339*0Sstevel@tonic-gate }
340*0Sstevel@tonic-gate 
341*0Sstevel@tonic-gate static int
342*0Sstevel@tonic-gate tuncl_walk_init(mdb_walk_state_t *wsp)
343*0Sstevel@tonic-gate {
344*0Sstevel@tonic-gate 	size_t tcl_nslots;
345*0Sstevel@tonic-gate 	tuncl_t **tcl_slots;
346*0Sstevel@tonic-gate 	struct tcl_walk_data *twd;
347*0Sstevel@tonic-gate 
348*0Sstevel@tonic-gate 	if (wsp == NULL)
349*0Sstevel@tonic-gate 		return (WALK_ERR);
350*0Sstevel@tonic-gate 
351*0Sstevel@tonic-gate 	if (wsp->walk_addr != 0)
352*0Sstevel@tonic-gate 		tuncl_walk_fini(wsp);
353*0Sstevel@tonic-gate 
354*0Sstevel@tonic-gate 	if (mdb_readvar(&tcl_nslots, "tcl_nslots") == -1) {
355*0Sstevel@tonic-gate 		mdb_warn("failed to read tcl_nslots");
356*0Sstevel@tonic-gate 		return (WALK_ERR);
357*0Sstevel@tonic-gate 	}
358*0Sstevel@tonic-gate 
359*0Sstevel@tonic-gate 	if (tcl_nslots == 0)
360*0Sstevel@tonic-gate 		return (WALK_DONE);
361*0Sstevel@tonic-gate 
362*0Sstevel@tonic-gate 	if (mdb_readvar(&tcl_slots, "tcl_slots") == -1) {
363*0Sstevel@tonic-gate 		mdb_warn("failed to read tcl_slots");
364*0Sstevel@tonic-gate 		return (WALK_ERR);
365*0Sstevel@tonic-gate 	}
366*0Sstevel@tonic-gate 
367*0Sstevel@tonic-gate 	twd = (struct tcl_walk_data *)mdb_alloc(sizeof (*twd) +
368*0Sstevel@tonic-gate 	    (tcl_nslots - 1) * sizeof (*tcl_slots), UM_NOSLEEP);
369*0Sstevel@tonic-gate 	if (twd == NULL)
370*0Sstevel@tonic-gate 		return (WALK_ERR);
371*0Sstevel@tonic-gate 	twd->tcl_nslots = tcl_nslots;
372*0Sstevel@tonic-gate 	twd->walkpos = 0;
373*0Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)twd;
374*0Sstevel@tonic-gate 
375*0Sstevel@tonic-gate 	if (mdb_vread(twd->tcl_slots, tcl_nslots * sizeof (twd->tcl_slots[0]),
376*0Sstevel@tonic-gate 	    (uintptr_t)tcl_slots) == -1) {
377*0Sstevel@tonic-gate 		mdb_warn("can't read tcl_slots at %p", tcl_slots);
378*0Sstevel@tonic-gate 		tuncl_walk_fini(wsp);
379*0Sstevel@tonic-gate 		return (WALK_ERR);
380*0Sstevel@tonic-gate 	}
381*0Sstevel@tonic-gate 
382*0Sstevel@tonic-gate 	return (WALK_NEXT);
383*0Sstevel@tonic-gate }
384*0Sstevel@tonic-gate 
385*0Sstevel@tonic-gate static int
386*0Sstevel@tonic-gate tuncl_walk_step(mdb_walk_state_t *wsp)
387*0Sstevel@tonic-gate {
388*0Sstevel@tonic-gate 	tuncl_t tcl;
389*0Sstevel@tonic-gate 	int status;
390*0Sstevel@tonic-gate 	struct tcl_walk_data *twd;
391*0Sstevel@tonic-gate 	uintptr_t addr;
392*0Sstevel@tonic-gate 
393*0Sstevel@tonic-gate 	if (wsp == NULL || wsp->walk_addr == NULL)
394*0Sstevel@tonic-gate 		return (WALK_DONE);
395*0Sstevel@tonic-gate 
396*0Sstevel@tonic-gate 	twd = (struct tcl_walk_data *)wsp->walk_addr;
397*0Sstevel@tonic-gate 
398*0Sstevel@tonic-gate 	while (twd->walkpos < twd->tcl_nslots &&
399*0Sstevel@tonic-gate 	    twd->tcl_slots[twd->walkpos] == NULL)
400*0Sstevel@tonic-gate 		twd->walkpos++;
401*0Sstevel@tonic-gate 	if (twd->walkpos >= twd->tcl_nslots)
402*0Sstevel@tonic-gate 		return (WALK_DONE);
403*0Sstevel@tonic-gate 
404*0Sstevel@tonic-gate 	addr = (uintptr_t)twd->tcl_slots[twd->walkpos];
405*0Sstevel@tonic-gate 	if (mdb_vread(&tcl, sizeof (tcl), addr) == -1) {
406*0Sstevel@tonic-gate 		mdb_warn("can't read tuncl_t at %p", addr);
407*0Sstevel@tonic-gate 		return (WALK_ERR);
408*0Sstevel@tonic-gate 	}
409*0Sstevel@tonic-gate 
410*0Sstevel@tonic-gate 	status = wsp->walk_callback(addr, &tcl, wsp->walk_cbdata);
411*0Sstevel@tonic-gate 
412*0Sstevel@tonic-gate 	twd->walkpos++;
413*0Sstevel@tonic-gate 	return (status);
414*0Sstevel@tonic-gate }
415*0Sstevel@tonic-gate 
416*0Sstevel@tonic-gate /* ARGSUSED */
417*0Sstevel@tonic-gate static int
418*0Sstevel@tonic-gate tuncl_format(uintptr_t addr, const tuncl_t *tcl, uint_t *qfmt)
419*0Sstevel@tonic-gate {
420*0Sstevel@tonic-gate 	mdb_printf("%?p %?p %?p", addr, tcl->tcl_data_tll, tcl->tcl_ctrl_tll);
421*0Sstevel@tonic-gate 	mdb_printf(" %-2d %04X %04X ", tcl->tcl_style,
422*0Sstevel@tonic-gate 	    tcl->tcl_lsessid, tcl->tcl_rsessid);
423*0Sstevel@tonic-gate 	if (tcl->tcl_flags & TCLF_DAEMON) {
424*0Sstevel@tonic-gate 		mdb_printf("<daemon>\n");
425*0Sstevel@tonic-gate 	} else {
426*0Sstevel@tonic-gate 		mdb_printf("sppp%d\n", tcl->tcl_unit);
427*0Sstevel@tonic-gate 	}
428*0Sstevel@tonic-gate 
429*0Sstevel@tonic-gate 	return (WALK_NEXT);
430*0Sstevel@tonic-gate }
431*0Sstevel@tonic-gate 
432*0Sstevel@tonic-gate /* ARGSUSED */
433*0Sstevel@tonic-gate static int
434*0Sstevel@tonic-gate tuncl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
435*0Sstevel@tonic-gate {
436*0Sstevel@tonic-gate 	uint_t qfmt = FALSE;
437*0Sstevel@tonic-gate 	tuncl_t tcl;
438*0Sstevel@tonic-gate 
439*0Sstevel@tonic-gate 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
440*0Sstevel@tonic-gate 		mdb_printf("%<u>%?s %?s %?s Ty LSes RSes %s%</u>\n", "Address",
441*0Sstevel@tonic-gate 		    "Data", "Control", "Interface");
442*0Sstevel@tonic-gate 	}
443*0Sstevel@tonic-gate 
444*0Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC) {
445*0Sstevel@tonic-gate 		if (mdb_vread(&tcl, sizeof (tcl), addr) == -1)
446*0Sstevel@tonic-gate 			mdb_warn("failed to read tuncl_t at %p", addr);
447*0Sstevel@tonic-gate 		else
448*0Sstevel@tonic-gate 			tuncl_format(addr, &tcl, &qfmt);
449*0Sstevel@tonic-gate 	} else if (mdb_walk("tuncl", (mdb_walk_cb_t)tuncl_format, &qfmt) ==
450*0Sstevel@tonic-gate 	    -1) {
451*0Sstevel@tonic-gate 		mdb_warn("failed to walk tcl_slots");
452*0Sstevel@tonic-gate 		return (DCMD_ERR);
453*0Sstevel@tonic-gate 	}
454*0Sstevel@tonic-gate 
455*0Sstevel@tonic-gate 	return (DCMD_OK);
456*0Sstevel@tonic-gate }
457*0Sstevel@tonic-gate 
458*0Sstevel@tonic-gate struct tll_walk_data {
459*0Sstevel@tonic-gate 	void *listhead;
460*0Sstevel@tonic-gate 	void *next;
461*0Sstevel@tonic-gate };
462*0Sstevel@tonic-gate 
463*0Sstevel@tonic-gate static void
464*0Sstevel@tonic-gate tunll_walk_fini(mdb_walk_state_t *wsp)
465*0Sstevel@tonic-gate {
466*0Sstevel@tonic-gate 	struct tll_walk_data *twd;
467*0Sstevel@tonic-gate 
468*0Sstevel@tonic-gate 	if (wsp != NULL && wsp->walk_addr != 0) {
469*0Sstevel@tonic-gate 		twd = (struct tll_walk_data *)wsp->walk_addr;
470*0Sstevel@tonic-gate 		mdb_free(twd, sizeof (*twd));
471*0Sstevel@tonic-gate 		wsp->walk_addr = 0;
472*0Sstevel@tonic-gate 	}
473*0Sstevel@tonic-gate }
474*0Sstevel@tonic-gate 
475*0Sstevel@tonic-gate static int
476*0Sstevel@tonic-gate tunll_walk_init(mdb_walk_state_t *wsp)
477*0Sstevel@tonic-gate {
478*0Sstevel@tonic-gate 	GElf_Sym sym;
479*0Sstevel@tonic-gate 	struct tll_walk_data *twd;
480*0Sstevel@tonic-gate 	struct qelem tunll_list;
481*0Sstevel@tonic-gate 
482*0Sstevel@tonic-gate 	if (wsp->walk_addr != 0)
483*0Sstevel@tonic-gate 		tunll_walk_fini(wsp);
484*0Sstevel@tonic-gate 
485*0Sstevel@tonic-gate 	if (mdb_lookup_by_obj("sppptun", "tunll_list", &sym) != 0) {
486*0Sstevel@tonic-gate 		mdb_warn("failed to find tunll_list");
487*0Sstevel@tonic-gate 		return (WALK_ERR);
488*0Sstevel@tonic-gate 	}
489*0Sstevel@tonic-gate 
490*0Sstevel@tonic-gate 	if (mdb_vread(&tunll_list, sizeof (tunll_list),
491*0Sstevel@tonic-gate 	    (uintptr_t)sym.st_value) == -1) {
492*0Sstevel@tonic-gate 		mdb_warn("can't read tunll_list at %p",
493*0Sstevel@tonic-gate 		    (uintptr_t)sym.st_value);
494*0Sstevel@tonic-gate 		return (WALK_ERR);
495*0Sstevel@tonic-gate 	}
496*0Sstevel@tonic-gate 
497*0Sstevel@tonic-gate 	twd = (struct tll_walk_data *)mdb_alloc(sizeof (*twd), UM_NOSLEEP);
498*0Sstevel@tonic-gate 	if (twd == NULL)
499*0Sstevel@tonic-gate 		return (WALK_ERR);
500*0Sstevel@tonic-gate 	twd->listhead = (void *)(uintptr_t)sym.st_value;
501*0Sstevel@tonic-gate 	twd->next = (void *)tunll_list.q_forw;
502*0Sstevel@tonic-gate 	wsp->walk_addr = (uintptr_t)twd;
503*0Sstevel@tonic-gate 
504*0Sstevel@tonic-gate 	return (WALK_NEXT);
505*0Sstevel@tonic-gate }
506*0Sstevel@tonic-gate 
507*0Sstevel@tonic-gate static int
508*0Sstevel@tonic-gate tunll_walk_step(mdb_walk_state_t *wsp)
509*0Sstevel@tonic-gate {
510*0Sstevel@tonic-gate 	struct tll_walk_data *twd;
511*0Sstevel@tonic-gate 	tunll_t tll;
512*0Sstevel@tonic-gate 	int status;
513*0Sstevel@tonic-gate 	uintptr_t addr;
514*0Sstevel@tonic-gate 
515*0Sstevel@tonic-gate 	if (wsp == NULL || wsp->walk_addr == 0)
516*0Sstevel@tonic-gate 		return (WALK_DONE);
517*0Sstevel@tonic-gate 
518*0Sstevel@tonic-gate 	twd = (struct tll_walk_data *)wsp->walk_addr;
519*0Sstevel@tonic-gate 	if (twd->next == NULL || twd->next == twd->listhead)
520*0Sstevel@tonic-gate 		return (WALK_DONE);
521*0Sstevel@tonic-gate 
522*0Sstevel@tonic-gate 	/* LINTED */
523*0Sstevel@tonic-gate 	addr = (uintptr_t)TO_TLL(twd->next);
524*0Sstevel@tonic-gate 	if (mdb_vread(&tll, sizeof (tll), addr) == -1) {
525*0Sstevel@tonic-gate 		mdb_warn("can't read tunll_t at %p", addr);
526*0Sstevel@tonic-gate 		return (WALK_ERR);
527*0Sstevel@tonic-gate 	}
528*0Sstevel@tonic-gate 
529*0Sstevel@tonic-gate 	status = wsp->walk_callback(addr, &tll, wsp->walk_cbdata);
530*0Sstevel@tonic-gate 
531*0Sstevel@tonic-gate 	twd->next = (void *)tll.tll_next;
532*0Sstevel@tonic-gate 	return (status);
533*0Sstevel@tonic-gate }
534*0Sstevel@tonic-gate 
535*0Sstevel@tonic-gate /* ARGSUSED */
536*0Sstevel@tonic-gate static int
537*0Sstevel@tonic-gate tunll_format(uintptr_t addr, const tunll_t *tll, uint_t *qfmt)
538*0Sstevel@tonic-gate {
539*0Sstevel@tonic-gate 	mdb_printf("%?p %-14s %?p", addr, tll->tll_name, tll->tll_defcl);
540*0Sstevel@tonic-gate 	if (tll->tll_style == PTS_PPPOE) {
541*0Sstevel@tonic-gate 		mdb_printf(" %x:%x:%x:%x:%x:%x",
542*0Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[0],
543*0Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[1],
544*0Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[2],
545*0Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[3],
546*0Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[4],
547*0Sstevel@tonic-gate 		    tll->tll_lcladdr.pta_pppoe.ptma_mac[5]);
548*0Sstevel@tonic-gate 	}
549*0Sstevel@tonic-gate 	mdb_printf("\n");
550*0Sstevel@tonic-gate 
551*0Sstevel@tonic-gate 	return (WALK_NEXT);
552*0Sstevel@tonic-gate }
553*0Sstevel@tonic-gate 
554*0Sstevel@tonic-gate /* ARGSUSED */
555*0Sstevel@tonic-gate static int
556*0Sstevel@tonic-gate tunll(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
557*0Sstevel@tonic-gate {
558*0Sstevel@tonic-gate 	uint_t qfmt = FALSE;
559*0Sstevel@tonic-gate 	tunll_t tll;
560*0Sstevel@tonic-gate 
561*0Sstevel@tonic-gate 	if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) {
562*0Sstevel@tonic-gate 		mdb_printf("%<u>%?s %-14s %?s %s%</u>\n", "Address",
563*0Sstevel@tonic-gate 		    "Interface Name", "Daemon", "Local Address");
564*0Sstevel@tonic-gate 	}
565*0Sstevel@tonic-gate 
566*0Sstevel@tonic-gate 	if (flags & DCMD_ADDRSPEC) {
567*0Sstevel@tonic-gate 		if (mdb_vread(&tll, sizeof (tll), addr) == -1)
568*0Sstevel@tonic-gate 			mdb_warn("failed to read tunll_t at %p", addr);
569*0Sstevel@tonic-gate 		else
570*0Sstevel@tonic-gate 			tunll_format(addr, &tll, &qfmt);
571*0Sstevel@tonic-gate 	} else if (mdb_walk("tunll", (mdb_walk_cb_t)tunll_format, &qfmt) ==
572*0Sstevel@tonic-gate 	    -1) {
573*0Sstevel@tonic-gate 		mdb_warn("failed to walk tunll_list");
574*0Sstevel@tonic-gate 		return (DCMD_ERR);
575*0Sstevel@tonic-gate 	}
576*0Sstevel@tonic-gate 
577*0Sstevel@tonic-gate 	return (DCMD_OK);
578*0Sstevel@tonic-gate }
579*0Sstevel@tonic-gate 
580*0Sstevel@tonic-gate union tun_state {
581*0Sstevel@tonic-gate 	uint32_t tunflags;
582*0Sstevel@tonic-gate 	tuncl_t tcl;
583*0Sstevel@tonic-gate 	tunll_t tll;
584*0Sstevel@tonic-gate };
585*0Sstevel@tonic-gate 
586*0Sstevel@tonic-gate static int
587*0Sstevel@tonic-gate tun_state_read(void *ptr, union tun_state *ts)
588*0Sstevel@tonic-gate {
589*0Sstevel@tonic-gate 	/*
590*0Sstevel@tonic-gate 	 * First, get the flags on this structure.  This is either a
591*0Sstevel@tonic-gate 	 * tuncl_t or a tunll_t.
592*0Sstevel@tonic-gate 	 */
593*0Sstevel@tonic-gate 	if (mdb_vread(&ts->tunflags, sizeof (ts->tunflags), (uintptr_t)ptr) ==
594*0Sstevel@tonic-gate 	    sizeof (ts->tunflags)) {
595*0Sstevel@tonic-gate 		if (ts->tunflags & TCLF_ISCLIENT) {
596*0Sstevel@tonic-gate 			if (mdb_vread(&ts->tcl, sizeof (ts->tcl),
597*0Sstevel@tonic-gate 			    (uintptr_t)ptr) == sizeof (ts->tcl)) {
598*0Sstevel@tonic-gate 				return (0);
599*0Sstevel@tonic-gate 			}
600*0Sstevel@tonic-gate 		} else {
601*0Sstevel@tonic-gate 			if (mdb_vread(&ts->tll, sizeof (ts->tll),
602*0Sstevel@tonic-gate 			    (uintptr_t)ptr) == sizeof (ts->tll)) {
603*0Sstevel@tonic-gate 				return (0);
604*0Sstevel@tonic-gate 			}
605*0Sstevel@tonic-gate 		}
606*0Sstevel@tonic-gate 	}
607*0Sstevel@tonic-gate 	return (-1);
608*0Sstevel@tonic-gate }
609*0Sstevel@tonic-gate 
610*0Sstevel@tonic-gate static void
611*0Sstevel@tonic-gate sppptun_qinfo(const queue_t *q, char *buf, size_t nbytes)
612*0Sstevel@tonic-gate {
613*0Sstevel@tonic-gate 	union tun_state ts;
614*0Sstevel@tonic-gate 
615*0Sstevel@tonic-gate 	if (tun_state_read(q->q_ptr, &ts) == -1)
616*0Sstevel@tonic-gate 		return;
617*0Sstevel@tonic-gate 
618*0Sstevel@tonic-gate 	if (ts.tcl.tcl_flags & TCLF_ISCLIENT)
619*0Sstevel@tonic-gate 		mdb_snprintf(buf, nbytes, "sppp%d client %04X",
620*0Sstevel@tonic-gate 		    ts.tcl.tcl_unit, ts.tcl.tcl_lsessid);
621*0Sstevel@tonic-gate 	else
622*0Sstevel@tonic-gate 		mdb_snprintf(buf, nbytes, "%s", ts.tll.tll_name);
623*0Sstevel@tonic-gate }
624*0Sstevel@tonic-gate 
625*0Sstevel@tonic-gate static uintptr_t
626*0Sstevel@tonic-gate sppptun_rnext(const queue_t *q)
627*0Sstevel@tonic-gate {
628*0Sstevel@tonic-gate 	union tun_state ts;
629*0Sstevel@tonic-gate 
630*0Sstevel@tonic-gate 	if (tun_state_read(q->q_ptr, &ts) == -1)
631*0Sstevel@tonic-gate 		return (NULL);
632*0Sstevel@tonic-gate 
633*0Sstevel@tonic-gate 	if (ts.tcl.tcl_flags & TCLF_ISCLIENT) {
634*0Sstevel@tonic-gate 		return ((uintptr_t)ts.tcl.tcl_rq);
635*0Sstevel@tonic-gate 	} else {
636*0Sstevel@tonic-gate 		/* Not quite right, but ... */
637*0Sstevel@tonic-gate 		return ((uintptr_t)ts.tll.tll_defcl);
638*0Sstevel@tonic-gate 	}
639*0Sstevel@tonic-gate }
640*0Sstevel@tonic-gate 
641*0Sstevel@tonic-gate static uintptr_t
642*0Sstevel@tonic-gate sppptun_wnext(const queue_t *q)
643*0Sstevel@tonic-gate {
644*0Sstevel@tonic-gate 	union tun_state ts;
645*0Sstevel@tonic-gate 
646*0Sstevel@tonic-gate 	if (tun_state_read(q->q_ptr, &ts) == -1)
647*0Sstevel@tonic-gate 		return (NULL);
648*0Sstevel@tonic-gate 
649*0Sstevel@tonic-gate 	if (ts.tcl.tcl_flags & TCLF_ISCLIENT) {
650*0Sstevel@tonic-gate 		if (ts.tcl.tcl_data_tll == NULL)
651*0Sstevel@tonic-gate 			return (NULL);
652*0Sstevel@tonic-gate 		if (mdb_vread(&ts.tll, sizeof (ts.tll),
653*0Sstevel@tonic-gate 		    (uintptr_t)ts.tcl.tcl_data_tll) != sizeof (ts.tll)) {
654*0Sstevel@tonic-gate 			return (NULL);
655*0Sstevel@tonic-gate 		}
656*0Sstevel@tonic-gate 	}
657*0Sstevel@tonic-gate 	return ((uintptr_t)ts.tll.tll_wq);
658*0Sstevel@tonic-gate }
659*0Sstevel@tonic-gate 
660*0Sstevel@tonic-gate static const mdb_dcmd_t dcmds[] = {
661*0Sstevel@tonic-gate 	{ "sppp", "[-q]", "display PPP stream state structures", sppp },
662*0Sstevel@tonic-gate 	{ "sppa", "", "display PPP attachment state structures", sppa },
663*0Sstevel@tonic-gate 	{ "tuncl", "", "display sppptun client stream state structures",
664*0Sstevel@tonic-gate 	    tuncl },
665*0Sstevel@tonic-gate 	{ "tunll", "", "display sppptun lower stream state structures",
666*0Sstevel@tonic-gate 	    tunll },
667*0Sstevel@tonic-gate 	{ NULL }
668*0Sstevel@tonic-gate };
669*0Sstevel@tonic-gate 
670*0Sstevel@tonic-gate static const mdb_walker_t walkers[] = {
671*0Sstevel@tonic-gate 	{ "sppp", "walk active spppstr_t structures",
672*0Sstevel@tonic-gate 	    sppp_walk_init, sppp_walk_step, NULL },
673*0Sstevel@tonic-gate 	{ "sppa", "walk active sppa_t structures",
674*0Sstevel@tonic-gate 	    sppa_walk_init, sppa_walk_step, NULL },
675*0Sstevel@tonic-gate 	{ "tuncl", "walk active tuncl_t structures",
676*0Sstevel@tonic-gate 	    tuncl_walk_init, tuncl_walk_step, tuncl_walk_fini },
677*0Sstevel@tonic-gate 	{ "tunll", "walk active tunll_t structures",
678*0Sstevel@tonic-gate 	    tunll_walk_init, tunll_walk_step, tunll_walk_fini },
679*0Sstevel@tonic-gate 	{ NULL }
680*0Sstevel@tonic-gate };
681*0Sstevel@tonic-gate 
682*0Sstevel@tonic-gate static const mdb_qops_t sppp_qops = { sppp_qinfo, sppp_rnext, sppp_wnext };
683*0Sstevel@tonic-gate static const mdb_qops_t sppptun_qops = {
684*0Sstevel@tonic-gate 	sppptun_qinfo, sppptun_rnext, sppptun_wnext
685*0Sstevel@tonic-gate };
686*0Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
687*0Sstevel@tonic-gate 
688*0Sstevel@tonic-gate const mdb_modinfo_t *
689*0Sstevel@tonic-gate _mdb_init(void)
690*0Sstevel@tonic-gate {
691*0Sstevel@tonic-gate 	GElf_Sym sym;
692*0Sstevel@tonic-gate 
693*0Sstevel@tonic-gate 	if (mdb_lookup_by_obj("sppp", "sppp_uwinit", &sym) == 0)
694*0Sstevel@tonic-gate 		mdb_qops_install(&sppp_qops, (uintptr_t)sym.st_value);
695*0Sstevel@tonic-gate 
696*0Sstevel@tonic-gate 	if (mdb_lookup_by_obj("sppptun", "sppptun_uwinit", &sym) == 0)
697*0Sstevel@tonic-gate 		mdb_qops_install(&sppptun_qops, (uintptr_t)sym.st_value);
698*0Sstevel@tonic-gate 
699*0Sstevel@tonic-gate 	return (&modinfo);
700*0Sstevel@tonic-gate }
701*0Sstevel@tonic-gate 
702*0Sstevel@tonic-gate void
703*0Sstevel@tonic-gate _mdb_fini(void)
704*0Sstevel@tonic-gate {
705*0Sstevel@tonic-gate 	GElf_Sym sym;
706*0Sstevel@tonic-gate 
707*0Sstevel@tonic-gate 	if (mdb_lookup_by_obj("sppptun", "sppptun_uwinit", &sym) == 0)
708*0Sstevel@tonic-gate 		mdb_qops_remove(&sppptun_qops, (uintptr_t)sym.st_value);
709*0Sstevel@tonic-gate 
710*0Sstevel@tonic-gate 	if (mdb_lookup_by_obj("sppp", "sppp_uwinit", &sym) == 0)
711*0Sstevel@tonic-gate 		mdb_qops_remove(&sppp_qops, (uintptr_t)sym.st_value);
712*0Sstevel@tonic-gate }
713