unix.c revision 38185
11590Srgrimes/*-
21590Srgrimes * Copyright (c) 1983, 1988, 1993
31590Srgrimes *	The Regents of the University of California.  All rights reserved.
41590Srgrimes *
51590Srgrimes * Redistribution and use in source and binary forms, with or without
61590Srgrimes * modification, are permitted provided that the following conditions
71590Srgrimes * are met:
81590Srgrimes * 1. Redistributions of source code must retain the above copyright
91590Srgrimes *    notice, this list of conditions and the following disclaimer.
101590Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111590Srgrimes *    notice, this list of conditions and the following disclaimer in the
121590Srgrimes *    documentation and/or other materials provided with the distribution.
131590Srgrimes * 3. All advertising materials mentioning features or use of this software
141590Srgrimes *    must display the following acknowledgement:
151590Srgrimes *	This product includes software developed by the University of
161590Srgrimes *	California, Berkeley and its contributors.
171590Srgrimes * 4. Neither the name of the University nor the names of its contributors
181590Srgrimes *    may be used to endorse or promote products derived from this software
191590Srgrimes *    without specific prior written permission.
201590Srgrimes *
211590Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221590Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231590Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241590Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251590Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261590Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271590Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281590Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291590Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301590Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311590Srgrimes * SUCH DAMAGE.
321590Srgrimes */
331590Srgrimes
341590Srgrimes#ifndef lint
3527753Scharnier#if 0
361590Srgrimesstatic char sccsid[] = "@(#)unix.c	8.1 (Berkeley) 6/6/93";
3727753Scharnier#endif
3827753Scharnierstatic const char rcsid[] =
3938185Sphk	"$Id: unix.c,v 1.9 1998/07/06 21:01:27 bde Exp $";
401590Srgrimes#endif /* not lint */
411590Srgrimes
421590Srgrimes/*
431590Srgrimes * Display protocol blocks in the unix domain.
441590Srgrimes */
451590Srgrimes#include <sys/param.h>
4614543Sdg#include <sys/queue.h>
471590Srgrimes#include <sys/protosw.h>
481590Srgrimes#include <sys/socket.h>
491590Srgrimes#include <sys/socketvar.h>
501590Srgrimes#include <sys/mbuf.h>
511590Srgrimes#include <sys/sysctl.h>
521590Srgrimes#include <sys/un.h>
531590Srgrimes#include <sys/unpcb.h>
541590Srgrimes
551590Srgrimes#include <netinet/in.h>
561590Srgrimes
5736080Swollman#include <errno.h>
5838185Sphk#include <err.h>
5936103Swollman#include <stddef.h>
601590Srgrimes#include <stdio.h>
611590Srgrimes#include <stdlib.h>
6236080Swollman#include <kvm.h>
631590Srgrimes#include "netstat.h"
641590Srgrimes
6536080Swollmanstatic	void unixdomainpr __P((struct xunpcb *, struct xsocket *));
661590Srgrimes
6736080Swollmanstatic	const char *const socktype[] =
6836080Swollman    { "#0", "stream", "dgram", "raw", "rdm", "seqpacket" };
691590Srgrimes
701590Srgrimesvoid
7136080Swollmanunixpr()
721590Srgrimes{
7336080Swollman	char 	*buf;
7436080Swollman	int	type;
7536080Swollman	size_t	len;
7636080Swollman	struct	xsocket *so;
7736080Swollman	struct	xunpgen *xug, *oxug;
7836080Swollman	struct	xunpcb *xunp;
7936080Swollman	char mibvar[sizeof "net.local.seqpacket.pcblist"];
801590Srgrimes
8136080Swollman	for (type = SOCK_STREAM; type < SOCK_SEQPACKET; type++) {
8236080Swollman		sprintf(mibvar, "net.local.%s.pcblist", socktype[type]);
8336080Swollman
8436080Swollman		len = 0;
8536080Swollman		if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
8636080Swollman			if (errno != ENOENT)
8736080Swollman				warn("sysctl: %s", mibvar);
881590Srgrimes			continue;
8936080Swollman		}
9036080Swollman		if ((buf = malloc(len)) == 0) {
9136080Swollman			warn("malloc %lu bytes", (u_long)len);
9236080Swollman			return;
9336080Swollman		}
9436080Swollman		if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
9536080Swollman			warn("sysctl: %s", mibvar);
9636080Swollman			free(buf);
9736080Swollman			return;
9836080Swollman		}
9936080Swollman
10036080Swollman		oxug = xug = (struct xunpgen *)buf;
10136080Swollman		for (xug = (struct xunpgen *)((char *)xug + xug->xug_len);
10236080Swollman		     xug->xug_len > sizeof(struct xunpgen);
10336080Swollman		     xug = (struct xunpgen *)((char *)xug + xug->xug_len)) {
10436080Swollman			xunp = (struct xunpcb *)xug;
10536080Swollman			so = &xunp->xu_socket;
10636080Swollman
10736080Swollman			/* Ignore PCBs which were freed during copyout. */
10836080Swollman			if (xunp->xu_unp.unp_gencnt > oxug->xug_gen)
10936080Swollman				continue;
11036080Swollman			unixdomainpr(xunp, so);
11136080Swollman		}
11236080Swollman		if (xug != oxug && xug->xug_gen != oxug->xug_gen) {
11336080Swollman			if (oxug->xug_count > xug->xug_count) {
11436080Swollman				printf("Some %s sockets may have been deleted.\n",
11536080Swollman				       socktype[type]);
11636080Swollman			} else if (oxug->xug_count < xug->xug_count) {
11736080Swollman				printf("Some %s sockets may have been created.\n",
11836080Swollman			       socktype[type]);
11936080Swollman			} else {
12036080Swollman				printf("Some %s sockets may have been created or deleted",
12136080Swollman			       socktype[type]);
12236080Swollman			}
12336080Swollman		}
12436080Swollman		free(buf);
1251590Srgrimes	}
1261590Srgrimes}
1271590Srgrimes
1281590Srgrimesstatic void
12936080Swollmanunixdomainpr(xunp, so)
13036080Swollman	struct xunpcb *xunp;
13136080Swollman	struct xsocket *so;
1321590Srgrimes{
13336080Swollman	struct unpcb *unp;
13436080Swollman	struct sockaddr_un *sa;
1351590Srgrimes	static int first = 1;
1361590Srgrimes
13736080Swollman	unp = &xunp->xu_unp;
13836080Swollman	if (unp->unp_addr)
13936080Swollman		sa = &xunp->xu_addr;
14036080Swollman	else
14128726Swollman		sa = (struct sockaddr_un *)0;
14236080Swollman
1431590Srgrimes	if (first) {
1441590Srgrimes		printf("Active UNIX domain sockets\n");
1451590Srgrimes		printf(
1461590Srgrimes"%-8.8s %-6.6s %-6.6s %-6.6s %8.8s %8.8s %8.8s %8.8s Addr\n",
1471590Srgrimes		    "Address", "Type", "Recv-Q", "Send-Q",
1481590Srgrimes		    "Inode", "Conn", "Refs", "Nextref");
1491590Srgrimes		first = 0;
1501590Srgrimes	}
15136080Swollman	printf("%8lx %-6.6s %6ld %6ld %8lx %8lx %8lx %8lx",
15236080Swollman	       (long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc,
15336080Swollman	       so->so_snd.sb_cc,
15436080Swollman	       (long)unp->unp_vnode, (long)unp->unp_conn,
15536080Swollman	       (long)unp->unp_refs.lh_first, (long)unp->unp_reflink.le_next);
15628726Swollman	if (sa)
15736091Sache		printf(" %.*s",
15837453Sbde		    (int)(sa->sun_len - offsetof(struct sockaddr_un, sun_path)),
15936091Sache		    sa->sun_path);
1601590Srgrimes	putchar('\n');
1611590Srgrimes}
162