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 #if 0 35 #ifndef lint 36 static char sccsid[] = "@(#)mbuf.c 8.1 (Berkeley) 6/6/93"; 37 #endif /* not lint */ 38 #endif 39 40 #include <sys/cdefs.h> 41 __FBSDID("$FreeBSD$"); 42 43 #include <sys/param.h> 44 #include <sys/mbuf.h> 45 #include <sys/protosw.h> 46 #include <sys/socket.h> 47 #include <sys/sysctl.h> 48 49 #include <err.h> 50 #include <stdio.h> 51 #include <stdlib.h> 52 #include <string.h> 53 #include "netstat.h" 54 55 #define YES 1 56 typedef int bool; 57 58 static struct mbtypenames { 59 short mt_type; 60 const 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 */ 98 void 99 mbpr(u_long mbaddr, u_long mbtaddr __unused, u_long nmbcaddr, u_long nmbufaddr, 100 u_long mbhiaddr, u_long clhiaddr, u_long mbloaddr, u_long clloaddr, 101 u_long cpusaddr __unused, u_long pgsaddr, u_long mbpaddr) 102 { 103 int i, nmbclusters; 104 int nsfbufs, nsfbufspeak, nsfbufsused; 105 short nmbtypes; 106 size_t mlen; 107 long *mbtypes = NULL; 108 struct mbstat *mbstat = NULL; 109 struct mbtypenames *mp; 110 bool *seen = NULL; 111 112 mlen = sizeof *mbstat; 113 if ((mbstat = malloc(mlen)) == NULL) { 114 warn("malloc: cannot allocate memory for mbstat"); 115 goto err; 116 } 117 118 if (mbaddr) { 119 if (kread(mbaddr, (char *)mbstat, sizeof mbstat)) 120 goto err; 121 if (kread(nmbcaddr, (char *)&nmbclusters, sizeof(int))) 122 goto err; 123 } else { 124 mlen = sizeof *mbstat; 125 if (sysctlbyname("kern.ipc.mbstat", mbstat, &mlen, NULL, 0) 126 < 0) { 127 warn("sysctl: retrieving mbstat"); 128 goto err; 129 } 130 mlen = sizeof(int); 131 if (sysctlbyname("kern.ipc.nmbclusters", &nmbclusters, &mlen, 132 NULL, 0) < 0) { 133 warn("sysctl: retrieving nmbclusters"); 134 goto err; 135 } 136 } 137 if (mbstat->m_mbufs < 0) mbstat->m_mbufs = 0; /* XXX */ 138 if (mbstat->m_mclusts < 0) mbstat->m_mclusts = 0; /* XXX */ 139 140 nmbtypes = mbstat->m_numtypes; 141 if ((seen = calloc(nmbtypes, sizeof(*seen))) == NULL) { 142 warn("calloc: cannot allocate memory for mbtypes seen flag"); 143 goto err; 144 } 145 if ((mbtypes = calloc(nmbtypes, sizeof(long *))) == NULL) { 146 warn("calloc: cannot allocate memory for mbtypes"); 147 goto err; 148 } 149 150 #undef MSIZE 151 #define MSIZE (mbstat->m_msize) 152 #undef MCLBYTES 153 #define MCLBYTES (mbstat->m_mclbytes) 154 155 printf("%lu mbufs in use\n", mbstat->m_mbufs); 156 157 for (mp = mbtypenames; mp->mt_name; mp++) { 158 if (mbtypes[mp->mt_type]) { 159 seen[mp->mt_type] = YES; 160 printf("\t %lu mbufs allocated to %s\n", 161 mbtypes[mp->mt_type], mp->mt_name); 162 } 163 } 164 for (i = 1; i < nmbtypes; i++) { 165 if (!seen[i] && mbtypes[i]) 166 printf("\t %lu mbufs allocated to <mbuf type: %d>\n", 167 mbtypes[i], i); 168 } 169 170 printf("%lu/%d mbuf clusters in use (current/max)\n", 171 mbstat->m_mclusts, nmbclusters); 172 173 mlen = sizeof(nsfbufs); 174 if (!sysctlbyname("kern.ipc.nsfbufs", &nsfbufs, &mlen, NULL, 0) && 175 !sysctlbyname("kern.ipc.nsfbufsused", &nsfbufsused, &mlen, NULL, 176 0) && 177 !sysctlbyname("kern.ipc.nsfbufspeak", &nsfbufspeak, &mlen, NULL, 178 0)) { 179 printf("%d/%d/%d sfbufs in use (current/peak/max)\n", 180 nsfbufsused, nsfbufspeak, nsfbufs); 181 } 182 printf("%lu KBytes allocated to network\n", (mbstat->m_mbufs * MSIZE + 183 mbstat->m_mclusts * MCLBYTES) / 1024); 184 printf("%lu requests for sfbufs denied\n", mbstat->sf_allocfail); 185 printf("%lu requests for sfbufs delayed\n", mbstat->sf_allocwait); 186 printf("%lu requests for I/O initiated by sendfile\n", 187 mbstat->sf_iocnt); 188 printf("%lu calls to protocol drain routines\n", mbstat->m_drain); 189 190 err: 191 if (mbtypes != NULL) 192 free(mbtypes); 193 if (seen != NULL) 194 free(seen); 195 if (mbstat != NULL) 196 free(mbstat); 197 } 198