1175061Sobrien/*- 252419Sjulian * Copyright (c) 1996-1999 Whistle Communications, Inc. 352419Sjulian * All rights reserved. 4175061Sobrien * 552419Sjulian * Subject to the following obligations and disclaimer of warranty, use and 652419Sjulian * redistribution of this software, in source or object code forms, with or 752419Sjulian * without modifications are expressly permitted by Whistle Communications; 852419Sjulian * provided, however, that: 952419Sjulian * 1. Any and all reproductions of the source or object code must include the 1052419Sjulian * copyright notice above and the following disclaimer of warranties; and 1152419Sjulian * 2. No rights are granted, in any manner or form, to use Whistle 1252419Sjulian * Communications, Inc. trademarks, including the mark "WHISTLE 1352419Sjulian * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 1452419Sjulian * such appears in the above copyright notice or in the software. 15175061Sobrien * 1652419Sjulian * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 1752419Sjulian * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 1852419Sjulian * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 1952419Sjulian * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 2052419Sjulian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 2152419Sjulian * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 2252419Sjulian * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 2352419Sjulian * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 2452419Sjulian * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 2552419Sjulian * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 2652419Sjulian * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 2752419Sjulian * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 2852419Sjulian * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 2952419Sjulian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3052419Sjulian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3152419Sjulian * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 3252419Sjulian * OF SUCH DAMAGE. 3352419Sjulian */ 3452419Sjulian 35132671Scharnier#include <sys/cdefs.h> 36132671Scharnier__FBSDID("$FreeBSD$"); 3752419Sjulian 3852419Sjulian#include <sys/param.h> 3952419Sjulian#include <sys/queue.h> 4052419Sjulian#include <sys/socket.h> 4152419Sjulian#include <sys/socketvar.h> 4252419Sjulian#include <sys/protosw.h> 4352419Sjulian#include <sys/linker.h> 4452419Sjulian 4552419Sjulian#include <net/route.h> 4652419Sjulian 4752450Sdillon#include <netgraph.h> 4852419Sjulian#include <netgraph/ng_message.h> 4952419Sjulian#include <netgraph/ng_socket.h> 5052419Sjulian#include <netgraph/ng_socketvar.h> 5152419Sjulian 5252419Sjulian#include <nlist.h> 53200462Sdelphij#include <errno.h> 54160787Syar#include <stdint.h> 5552419Sjulian#include <stdio.h> 5652419Sjulian#include <string.h> 57200462Sdelphij#include <unistd.h> 5852419Sjulian#include <err.h> 5952419Sjulian#include "netstat.h" 6052419Sjulian 6152419Sjulianstatic int first = 1; 6252419Sjulianstatic int csock = -1; 6352419Sjulian 6452419Sjulianvoid 65171465Sjhbnetgraphprotopr(u_long off, const char *name, int af1 __unused, 66171465Sjhb int proto __unused) 6752419Sjulian{ 6852419Sjulian struct ngpcb *this, *next; 6952419Sjulian struct ngpcb ngpcb; 7052419Sjulian struct ngsock info; 7152419Sjulian struct socket sockb; 7252419Sjulian int debug = 1; 7352419Sjulian 7452419Sjulian /* If symbol not found, try looking in the KLD module */ 7552419Sjulian if (off == 0) { 7652419Sjulian const char *const modname = "ng_socket.ko"; 7752419Sjulian/* XXX We should get "mpath" from "sysctl kern.module_path" */ 7852419Sjulian const char *mpath[] = { "/", "/boot/", "/modules/", NULL }; 79160789Syar struct nlist sym[] = { { .n_name = "_ngsocklist" }, 80160789Syar { .n_name = NULL } }; 8152419Sjulian const char **pre; 8252419Sjulian struct kld_file_stat ks; 8352419Sjulian int fileid; 8452419Sjulian 85171465Sjhb /* Can't do this for core dumps. */ 86171465Sjhb if (!live) 87171465Sjhb return; 88171465Sjhb 8952419Sjulian /* See if module is loaded */ 9052419Sjulian if ((fileid = kldfind(modname)) < 0) { 9152419Sjulian if (debug) 9252419Sjulian warn("kldfind(%s)", modname); 9352419Sjulian return; 9452419Sjulian } 9552419Sjulian 9652419Sjulian /* Get module info */ 9752419Sjulian memset(&ks, 0, sizeof(ks)); 9852419Sjulian ks.version = sizeof(struct kld_file_stat); 9952419Sjulian if (kldstat(fileid, &ks) < 0) { 10052419Sjulian if (debug) 10152419Sjulian warn("kldstat(%d)", fileid); 10252419Sjulian return; 10352419Sjulian } 10452419Sjulian 10552419Sjulian /* Get symbol table from module file */ 10652419Sjulian for (pre = mpath; *pre; pre++) { 10752419Sjulian char path[MAXPATHLEN]; 10852419Sjulian 10952419Sjulian snprintf(path, sizeof(path), "%s%s", *pre, modname); 11052419Sjulian if (nlist(path, sym) == 0) 11152419Sjulian break; 11252419Sjulian } 11352419Sjulian 11452419Sjulian /* Did we find it? */ 11552419Sjulian if (sym[0].n_value == 0) { 11652419Sjulian if (debug) 11752419Sjulian warnx("%s not found", modname); 11852419Sjulian return; 11952419Sjulian } 12052419Sjulian 12152419Sjulian /* Symbol found at load address plus symbol offset */ 12252419Sjulian off = (u_long) ks.address + sym[0].n_value; 12352419Sjulian } 12452419Sjulian 12552419Sjulian /* Get pointer to first socket */ 12652419Sjulian kread(off, (char *)&this, sizeof(this)); 12752419Sjulian 12852419Sjulian /* Get my own socket node */ 12952419Sjulian if (csock == -1) 13052419Sjulian NgMkSockNode(NULL, &csock, NULL); 13152419Sjulian 13252419Sjulian for (; this != NULL; this = next) { 13352419Sjulian u_char rbuf[sizeof(struct ng_mesg) + sizeof(struct nodeinfo)]; 13452419Sjulian struct ng_mesg *resp = (struct ng_mesg *) rbuf; 13552419Sjulian struct nodeinfo *ni = (struct nodeinfo *) resp->data; 13652419Sjulian char path[64]; 13752419Sjulian 13852419Sjulian /* Read in ngpcb structure */ 13952419Sjulian kread((u_long)this, (char *)&ngpcb, sizeof(ngpcb)); 14070524Sphk next = LIST_NEXT(&ngpcb, socks); 14152419Sjulian 14252419Sjulian /* Read in socket structure */ 14352419Sjulian kread((u_long)ngpcb.ng_socket, (char *)&sockb, sizeof(sockb)); 14452419Sjulian 14552419Sjulian /* Check type of socket */ 14652419Sjulian if (strcmp(name, "ctrl") == 0 && ngpcb.type != NG_CONTROL) 14752419Sjulian continue; 14852419Sjulian if (strcmp(name, "data") == 0 && ngpcb.type != NG_DATA) 14952419Sjulian continue; 15052419Sjulian 15152419Sjulian /* Do headline */ 15252419Sjulian if (first) { 15352419Sjulian printf("Netgraph sockets\n"); 15452419Sjulian if (Aflag) 15552419Sjulian printf("%-8.8s ", "PCB"); 15652419Sjulian printf("%-5.5s %-6.6s %-6.6s %-14.14s %s\n", 15752419Sjulian "Type", "Recv-Q", "Send-Q", 15852419Sjulian "Node Address", "#Hooks"); 15952419Sjulian first = 0; 16052419Sjulian } 16152419Sjulian 16252419Sjulian /* Show socket */ 16352419Sjulian if (Aflag) 16452419Sjulian printf("%8lx ", (u_long) this); 165100591Sjdp printf("%-5.5s %6u %6u ", 16652419Sjulian name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); 16752419Sjulian 16852419Sjulian /* Get ngsock structure */ 169205083Sglebius if (ngpcb.sockdata == NULL) /* unconnected data socket */ 17052419Sjulian goto finish; 17152419Sjulian kread((u_long)ngpcb.sockdata, (char *)&info, sizeof(info)); 17252419Sjulian 17352419Sjulian /* Get info on associated node */ 174205083Sglebius if (info.node_id == 0 || csock == -1) 17552419Sjulian goto finish; 176205083Sglebius snprintf(path, sizeof(path), "[%x]:", info.node_id); 17752419Sjulian if (NgSendMsg(csock, path, 17852419Sjulian NGM_GENERIC_COOKIE, NGM_NODEINFO, NULL, 0) < 0) 17952419Sjulian goto finish; 18052419Sjulian if (NgRecvMsg(csock, resp, sizeof(rbuf), NULL) < 0) 18152419Sjulian goto finish; 18252419Sjulian 18352419Sjulian /* Display associated node info */ 18452419Sjulian if (*ni->name != '\0') 18552419Sjulian snprintf(path, sizeof(path), "%s:", ni->name); 18652419Sjulian printf("%-14.14s %4d", path, ni->hooks); 18752419Sjulianfinish: 18852419Sjulian putchar('\n'); 18952419Sjulian } 19052419Sjulian} 19152419Sjulian 192