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 36 static char sccsid[] = "@(#)mbuf.c 8.1 (Berkeley) 6/6/93"; 37 #endif 38 static const char rcsid[] = 39 "$FreeBSD$"; 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 <string.h> 52 #include "netstat.h" 53 54 #define YES 1 55 typedef int bool; 56 57 static struct mbtypenames { 58 short mt_type; 59 const char *mt_name; 60 } mbtypenames[] = { 61 { MT_DATA, "data" }, 62 { MT_OOBDATA, "oob data" }, 63 { MT_CONTROL, "ancillary data" }, 64 { MT_HEADER, "packet headers" }, 65 #ifdef MT_SOCKET 66 { MT_SOCKET, "socket structures" }, /* XXX */ 67 #endif 68 #ifdef MT_PCB 69 { MT_PCB, "protocol control blocks" }, /* XXX */ 70 #endif 71 #ifdef MT_RTABLE 72 { MT_RTABLE, "routing table entries" }, /* XXX */ 73 #endif 74 #ifdef MT_HTABLE 75 { MT_HTABLE, "IMP host table entries" }, /* XXX */ 76 #endif 77 #ifdef MT_ATABLE 78 { MT_ATABLE, "address resolution tables" }, 79 #endif 80 { MT_FTABLE, "fragment reassembly queue headers" }, /* XXX */ 81 { MT_SONAME, "socket names and addresses" }, 82 #ifdef MT_SOOPTS 83 { MT_SOOPTS, "socket options" }, 84 #endif 85 #ifdef MT_RIGHTS 86 { MT_RIGHTS, "access rights" }, 87 #endif 88 #ifdef MT_IFADDR 89 { MT_IFADDR, "interface addresses" }, /* XXX */ 90 #endif 91 { 0, 0 } 92 }; 93 94 /* 95 * Print mbuf statistics. 96 */ 97 void 98 mbpr(u_long mbaddr, u_long mbtaddr __unused, u_long nmbcaddr, u_long nmbufaddr, 99 u_long mbhiaddr, u_long clhiaddr, u_long mbloaddr, u_long clloaddr, 100 u_long cpusaddr __unused, u_long pgsaddr, u_long mbpaddr) 101 { 102 int i, nmbclusters; 103 int nsfbufs, nsfbufspeak, nsfbufsused; 104 short nmbtypes; 105 size_t mlen; 106 long *mbtypes = NULL; 107 struct mbstat *mbstat = NULL; 108 struct mbtypenames *mp; 109 bool *seen = NULL; 110 111 mlen = sizeof *mbstat; 112 if ((mbstat = malloc(mlen)) == NULL) { 113 warn("malloc: cannot allocate memory for mbstat"); 114 goto err; 115 } 116 117 if (mbaddr) { 118 if (kread(mbaddr, (char *)mbstat, sizeof mbstat)) 119 goto err; 120 if (kread(nmbcaddr, (char *)&nmbclusters, sizeof(int))) 121 goto err; 122 } else { 123 mlen = sizeof *mbstat; 124 if (sysctlbyname("kern.ipc.mbstat", mbstat, &mlen, NULL, 0) 125 < 0) { 126 warn("sysctl: retrieving mbstat"); 127 goto err; 128 } 129 mlen = sizeof(int); 130 if (sysctlbyname("kern.ipc.nmbclusters", &nmbclusters, &mlen, 131 NULL, 0) < 0) { 132 warn("sysctl: retrieving nmbclusters"); 133 goto err; 134 } 135 } 136 if (mbstat->m_mbufs < 0) mbstat->m_mbufs = 0; /* XXX */ 137 if (mbstat->m_mclusts < 0) mbstat->m_mclusts = 0; /* XXX */ 138 139 nmbtypes = mbstat->m_numtypes; 140 if ((seen = calloc(nmbtypes, sizeof(*seen))) == NULL) { 141 warn("calloc: cannot allocate memory for mbtypes seen flag"); 142 goto err; 143 } 144 if ((mbtypes = calloc(nmbtypes, sizeof(long *))) == NULL) { 145 warn("calloc: cannot allocate memory for mbtypes"); 146 goto err; 147 } 148 149 #undef MSIZE 150 #define MSIZE (mbstat->m_msize) 151 #undef MCLBYTES 152 #define MCLBYTES (mbstat->m_mclbytes) 153 154 printf("%lu mbufs in use\n", mbstat->m_mbufs); 155 156 for (mp = mbtypenames; mp->mt_name; mp++) { 157 if (mbtypes[mp->mt_type]) { 158 seen[mp->mt_type] = YES; 159 printf("\t %lu mbufs allocated to %s\n", 160 mbtypes[mp->mt_type], mp->mt_name); 161 } 162 } 163 for (i = 1; i < nmbtypes; i++) { 164 if (!seen[i] && mbtypes[i]) 165 printf("\t %lu mbufs allocated to <mbuf type: %d>\n", 166 mbtypes[i], i); 167 } 168 169 printf("%lu/%d mbuf clusters in use (current/max)\n", 170 mbstat->m_mclusts, nmbclusters); 171 172 mlen = sizeof(nsfbufs); 173 if (!sysctlbyname("kern.ipc.nsfbufs", &nsfbufs, &mlen, NULL, 0) && 174 !sysctlbyname("kern.ipc.nsfbufsused", &nsfbufsused, &mlen, NULL, 175 0) && 176 !sysctlbyname("kern.ipc.nsfbufspeak", &nsfbufspeak, &mlen, NULL, 177 0)) { 178 printf("%d/%d/%d sfbufs in use (current/peak/max)\n", 179 nsfbufsused, nsfbufspeak, nsfbufs); 180 } 181 printf("%lu KBytes allocated to network\n", (mbstat->m_mbufs * MSIZE + 182 mbstat->m_mclusts * MCLBYTES) / 1024); 183 printf("%lu requests for sfbufs denied\n", mbstat->sf_allocfail); 184 printf("%lu requests for sfbufs delayed\n", mbstat->sf_allocwait); 185 printf("%lu requests for I/O initiated by sendfile\n", 186 mbstat->sf_iocnt); 187 printf("%lu calls to protocol drain routines\n", mbstat->m_drain); 188 189 err: 190 if (mbtypes != NULL) 191 free(mbtypes); 192 if (seen != NULL) 193 free(seen); 194 if (mbstat != NULL) 195 free(mbstat); 196 } 197