unix.c revision 160787
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
34132671Scharnier#if 0
351590Srgrimes#ifndef lint
361590Srgrimesstatic char sccsid[] = "@(#)unix.c	8.1 (Berkeley) 6/6/93";
37132671Scharnier#endif /* not lint */
3827753Scharnier#endif
391590Srgrimes
40132671Scharnier#include <sys/cdefs.h>
41132671Scharnier__FBSDID("$FreeBSD: head/usr.bin/netstat/unix.c 160787 2006-07-28 16:09:19Z yar $");
42132671Scharnier
431590Srgrimes/*
441590Srgrimes * Display protocol blocks in the unix domain.
451590Srgrimes */
461590Srgrimes#include <sys/param.h>
4714543Sdg#include <sys/queue.h>
481590Srgrimes#include <sys/protosw.h>
491590Srgrimes#include <sys/socket.h>
501590Srgrimes#include <sys/socketvar.h>
511590Srgrimes#include <sys/mbuf.h>
521590Srgrimes#include <sys/sysctl.h>
531590Srgrimes#include <sys/un.h>
541590Srgrimes#include <sys/unpcb.h>
551590Srgrimes
561590Srgrimes#include <netinet/in.h>
571590Srgrimes
5836080Swollman#include <errno.h>
5938185Sphk#include <err.h>
6036103Swollman#include <stddef.h>
61160787Syar#include <stdint.h>
621590Srgrimes#include <stdio.h>
631590Srgrimes#include <stdlib.h>
6436080Swollman#include <kvm.h>
651590Srgrimes#include "netstat.h"
661590Srgrimes
6778314Sassarstatic	void unixdomainpr (struct xunpcb *, struct xsocket *);
681590Srgrimes
6936080Swollmanstatic	const char *const socktype[] =
7036080Swollman    { "#0", "stream", "dgram", "raw", "rdm", "seqpacket" };
711590Srgrimes
721590Srgrimesvoid
7378314Sassarunixpr(void)
741590Srgrimes{
7536080Swollman	char 	*buf;
7636080Swollman	int	type;
7736080Swollman	size_t	len;
7836080Swollman	struct	xsocket *so;
7936080Swollman	struct	xunpgen *xug, *oxug;
8036080Swollman	struct	xunpcb *xunp;
8136080Swollman	char mibvar[sizeof "net.local.seqpacket.pcblist"];
821590Srgrimes
8344091Sfenner	for (type = SOCK_STREAM; type <= SOCK_SEQPACKET; type++) {
8436080Swollman		sprintf(mibvar, "net.local.%s.pcblist", socktype[type]);
8536080Swollman
8636080Swollman		len = 0;
8736080Swollman		if (sysctlbyname(mibvar, 0, &len, 0, 0) < 0) {
8836080Swollman			if (errno != ENOENT)
8936080Swollman				warn("sysctl: %s", mibvar);
901590Srgrimes			continue;
9136080Swollman		}
9236080Swollman		if ((buf = malloc(len)) == 0) {
93132671Scharnier			warnx("malloc %lu bytes", (u_long)len);
9436080Swollman			return;
9536080Swollman		}
9636080Swollman		if (sysctlbyname(mibvar, buf, &len, 0, 0) < 0) {
9736080Swollman			warn("sysctl: %s", mibvar);
9836080Swollman			free(buf);
9936080Swollman			return;
10036080Swollman		}
10136080Swollman
10236080Swollman		oxug = xug = (struct xunpgen *)buf;
10336080Swollman		for (xug = (struct xunpgen *)((char *)xug + xug->xug_len);
10436080Swollman		     xug->xug_len > sizeof(struct xunpgen);
10536080Swollman		     xug = (struct xunpgen *)((char *)xug + xug->xug_len)) {
10636080Swollman			xunp = (struct xunpcb *)xug;
10736080Swollman			so = &xunp->xu_socket;
10836080Swollman
10936080Swollman			/* Ignore PCBs which were freed during copyout. */
11036080Swollman			if (xunp->xu_unp.unp_gencnt > oxug->xug_gen)
11136080Swollman				continue;
11236080Swollman			unixdomainpr(xunp, so);
11336080Swollman		}
11436080Swollman		if (xug != oxug && xug->xug_gen != oxug->xug_gen) {
11536080Swollman			if (oxug->xug_count > xug->xug_count) {
11636080Swollman				printf("Some %s sockets may have been deleted.\n",
11736080Swollman				       socktype[type]);
11836080Swollman			} else if (oxug->xug_count < xug->xug_count) {
11936080Swollman				printf("Some %s sockets may have been created.\n",
12036080Swollman			       socktype[type]);
12136080Swollman			} else {
12236080Swollman				printf("Some %s sockets may have been created or deleted",
12336080Swollman			       socktype[type]);
12436080Swollman			}
12536080Swollman		}
12636080Swollman		free(buf);
1271590Srgrimes	}
1281590Srgrimes}
1291590Srgrimes
1301590Srgrimesstatic void
13178314Sassarunixdomainpr(struct xunpcb *xunp, 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	}
151100591Sjdp	printf("%8lx %-6.6s %6u %6u %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,
15570524Sphk	       (long)LIST_FIRST(&unp->unp_refs), (long)LIST_NEXT(unp, unp_reflink));
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