unix.c revision 44091
1187962Sdas/*-
2187962Sdas * Copyright (c) 1983, 1988, 1993
3187962Sdas *	The Regents of the University of California.  All rights reserved.
4187962Sdas *
5187962Sdas * Redistribution and use in source and binary forms, with or without
6187962Sdas * modification, are permitted provided that the following conditions
7187962Sdas * are met:
8187962Sdas * 1. Redistributions of source code must retain the above copyright
9187962Sdas *    notice, this list of conditions and the following disclaimer.
10187962Sdas * 2. Redistributions in binary form must reproduce the above copyright
11187962Sdas *    notice, this list of conditions and the following disclaimer in the
12187962Sdas *    documentation and/or other materials provided with the distribution.
13187962Sdas * 3. All advertising materials mentioning features or use of this software
14187962Sdas *    must display the following acknowledgement:
15187962Sdas *	This product includes software developed by the University of
16187962Sdas *	California, Berkeley and its contributors.
17187962Sdas * 4. Neither the name of the University nor the names of its contributors
18187962Sdas *    may be used to endorse or promote products derived from this software
19187962Sdas *    without specific prior written permission.
20187962Sdas *
21187962Sdas * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22187962Sdas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23187962Sdas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24187962Sdas * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25187962Sdas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26187962Sdas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27187962Sdas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28187962Sdas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29187962Sdas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30187962Sdas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31187962Sdas * SUCH DAMAGE.
32187962Sdas */
33187962Sdas
34187962Sdas#ifndef lint
35187962Sdas#if 0
36187962Sdasstatic char sccsid[] = "@(#)unix.c	8.1 (Berkeley) 6/6/93";
37187962Sdas#endif
38187962Sdasstatic const char rcsid[] =
39187962Sdas	"$Id: unix.c,v 1.10 1998/08/08 08:13:04 phk Exp $";
40251241Sdas#endif /* not lint */
41251241Sdas
42271296Sngie/*
43187962Sdas * Display protocol blocks in the unix domain.
44187962Sdas */
45187962Sdas#include <sys/param.h>
46187962Sdas#include <sys/queue.h>
47187962Sdas#include <sys/protosw.h>
48187962Sdas#include <sys/socket.h>
49187962Sdas#include <sys/socketvar.h>
50187962Sdas#include <sys/mbuf.h>
51187962Sdas#include <sys/sysctl.h>
52187962Sdas#include <sys/un.h>
53187962Sdas#include <sys/unpcb.h>
54187962Sdas
55187962Sdas#include <netinet/in.h>
56187962Sdas
57187962Sdas#include <errno.h>
58187962Sdas#include <err.h>
59187962Sdas#include <stddef.h>
60187962Sdas#include <stdio.h>
61187962Sdas#include <stdlib.h>
62187962Sdas#include <kvm.h>
63187962Sdas#include "netstat.h"
64187962Sdas
65187962Sdasstatic	void unixdomainpr __P((struct xunpcb *, struct xsocket *));
66187962Sdas
67187962Sdasstatic	const char *const socktype[] =
68187962Sdas    { "#0", "stream", "dgram", "raw", "rdm", "seqpacket" };
69187962Sdas
70187962Sdasvoid
71187962Sdasunixpr()
72187962Sdas{
73187962Sdas	char 	*buf;
74187962Sdas	int	type;
75187962Sdas	size_t	len;
76187962Sdas	struct	xsocket *so;
77187962Sdas	struct	xunpgen *xug, *oxug;
78187962Sdas	struct	xunpcb *xunp;
79187962Sdas	char mibvar[sizeof "net.local.seqpacket.pcblist"];
80187962Sdas
81187962Sdas	for (type = SOCK_STREAM; type <= SOCK_SEQPACKET; type++) {
82187962Sdas		sprintf(mibvar, "net.local.%s.pcblist", socktype[type]);
83187962Sdas
84187962Sdas		len = 0;
85187962Sdas		if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
86187962Sdas			if (errno != ENOENT)
87187962Sdas				warn("sysctl: %s", mibvar);
88187962Sdas			continue;
89187962Sdas		}
90187962Sdas		if ((buf = malloc(len)) == 0) {
91187962Sdas			warn("malloc %lu bytes", (u_long)len);
92187962Sdas			return;
93187962Sdas		}
94187962Sdas		if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
95187962Sdas			warn("sysctl: %s", mibvar);
96187962Sdas			free(buf);
97187962Sdas			return;
98187962Sdas		}
99187962Sdas
100187962Sdas		oxug = xug = (struct xunpgen *)buf;
101187962Sdas		for (xug = (struct xunpgen *)((char *)xug + xug->xug_len);
102187962Sdas		     xug->xug_len > sizeof(struct xunpgen);
103187962Sdas		     xug = (struct xunpgen *)((char *)xug + xug->xug_len)) {
104187962Sdas			xunp = (struct xunpcb *)xug;
105187962Sdas			so = &xunp->xu_socket;
106187962Sdas
107187962Sdas			/* Ignore PCBs which were freed during copyout. */
108187962Sdas			if (xunp->xu_unp.unp_gencnt > oxug->xug_gen)
109187962Sdas				continue;
110187962Sdas			unixdomainpr(xunp, so);
111187962Sdas		}
112187962Sdas		if (xug != oxug && xug->xug_gen != oxug->xug_gen) {
113187962Sdas			if (oxug->xug_count > xug->xug_count) {
114187962Sdas				printf("Some %s sockets may have been deleted.\n",
115187962Sdas				       socktype[type]);
116187962Sdas			} else if (oxug->xug_count < xug->xug_count) {
117187962Sdas				printf("Some %s sockets may have been created.\n",
118187962Sdas			       socktype[type]);
119187962Sdas			} else {
120187962Sdas				printf("Some %s sockets may have been created or deleted",
121187962Sdas			       socktype[type]);
122187962Sdas			}
123187962Sdas		}
124187962Sdas		free(buf);
125187962Sdas	}
126187962Sdas}
127187962Sdas
128187962Sdasstatic void
129187962Sdasunixdomainpr(xunp, so)
130187962Sdas	struct xunpcb *xunp;
131187962Sdas	struct xsocket *so;
132187962Sdas{
133187962Sdas	struct unpcb *unp;
134187962Sdas	struct sockaddr_un *sa;
135187962Sdas	static int first = 1;
136187962Sdas
137187962Sdas	unp = &xunp->xu_unp;
138187962Sdas	if (unp->unp_addr)
139187962Sdas		sa = &xunp->xu_addr;
140	else
141		sa = (struct sockaddr_un *)0;
142
143	if (first) {
144		printf("Active UNIX domain sockets\n");
145		printf(
146"%-8.8s %-6.6s %-6.6s %-6.6s %8.8s %8.8s %8.8s %8.8s Addr\n",
147		    "Address", "Type", "Recv-Q", "Send-Q",
148		    "Inode", "Conn", "Refs", "Nextref");
149		first = 0;
150	}
151	printf("%8lx %-6.6s %6ld %6ld %8lx %8lx %8lx %8lx",
152	       (long)so->so_pcb, socktype[so->so_type], so->so_rcv.sb_cc,
153	       so->so_snd.sb_cc,
154	       (long)unp->unp_vnode, (long)unp->unp_conn,
155	       (long)unp->unp_refs.lh_first, (long)unp->unp_reflink.le_next);
156	if (sa)
157		printf(" %.*s",
158		    (int)(sa->sun_len - offsetof(struct sockaddr_un, sun_path)),
159		    sa->sun_path);
160	putchar('\n');
161}
162