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 5*f53eecf5SJames Carlson * Common Development and Distribution License (the "License"). 6*f53eecf5SJames 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 /* 22*f53eecf5SJames 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 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 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 677c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL) 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 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) { 94*f53eecf5SJames Carlson mdb_printf("? unset "); 957c478bd9Sstevel@tonic-gate } else if (mdb_vread(&ppa, sizeof (ppa), (uintptr_t)sps->sps_ppa) == 967c478bd9Sstevel@tonic-gate -1) { 97*f53eecf5SJames Carlson mdb_printf("? ?%p ", sps->sps_ppa); 987c478bd9Sstevel@tonic-gate } else { 99*f53eecf5SJames 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; 1137c478bd9Sstevel@tonic-gate while (upaddr != NULL) { 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 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) { 186*f53eecf5SJames Carlson mdb_printf("%<u>%?s %?s %-6s %-9s %s%</u>\n", "Address", 187*f53eecf5SJames Carlson "RecvQ", "ZoneID", "Interface", "Type"); 1887c478bd9Sstevel@tonic-gate } else { 189*f53eecf5SJames Carlson mdb_printf("%<u>%?s %-6s %-9s %s%</u>\n", "Address", 190*f53eecf5SJames 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 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 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 2227c478bd9Sstevel@tonic-gate if (wsp->walk_addr == NULL) 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 2387c478bd9Sstevel@tonic-gate ppa_format(uintptr_t addr, const sppa_t *ppa, uint_t *qfmt) 2397c478bd9Sstevel@tonic-gate { 240*f53eecf5SJames Carlson mdb_printf("%?p %-6d sppp%-5d %?p %?p\n", addr, ppa->ppa_zoneid, 241*f53eecf5SJames 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 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)) { 254*f53eecf5SJames Carlson mdb_printf("%<u>%?s %-6s %-9s %?s %?s%</u>\n", "Address", 255*f53eecf5SJames 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 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 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 2977c478bd9Sstevel@tonic-gate return (NULL); 2987c478bd9Sstevel@tonic-gate } 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate static uintptr_t 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)) 3077c478bd9Sstevel@tonic-gate return (NULL); 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 3147c478bd9Sstevel@tonic-gate return (NULL); 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 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 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 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 3907c478bd9Sstevel@tonic-gate if (wsp == NULL || wsp->walk_addr == NULL) 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 4157c478bd9Sstevel@tonic-gate tuncl_format(uintptr_t addr, const tuncl_t *tcl, uint_t *qfmt) 4167c478bd9Sstevel@tonic-gate { 417*f53eecf5SJames Carlson mdb_printf("%?p %-6d %?p %?p", addr, tcl->tcl_zoneid, tcl->tcl_data_tll, 418*f53eecf5SJames 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 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)) { 438*f53eecf5SJames Carlson mdb_printf("%<u>%?s %-6s %?s %?s Ty LSes RSes %s%</u>\n", 439*f53eecf5SJames 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 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 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 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 5357c478bd9Sstevel@tonic-gate tunll_format(uintptr_t addr, const tunll_t *tll, uint_t *qfmt) 5367c478bd9Sstevel@tonic-gate { 537*f53eecf5SJames Carlson mdb_printf("%?p %-6d %-14s %?p", addr, tll->tll_zoneid, tll->tll_name, 538*f53eecf5SJames 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 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)) { 561*f53eecf5SJames Carlson mdb_printf("%<u>%?s %-6s %-14s %?s %s%</u>\n", "Address", 562*f53eecf5SJames 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 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 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 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) 6307c478bd9Sstevel@tonic-gate return (NULL); 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 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) 6467c478bd9Sstevel@tonic-gate return (NULL); 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate if (ts.tcl.tcl_flags & TCLF_ISCLIENT) { 6497c478bd9Sstevel@tonic-gate if (ts.tcl.tcl_data_tll == NULL) 6507c478bd9Sstevel@tonic-gate return (NULL); 6517c478bd9Sstevel@tonic-gate if (mdb_vread(&ts.tll, sizeof (ts.tll), 6527c478bd9Sstevel@tonic-gate (uintptr_t)ts.tcl.tcl_data_tll) != sizeof (ts.tll)) { 6537c478bd9Sstevel@tonic-gate return (NULL); 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 6817c478bd9Sstevel@tonic-gate static const mdb_qops_t sppp_qops = { sppp_qinfo, sppp_rnext, sppp_wnext }; 6827c478bd9Sstevel@tonic-gate static const mdb_qops_t sppptun_qops = { 6837c478bd9Sstevel@tonic-gate sppptun_qinfo, sppptun_rnext, sppptun_wnext 6847c478bd9Sstevel@tonic-gate }; 6857c478bd9Sstevel@tonic-gate static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers }; 6867c478bd9Sstevel@tonic-gate 6877c478bd9Sstevel@tonic-gate const mdb_modinfo_t * 6887c478bd9Sstevel@tonic-gate _mdb_init(void) 6897c478bd9Sstevel@tonic-gate { 6907c478bd9Sstevel@tonic-gate GElf_Sym sym; 6917c478bd9Sstevel@tonic-gate 6927c478bd9Sstevel@tonic-gate if (mdb_lookup_by_obj("sppp", "sppp_uwinit", &sym) == 0) 6937c478bd9Sstevel@tonic-gate mdb_qops_install(&sppp_qops, (uintptr_t)sym.st_value); 6947c478bd9Sstevel@tonic-gate 6957c478bd9Sstevel@tonic-gate if (mdb_lookup_by_obj("sppptun", "sppptun_uwinit", &sym) == 0) 6967c478bd9Sstevel@tonic-gate mdb_qops_install(&sppptun_qops, (uintptr_t)sym.st_value); 6977c478bd9Sstevel@tonic-gate 6987c478bd9Sstevel@tonic-gate return (&modinfo); 6997c478bd9Sstevel@tonic-gate } 7007c478bd9Sstevel@tonic-gate 7017c478bd9Sstevel@tonic-gate void 7027c478bd9Sstevel@tonic-gate _mdb_fini(void) 7037c478bd9Sstevel@tonic-gate { 7047c478bd9Sstevel@tonic-gate GElf_Sym sym; 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate if (mdb_lookup_by_obj("sppptun", "sppptun_uwinit", &sym) == 0) 7077c478bd9Sstevel@tonic-gate mdb_qops_remove(&sppptun_qops, (uintptr_t)sym.st_value); 7087c478bd9Sstevel@tonic-gate 7097c478bd9Sstevel@tonic-gate if (mdb_lookup_by_obj("sppp", "sppp_uwinit", &sym) == 0) 7107c478bd9Sstevel@tonic-gate mdb_qops_remove(&sppp_qops, (uintptr_t)sym.st_value); 7117c478bd9Sstevel@tonic-gate } 712