mbuf.c revision 63203
1/*
2 * Copyright (c) 1983, 1988, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 *    must display the following acknowledgement:
15 *	This product includes software developed by the University of
16 *	California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35#if 0
36static char sccsid[] = "@(#)mbuf.c	8.1 (Berkeley) 6/6/93";
37#endif
38static const char rcsid[] =
39  "$FreeBSD: head/usr.bin/netstat/mbuf.c 63203 2000-07-15 06:02:48Z alfred $";
40#endif /* not lint */
41
42#include <sys/param.h>
43#include <sys/mbuf.h>
44#include <sys/protosw.h>
45#include <sys/socket.h>
46#include <sys/sysctl.h>
47
48#include <err.h>
49#include <stdio.h>
50#include <stdlib.h>
51#include "netstat.h"
52
53#define	YES	1
54typedef int bool;
55
56struct	mbstat mbstat;
57
58static struct mbtypenames {
59	int	mt_type;
60	char	*mt_name;
61} mbtypenames[] = {
62	{ MT_DATA,	"data" },
63	{ MT_OOBDATA,	"oob data" },
64	{ MT_CONTROL,	"ancillary data" },
65	{ MT_HEADER,	"packet headers" },
66#ifdef MT_SOCKET
67	{ MT_SOCKET,	"socket structures" },			/* XXX */
68#endif
69#ifdef MT_PCB
70	{ MT_PCB,	"protocol control blocks" },		/* XXX */
71#endif
72#ifdef MT_RTABLE
73	{ MT_RTABLE,	"routing table entries" },		/* XXX */
74#endif
75#ifdef MT_HTABLE
76	{ MT_HTABLE,	"IMP host table entries" },		/* XXX */
77#endif
78#ifdef MT_ATABLE
79	{ MT_ATABLE,	"address resolution tables" },
80#endif
81	{ MT_FTABLE,	"fragment reassembly queue headers" },	/* XXX */
82	{ MT_SONAME,	"socket names and addresses" },
83#ifdef MT_SOOPTS
84	{ MT_SOOPTS,	"socket options" },
85#endif
86#ifdef MT_RIGHTS
87	{ MT_RIGHTS,	"access rights" },
88#endif
89#ifdef MT_IFADDR
90	{ MT_IFADDR,	"interface addresses" },		/* XXX */
91#endif
92	{ 0, 0 }
93};
94
95/*
96 * Print mbuf statistics.
97 */
98void
99mbpr()
100{
101	register int totmem, totfree, totmbufs;
102	register int i;
103	struct mbtypenames *mp;
104	int name[3], nmbclusters, nmbufs, nmbtypes;
105	size_t nmbclen, nmbuflen, mbstatlen, mbtypeslen;
106	u_long *mbtypes;
107	bool *seen;	/* "have we seen this type yet?" */
108
109	mbtypes = NULL;
110	seen = NULL;
111
112	name[0] = CTL_KERN;
113	name[1] = KERN_IPC;
114	name[2] = KIPC_MBSTAT;
115	mbstatlen = sizeof mbstat;
116	if (sysctl(name, 3, &mbstat, &mbstatlen, 0, 0) < 0) {
117		warn("sysctl: retrieving mbstat");
118		goto err;
119	}
120
121	if (sysctlbyname("kern.ipc.mbtypes", NULL, &mbtypeslen, NULL, 0) < 0) {
122		warn("sysctl: retrieving mbtypes length");
123		goto err;
124	}
125	if ((mbtypes = malloc(mbtypeslen)) == NULL) {
126		warn("malloc: %lu bytes for mbtypes", (u_long)mbtypeslen);
127		goto err;
128	}
129	if (sysctlbyname("kern.ipc.mbtypes", mbtypes, &mbtypeslen, NULL,
130	    0) < 0) {
131		warn("sysctl: retrieving mbtypes");
132		goto err;
133	}
134
135	nmbtypes = mbtypeslen / sizeof(*mbtypes);
136	if ((seen = calloc(nmbtypes, sizeof(*seen))) == NULL) {
137		warn("calloc");
138		goto err;
139	}
140
141	name[2] = KIPC_NMBCLUSTERS;
142	nmbclen = sizeof(int);
143	if (sysctl(name, 3, &nmbclusters, &nmbclen, 0, 0) < 0) {
144		warn("sysctl: retrieving nmbclusters");
145		goto err;
146	}
147
148	nmbuflen = sizeof(int);
149	if (sysctlbyname("kern.ipc.nmbufs", &nmbufs, &nmbuflen, 0, 0) < 0) {
150		warn("sysctl: retrieving nmbufs");
151		goto err;
152	}
153
154#undef MSIZE
155#define MSIZE		(mbstat.m_msize)
156#undef MCLBYTES
157#define	MCLBYTES	(mbstat.m_mclbytes)
158
159	totmbufs = 0;
160	for (mp = mbtypenames; mp->mt_name; mp++)
161		totmbufs += mbtypes[mp->mt_type];
162	printf("%u/%lu/%u mbufs in use (current/peak/max):\n", totmbufs,
163	    mbstat.m_mbufs, nmbufs);
164	for (mp = mbtypenames; mp->mt_name; mp++)
165		if (mbtypes[mp->mt_type]) {
166			seen[mp->mt_type] = YES;
167			printf("\t%lu mbufs allocated to %s\n",
168			    mbtypes[mp->mt_type], mp->mt_name);
169		}
170	seen[MT_FREE] = YES;
171	for (i = 0; i < nmbtypes; i++)
172		if (!seen[i] && mbtypes[i]) {
173			printf("\t%lu mbufs allocated to <mbuf type %d>\n",
174			    mbtypes[i], i);
175		}
176	printf("%lu/%lu/%u mbuf clusters in use (current/peak/max)\n",
177		mbstat.m_clusters - mbstat.m_clfree, mbstat.m_clusters,
178		nmbclusters);
179	totmem = mbstat.m_mbufs * MSIZE + mbstat.m_clusters * MCLBYTES;
180	totfree = mbstat.m_clfree * MCLBYTES +
181		MSIZE * (mbstat.m_mbufs - totmbufs);
182	printf("%u Kbytes allocated to network (%d%% in use)\n",
183		totmem / 1024, (unsigned) (totmem - totfree) * 100 / totmem);
184	printf("%lu requests for memory denied\n", mbstat.m_drops);
185	printf("%lu requests for memory delayed\n", mbstat.m_wait);
186	printf("%lu calls to protocol drain routines\n", mbstat.m_drain);
187
188err:
189	if (mbtypes != NULL)
190		free(mbtypes);
191	if (seen != NULL)
192		free(seen);
193}
194