1df8bae1dSRodney W. Grimes /*- 2df8bae1dSRodney W. Grimes * Copyright (c) 1982, 1986, 1989, 1993 3df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved. 4df8bae1dSRodney W. Grimes * 5df8bae1dSRodney W. Grimes * This code is derived from software contributed to Berkeley by 6df8bae1dSRodney W. Grimes * Mike Karels at Berkeley Software Design, Inc. 7df8bae1dSRodney W. Grimes * 8df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 9df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions 10df8bae1dSRodney W. Grimes * are met: 11df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 12df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 13df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 14df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 15df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution. 16df8bae1dSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 17df8bae1dSRodney W. Grimes * must display the following acknowledgement: 18df8bae1dSRodney W. Grimes * This product includes software developed by the University of 19df8bae1dSRodney W. Grimes * California, Berkeley and its contributors. 20df8bae1dSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 21df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 22df8bae1dSRodney W. Grimes * without specific prior written permission. 23df8bae1dSRodney W. Grimes * 24df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34df8bae1dSRodney W. Grimes * SUCH DAMAGE. 35df8bae1dSRodney W. Grimes * 36df8bae1dSRodney W. Grimes * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94 374b2af45fSPoul-Henning Kamp * $Id: kern_sysctl.c,v 1.51 1995/11/16 18:59:49 phk Exp $ 38df8bae1dSRodney W. Grimes */ 39df8bae1dSRodney W. Grimes 40df8bae1dSRodney W. Grimes /* 41df8bae1dSRodney W. Grimes * sysctl system call. 42df8bae1dSRodney W. Grimes */ 43df8bae1dSRodney W. Grimes 44df8bae1dSRodney W. Grimes #include <sys/param.h> 45df8bae1dSRodney W. Grimes #include <sys/systm.h> 46d2d3e875SBruce Evans #include <sys/sysproto.h> 47df8bae1dSRodney W. Grimes #include <sys/kernel.h> 48df8bae1dSRodney W. Grimes #include <sys/vnode.h> 49df8bae1dSRodney W. Grimes #include <sys/unistd.h> 505bb4f738SGarrett Wollman #include <sys/conf.h> 51df8bae1dSRodney W. Grimes #include <sys/sysctl.h> 52df8bae1dSRodney W. Grimes 534b2af45fSPoul-Henning Kamp /* 544b2af45fSPoul-Henning Kamp * Locking and stats 554b2af45fSPoul-Henning Kamp */ 564b2af45fSPoul-Henning Kamp static struct sysctl_lock { 574b2af45fSPoul-Henning Kamp int sl_lock; 584b2af45fSPoul-Henning Kamp int sl_want; 594b2af45fSPoul-Henning Kamp int sl_locked; 604b2af45fSPoul-Henning Kamp } memlock; 614b2af45fSPoul-Henning Kamp 624b2af45fSPoul-Henning Kamp static int sysctl_root SYSCTL_HANDLER_ARGS; 634b2af45fSPoul-Henning Kamp 64787d58f2SPoul-Henning Kamp extern struct linker_set sysctl_; 65787d58f2SPoul-Henning Kamp 66b396cd83SPoul-Henning Kamp /* BEGIN_MIB */ 67787d58f2SPoul-Henning Kamp SYSCTL_NODE(, 0, sysctl, CTLFLAG_RW, 0, 68787d58f2SPoul-Henning Kamp "Sysctl internal magic"); 692e210993SPoul-Henning Kamp SYSCTL_NODE(, CTL_KERN, kern, CTLFLAG_RW, 0, 702e210993SPoul-Henning Kamp "High kernel, proc, limits &c"); 712e210993SPoul-Henning Kamp SYSCTL_NODE(, CTL_VM, vm, CTLFLAG_RW, 0, 722e210993SPoul-Henning Kamp "Virtual memory"); 732e210993SPoul-Henning Kamp SYSCTL_NODE(, CTL_FS, fs, CTLFLAG_RW, 0, 742e210993SPoul-Henning Kamp "File system"); 752e210993SPoul-Henning Kamp SYSCTL_NODE(, CTL_NET, net, CTLFLAG_RW, 0, 762e210993SPoul-Henning Kamp "Network, (see socket.h)"); 772e210993SPoul-Henning Kamp SYSCTL_NODE(, CTL_DEBUG, debug, CTLFLAG_RW, 0, 782e210993SPoul-Henning Kamp "Debugging"); 792e210993SPoul-Henning Kamp SYSCTL_NODE(, CTL_HW, hw, CTLFLAG_RW, 0, 802e210993SPoul-Henning Kamp "hardware"); 812e210993SPoul-Henning Kamp SYSCTL_NODE(, CTL_MACHDEP, machdep, CTLFLAG_RW, 0, 822e210993SPoul-Henning Kamp "machine dependent"); 832e210993SPoul-Henning Kamp SYSCTL_NODE(, CTL_USER, user, CTLFLAG_RW, 0, 842e210993SPoul-Henning Kamp "user-level"); 85b396cd83SPoul-Henning Kamp 862e210993SPoul-Henning Kamp SYSCTL_STRING(_kern, KERN_OSRELEASE, osrelease, CTLFLAG_RD, osrelease, 0, ""); 87b396cd83SPoul-Henning Kamp 882e210993SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_OSREV, osrevision, CTLFLAG_RD, 0, BSD, ""); 89b396cd83SPoul-Henning Kamp 902e210993SPoul-Henning Kamp SYSCTL_STRING(_kern, KERN_VERSION, version, CTLFLAG_RD, version, 0, ""); 91b396cd83SPoul-Henning Kamp 922e210993SPoul-Henning Kamp SYSCTL_STRING(_kern, KERN_OSTYPE, ostype, CTLFLAG_RD, ostype, 0, ""); 93b396cd83SPoul-Henning Kamp 94b396cd83SPoul-Henning Kamp extern int osreldate; 952e210993SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_OSRELDATE, osreldate, CTLFLAG_RD, &osreldate, 0, ""); 96b396cd83SPoul-Henning Kamp 972e210993SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_MAXVNODES, maxvnodes, CTLFLAG_RD, &desiredvnodes, 0, ""); 98b396cd83SPoul-Henning Kamp 992e210993SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_MAXPROC, maxproc, CTLFLAG_RD, &maxproc, 0, ""); 100b396cd83SPoul-Henning Kamp 101b396cd83SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_MAXPROCPERUID, maxprocperuid, 1023a34a5c3SPoul-Henning Kamp CTLFLAG_RD, &maxprocperuid, 0, ""); 103b396cd83SPoul-Henning Kamp 1042e210993SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_ARGMAX, argmax, CTLFLAG_RD, 0, ARG_MAX, ""); 105b396cd83SPoul-Henning Kamp 1062e210993SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_POSIX1, posix1version, CTLFLAG_RD, 0, _POSIX_VERSION, ""); 107b396cd83SPoul-Henning Kamp 1082e210993SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_NGROUPS, ngroups, CTLFLAG_RD, 0, NGROUPS_MAX, ""); 109b396cd83SPoul-Henning Kamp 1102e210993SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_JOB_CONTROL, job_control, CTLFLAG_RD, 0, 1, ""); 111b396cd83SPoul-Henning Kamp 112b396cd83SPoul-Henning Kamp #ifdef _POSIX_SAVED_IDS 1132e210993SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD, 0, 1, ""); 114b396cd83SPoul-Henning Kamp #else 1152e210993SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_SAVED_IDS, saved_ids, CTLFLAG_RD, 0, 0, ""); 116b396cd83SPoul-Henning Kamp #endif 117b396cd83SPoul-Henning Kamp 118b396cd83SPoul-Henning Kamp char kernelname[MAXPATHLEN] = "/kernel"; /* XXX bloat */ 119b396cd83SPoul-Henning Kamp 120b396cd83SPoul-Henning Kamp SYSCTL_STRING(_kern, KERN_BOOTFILE, bootfile, 1213a34a5c3SPoul-Henning Kamp CTLFLAG_RW, kernelname, sizeof kernelname, ""); 122b396cd83SPoul-Henning Kamp 123b396cd83SPoul-Henning Kamp SYSCTL_STRUCT(_kern, KERN_BOOTTIME, boottime, 1243a34a5c3SPoul-Henning Kamp CTLFLAG_RW, &boottime, timeval, ""); 125b396cd83SPoul-Henning Kamp 1262e210993SPoul-Henning Kamp SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); 127b396cd83SPoul-Henning Kamp 128787d58f2SPoul-Henning Kamp SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, cpu_model, 0, ""); 129b396cd83SPoul-Henning Kamp 1302e210993SPoul-Henning Kamp SYSCTL_INT(_hw, HW_NCPU, ncpu, CTLFLAG_RD, 0, 1, ""); 131b396cd83SPoul-Henning Kamp 1322e210993SPoul-Henning Kamp SYSCTL_INT(_hw, HW_BYTEORDER, byteorder, CTLFLAG_RD, 0, BYTE_ORDER, ""); 133b396cd83SPoul-Henning Kamp 1342e210993SPoul-Henning Kamp SYSCTL_INT(_hw, HW_PAGESIZE, pagesize, CTLFLAG_RD, 0, PAGE_SIZE, ""); 135b396cd83SPoul-Henning Kamp 136b396cd83SPoul-Henning Kamp /* END_MIB */ 137b396cd83SPoul-Henning Kamp 138b396cd83SPoul-Henning Kamp extern int vfs_update_wakeup; 139b396cd83SPoul-Henning Kamp extern int vfs_update_interval; 140b396cd83SPoul-Henning Kamp static int 1413a34a5c3SPoul-Henning Kamp sysctl_kern_updateinterval SYSCTL_HANDLER_ARGS 142b396cd83SPoul-Henning Kamp { 1433a34a5c3SPoul-Henning Kamp int error = sysctl_handle_int(oidp, 144ae0eb976SPoul-Henning Kamp oidp->oid_arg1, oidp->oid_arg2, req); 1453a34a5c3SPoul-Henning Kamp if (!error) 146b396cd83SPoul-Henning Kamp wakeup(&vfs_update_wakeup); 1473a34a5c3SPoul-Henning Kamp return error; 148b396cd83SPoul-Henning Kamp } 149b396cd83SPoul-Henning Kamp 1502e210993SPoul-Henning Kamp SYSCTL_PROC(_kern, KERN_UPDATEINTERVAL, update, CTLTYPE_INT|CTLFLAG_RW, 1513a34a5c3SPoul-Henning Kamp &vfs_update_interval, 0, sysctl_kern_updateinterval, ""); 152b396cd83SPoul-Henning Kamp 1532e210993SPoul-Henning Kamp 1542e210993SPoul-Henning Kamp char hostname[MAXHOSTNAMELEN]; 1552e210993SPoul-Henning Kamp 1569565c0e6SPoul-Henning Kamp SYSCTL_STRING(_kern, KERN_HOSTNAME, hostname, CTLFLAG_RW, 1579565c0e6SPoul-Henning Kamp hostname, sizeof(hostname), ""); 1582e210993SPoul-Henning Kamp 1594b2af45fSPoul-Henning Kamp int securelevel = -1; 1604b2af45fSPoul-Henning Kamp 1614b2af45fSPoul-Henning Kamp static int 1624b2af45fSPoul-Henning Kamp sysctl_kern_securelvl SYSCTL_HANDLER_ARGS 1634b2af45fSPoul-Henning Kamp { 1644b2af45fSPoul-Henning Kamp int error, level; 1654b2af45fSPoul-Henning Kamp 1664b2af45fSPoul-Henning Kamp level = securelevel; 1674b2af45fSPoul-Henning Kamp error = sysctl_handle_int(oidp, &level, 0, req); 1684b2af45fSPoul-Henning Kamp if (error || !req->newptr) 1694b2af45fSPoul-Henning Kamp return (error); 1704b2af45fSPoul-Henning Kamp if (level < securelevel && req->p->p_pid != 1) 1714b2af45fSPoul-Henning Kamp return (EPERM); 1724b2af45fSPoul-Henning Kamp securelevel = level; 1734b2af45fSPoul-Henning Kamp return (error); 1744b2af45fSPoul-Henning Kamp } 1754b2af45fSPoul-Henning Kamp 1764b2af45fSPoul-Henning Kamp SYSCTL_PROC(_kern, KERN_SECURELVL, securelevel, CTLTYPE_INT|CTLFLAG_RW, 1774b2af45fSPoul-Henning Kamp 0, 0, sysctl_kern_securelvl, ""); 1784b2af45fSPoul-Henning Kamp 1794b2af45fSPoul-Henning Kamp static int 1804b2af45fSPoul-Henning Kamp sysctl_kern_dumpdev SYSCTL_HANDLER_ARGS 1814b2af45fSPoul-Henning Kamp { 1824b2af45fSPoul-Henning Kamp int error; 1834b2af45fSPoul-Henning Kamp dev_t ndumpdev; 1844b2af45fSPoul-Henning Kamp 1854b2af45fSPoul-Henning Kamp ndumpdev = dumpdev; 1864b2af45fSPoul-Henning Kamp error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req); 1874b2af45fSPoul-Henning Kamp if (!error && ndumpdev != dumpdev) { 1884b2af45fSPoul-Henning Kamp error = setdumpdev(ndumpdev); 1894b2af45fSPoul-Henning Kamp } 1904b2af45fSPoul-Henning Kamp return (error); 1914b2af45fSPoul-Henning Kamp } 1924b2af45fSPoul-Henning Kamp 1934b2af45fSPoul-Henning Kamp SYSCTL_PROC(_kern, KERN_DUMPDEV, dumpdev, CTLTYPE_OPAQUE|CTLFLAG_RW, 1944b2af45fSPoul-Henning Kamp 0, sizeof dumpdev, sysctl_kern_dumpdev, ""); 1954b2af45fSPoul-Henning Kamp 1964b2af45fSPoul-Henning Kamp static int 1974b2af45fSPoul-Henning Kamp sysctl_hw_physmem SYSCTL_HANDLER_ARGS 1984b2af45fSPoul-Henning Kamp { 1994b2af45fSPoul-Henning Kamp int error = sysctl_handle_int(oidp, 0, ctob(physmem), req); 2004b2af45fSPoul-Henning Kamp return (error); 2014b2af45fSPoul-Henning Kamp } 2024b2af45fSPoul-Henning Kamp 2034b2af45fSPoul-Henning Kamp SYSCTL_PROC(_hw, HW_PHYSMEM, physmem, CTLTYPE_INT|CTLFLAG_RD, 2044b2af45fSPoul-Henning Kamp 0, 0, sysctl_hw_physmem, ""); 2054b2af45fSPoul-Henning Kamp 2064b2af45fSPoul-Henning Kamp static int 2074b2af45fSPoul-Henning Kamp sysctl_hw_usermem SYSCTL_HANDLER_ARGS 2084b2af45fSPoul-Henning Kamp { 2094b2af45fSPoul-Henning Kamp int error = sysctl_handle_int(oidp, 0, 2104b2af45fSPoul-Henning Kamp ctob(physmem - cnt.v_wire_count), req); 2114b2af45fSPoul-Henning Kamp return (error); 2124b2af45fSPoul-Henning Kamp } 2134b2af45fSPoul-Henning Kamp 2144b2af45fSPoul-Henning Kamp SYSCTL_PROC(_hw, HW_USERMEM, usermem, CTLTYPE_INT|CTLFLAG_RD, 2154b2af45fSPoul-Henning Kamp 0, 0, sysctl_hw_usermem, ""); 2164b2af45fSPoul-Henning Kamp 2174b2af45fSPoul-Henning Kamp /* END_MIB */ 2184b2af45fSPoul-Henning Kamp 219787d58f2SPoul-Henning Kamp static int 2203c8e79ddSBruce Evans sysctl_order_cmp(const void *a, const void *b) 221787d58f2SPoul-Henning Kamp { 2223c8e79ddSBruce Evans const struct sysctl_oid **pa, **pb; 2233c8e79ddSBruce Evans 2243c8e79ddSBruce Evans pa = (const struct sysctl_oid **)a; 2253c8e79ddSBruce Evans pb = (const struct sysctl_oid **)b; 2263c8e79ddSBruce Evans if (*pa == NULL) 2273c8e79ddSBruce Evans return (1); 2283c8e79ddSBruce Evans if (*pb == NULL) 2293c8e79ddSBruce Evans return (-1); 230787d58f2SPoul-Henning Kamp return ((*pa)->oid_number - (*pb)->oid_number); 231787d58f2SPoul-Henning Kamp } 232787d58f2SPoul-Henning Kamp 233787d58f2SPoul-Henning Kamp static void 234787d58f2SPoul-Henning Kamp sysctl_order(void *arg) 235787d58f2SPoul-Henning Kamp { 236b8da2396SPoul-Henning Kamp int j; 237787d58f2SPoul-Henning Kamp struct linker_set *l = (struct linker_set *) arg; 238787d58f2SPoul-Henning Kamp struct sysctl_oid **oidpp; 239787d58f2SPoul-Henning Kamp 240787d58f2SPoul-Henning Kamp j = l->ls_length; 241787d58f2SPoul-Henning Kamp oidpp = (struct sysctl_oid **) l->ls_items; 242787d58f2SPoul-Henning Kamp for (; j--; oidpp++) { 243787d58f2SPoul-Henning Kamp if (!*oidpp) 244787d58f2SPoul-Henning Kamp continue; 245787d58f2SPoul-Henning Kamp if ((*oidpp)->oid_arg1 == arg) { 246787d58f2SPoul-Henning Kamp *oidpp = 0; 247787d58f2SPoul-Henning Kamp continue; 248787d58f2SPoul-Henning Kamp } 249787d58f2SPoul-Henning Kamp if (((*oidpp)->oid_kind & CTLTYPE) == CTLTYPE_NODE) 250787d58f2SPoul-Henning Kamp if (!(*oidpp)->oid_handler) 251787d58f2SPoul-Henning Kamp sysctl_order((*oidpp)->oid_arg1); 252787d58f2SPoul-Henning Kamp } 253787d58f2SPoul-Henning Kamp qsort(l->ls_items, l->ls_length, sizeof l->ls_items[0], 254787d58f2SPoul-Henning Kamp sysctl_order_cmp); 255787d58f2SPoul-Henning Kamp } 256787d58f2SPoul-Henning Kamp 257787d58f2SPoul-Henning Kamp SYSINIT(sysctl, SI_SUB_KMEM, SI_ORDER_ANY, sysctl_order, &sysctl_); 258787d58f2SPoul-Henning Kamp 259787d58f2SPoul-Henning Kamp static void 260787d58f2SPoul-Henning Kamp sysctl_sysctl_debug_dump_node(struct linker_set *l, int i) 261787d58f2SPoul-Henning Kamp { 262787d58f2SPoul-Henning Kamp int j, k; 263787d58f2SPoul-Henning Kamp struct sysctl_oid **oidpp; 264787d58f2SPoul-Henning Kamp 265787d58f2SPoul-Henning Kamp j = l->ls_length; 266787d58f2SPoul-Henning Kamp oidpp = (struct sysctl_oid **) l->ls_items; 267787d58f2SPoul-Henning Kamp for (; j--; oidpp++) { 268787d58f2SPoul-Henning Kamp 269787d58f2SPoul-Henning Kamp if (!*oidpp) 270787d58f2SPoul-Henning Kamp continue; 271787d58f2SPoul-Henning Kamp 272787d58f2SPoul-Henning Kamp for (k=0; k<i; k++) 273787d58f2SPoul-Henning Kamp printf(" "); 274787d58f2SPoul-Henning Kamp 275787d58f2SPoul-Henning Kamp if ((*oidpp)->oid_number > 100) { 276b8da2396SPoul-Henning Kamp printf("Junk! %p # %d %s k %x a1 %p a2 %x h %p\n", 277787d58f2SPoul-Henning Kamp *oidpp, 278787d58f2SPoul-Henning Kamp (*oidpp)->oid_number, (*oidpp)->oid_name, 279787d58f2SPoul-Henning Kamp (*oidpp)->oid_kind, (*oidpp)->oid_arg1, 280787d58f2SPoul-Henning Kamp (*oidpp)->oid_arg2, (*oidpp)->oid_handler); 281787d58f2SPoul-Henning Kamp continue; 282787d58f2SPoul-Henning Kamp } 283787d58f2SPoul-Henning Kamp printf("%d %s ", (*oidpp)->oid_number, (*oidpp)->oid_name); 284787d58f2SPoul-Henning Kamp 285787d58f2SPoul-Henning Kamp printf("%c%c", 286787d58f2SPoul-Henning Kamp (*oidpp)->oid_kind & CTLFLAG_RD ? 'R':' ', 287787d58f2SPoul-Henning Kamp (*oidpp)->oid_kind & CTLFLAG_WR ? 'W':' '); 288787d58f2SPoul-Henning Kamp 289787d58f2SPoul-Henning Kamp switch ((*oidpp)->oid_kind & CTLTYPE) { 290787d58f2SPoul-Henning Kamp case CTLTYPE_NODE: 291787d58f2SPoul-Henning Kamp if ((*oidpp)->oid_handler) { 292787d58f2SPoul-Henning Kamp printf(" Node(proc)\n"); 293787d58f2SPoul-Henning Kamp } else { 294787d58f2SPoul-Henning Kamp printf(" Node\n"); 295787d58f2SPoul-Henning Kamp sysctl_sysctl_debug_dump_node( 296787d58f2SPoul-Henning Kamp (*oidpp)->oid_arg1, i+2); 297787d58f2SPoul-Henning Kamp } 298787d58f2SPoul-Henning Kamp break; 299787d58f2SPoul-Henning Kamp case CTLTYPE_INT: printf(" Int\n"); break; 300787d58f2SPoul-Henning Kamp case CTLTYPE_STRING: printf(" String\n"); break; 301787d58f2SPoul-Henning Kamp case CTLTYPE_QUAD: printf(" Quad\n"); break; 302787d58f2SPoul-Henning Kamp case CTLTYPE_OPAQUE: printf(" Opaque/struct\n"); break; 303787d58f2SPoul-Henning Kamp default: printf("\n"); 304787d58f2SPoul-Henning Kamp } 305787d58f2SPoul-Henning Kamp 306787d58f2SPoul-Henning Kamp } 307787d58f2SPoul-Henning Kamp } 308787d58f2SPoul-Henning Kamp 309787d58f2SPoul-Henning Kamp 310787d58f2SPoul-Henning Kamp static int 311787d58f2SPoul-Henning Kamp sysctl_sysctl_debug SYSCTL_HANDLER_ARGS 312787d58f2SPoul-Henning Kamp { 313787d58f2SPoul-Henning Kamp sysctl_sysctl_debug_dump_node(&sysctl_, 0); 314787d58f2SPoul-Henning Kamp return ENOENT; 315787d58f2SPoul-Henning Kamp } 316787d58f2SPoul-Henning Kamp 317787d58f2SPoul-Henning Kamp SYSCTL_PROC(_sysctl, 0, debug, CTLTYPE_STRING|CTLFLAG_RD, 318787d58f2SPoul-Henning Kamp 0, 0, sysctl_sysctl_debug, ""); 3192e210993SPoul-Henning Kamp 3202e210993SPoul-Henning Kamp char domainname[MAXHOSTNAMELEN]; 32127aef046SPoul-Henning Kamp SYSCTL_STRING(_kern, KERN_DOMAINNAME, domainname, CTLFLAG_RW, 32227aef046SPoul-Henning Kamp &domainname, sizeof(domainname), ""); 3232e210993SPoul-Henning Kamp 3242e210993SPoul-Henning Kamp long hostid; 3252e210993SPoul-Henning Kamp /* Some trouble here, if sizeof (int) != sizeof (long) */ 3262e210993SPoul-Henning Kamp SYSCTL_INT(_kern, KERN_HOSTID, hostid, CTLFLAG_RW, &hostid, 0, ""); 3272e210993SPoul-Henning Kamp 328ae0eb976SPoul-Henning Kamp /* 329ae0eb976SPoul-Henning Kamp * Handle an integer, signed or unsigned. 330ae0eb976SPoul-Henning Kamp * Two cases: 331ae0eb976SPoul-Henning Kamp * a variable: point arg1 at it. 332ae0eb976SPoul-Henning Kamp * a constant: pass it in arg2. 333ae0eb976SPoul-Henning Kamp */ 334ae0eb976SPoul-Henning Kamp 3353a34a5c3SPoul-Henning Kamp int 3363a34a5c3SPoul-Henning Kamp sysctl_handle_int SYSCTL_HANDLER_ARGS 337b396cd83SPoul-Henning Kamp { 338ae0eb976SPoul-Henning Kamp int error = 0; 339b396cd83SPoul-Henning Kamp 340ae0eb976SPoul-Henning Kamp if (arg1) 341ae0eb976SPoul-Henning Kamp error = SYSCTL_OUT(req, arg1, sizeof(int)); 342ae0eb976SPoul-Henning Kamp else if (arg2) 343ae0eb976SPoul-Henning Kamp error = SYSCTL_OUT(req, &arg2, sizeof(int)); 344b396cd83SPoul-Henning Kamp 345ae0eb976SPoul-Henning Kamp if (error || !req->newptr) 346ae0eb976SPoul-Henning Kamp return (error); 347b396cd83SPoul-Henning Kamp 348ae0eb976SPoul-Henning Kamp if (!arg1) 349ae0eb976SPoul-Henning Kamp error = EPERM; 350ae0eb976SPoul-Henning Kamp else 351ae0eb976SPoul-Henning Kamp error = SYSCTL_IN(req, arg1, sizeof(int)); 352ae0eb976SPoul-Henning Kamp return (error); 353b396cd83SPoul-Henning Kamp } 354b396cd83SPoul-Henning Kamp 355ae0eb976SPoul-Henning Kamp /* 356ae0eb976SPoul-Henning Kamp * Handle our generic '\0' terminated 'C' string. 357ae0eb976SPoul-Henning Kamp * Two cases: 358ae0eb976SPoul-Henning Kamp * a variable string: point arg1 at it, arg2 is max length. 359ae0eb976SPoul-Henning Kamp * a constant string: point arg1 at it, arg2 is zero. 360ae0eb976SPoul-Henning Kamp */ 361ae0eb976SPoul-Henning Kamp 3623a34a5c3SPoul-Henning Kamp int 3633a34a5c3SPoul-Henning Kamp sysctl_handle_string SYSCTL_HANDLER_ARGS 364b396cd83SPoul-Henning Kamp { 365ae0eb976SPoul-Henning Kamp int error=0; 366b396cd83SPoul-Henning Kamp 367ae0eb976SPoul-Henning Kamp error = SYSCTL_OUT(req, arg1, strlen((char *)arg1)+1); 368b396cd83SPoul-Henning Kamp 369deae269aSPoul-Henning Kamp if (error || !req->newptr || !arg2) 370ae0eb976SPoul-Henning Kamp return (error); 371ae0eb976SPoul-Henning Kamp 372ae0eb976SPoul-Henning Kamp if ((req->newlen - req->newidx) > arg2) { 373ae0eb976SPoul-Henning Kamp error = E2BIG; 374ae0eb976SPoul-Henning Kamp } else { 375ae0eb976SPoul-Henning Kamp arg2 = (req->newlen - req->newidx); 376ae0eb976SPoul-Henning Kamp error = SYSCTL_IN(req, arg1, arg2); 377ae0eb976SPoul-Henning Kamp ((char *)arg1)[arg2] = '\0'; 378b396cd83SPoul-Henning Kamp } 379b396cd83SPoul-Henning Kamp 3802e210993SPoul-Henning Kamp return (error); 381b396cd83SPoul-Henning Kamp } 382b396cd83SPoul-Henning Kamp 383ae0eb976SPoul-Henning Kamp /* 384ae0eb976SPoul-Henning Kamp * Handle any kind of opaque data. 385ae0eb976SPoul-Henning Kamp * arg1 points to it, arg2 is the size. 386ae0eb976SPoul-Henning Kamp */ 387ae0eb976SPoul-Henning Kamp 3883a34a5c3SPoul-Henning Kamp int 3893a34a5c3SPoul-Henning Kamp sysctl_handle_opaque SYSCTL_HANDLER_ARGS 390b396cd83SPoul-Henning Kamp { 391ae0eb976SPoul-Henning Kamp int error; 392b396cd83SPoul-Henning Kamp 393ae0eb976SPoul-Henning Kamp error = SYSCTL_OUT(req, arg1, arg2); 394b396cd83SPoul-Henning Kamp 395ae0eb976SPoul-Henning Kamp if (error || !req->newptr) 396ae0eb976SPoul-Henning Kamp return (error); 397ae0eb976SPoul-Henning Kamp 398ae0eb976SPoul-Henning Kamp error = SYSCTL_IN(req, arg1, arg2); 399ae0eb976SPoul-Henning Kamp 400ae0eb976SPoul-Henning Kamp return (error); 401b396cd83SPoul-Henning Kamp } 402ae0eb976SPoul-Henning Kamp 403deae269aSPoul-Henning Kamp /* 404deae269aSPoul-Henning Kamp * Transfer functions to/from kernel space. 405deae269aSPoul-Henning Kamp * XXX: rather untested at this point 406deae269aSPoul-Henning Kamp */ 407deae269aSPoul-Henning Kamp static int 408ae0eb976SPoul-Henning Kamp sysctl_old_kernel(struct sysctl_req *req, void *p, int l) 409ae0eb976SPoul-Henning Kamp { 410deae269aSPoul-Henning Kamp int i = 0; 411deae269aSPoul-Henning Kamp 412deae269aSPoul-Henning Kamp if (req->oldptr) { 413deae269aSPoul-Henning Kamp i = min(req->oldlen - req->oldidx, l); 414deae269aSPoul-Henning Kamp if (i > 0) 415ae0eb976SPoul-Henning Kamp bcopy(p, req->oldptr + req->oldidx, i); 416ae0eb976SPoul-Henning Kamp } 417deae269aSPoul-Henning Kamp req->oldidx += l; 418ae0eb976SPoul-Henning Kamp if (i != l) 419ae0eb976SPoul-Henning Kamp return (ENOMEM); 4202e210993SPoul-Henning Kamp return (0); 421ae0eb976SPoul-Henning Kamp 422ae0eb976SPoul-Henning Kamp } 423ae0eb976SPoul-Henning Kamp 424deae269aSPoul-Henning Kamp static int 425ae0eb976SPoul-Henning Kamp sysctl_new_kernel(struct sysctl_req *req, void *p, int l) 426ae0eb976SPoul-Henning Kamp { 427deae269aSPoul-Henning Kamp if (!req->newptr) 428deae269aSPoul-Henning Kamp return 0; 429deae269aSPoul-Henning Kamp if (req->newlen - req->newidx < l) 430ae0eb976SPoul-Henning Kamp return (EINVAL); 431ae0eb976SPoul-Henning Kamp bcopy(req->newptr + req->newidx, p, l); 432ae0eb976SPoul-Henning Kamp req->newidx += l; 433ae0eb976SPoul-Henning Kamp return (0); 434ae0eb976SPoul-Henning Kamp } 435ae0eb976SPoul-Henning Kamp 436deae269aSPoul-Henning Kamp /* 437deae269aSPoul-Henning Kamp * Transfer function to/from user space. 438deae269aSPoul-Henning Kamp */ 439deae269aSPoul-Henning Kamp static int 440ae0eb976SPoul-Henning Kamp sysctl_old_user(struct sysctl_req *req, void *p, int l) 441ae0eb976SPoul-Henning Kamp { 442deae269aSPoul-Henning Kamp int error = 0, i = 0; 443ae0eb976SPoul-Henning Kamp 4444b2af45fSPoul-Henning Kamp if (req->lock == 1 && req->oldptr) { 4454b2af45fSPoul-Henning Kamp vslock(req->oldptr, req->oldlen); 4464b2af45fSPoul-Henning Kamp req->lock = 2; 4474b2af45fSPoul-Henning Kamp } 448deae269aSPoul-Henning Kamp if (req->oldptr) { 449deae269aSPoul-Henning Kamp i = min(req->oldlen - req->oldidx, l); 450deae269aSPoul-Henning Kamp if (i > 0) 451ae0eb976SPoul-Henning Kamp error = copyout(p, req->oldptr + req->oldidx, i); 452deae269aSPoul-Henning Kamp } 453deae269aSPoul-Henning Kamp req->oldidx += l; 454ae0eb976SPoul-Henning Kamp if (error) 455ae0eb976SPoul-Henning Kamp return (error); 456deae269aSPoul-Henning Kamp if (req->oldptr && i < l) 457ae0eb976SPoul-Henning Kamp return (ENOMEM); 458deae269aSPoul-Henning Kamp return (0); 459ae0eb976SPoul-Henning Kamp } 460ae0eb976SPoul-Henning Kamp 461deae269aSPoul-Henning Kamp static int 462ae0eb976SPoul-Henning Kamp sysctl_new_user(struct sysctl_req *req, void *p, int l) 463ae0eb976SPoul-Henning Kamp { 46416cd04a3SPoul-Henning Kamp int error; 465deae269aSPoul-Henning Kamp 466deae269aSPoul-Henning Kamp if (!req->newptr) 467deae269aSPoul-Henning Kamp return 0; 468deae269aSPoul-Henning Kamp if (req->newlen - req->newidx < l) 469ae0eb976SPoul-Henning Kamp return (EINVAL); 470ae0eb976SPoul-Henning Kamp error = copyin(req->newptr + req->newidx, p, l); 471ae0eb976SPoul-Henning Kamp req->newidx += l; 472ae0eb976SPoul-Henning Kamp return (error); 473b396cd83SPoul-Henning Kamp } 474b396cd83SPoul-Henning Kamp 475df8bae1dSRodney W. Grimes /* 4762e210993SPoul-Henning Kamp * Traverse our tree, and find the right node, execute whatever it points 4772e210993SPoul-Henning Kamp * at, and return the resulting error code. 4782e210993SPoul-Henning Kamp */ 4792e210993SPoul-Henning Kamp 4802e210993SPoul-Henning Kamp int 4812e210993SPoul-Henning Kamp sysctl_root SYSCTL_HANDLER_ARGS 4822e210993SPoul-Henning Kamp { 4832e210993SPoul-Henning Kamp int *name = (int *) arg1; 4842e210993SPoul-Henning Kamp int namelen = arg2; 4852e210993SPoul-Henning Kamp int indx, i, j; 4862e210993SPoul-Henning Kamp struct sysctl_oid **oidpp; 4872e210993SPoul-Henning Kamp struct linker_set *lsp = &sysctl_; 4882e210993SPoul-Henning Kamp 4892e210993SPoul-Henning Kamp j = lsp->ls_length; 4902e210993SPoul-Henning Kamp oidpp = (struct sysctl_oid **) lsp->ls_items; 4912e210993SPoul-Henning Kamp 4922e210993SPoul-Henning Kamp indx = 0; 4932e210993SPoul-Henning Kamp while (j-- && indx < CTL_MAXNAME) { 494787d58f2SPoul-Henning Kamp if (*oidpp && ((*oidpp)->oid_number == name[indx])) { 4952e210993SPoul-Henning Kamp indx++; 4964b2af45fSPoul-Henning Kamp if ((*oidpp)->oid_kind & CTLFLAG_NOLOCK) 4974b2af45fSPoul-Henning Kamp req->lock = 0; 4982e210993SPoul-Henning Kamp if (((*oidpp)->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 4992e210993SPoul-Henning Kamp if ((*oidpp)->oid_handler) 5002e210993SPoul-Henning Kamp goto found; 5012e210993SPoul-Henning Kamp if (indx == namelen) 5022e210993SPoul-Henning Kamp return ENOENT; 5032e210993SPoul-Henning Kamp lsp = (struct linker_set*)(*oidpp)->oid_arg1; 5042e210993SPoul-Henning Kamp j = lsp->ls_length; 5052e210993SPoul-Henning Kamp oidpp = (struct sysctl_oid **)lsp->ls_items; 5062e210993SPoul-Henning Kamp } else { 5072e210993SPoul-Henning Kamp if (indx != namelen) 5082e210993SPoul-Henning Kamp return EISDIR; 5092e210993SPoul-Henning Kamp goto found; 5102e210993SPoul-Henning Kamp } 5112e210993SPoul-Henning Kamp } else { 5122e210993SPoul-Henning Kamp oidpp++; 5132e210993SPoul-Henning Kamp } 5142e210993SPoul-Henning Kamp } 515deae269aSPoul-Henning Kamp return ENOENT; 5162e210993SPoul-Henning Kamp found: 5172e210993SPoul-Henning Kamp 5182e210993SPoul-Henning Kamp /* If writing isn't allowed */ 519ae0eb976SPoul-Henning Kamp if (req->newptr && !((*oidpp)->oid_kind & CTLFLAG_WR)) 5202e210993SPoul-Henning Kamp return (EPERM); 5212e210993SPoul-Henning Kamp 5222e210993SPoul-Henning Kamp if (!(*oidpp)->oid_handler) 5232e210993SPoul-Henning Kamp return EINVAL; 5242e210993SPoul-Henning Kamp 5252e210993SPoul-Henning Kamp if (((*oidpp)->oid_kind & CTLTYPE) == CTLTYPE_NODE) { 5262e210993SPoul-Henning Kamp i = ((*oidpp)->oid_handler) (*oidpp, 5272e210993SPoul-Henning Kamp name + indx, namelen - indx, 528ae0eb976SPoul-Henning Kamp req); 5292e210993SPoul-Henning Kamp } else { 5302e210993SPoul-Henning Kamp i = ((*oidpp)->oid_handler) (*oidpp, 5312e210993SPoul-Henning Kamp (*oidpp)->oid_arg1, (*oidpp)->oid_arg2, 532ae0eb976SPoul-Henning Kamp req); 5332e210993SPoul-Henning Kamp } 5342e210993SPoul-Henning Kamp return (i); 5352e210993SPoul-Henning Kamp } 5362e210993SPoul-Henning Kamp 537d2d3e875SBruce Evans #ifndef _SYS_SYSPROTO_H_ 538b8da2396SPoul-Henning Kamp struct sysctl_args { 539b8da2396SPoul-Henning Kamp int *name; 540b8da2396SPoul-Henning Kamp u_int namelen; 541b8da2396SPoul-Henning Kamp void *old; 542b8da2396SPoul-Henning Kamp size_t *oldlenp; 543b8da2396SPoul-Henning Kamp void *new; 544b8da2396SPoul-Henning Kamp size_t newlen; 545b8da2396SPoul-Henning Kamp }; 546d2d3e875SBruce Evans #endif 547b8da2396SPoul-Henning Kamp 548df8bae1dSRodney W. Grimes int 5494b2af45fSPoul-Henning Kamp __sysctl(struct proc *p, struct sysctl_args *uap, int *retval) 550df8bae1dSRodney W. Grimes { 551deae269aSPoul-Henning Kamp int error, i, j, name[CTL_MAXNAME]; 552b396cd83SPoul-Henning Kamp 553df8bae1dSRodney W. Grimes if (uap->namelen > CTL_MAXNAME || uap->namelen < 2) 554df8bae1dSRodney W. Grimes return (EINVAL); 555b396cd83SPoul-Henning Kamp 556797f2d22SPoul-Henning Kamp error = copyin(uap->name, &name, uap->namelen * sizeof(int)); 557797f2d22SPoul-Henning Kamp if (error) 558df8bae1dSRodney W. Grimes return (error); 559df8bae1dSRodney W. Grimes 560deae269aSPoul-Henning Kamp error = userland_sysctl(p, name, uap->namelen, 561b8da2396SPoul-Henning Kamp uap->old, uap->oldlenp, 0, 562deae269aSPoul-Henning Kamp uap->new, uap->newlen, &j); 563deae269aSPoul-Henning Kamp if (error && error != ENOMEM) 564deae269aSPoul-Henning Kamp return (error); 565deae269aSPoul-Henning Kamp if (uap->oldlenp) { 566deae269aSPoul-Henning Kamp i = copyout(&j, uap->oldlenp, sizeof(j)); 567deae269aSPoul-Henning Kamp if (i) 568deae269aSPoul-Henning Kamp return (i); 569deae269aSPoul-Henning Kamp } 570deae269aSPoul-Henning Kamp return (error); 571b8da2396SPoul-Henning Kamp } 572b8da2396SPoul-Henning Kamp 573b8da2396SPoul-Henning Kamp /* 574b8da2396SPoul-Henning Kamp * This is used from various compatibility syscalls too. That's why name 575b8da2396SPoul-Henning Kamp * must be in kernel space. 576b8da2396SPoul-Henning Kamp */ 577b8da2396SPoul-Henning Kamp int 578b8da2396SPoul-Henning Kamp userland_sysctl(struct proc *p, int *name, u_int namelen, void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen, int *retval) 579b8da2396SPoul-Henning Kamp { 5804b2af45fSPoul-Henning Kamp int error = 0; 581ae0eb976SPoul-Henning Kamp struct sysctl_req req; 582ae0eb976SPoul-Henning Kamp 583ae0eb976SPoul-Henning Kamp bzero(&req, sizeof req); 584b8da2396SPoul-Henning Kamp 58516cd04a3SPoul-Henning Kamp req.p = p; 58616cd04a3SPoul-Henning Kamp 587b8da2396SPoul-Henning Kamp if (new != NULL && (error = suser(p->p_ucred, &p->p_acflag))) 588b396cd83SPoul-Henning Kamp return (error); 589b396cd83SPoul-Henning Kamp 590b8da2396SPoul-Henning Kamp if (oldlenp) { 591b8da2396SPoul-Henning Kamp if (inkernel) { 592ae0eb976SPoul-Henning Kamp req.oldlen = *oldlenp; 593b8da2396SPoul-Henning Kamp } else { 594deae269aSPoul-Henning Kamp error = copyin(oldlenp, &req.oldlen, sizeof(*oldlenp)); 595b8da2396SPoul-Henning Kamp if (error) 596b8da2396SPoul-Henning Kamp return (error); 597b8da2396SPoul-Henning Kamp } 598b8da2396SPoul-Henning Kamp } 599b8da2396SPoul-Henning Kamp 600ae0eb976SPoul-Henning Kamp if (old) { 601ae0eb976SPoul-Henning Kamp if (!useracc(old, req.oldlen, B_WRITE)) 602ae0eb976SPoul-Henning Kamp return (EFAULT); 603ae0eb976SPoul-Henning Kamp req.oldptr= old; 604ae0eb976SPoul-Henning Kamp } 6052e210993SPoul-Henning Kamp 606b8da2396SPoul-Henning Kamp if (newlen) { 607ae0eb976SPoul-Henning Kamp if (!useracc(new, req.newlen, B_READ)) 608ae0eb976SPoul-Henning Kamp return (EFAULT); 609ae0eb976SPoul-Henning Kamp req.newlen = newlen; 610ae0eb976SPoul-Henning Kamp req.newptr = new; 611b396cd83SPoul-Henning Kamp } 612b396cd83SPoul-Henning Kamp 613ae0eb976SPoul-Henning Kamp req.oldfunc = sysctl_old_user; 614ae0eb976SPoul-Henning Kamp req.newfunc = sysctl_new_user; 6154b2af45fSPoul-Henning Kamp req.lock = 1; 6164b2af45fSPoul-Henning Kamp 6174b2af45fSPoul-Henning Kamp /* XXX this should probably be done in a general way */ 6184b2af45fSPoul-Henning Kamp while (memlock.sl_lock) { 6194b2af45fSPoul-Henning Kamp memlock.sl_want = 1; 6204b2af45fSPoul-Henning Kamp (void) tsleep((caddr_t)&memlock, PRIBIO+1, "sysctl", 0); 6214b2af45fSPoul-Henning Kamp memlock.sl_locked++; 6224b2af45fSPoul-Henning Kamp } 6234b2af45fSPoul-Henning Kamp memlock.sl_lock = 1; 624ae0eb976SPoul-Henning Kamp 625ae0eb976SPoul-Henning Kamp error = sysctl_root(0, name, namelen, &req); 626b396cd83SPoul-Henning Kamp 6274b2af45fSPoul-Henning Kamp if (req.lock == 2) 6284b2af45fSPoul-Henning Kamp vsunlock(req.oldptr, req.oldlen, B_WRITE); 6294b2af45fSPoul-Henning Kamp 6304b2af45fSPoul-Henning Kamp memlock.sl_lock = 0; 6314b2af45fSPoul-Henning Kamp 6324b2af45fSPoul-Henning Kamp if (memlock.sl_want) { 6334b2af45fSPoul-Henning Kamp memlock.sl_want = 0; 6344b2af45fSPoul-Henning Kamp wakeup((caddr_t)&memlock); 6354b2af45fSPoul-Henning Kamp } 6364b2af45fSPoul-Henning Kamp 637deae269aSPoul-Henning Kamp if (error && error != ENOMEM) 638deae269aSPoul-Henning Kamp return (error); 639deae269aSPoul-Henning Kamp 640deae269aSPoul-Henning Kamp if (retval) { 641deae269aSPoul-Henning Kamp if (req.oldptr && req.oldidx > req.oldlen) 642ae0eb976SPoul-Henning Kamp *retval = req.oldlen; 643deae269aSPoul-Henning Kamp else 644deae269aSPoul-Henning Kamp *retval = req.oldidx; 645b8da2396SPoul-Henning Kamp } 6462e210993SPoul-Henning Kamp return (error); 647df8bae1dSRodney W. Grimes } 648df8bae1dSRodney W. Grimes 649df8bae1dSRodney W. Grimes #ifdef COMPAT_43 650df8bae1dSRodney W. Grimes #include <sys/socket.h> 651df8bae1dSRodney W. Grimes #define KINFO_PROC (0<<8) 652df8bae1dSRodney W. Grimes #define KINFO_RT (1<<8) 653df8bae1dSRodney W. Grimes #define KINFO_VNODE (2<<8) 654df8bae1dSRodney W. Grimes #define KINFO_FILE (3<<8) 655df8bae1dSRodney W. Grimes #define KINFO_METER (4<<8) 656df8bae1dSRodney W. Grimes #define KINFO_LOADAVG (5<<8) 657df8bae1dSRodney W. Grimes #define KINFO_CLOCKRATE (6<<8) 658df8bae1dSRodney W. Grimes 6596ece4a51SPeter Wemm /* Non-standard BSDI extension - only present on their 4.3 net-2 releases */ 6606ece4a51SPeter Wemm #define KINFO_BSDI_SYSINFO (101<<8) 6616ece4a51SPeter Wemm 6626ece4a51SPeter Wemm /* 6636ece4a51SPeter Wemm * XXX this is bloat, but I hope it's better here than on the potentially 6646ece4a51SPeter Wemm * limited kernel stack... -Peter 6656ece4a51SPeter Wemm */ 6666ece4a51SPeter Wemm 6676ece4a51SPeter Wemm struct { 6686ece4a51SPeter Wemm int bsdi_machine; /* "i386" on BSD/386 */ 6696ece4a51SPeter Wemm /* ^^^ this is an offset to the string, relative to the struct start */ 6706ece4a51SPeter Wemm char *pad0; 6716ece4a51SPeter Wemm long pad1; 6726ece4a51SPeter Wemm long pad2; 6736ece4a51SPeter Wemm long pad3; 6746ece4a51SPeter Wemm u_long pad4; 6756ece4a51SPeter Wemm u_long pad5; 6766ece4a51SPeter Wemm u_long pad6; 6776ece4a51SPeter Wemm 6786ece4a51SPeter Wemm int bsdi_ostype; /* "BSD/386" on BSD/386 */ 6796ece4a51SPeter Wemm int bsdi_osrelease; /* "1.1" on BSD/386 */ 6806ece4a51SPeter Wemm long pad7; 6816ece4a51SPeter Wemm long pad8; 6826ece4a51SPeter Wemm char *pad9; 6836ece4a51SPeter Wemm 6846ece4a51SPeter Wemm long pad10; 6856ece4a51SPeter Wemm long pad11; 6866ece4a51SPeter Wemm int pad12; 6876ece4a51SPeter Wemm long pad13; 6886ece4a51SPeter Wemm quad_t pad14; 6896ece4a51SPeter Wemm long pad15; 6906ece4a51SPeter Wemm 6916ece4a51SPeter Wemm struct timeval pad16; 6926ece4a51SPeter Wemm /* we dont set this, because BSDI's uname used gethostname() instead */ 6936ece4a51SPeter Wemm int bsdi_hostname; /* hostname on BSD/386 */ 6946ece4a51SPeter Wemm 6956ece4a51SPeter Wemm /* the actual string data is appended here */ 6966ece4a51SPeter Wemm 6976ece4a51SPeter Wemm } bsdi_si; 6986ece4a51SPeter Wemm /* 6996ece4a51SPeter Wemm * this data is appended to the end of the bsdi_si structure during copyout. 7006ece4a51SPeter Wemm * The "char *" offsets are relative to the base of the bsdi_si struct. 7016ece4a51SPeter Wemm * This contains "FreeBSD\02.0-BUILT-nnnnnn\0i386\0", and these strings 7026ece4a51SPeter Wemm * should not exceed the length of the buffer here... (or else!! :-) 7036ece4a51SPeter Wemm */ 7046ece4a51SPeter Wemm char bsdi_strings[80]; /* It had better be less than this! */ 7056ece4a51SPeter Wemm 706d2d3e875SBruce Evans #ifndef _SYS_SYSPROTO_H_ 707df8bae1dSRodney W. Grimes struct getkerninfo_args { 708df8bae1dSRodney W. Grimes int op; 709df8bae1dSRodney W. Grimes char *where; 710df8bae1dSRodney W. Grimes int *size; 711df8bae1dSRodney W. Grimes int arg; 712df8bae1dSRodney W. Grimes }; 713d2d3e875SBruce Evans #endif 714df8bae1dSRodney W. Grimes 71526f9a767SRodney W. Grimes int 7164b2af45fSPoul-Henning Kamp ogetkerninfo(struct proc *p, struct getkerninfo_args *uap, int *retval) 717df8bae1dSRodney W. Grimes { 718b8da2396SPoul-Henning Kamp int error, name[6]; 719df8bae1dSRodney W. Grimes u_int size; 720df8bae1dSRodney W. Grimes 721df8bae1dSRodney W. Grimes switch (uap->op & 0xff00) { 722df8bae1dSRodney W. Grimes 723df8bae1dSRodney W. Grimes case KINFO_RT: 724b8da2396SPoul-Henning Kamp name[0] = CTL_NET; 725b8da2396SPoul-Henning Kamp name[1] = PF_ROUTE; 726b8da2396SPoul-Henning Kamp name[2] = 0; 727b8da2396SPoul-Henning Kamp name[3] = (uap->op & 0xff0000) >> 16; 728b8da2396SPoul-Henning Kamp name[4] = uap->op & 0xff; 729b8da2396SPoul-Henning Kamp name[5] = uap->arg; 730b8da2396SPoul-Henning Kamp error = userland_sysctl(p, name, 6, uap->where, uap->size, 7314b2af45fSPoul-Henning Kamp 0, 0, 0, &size); 732df8bae1dSRodney W. Grimes break; 733df8bae1dSRodney W. Grimes 734df8bae1dSRodney W. Grimes case KINFO_VNODE: 735b8da2396SPoul-Henning Kamp name[0] = CTL_KERN; 736b8da2396SPoul-Henning Kamp name[1] = KERN_VNODE; 737b8da2396SPoul-Henning Kamp error = userland_sysctl(p, name, 2, uap->where, uap->size, 7384b2af45fSPoul-Henning Kamp 0, 0, 0, &size); 739df8bae1dSRodney W. Grimes break; 740df8bae1dSRodney W. Grimes 741df8bae1dSRodney W. Grimes case KINFO_PROC: 742b8da2396SPoul-Henning Kamp name[0] = CTL_KERN; 743b8da2396SPoul-Henning Kamp name[1] = KERN_PROC; 744b8da2396SPoul-Henning Kamp name[2] = uap->op & 0xff; 745b8da2396SPoul-Henning Kamp name[3] = uap->arg; 746b8da2396SPoul-Henning Kamp error = userland_sysctl(p, name, 4, uap->where, uap->size, 7474b2af45fSPoul-Henning Kamp 0, 0, 0, &size); 748df8bae1dSRodney W. Grimes break; 749df8bae1dSRodney W. Grimes 750df8bae1dSRodney W. Grimes case KINFO_FILE: 751b8da2396SPoul-Henning Kamp name[0] = CTL_KERN; 752b8da2396SPoul-Henning Kamp name[1] = KERN_FILE; 753b8da2396SPoul-Henning Kamp error = userland_sysctl(p, name, 2, uap->where, uap->size, 7544b2af45fSPoul-Henning Kamp 0, 0, 0, &size); 755df8bae1dSRodney W. Grimes break; 756df8bae1dSRodney W. Grimes 757df8bae1dSRodney W. Grimes case KINFO_METER: 758b8da2396SPoul-Henning Kamp name[0] = CTL_VM; 759b8da2396SPoul-Henning Kamp name[1] = VM_METER; 760b8da2396SPoul-Henning Kamp error = userland_sysctl(p, name, 2, uap->where, uap->size, 7614b2af45fSPoul-Henning Kamp 0, 0, 0, &size); 762df8bae1dSRodney W. Grimes break; 763df8bae1dSRodney W. Grimes 764df8bae1dSRodney W. Grimes case KINFO_LOADAVG: 765b8da2396SPoul-Henning Kamp name[0] = CTL_VM; 766b8da2396SPoul-Henning Kamp name[1] = VM_LOADAVG; 767b8da2396SPoul-Henning Kamp error = userland_sysctl(p, name, 2, uap->where, uap->size, 7684b2af45fSPoul-Henning Kamp 0, 0, 0, &size); 769df8bae1dSRodney W. Grimes break; 770df8bae1dSRodney W. Grimes 771df8bae1dSRodney W. Grimes case KINFO_CLOCKRATE: 772b8da2396SPoul-Henning Kamp name[0] = CTL_KERN; 773b8da2396SPoul-Henning Kamp name[1] = KERN_CLOCKRATE; 774b8da2396SPoul-Henning Kamp error = userland_sysctl(p, name, 2, uap->where, uap->size, 7754b2af45fSPoul-Henning Kamp 0, 0, 0, &size); 776df8bae1dSRodney W. Grimes break; 777df8bae1dSRodney W. Grimes 7786ece4a51SPeter Wemm case KINFO_BSDI_SYSINFO: { 7796ece4a51SPeter Wemm /* 7806ece4a51SPeter Wemm * this is pretty crude, but it's just enough for uname() 7816ece4a51SPeter Wemm * from BSDI's 1.x libc to work. 7826ece4a51SPeter Wemm * 7836ece4a51SPeter Wemm * In particular, it doesn't return the same results when 7846ece4a51SPeter Wemm * the supplied buffer is too small. BSDI's version apparently 7856ece4a51SPeter Wemm * will return the amount copied, and set the *size to how 7866ece4a51SPeter Wemm * much was needed. The emulation framework here isn't capable 7876ece4a51SPeter Wemm * of that, so we just set both to the amount copied. 7886ece4a51SPeter Wemm * BSDI's 2.x product apparently fails with ENOMEM in this 7896ece4a51SPeter Wemm * scenario. 7906ece4a51SPeter Wemm */ 7916ece4a51SPeter Wemm 7926ece4a51SPeter Wemm u_int needed; 7936ece4a51SPeter Wemm u_int left; 7946ece4a51SPeter Wemm char *s; 7956ece4a51SPeter Wemm 7966ece4a51SPeter Wemm bzero((char *)&bsdi_si, sizeof(bsdi_si)); 7976ece4a51SPeter Wemm bzero(bsdi_strings, sizeof(bsdi_strings)); 7986ece4a51SPeter Wemm 7996ece4a51SPeter Wemm s = bsdi_strings; 8006ece4a51SPeter Wemm 8016ece4a51SPeter Wemm bsdi_si.bsdi_ostype = (s - bsdi_strings) + sizeof(bsdi_si); 8026ece4a51SPeter Wemm strcpy(s, ostype); 8036ece4a51SPeter Wemm s += strlen(s) + 1; 8046ece4a51SPeter Wemm 8056ece4a51SPeter Wemm bsdi_si.bsdi_osrelease = (s - bsdi_strings) + sizeof(bsdi_si); 8066ece4a51SPeter Wemm strcpy(s, osrelease); 8076ece4a51SPeter Wemm s += strlen(s) + 1; 8086ece4a51SPeter Wemm 8096ece4a51SPeter Wemm bsdi_si.bsdi_machine = (s - bsdi_strings) + sizeof(bsdi_si); 8106ece4a51SPeter Wemm strcpy(s, machine); 8116ece4a51SPeter Wemm s += strlen(s) + 1; 8126ece4a51SPeter Wemm 8136ece4a51SPeter Wemm needed = sizeof(bsdi_si) + (s - bsdi_strings); 8146ece4a51SPeter Wemm 8156ece4a51SPeter Wemm if (uap->where == NULL) { 8166ece4a51SPeter Wemm /* process is asking how much buffer to supply.. */ 8176ece4a51SPeter Wemm size = needed; 8186ece4a51SPeter Wemm error = 0; 8196ece4a51SPeter Wemm break; 8206ece4a51SPeter Wemm } 8216ece4a51SPeter Wemm 8226ece4a51SPeter Wemm 8236ece4a51SPeter Wemm /* if too much buffer supplied, trim it down */ 8246ece4a51SPeter Wemm if (size > needed) 8256ece4a51SPeter Wemm size = needed; 8266ece4a51SPeter Wemm 8276ece4a51SPeter Wemm /* how much of the buffer is remaining */ 8286ece4a51SPeter Wemm left = size; 8296ece4a51SPeter Wemm 8306ece4a51SPeter Wemm if ((error = copyout((char *)&bsdi_si, uap->where, left)) != 0) 8316ece4a51SPeter Wemm break; 8326ece4a51SPeter Wemm 8336ece4a51SPeter Wemm /* is there any point in continuing? */ 8346ece4a51SPeter Wemm if (left > sizeof(bsdi_si)) { 8356ece4a51SPeter Wemm left -= sizeof(bsdi_si); 8366ece4a51SPeter Wemm error = copyout(&bsdi_strings, 8376ece4a51SPeter Wemm uap->where + sizeof(bsdi_si), left); 8386ece4a51SPeter Wemm } 8396ece4a51SPeter Wemm break; 8406ece4a51SPeter Wemm } 8416ece4a51SPeter Wemm 842df8bae1dSRodney W. Grimes default: 843df8bae1dSRodney W. Grimes return (EOPNOTSUPP); 844df8bae1dSRodney W. Grimes } 845df8bae1dSRodney W. Grimes if (error) 846df8bae1dSRodney W. Grimes return (error); 847df8bae1dSRodney W. Grimes *retval = size; 848df8bae1dSRodney W. Grimes if (uap->size) 849df8bae1dSRodney W. Grimes error = copyout((caddr_t)&size, (caddr_t)uap->size, 850df8bae1dSRodney W. Grimes sizeof(size)); 851df8bae1dSRodney W. Grimes return (error); 852df8bae1dSRodney W. Grimes } 853df8bae1dSRodney W. Grimes #endif /* COMPAT_43 */ 854