xref: /onnv-gate/usr/src/cmd/mdb/common/modules/hook/hook.c (revision 7513:18aa777d3f09)
12958Sdr146992 /*
22958Sdr146992  * CDDL HEADER START
32958Sdr146992  *
42958Sdr146992  * The contents of this file are subject to the terms of the
52958Sdr146992  * Common Development and Distribution License (the "License").
62958Sdr146992  * You may not use this file except in compliance with the License.
72958Sdr146992  *
82958Sdr146992  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92958Sdr146992  * or http://www.opensolaris.org/os/licensing.
102958Sdr146992  * See the License for the specific language governing permissions
112958Sdr146992  * and limitations under the License.
122958Sdr146992  *
132958Sdr146992  * When distributing Covered Code, include this CDDL HEADER in each
142958Sdr146992  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152958Sdr146992  * If applicable, add the following below this CDDL HEADER, with the
162958Sdr146992  * fields enclosed by brackets "[]" replaced with your own identifying
172958Sdr146992  * information: Portions Copyright [yyyy] [name of copyright owner]
182958Sdr146992  *
192958Sdr146992  * CDDL HEADER END
202958Sdr146992  */
212958Sdr146992 /*
22*7513SDarren.Reed@Sun.COM  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
232958Sdr146992  * Use is subject to license terms.
242958Sdr146992  */
252958Sdr146992 
262958Sdr146992 #include <sys/types.h>
272958Sdr146992 #include <sys/rwlock.h>
282958Sdr146992 #include <mdb/mdb_modapi.h>
292958Sdr146992 #include <sys/queue.h>
303448Sdh155122 #include <inet/ip.h>
312958Sdr146992 #include <sys/hook.h>
322958Sdr146992 #include <sys/hook_impl.h>
332958Sdr146992 
342958Sdr146992 #define	MAX_LENGTH 64
352958Sdr146992 
362958Sdr146992 /*
372958Sdr146992  * List pfhooks hook list information.
382958Sdr146992  */
392958Sdr146992 /*ARGSUSED*/
402958Sdr146992 int
hooklist(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)412958Sdr146992 hooklist(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
422958Sdr146992 {
432958Sdr146992 	hook_event_int_t hr;
442958Sdr146992 	hook_int_t hl, *hlp;
452958Sdr146992 	char hrstr[MAX_LENGTH];
462958Sdr146992 	GElf_Sym sym;
472958Sdr146992 	char buf[MDB_SYM_NAMLEN + 1];
48*7513SDarren.Reed@Sun.COM 	char *hintname;
49*7513SDarren.Reed@Sun.COM 	hook_t *h;
502958Sdr146992 
512958Sdr146992 	if (argc)
522958Sdr146992 		return (DCMD_USAGE);
532958Sdr146992 
542958Sdr146992 	if (mdb_vread((void *)&hr, sizeof (hr), (uintptr_t)addr) == -1) {
552958Sdr146992 		mdb_warn("couldn't read hook register at %p", addr);
562958Sdr146992 		return (DCMD_ERR);
572958Sdr146992 	}
582958Sdr146992 
59*7513SDarren.Reed@Sun.COM 	mdb_printf("%<u>%?s %8s %20s %4s %24s %24s%</u>\n",
60*7513SDarren.Reed@Sun.COM 	    "ADDR", "FLAG", "FUNC", "HINT", "NAME", "HINTVALUE");
61*7513SDarren.Reed@Sun.COM 	h = &hl.hi_hook;
622958Sdr146992 	hlp = TAILQ_FIRST(&hr.hei_head);
632958Sdr146992 	while (hlp) {
642958Sdr146992 		if (mdb_vread((void *)&hl, sizeof (hl),
652958Sdr146992 		    (uintptr_t)hlp) == -1) {
662958Sdr146992 			mdb_warn("couldn't read hook list at %p",
672958Sdr146992 			    hlp);
682958Sdr146992 			return (DCMD_ERR);
692958Sdr146992 		}
70*7513SDarren.Reed@Sun.COM 		if (!h->h_name) {
71*7513SDarren.Reed@Sun.COM 			mdb_warn("hook list at %p has null role", h);
722958Sdr146992 			return (DCMD_ERR);
732958Sdr146992 		}
742958Sdr146992 		if (mdb_readstr((char *)hrstr, sizeof (hrstr),
75*7513SDarren.Reed@Sun.COM 		    (uintptr_t)h->h_name) == -1) {
76*7513SDarren.Reed@Sun.COM 			mdb_warn("couldn't read list role at %p", h->h_name);
772958Sdr146992 			return (DCMD_ERR);
782958Sdr146992 		}
79*7513SDarren.Reed@Sun.COM 		switch (h->h_hint) {
80*7513SDarren.Reed@Sun.COM 		case HH_BEFORE :
81*7513SDarren.Reed@Sun.COM 		case HH_AFTER :
82*7513SDarren.Reed@Sun.COM 			hintname =  h->h_hintvalue ?
83*7513SDarren.Reed@Sun.COM 			    (char *)h->h_hintvalue : "";
84*7513SDarren.Reed@Sun.COM 			break;
85*7513SDarren.Reed@Sun.COM 		default :
86*7513SDarren.Reed@Sun.COM 			hintname = "";
87*7513SDarren.Reed@Sun.COM 			break;
88*7513SDarren.Reed@Sun.COM 		}
89*7513SDarren.Reed@Sun.COM 		if (mdb_lookup_by_addr((uintptr_t)h->h_func,
902958Sdr146992 		    MDB_SYM_EXACT, buf, sizeof (buf), &sym) == -1)
91*7513SDarren.Reed@Sun.COM 			mdb_printf("%0?p %8x %0?p %4d %24s %24s\n",
92*7513SDarren.Reed@Sun.COM 			    hlp, h->h_flags, h->h_func,
93*7513SDarren.Reed@Sun.COM 			    h->h_hint, hrstr, hintname);
942958Sdr146992 		else
95*7513SDarren.Reed@Sun.COM 			mdb_printf("%0?p %8x %20s %4d %24s %24s\n",
96*7513SDarren.Reed@Sun.COM 			    hlp, h->h_flags, buf,
97*7513SDarren.Reed@Sun.COM 			    h->h_hint, hrstr, hintname);
982958Sdr146992 		hlp = TAILQ_NEXT(&hl, hi_entry);
992958Sdr146992 	}
1002958Sdr146992 	return (DCMD_OK);
1012958Sdr146992 }
1022958Sdr146992 
1032958Sdr146992 /*
1042958Sdr146992  * List pfhooks event information.
1052958Sdr146992  * List the hooks information in verbose mode as well.
1062958Sdr146992  */
1072958Sdr146992 /*ARGSUSED*/
1082958Sdr146992 int
hookeventlist(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1092958Sdr146992 hookeventlist(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1102958Sdr146992 {
1112958Sdr146992 	hook_family_int_t hf;
1122958Sdr146992 	hook_event_int_t hr, *hrp;
1132958Sdr146992 	hook_event_t hp;
1142958Sdr146992 	char hprstr[MAX_LENGTH];
1152958Sdr146992 
1162958Sdr146992 	if (argc)
1172958Sdr146992 		return (DCMD_USAGE);
1182958Sdr146992 
1192958Sdr146992 	if (mdb_vread((void *)&hf, sizeof (hf), (uintptr_t)addr) == -1) {
1202958Sdr146992 		mdb_warn("couldn't read hook family at %p", addr);
1212958Sdr146992 		return (DCMD_ERR);
1222958Sdr146992 	}
1232958Sdr146992 
1242958Sdr146992 	mdb_printf("%<u>%?s %10s %20s%</u>\n", "ADDR", "FLAG", "NAME");
1252958Sdr146992 	hrp = SLIST_FIRST(&hf.hfi_head);
1262958Sdr146992 	while (hrp) {
1272958Sdr146992 		if (mdb_vread((void *)&hr, sizeof (hr), (uintptr_t)hrp) == -1) {
1282958Sdr146992 			mdb_warn("couldn't read hook register at %p", hrp);
1292958Sdr146992 			return (DCMD_ERR);
1302958Sdr146992 		}
1312958Sdr146992 		if (!hr.hei_event) {
1322958Sdr146992 			mdb_warn("hook register at %p has no hook provider",
1332958Sdr146992 			    hrp);
1342958Sdr146992 			return (DCMD_ERR);
1352958Sdr146992 		}
1362958Sdr146992 		if (mdb_vread((void *)&hp, sizeof (hp),
1372958Sdr146992 		    (uintptr_t)hr.hei_event) == -1) {
1382958Sdr146992 			mdb_warn("hook provider at %p has null role",
1392958Sdr146992 			    hr.hei_event);
1402958Sdr146992 			return (DCMD_ERR);
1412958Sdr146992 		}
1422958Sdr146992 		if (!hp.he_name) {
1432958Sdr146992 			mdb_warn("hook provider at %p has null role",
1442958Sdr146992 			    hr.hei_event);
1452958Sdr146992 			return (DCMD_ERR);
1462958Sdr146992 		}
1472958Sdr146992 		if (mdb_readstr((char *)hprstr, sizeof (hprstr),
1482958Sdr146992 		    (uintptr_t)hp.he_name) == -1) {
1492958Sdr146992 			mdb_warn("couldn't read provider role at %p",
1502958Sdr146992 			    hp.he_name);
1512958Sdr146992 			return (DCMD_ERR);
1522958Sdr146992 		}
1532958Sdr146992 		mdb_printf("%0?p %10x %20s\n", hrp, hp.he_flags, hprstr);
1542958Sdr146992 		hrp = SLIST_NEXT(&hr, hei_entry);
1552958Sdr146992 	}
1562958Sdr146992 
1572958Sdr146992 	return (DCMD_OK);
1582958Sdr146992 }
1592958Sdr146992 
1602958Sdr146992 /*
1612958Sdr146992  * List pfhooks family information.
1622958Sdr146992  */
1632958Sdr146992 /*ARGSUSED*/
1642958Sdr146992 int
hookrootlist(uintptr_t addr,uint_t flags,int argc,const mdb_arg_t * argv)1652958Sdr146992 hookrootlist(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1662958Sdr146992 {
1673448Sdh155122 	struct hook_stack *hks;
1682958Sdr146992 	hook_family_int_head_t hfh;
1692958Sdr146992 	hook_family_int_t hf, *hfp;
1702958Sdr146992 	char hrrstr[MAX_LENGTH];
1712958Sdr146992 
1722958Sdr146992 	if (argc)
1732958Sdr146992 		return (DCMD_USAGE);
1742958Sdr146992 
1753448Sdh155122 	if (mdb_vread((void *)&hks, sizeof (hks),
1763448Sdh155122 	    (uintptr_t)(addr + OFFSETOF(netstack_t, netstack_hook))) == -1) {
1773448Sdh155122 		mdb_warn("couldn't read netstack_hook");
1783448Sdh155122 		return (DCMD_ERR);
1793448Sdh155122 	}
1803448Sdh155122 
1813448Sdh155122 	if (mdb_vread((void *)&hfh, sizeof (hfh), (uintptr_t)((uintptr_t)hks +
1823448Sdh155122 	    OFFSETOF(hook_stack_t, hks_familylist))) == -1) {
1833448Sdh155122 		mdb_warn("couldn't read hook family head");
1842958Sdr146992 		return (DCMD_ERR);
1852958Sdr146992 	}
1862958Sdr146992 
1872958Sdr146992 	mdb_printf("%<u>%?s %10s%</u>\n", "ADDR", "FAMILY");
1882958Sdr146992 	hfp = SLIST_FIRST(&hfh);
1892958Sdr146992 	while (hfp) {
1902958Sdr146992 		if (mdb_vread((void *)&hf, sizeof (hf), (uintptr_t)hfp) == -1) {
1912958Sdr146992 			mdb_warn("couldn't read hook family at %p", hfp);
1922958Sdr146992 			return (DCMD_ERR);
1932958Sdr146992 		}
1942958Sdr146992 		if (!hf.hfi_family.hf_name) {
1952958Sdr146992 			mdb_warn("hook root at %p has null role",
1962958Sdr146992 			    hf.hfi_family);
1972958Sdr146992 			return (DCMD_ERR);
1982958Sdr146992 		}
1992958Sdr146992 		if (mdb_readstr((char *)hrrstr, sizeof (hrrstr),
2002958Sdr146992 		    (uintptr_t)hf.hfi_family.hf_name) == -1) {
2012958Sdr146992 			mdb_warn("couldn't read root role at %p",
2022958Sdr146992 			    hf.hfi_family.hf_name);
2032958Sdr146992 			return (DCMD_ERR);
2042958Sdr146992 		}
2052958Sdr146992 		mdb_printf("%0?p %10s\n", hfp, hrrstr);
2062958Sdr146992 		hfp = SLIST_NEXT(&hf, hfi_entry);
2072958Sdr146992 	}
2082958Sdr146992 
2092958Sdr146992 	return (DCMD_OK);
2102958Sdr146992 }
2112958Sdr146992 
2122958Sdr146992 
2132958Sdr146992 static int
hookevent_stack_walk_init(mdb_walk_state_t * wsp)2143448Sdh155122 hookevent_stack_walk_init(mdb_walk_state_t *wsp)
2152958Sdr146992 {
2162958Sdr146992 	hook_family_int_t hf;
2172958Sdr146992 
2182958Sdr146992 	if (wsp->walk_addr == NULL) {
2192958Sdr146992 		mdb_warn("global walk not supported\n");
2202958Sdr146992 		return (WALK_ERR);
2212958Sdr146992 	}
2222958Sdr146992 
2232958Sdr146992 	if (mdb_vread((void *)&hf, sizeof (hf),
2242958Sdr146992 	    (uintptr_t)wsp->walk_addr) == -1) {
2252958Sdr146992 		mdb_warn("couldn't read hook family at %p", wsp->walk_addr);
2262958Sdr146992 		return (DCMD_ERR);
2272958Sdr146992 	}
2282958Sdr146992 	wsp->walk_addr = (uintptr_t)SLIST_FIRST(&hf.hfi_head);
2292958Sdr146992 	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
230*7513SDarren.Reed@Sun.COM 	    wsp->walk_cbdata));
2312958Sdr146992 }
2322958Sdr146992 
2332958Sdr146992 static int
hookevent_stack_walk_step(mdb_walk_state_t * wsp)2343448Sdh155122 hookevent_stack_walk_step(mdb_walk_state_t *wsp)
2352958Sdr146992 {
2362958Sdr146992 	hook_event_int_t hr;
2372958Sdr146992 
2382958Sdr146992 	if (mdb_vread((void *)&hr, sizeof (hr),
2392958Sdr146992 	    (uintptr_t)wsp->walk_addr) == -1) {
2402958Sdr146992 		mdb_warn("couldn't read hook event at %p", wsp->walk_addr);
2412958Sdr146992 		return (DCMD_ERR);
2422958Sdr146992 	}
2432958Sdr146992 	wsp->walk_addr = (uintptr_t)SLIST_NEXT(&hr, hei_entry);
2442958Sdr146992 	if (wsp->walk_addr == NULL)
2452958Sdr146992 		return (WALK_DONE);
2462958Sdr146992 	return (wsp->walk_callback(wsp->walk_addr, wsp->walk_data,
247*7513SDarren.Reed@Sun.COM 	    wsp->walk_cbdata));
2482958Sdr146992 }
2492958Sdr146992 
2502958Sdr146992 static const mdb_dcmd_t dcmds[] = {
2512958Sdr146992 	{ "hookrootlist", "", "display hook family information", hookrootlist },
2522958Sdr146992 	{ "hookeventlist", "", "display hook event information",
2532958Sdr146992 		hookeventlist, NULL },
2542958Sdr146992 	{ "hooklist", "", "display hooks", hooklist },
2552958Sdr146992 	{ NULL }
2562958Sdr146992 };
2572958Sdr146992 
2582958Sdr146992 static const mdb_walker_t walkers[] = {
2593448Sdh155122 	{ "hookevent_stack", "walk list of hooks",
2603448Sdh155122 		hookevent_stack_walk_init, hookevent_stack_walk_step, NULL },
2612958Sdr146992 	{ NULL }
2622958Sdr146992 };
2632958Sdr146992 
2642958Sdr146992 static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
2652958Sdr146992 
2662958Sdr146992 const mdb_modinfo_t *
_mdb_init(void)2672958Sdr146992 _mdb_init(void)
2682958Sdr146992 {
2692958Sdr146992 	return (&modinfo);
2702958Sdr146992 }
271