sysctl.c revision 1.88
1/* $OpenBSD: sysctl.c,v 1.88 2003/04/25 20:27:19 grange Exp $ */ 2/* $NetBSD: sysctl.c,v 1.9 1995/09/30 07:12:50 thorpej Exp $ */ 3 4/* 5 * Copyright (c) 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by the University of 19 * California, Berkeley and its contributors. 20 * 4. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 */ 36 37#ifndef lint 38static const char copyright[] = 39"@(#) Copyright (c) 1993\n\ 40 The Regents of the University of California. All rights reserved.\n"; 41#endif /* not lint */ 42 43#ifndef lint 44#if 0 45static const char sccsid[] = "@(#)sysctl.c 8.5 (Berkeley) 5/9/95"; 46#else 47static char *rcsid = "$OpenBSD: sysctl.c,v 1.88 2003/04/25 20:27:19 grange Exp $"; 48#endif 49#endif /* not lint */ 50 51#include <sys/param.h> 52#include <sys/gmon.h> 53#include <sys/mount.h> 54#include <sys/stat.h> 55#include <sys/sem.h> 56#include <sys/shm.h> 57#include <sys/sysctl.h> 58#include <sys/socket.h> 59#include <sys/malloc.h> 60#include <sys/dkstat.h> 61#include <sys/uio.h> 62#include <sys/tty.h> 63#include <sys/namei.h> 64#include <machine/cpu.h> 65#include <net/route.h> 66 67#include <netinet/in.h> 68#include <netinet/in_systm.h> 69#include <netinet/ip.h> 70#include <netinet/in_pcb.h> 71#include <netinet/ip_icmp.h> 72#include <netinet/ip_ipip.h> 73#include <netinet/ip_ether.h> 74#include <netinet/ip_ah.h> 75#include <netinet/ip_esp.h> 76#include <netinet/icmp_var.h> 77#include <netinet/ip_var.h> 78#include <netinet/udp.h> 79#include <netinet/udp_var.h> 80#include <netinet/tcp.h> 81#include <netinet/tcp_timer.h> 82#include <netinet/tcp_var.h> 83#include <netinet/ip_gre.h> 84#include <netinet/ip_ipcomp.h> 85 86#ifdef INET6 87#include <netinet/ip6.h> 88#include <netinet/icmp6.h> 89#include <netinet6/ip6_var.h> 90#include <netinet6/pim6_var.h> 91#endif 92 93#include <uvm/uvm_swap_encrypt.h> 94 95#include <ufs/ufs/quota.h> 96#include <ufs/ufs/inode.h> 97#include <ufs/ffs/fs.h> 98#include <ufs/ffs/ffs_extern.h> 99 100#include <nfs/rpcv2.h> 101#include <nfs/nfsproto.h> 102#include <nfs/nfs.h> 103 104#include <netipx/ipx.h> 105#include <netipx/ipx_var.h> 106#include <netipx/spx_var.h> 107#include <ddb/db_var.h> 108#include <dev/rndvar.h> 109 110#include <err.h> 111#include <errno.h> 112#include <stdio.h> 113#include <stdlib.h> 114#include <string.h> 115#include <ctype.h> 116 117#ifdef CPU_BIOS 118#include <machine/biosvar.h> 119#endif 120 121struct ctlname topname[] = CTL_NAMES; 122struct ctlname kernname[] = CTL_KERN_NAMES; 123struct ctlname vmname[] = CTL_VM_NAMES; 124struct ctlname fsname[] = CTL_FS_NAMES; 125struct ctlname netname[] = CTL_NET_NAMES; 126struct ctlname hwname[] = CTL_HW_NAMES; 127struct ctlname username[] = CTL_USER_NAMES; 128struct ctlname debugname[CTL_DEBUG_MAXID]; 129struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES; 130struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES; 131struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES; 132struct ctlname ttyname[] = CTL_KERN_TTY_NAMES; 133struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES; 134struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES; 135struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES; 136struct ctlname *vfsname; 137#ifdef CTL_MACHDEP_NAMES 138struct ctlname machdepname[] = CTL_MACHDEP_NAMES; 139#endif 140struct ctlname ddbname[] = CTL_DDB_NAMES; 141char names[BUFSIZ]; 142int lastused; 143 144struct list { 145 struct ctlname *list; 146 int size; 147}; 148struct list toplist = { topname, CTL_MAXID }; 149struct list secondlevel[] = { 150 { 0, 0 }, /* CTL_UNSPEC */ 151 { kernname, KERN_MAXID }, /* CTL_KERN */ 152 { vmname, VM_MAXID }, /* CTL_VM */ 153 { fsname, FS_MAXID }, /* CTL_FS */ 154 { netname, NET_MAXID }, /* CTL_NET */ 155 { 0, CTL_DEBUG_MAXID }, /* CTL_DEBUG */ 156 { hwname, HW_MAXID }, /* CTL_HW */ 157#ifdef CTL_MACHDEP_NAMES 158 { machdepname, CPU_MAXID }, /* CTL_MACHDEP */ 159#else 160 { 0, 0 }, /* CTL_MACHDEP */ 161#endif 162 { username, USER_MAXID }, /* CTL_USER_NAMES */ 163 { ddbname, DBCTL_MAXID }, /* CTL_DDB_NAMES */ 164 { 0, 0 }, /* CTL_VFS */ 165}; 166 167int Aflag, aflag, nflag, wflag; 168 169/* 170 * Variables requiring special processing. 171 */ 172#define CLOCK 0x00000001 173#define BOOTTIME 0x00000002 174#define CHRDEV 0x00000004 175#define BLKDEV 0x00000008 176#define RNDSTATS 0x00000010 177#define BADDYNAMIC 0x00000020 178#define BIOSGEO 0x00000040 179#define BIOSDEV 0x00000080 180#define MAJ2DEV 0x00000100 181#define UNSIGNED 0x00000200 182#define KMEMBUCKETS 0x00000400 183#define LONGARRAY 0x00000800 184#define KMEMSTATS 0x00001000 185 186/* prototypes */ 187void debuginit(void); 188void listall(char *, struct list *); 189void parse(char *, int); 190void parse_baddynamic(int *, size_t, char *, void **, size_t *, int, int); 191void usage(void); 192int findname(char *, char *, char **, struct list *); 193int sysctl_inet(char *, char **, int *, int, int *); 194#ifdef INET6 195int sysctl_inet6(char *, char **, int *, int, int *); 196#endif 197int sysctl_ipx(char *, char **, int *, int, int *); 198int sysctl_fs(char *, char **, int *, int, int *); 199static int sysctl_vfs(char *, char **, int[], int, int *); 200static int sysctl_vfsgen(char *, char **, int[], int, int *); 201int sysctl_bios(char *, char **, int *, int, int *); 202int sysctl_swpenc(char *, char **, int *, int, int *); 203int sysctl_forkstat(char *, char **, int *, int, int *); 204int sysctl_tty(char *, char **, int *, int, int *); 205int sysctl_nchstats(char *, char **, int *, int, int *); 206int sysctl_malloc(char *, char **, int *, int, int *); 207int sysctl_seminfo(char *, char **, int *, int, int *); 208int sysctl_shminfo(char *, char **, int *, int, int *); 209int sysctl_watchdog(char *, char **, int *, int, int *); 210#ifdef CPU_CHIPSET 211int sysctl_chipset(char *, char **, int *, int, int *); 212#endif 213void vfsinit(void); 214 215int 216main(int argc, char *argv[]) 217{ 218 int ch, lvl1; 219 220 while ((ch = getopt(argc, argv, "Aanw")) != -1) { 221 switch (ch) { 222 223 case 'A': 224 Aflag = 1; 225 break; 226 227 case 'a': 228 aflag = 1; 229 break; 230 231 case 'n': 232 nflag = 1; 233 break; 234 235 case 'w': 236 wflag = 1; 237 break; 238 239 default: 240 usage(); 241 } 242 } 243 argc -= optind; 244 argv += optind; 245 246 if (argc == 0 && (Aflag || aflag)) { 247 debuginit(); 248 vfsinit(); 249 for (lvl1 = 1; lvl1 < CTL_MAXID; lvl1++) 250 listall(topname[lvl1].ctl_name, &secondlevel[lvl1]); 251 return (0); 252 } 253 if (argc == 0) 254 usage(); 255 for (; *argv != NULL; ++argv) 256 parse(*argv, 1); 257 return (0); 258} 259 260/* 261 * List all variables known to the system. 262 */ 263void 264listall(char *prefix, struct list *lp) 265{ 266 char *cp, name[BUFSIZ]; 267 int lvl2, len; 268 269 if (lp->list == NULL) 270 return; 271 if ((len = strlcpy(name, prefix, sizeof(name))) >= sizeof(name)) 272 warn("%s: name too long", prefix); 273 cp = name + len++; 274 *cp++ = '.'; 275 for (lvl2 = 0; lvl2 < lp->size; lvl2++) { 276 if (lp->list[lvl2].ctl_name == NULL) 277 continue; 278 if (strlcpy(cp, lp->list[lvl2].ctl_name, 279 sizeof(name) - len) >= sizeof(name) - len) 280 warn("%s: name too long", lp->list[lvl2].ctl_name); 281 parse(name, Aflag); 282 } 283} 284 285/* 286 * Parse a name into a MIB entry. 287 * Lookup and print out the MIB entry if it exists. 288 * Set a new value if requested. 289 */ 290void 291parse(char *string, int flags) 292{ 293 int indx, type, state, intval, len; 294 size_t size, newsize = 0; 295 int lal = 0, special = 0; 296 void *newval = 0; 297 int64_t quadval; 298 struct list *lp; 299 int mib[CTL_MAXNAME]; 300 char *cp, *bufp, buf[BUFSIZ]; 301 302 (void)strlcpy(buf, string, sizeof(buf)); 303 bufp = buf; 304 if ((cp = strchr(string, '=')) != NULL) { 305 if (!wflag) 306 errx(2, "must specify -w to set variables"); 307 *strchr(buf, '=') = '\0'; 308 *cp++ = '\0'; 309 while (isspace(*cp)) 310 cp++; 311 newval = cp; 312 newsize = strlen(cp); 313 } 314 if ((indx = findname(string, "top", &bufp, &toplist)) == -1) 315 return; 316 mib[0] = indx; 317 if (indx == CTL_VFS) 318 vfsinit(); 319 if (indx == CTL_DEBUG) 320 debuginit(); 321 lp = &secondlevel[indx]; 322 if (lp->list == 0) { 323 warnx("%s: class is not implemented", topname[indx].ctl_name); 324 return; 325 } 326 if (bufp == NULL) { 327 listall(topname[indx].ctl_name, lp); 328 return; 329 } 330 if ((indx = findname(string, "second", &bufp, lp)) == -1) 331 return; 332 mib[1] = indx; 333 type = lp->list[indx].ctl_type; 334 len = 2; 335 switch (mib[0]) { 336 337 case CTL_KERN: 338 switch (mib[1]) { 339 case KERN_PROF: 340 mib[2] = GPROF_STATE; 341 size = sizeof(state); 342 if (sysctl(mib, 3, &state, &size, NULL, 0) == -1) { 343 if (flags == 0) 344 return; 345 if (!nflag) 346 (void)printf("%s: ", string); 347 (void)puts("kernel is not compiled for profiling"); 348 return; 349 } 350 if (!nflag) 351 (void)printf("%s = %s\n", string, 352 state == GMON_PROF_OFF ? "off" : "running"); 353 return; 354 case KERN_FORKSTAT: 355 sysctl_forkstat(string, &bufp, mib, flags, &type); 356 return; 357 case KERN_TTY: 358 len = sysctl_tty(string, &bufp, mib, flags, &type); 359 if (len < 0) 360 return; 361 newsize = 0; 362 break; 363 case KERN_NCHSTATS: 364 sysctl_nchstats(string, &bufp, mib, flags, &type); 365 return; 366 case KERN_MALLOCSTATS: 367 len = sysctl_malloc(string, &bufp, mib, flags, &type); 368 if (len < 0) 369 return; 370 if (mib[2] == KERN_MALLOC_BUCKET) 371 special |= KMEMBUCKETS; 372 if (mib[2] == KERN_MALLOC_KMEMSTATS) 373 special |= KMEMSTATS; 374 newsize = 0; 375 break; 376 case KERN_MBSTAT: 377 if (flags == 0) 378 return; 379 warnx("use netstat to view %s", string); 380 return; 381 case KERN_MSGBUF: 382 if (flags == 0) 383 return; 384 warnx("use dmesg to view %s", string); 385 return; 386 case KERN_VNODE: 387 case KERN_FILE: 388 if (flags == 0) 389 return; 390 warnx("use pstat to view %s information", string); 391 return; 392 case KERN_PROC: 393 if (flags == 0) 394 return; 395 warnx("use ps to view %s information", string); 396 return; 397 case KERN_CLOCKRATE: 398 special |= CLOCK; 399 break; 400 case KERN_BOOTTIME: 401 special |= BOOTTIME; 402 break; 403 case KERN_RND: 404 special |= RNDSTATS; 405 break; 406 case KERN_HOSTID: 407 case KERN_ARND: 408 special |= UNSIGNED; 409 break; 410 case KERN_CPTIME: 411 special |= LONGARRAY; 412 lal = CPUSTATES; 413 break; 414 case KERN_SEMINFO: 415 len = sysctl_seminfo(string, &bufp, mib, flags, &type); 416 if (len < 0) 417 return; 418 break; 419 case KERN_SHMINFO: 420 len = sysctl_shminfo(string, &bufp, mib, flags, &type); 421 if (len < 0) 422 return; 423 break; 424 case KERN_WATCHDOG: 425 len = sysctl_watchdog(string, &bufp, mib, flags, 426 &type); 427 if (len < 0) 428 return; 429 break; 430 } 431 break; 432 433 case CTL_HW: 434 switch (mib[1]) { 435 case HW_DISKSTATS: 436 /* 437 * Only complain if someone asks explicitly for this, 438 * otherwise "fail" silently. 439 */ 440 if (flags) 441 warnx("use vmstat to view %s information", 442 string); 443 return; 444 } 445 break; 446 447 case CTL_VM: 448 if (mib[1] == VM_LOADAVG) { 449 double loads[3]; 450 451 getloadavg(loads, 3); 452 if (!nflag) 453 (void)printf("%s = ", string); 454 (void)printf("%.2f %.2f %.2f\n", loads[0], 455 loads[1], loads[2]); 456 return; 457 } else if (mib[1] == VM_PSSTRINGS) { 458 struct _ps_strings _ps; 459 460 size = sizeof(_ps); 461 if (sysctl(mib, 2, &_ps, &size, NULL, 0) == -1) { 462 if (flags == 0) 463 return; 464 if (!nflag) 465 (void)printf("%s: ", string); 466 (void)puts("can't find ps strings"); 467 return; 468 } 469 if (!nflag) 470 (void)printf("%s = ", string); 471 (void)printf("%p\n", _ps.val); 472 return; 473 } else if (mib[1] == VM_SWAPENCRYPT) { 474 len = sysctl_swpenc(string, &bufp, mib, flags, &type); 475 if (len < 0) 476 return; 477 478 break; 479 } else if (mib[1] == VM_NKMEMPAGES || 480 mib[1] == VM_ANONMIN || 481 mib[1] == VM_VTEXTMIN || 482 mib[1] == VM_VNODEMIN) { 483 break; 484 } 485 if (flags == 0) 486 return; 487 warnx("use vmstat or systat to view %s information", string); 488 return; 489 490 break; 491 492 case CTL_NET: 493 if (mib[1] == PF_INET) { 494 len = sysctl_inet(string, &bufp, mib, flags, &type); 495 if (len < 0) 496 return; 497 498 if ((mib[2] == IPPROTO_TCP && 499 mib[3] == TCPCTL_BADDYNAMIC) || 500 (mib[2] == IPPROTO_UDP && 501 mib[3] == UDPCTL_BADDYNAMIC)) { 502 503 special |= BADDYNAMIC; 504 505 if (newval != NULL) 506 parse_baddynamic(mib, len, string, 507 &newval, &newsize, flags, nflag); 508 } 509 break; 510 } 511#ifdef INET6 512 if (mib[1] == PF_INET6) { 513 len = sysctl_inet6(string, &bufp, mib, flags, &type); 514 if (len < 0) 515 return; 516 517 break; 518 } 519#endif 520 if (mib[1] == PF_IPX) { 521 len = sysctl_ipx(string, &bufp, mib, flags, &type); 522 if (len >= 0) 523 break; 524 return; 525 } 526 if (flags == 0) 527 return; 528 warnx("use netstat to view %s information", string); 529 return; 530 531 case CTL_DEBUG: 532 mib[2] = CTL_DEBUG_VALUE; 533 len = 3; 534 break; 535 536 case CTL_MACHDEP: 537#ifdef CPU_CONSDEV 538 if (mib[1] == CPU_CONSDEV) 539 special |= CHRDEV; 540#endif 541#ifdef CPU_BLK2CHR 542 if (mib[1] == CPU_BLK2CHR) { 543 if (bufp == NULL) 544 return; 545 mib[2] = makedev(atoi(bufp),0); 546 bufp = NULL; 547 len = 3; 548 special |= CHRDEV; 549 break; 550 } 551#endif 552#ifdef CPU_CHR2BLK 553 if (mib[1] == CPU_CHR2BLK) { 554 if (bufp == NULL) 555 return; 556 mib[2] = makedev(atoi(bufp),0); 557 bufp = NULL; 558 len = 3; 559 special |= BLKDEV; 560 break; 561 } 562#endif 563#ifdef CPU_BIOS 564 if (mib[1] == CPU_BIOS) { 565 len = sysctl_bios(string, &bufp, mib, flags, &type); 566 if (len < 0) 567 return; 568 if (mib[2] == BIOS_DEV) 569 special |= BIOSDEV; 570 if (mib[2] == BIOS_DISKINFO) 571 special |= BIOSGEO; 572 break; 573 } 574#endif 575#ifdef CPU_CHIPSET 576 if (mib[1] == CPU_CHIPSET) { 577 len = sysctl_chipset(string, &bufp, mib, flags, &type); 578 if (len < 0) 579 return; 580 break; 581 } 582#endif 583 break; 584 585 case CTL_FS: 586 len = sysctl_fs(string, &bufp, mib, flags, &type); 587 if (len >= 0) 588 break; 589 return; 590 591 case CTL_VFS: 592 if (mib[1]) 593 len = sysctl_vfs(string, &bufp, mib, flags, &type); 594 else 595 len = sysctl_vfsgen(string, &bufp, mib, flags, &type); 596 if (len >= 0) { 597 if (type == CTLTYPE_STRUCT) { 598 if (flags) 599 warnx("use nfsstat to view %s information", 600 MOUNT_NFS); 601 return; 602 } else 603 break; 604 } 605 return; 606 607 case CTL_USER: 608 case CTL_DDB: 609 break; 610 611 default: 612 warnx("illegal top level value: %d", mib[0]); 613 return; 614 615 } 616 if (bufp) { 617 warnx("name %s in %s is unknown", bufp, string); 618 return; 619 } 620 if (newsize > 0) { 621 switch (type) { 622 case CTLTYPE_INT: 623 errno = 0; 624 if (special & UNSIGNED) 625 intval = strtoul(newval, &cp, 10); 626 else 627 intval = strtol(newval, &cp, 10); 628 if (*cp != '\0') { 629 warnx("%s: illegal value: %s", string, 630 (char *)newval); 631 return; 632 } 633 if (errno == ERANGE) { 634 warnx("%s: value %s out of range", string, 635 (char *)newval); 636 return; 637 } 638 newval = &intval; 639 newsize = sizeof(intval); 640 break; 641 642 case CTLTYPE_QUAD: 643 /* XXX - assumes sizeof(long long) == sizeof(quad_t) */ 644 (void)sscanf(newval, "%lld", (long long *)&quadval); 645 newval = &quadval; 646 newsize = sizeof(quadval); 647 break; 648 } 649 } 650 size = BUFSIZ; 651 if (sysctl(mib, len, buf, &size, newval, newsize) == -1) { 652 if (flags == 0) 653 return; 654 switch (errno) { 655 case EOPNOTSUPP: 656 warnx("%s: value is not available", string); 657 return; 658 case ENOTDIR: 659 warnx("%s: specification is incomplete", string); 660 return; 661 case ENOMEM: 662 warnx("%s: type is unknown to this program", string); 663 return; 664 case ENXIO: 665 if (special & BIOSGEO) 666 return; 667 default: 668 warn("%s", string); 669 return; 670 } 671 } 672 if (special & KMEMBUCKETS) { 673 struct kmembuckets *kb = (struct kmembuckets *)buf; 674 if (!nflag) 675 (void)printf("%s = ", string); 676 printf("("); 677 printf("calls = %llu ", (long long)kb->kb_calls); 678 printf("total_allocated = %llu ", (long long)kb->kb_total); 679 printf("total_free = %lld ", (long long)kb->kb_totalfree); 680 printf("elements = %lld ", (long long)kb->kb_elmpercl); 681 printf("high watermark = %lld ", (long long)kb->kb_highwat); 682 printf("could_free = %lld", (long long)kb->kb_couldfree); 683 printf(")\n"); 684 return; 685 } 686 if (special & KMEMSTATS) { 687 struct kmemstats *km = (struct kmemstats *)buf; 688 int j, first = 1; 689 690 if (!nflag) 691 (void)printf("%s = ", string); 692 (void)printf("(inuse = %ld, calls = %ld, memuse = %ldK, " 693 "limblocks = %d, mapblocks = %d, maxused = %ldK, " 694 "limit = %ldK, spare = %ld, sizes = (", 695 km->ks_inuse, km->ks_calls, 696 (km->ks_memuse + 1023) / 1024, km->ks_limblocks, 697 km->ks_mapblocks, (km->ks_maxused + 1023) / 1024, 698 (km->ks_limit + 1023) / 1024, km->ks_spare); 699 for (j = 1 << MINBUCKET; j < 1 << (MINBUCKET + 16); j <<= 1) { 700 if ((km->ks_size & j ) == 0) 701 continue; 702 if (first) 703 (void)printf("%d", j); 704 else 705 (void)printf(",%d", j); 706 first = 0; 707 } 708 if (first) 709 (void)printf("none"); 710 (void)printf("))\n"); 711 return; 712 } 713 if (special & CLOCK) { 714 struct clockinfo *clkp = (struct clockinfo *)buf; 715 716 if (!nflag) 717 (void)printf("%s = ", string); 718 (void)printf( 719 "tick = %d, tickadj = %d, hz = %d, profhz = %d, stathz = %d\n", 720 clkp->tick, clkp->tickadj, clkp->hz, clkp->profhz, clkp->stathz); 721 return; 722 } 723 if (special & BOOTTIME) { 724 struct timeval *btp = (struct timeval *)buf; 725 time_t boottime; 726 727 if (!nflag) { 728 boottime = btp->tv_sec; 729 (void)printf("%s = %s", string, ctime(&boottime)); 730 } else 731 (void)printf("%ld\n", btp->tv_sec); 732 return; 733 } 734 if (special & BLKDEV) { 735 dev_t dev = *(dev_t *)buf; 736 737 if (!nflag) 738 (void)printf("%s = %s\n", string, 739 devname(dev, S_IFBLK)); 740 else 741 (void)printf("0x%x\n", dev); 742 return; 743 } 744 if (special & CHRDEV) { 745 dev_t dev = *(dev_t *)buf; 746 747 if (!nflag) 748 (void)printf("%s = %s\n", string, 749 devname(dev, S_IFCHR)); 750 else 751 (void)printf("0x%x\n", dev); 752 return; 753 } 754#ifdef CPU_BIOS 755 if (special & BIOSGEO) { 756 bios_diskinfo_t *pdi = (bios_diskinfo_t *)buf; 757 758 if (!nflag) 759 (void)printf("%s = ", string); 760 (void)printf("bootdev = 0x%x, " 761 "cylinders = %u, heads = %u, sectors = %u\n", 762 pdi->bsd_dev, pdi->bios_cylinders, 763 pdi->bios_heads, pdi->bios_sectors); 764 return; 765 } 766 if (special & BIOSDEV) { 767 int dev = *(int*)buf; 768 769 if (!nflag) 770 (void)printf("%s = ", string); 771 (void) printf("0x%02x\n", dev); 772 return; 773 } 774#endif 775 if (special & UNSIGNED) { 776 if (newsize == 0) { 777 if (!nflag) 778 (void)printf("%s = ", string); 779 (void)printf("%u\n", *(u_int *)buf); 780 } else { 781 if (!nflag) 782 (void)printf("%s: %u -> ", string, 783 *(u_int *)buf); 784 (void)printf("%u\n", *(u_int *)newval); 785 } 786 return; 787 } 788 if (special & RNDSTATS) { 789 struct rndstats *rndstats = (struct rndstats *)buf; 790 int i; 791 792 if (!nflag) 793 (void)printf("%s = ", string); 794 (void)printf( 795 "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu", 796 (unsigned long long)rndstats->rnd_total, 797 (unsigned long long)rndstats->rnd_used, 798 (unsigned long long)rndstats->rnd_reads, 799 (unsigned long long)rndstats->arc4_reads, 800 (unsigned long long)rndstats->arc4_nstirs, 801 (unsigned long long)rndstats->arc4_stirs, 802 (unsigned long long)rndstats->rnd_pad[0], 803 (unsigned long long)rndstats->rnd_pad[1], 804 (unsigned long long)rndstats->rnd_pad[2], 805 (unsigned long long)rndstats->rnd_pad[3], 806 (unsigned long long)rndstats->rnd_pad[4], 807 (unsigned long long)rndstats->rnd_waits, 808 (unsigned long long)rndstats->rnd_enqs, 809 (unsigned long long)rndstats->rnd_deqs, 810 (unsigned long long)rndstats->rnd_drops, 811 (unsigned long long)rndstats->rnd_drople); 812 for (i = 0; i < sizeof(rndstats->rnd_ed)/sizeof(rndstats->rnd_ed[0]); 813 i++) 814 (void)printf(" %llu", (unsigned long long)rndstats->rnd_ed[i]); 815 for (i = 0; i < sizeof(rndstats->rnd_sc)/sizeof(rndstats->rnd_sc[0]); 816 i++) 817 (void)printf(" %llu", (unsigned long long)rndstats->rnd_sc[i]); 818 for (i = 0; i < sizeof(rndstats->rnd_sb)/sizeof(rndstats->rnd_sb[0]); 819 i++) 820 (void)printf(" %llu", (unsigned long long)rndstats->rnd_sb[i]); 821 printf("\n"); 822 return; 823 } 824 if (special & BADDYNAMIC) { 825 in_port_t port, lastport; 826 u_int32_t *baddynamic = (u_int32_t *)buf; 827 828 if (!nflag) 829 (void)printf("%s%s", string, newsize ? ": " : " = "); 830 lastport = 0; 831 for (port = IPPORT_RESERVED/2; port < IPPORT_RESERVED; port++) 832 if (DP_ISSET(baddynamic, port)) { 833 (void)printf("%s%hd", lastport ? "," : "", 834 port); 835 lastport = port; 836 } 837 if (newsize != 0) { 838 if (!nflag) 839 fputs(" -> ", stdout); 840 baddynamic = (u_int32_t *)newval; 841 lastport = 0; 842 for (port = IPPORT_RESERVED/2; port < IPPORT_RESERVED; 843 port++) 844 if (DP_ISSET(baddynamic, port)) { 845 (void)printf("%s%hd", 846 lastport ? "," : "", port); 847 lastport = port; 848 } 849 } 850 (void)putchar('\n'); 851 return; 852 } 853 if (special & LONGARRAY) { 854 long *la = (long *)buf; 855 if (!nflag) 856 printf("%s = ", string); 857 while (lal--) 858 printf("%ld%s", *la++, lal? ",":""); 859 putchar('\n'); 860 return; 861 } 862 switch (type) { 863 case CTLTYPE_INT: 864 if (newsize == 0) { 865 if (!nflag) 866 (void)printf("%s = ", string); 867 (void)printf("%d\n", *(int *)buf); 868 } else { 869 if (!nflag) 870 (void)printf("%s: %d -> ", string, 871 *(int *)buf); 872 (void)printf("%d\n", *(int *)newval); 873 } 874 return; 875 876 case CTLTYPE_STRING: 877 if (newval == NULL) { 878 if (!nflag) 879 (void)printf("%s = ", string); 880 (void)puts(buf); 881 } else { 882 if (!nflag) 883 (void)printf("%s: %s -> ", string, buf); 884 (void)puts((char *)newval); 885 } 886 return; 887 888 case CTLTYPE_QUAD: 889 if (newsize == 0) { 890 long long tmp = *(quad_t *)buf; 891 892 if (!nflag) 893 (void)printf("%s = ", string); 894 (void)printf("%lld\n", tmp); 895 } else { 896 long long tmp = *(quad_t *)buf; 897 898 if (!nflag) 899 (void)printf("%s: %lld -> ", string, tmp); 900 tmp = *(quad_t *)newval; 901 (void)printf("%qd\n", tmp); 902 } 903 return; 904 905 case CTLTYPE_STRUCT: 906 warnx("%s: unknown structure returned", string); 907 return; 908 909 default: 910 case CTLTYPE_NODE: 911 warnx("%s: unknown type returned", string); 912 return; 913 } 914} 915 916void 917parse_baddynamic(int mib[], size_t len, char *string, void **newvalp, 918 size_t *newsizep, int flags, int nflag) 919{ 920 static u_int32_t newbaddynamic[DP_MAPSIZE]; 921 in_port_t port; 922 size_t size; 923 char action, *cp; 924 925 if (strchr((char *)*newvalp, '+') || strchr((char *)*newvalp, '-')) { 926 size = sizeof(newbaddynamic); 927 if (sysctl(mib, len, newbaddynamic, &size, 0, 0) == -1) { 928 if (flags == 0) 929 return; 930 if (!nflag) 931 (void)printf("%s: ", string); 932 (void)puts("kernel does contain bad dynamic port tables"); 933 return; 934 } 935 936 while (*newvalp && (cp = strsep((char **)newvalp, ", \t")) && *cp) { 937 if (*cp != '+' && *cp != '-') 938 errx(1, "cannot mix +/- with full list"); 939 action = *cp++; 940 port = atoi(cp); 941 if (port < IPPORT_RESERVED/2 || port >= IPPORT_RESERVED) 942 errx(1, "invalid port, range is %d to %d", 943 IPPORT_RESERVED/2, IPPORT_RESERVED-1); 944 if (action == '+') 945 DP_SET(newbaddynamic, port); 946 else 947 DP_CLR(newbaddynamic, port); 948 } 949 } else { 950 (void)memset((void *)newbaddynamic, 0, sizeof(newbaddynamic)); 951 while (*newvalp && (cp = strsep((char **)newvalp, ", \t")) && *cp) { 952 port = atoi(cp); 953 if (port < IPPORT_RESERVED/2 || port >= IPPORT_RESERVED) 954 errx(1, "invalid port, range is %d to %d", 955 IPPORT_RESERVED/2, IPPORT_RESERVED-1); 956 DP_SET(newbaddynamic, port); 957 } 958 } 959 960 *newvalp = (void *)newbaddynamic; 961 *newsizep = sizeof(newbaddynamic); 962} 963 964/* 965 * Initialize the set of debugging names 966 */ 967void 968debuginit(void) 969{ 970 int mib[3], loc, i; 971 size_t size; 972 973 if (secondlevel[CTL_DEBUG].list != 0) 974 return; 975 secondlevel[CTL_DEBUG].list = debugname; 976 mib[0] = CTL_DEBUG; 977 mib[2] = CTL_DEBUG_NAME; 978 for (loc = lastused, i = 0; i < CTL_DEBUG_MAXID; i++) { 979 mib[1] = i; 980 size = BUFSIZ - loc; 981 if (sysctl(mib, 3, &names[loc], &size, NULL, 0) == -1) 982 continue; 983 debugname[i].ctl_name = &names[loc]; 984 debugname[i].ctl_type = CTLTYPE_INT; 985 loc += size; 986 } 987 lastused = loc; 988} 989 990struct ctlname vfsgennames[] = CTL_VFSGENCTL_NAMES; 991struct ctlname ffsname[] = FFS_NAMES; 992struct ctlname nfsname[] = FS_NFS_NAMES; 993struct list *vfsvars; 994int *vfs_typenums; 995 996/* 997 * Initialize the set of filesystem names 998 */ 999void 1000vfsinit(void) 1001{ 1002 int mib[4], maxtypenum, cnt, loc, size; 1003 struct vfsconf vfc; 1004 size_t buflen; 1005 1006 if (secondlevel[CTL_VFS].list != 0) 1007 return; 1008 mib[0] = CTL_VFS; 1009 mib[1] = VFS_GENERIC; 1010 mib[2] = VFS_MAXTYPENUM; 1011 buflen = 4; 1012 if (sysctl(mib, 3, &maxtypenum, &buflen, (void *)0, (size_t)0) < 0) 1013 return; 1014 maxtypenum++; /* + generic */ 1015 if ((vfs_typenums = malloc(maxtypenum * sizeof(int))) == NULL) 1016 return; 1017 memset(vfs_typenums, 0, maxtypenum * sizeof(int)); 1018 if ((vfsvars = malloc(maxtypenum * sizeof(*vfsvars))) == NULL) { 1019 free(vfs_typenums); 1020 return; 1021 } 1022 memset(vfsvars, 0, maxtypenum * sizeof(*vfsvars)); 1023 if ((vfsname = malloc(maxtypenum * sizeof(*vfsname))) == NULL) { 1024 free(vfs_typenums); 1025 free(vfsvars); 1026 return; 1027 } 1028 memset(vfsname, 0, maxtypenum * sizeof(*vfsname)); 1029 mib[2] = VFS_CONF; 1030 buflen = sizeof vfc; 1031 for (loc = lastused, cnt = 1; cnt < maxtypenum; cnt++) { 1032 mib[3] = cnt - 1; 1033 if (sysctl(mib, 4, &vfc, &buflen, (void *)0, (size_t)0) < 0) { 1034 if (errno == EOPNOTSUPP) 1035 continue; 1036 warn("vfsinit"); 1037 free(vfsname); 1038 return; 1039 } 1040 if (!strcmp(vfc.vfc_name, MOUNT_FFS)) { 1041 vfsvars[cnt].list = ffsname; 1042 vfsvars[cnt].size = FFS_MAXID; 1043 } 1044 if (!strcmp(vfc.vfc_name, MOUNT_NFS)) { 1045 vfsvars[cnt].list = nfsname; 1046 vfsvars[cnt].size = NFS_MAXID; 1047 } 1048 vfs_typenums[cnt] = vfc.vfc_typenum; 1049 strlcat(&names[loc], vfc.vfc_name, sizeof names - loc); 1050 vfsname[cnt].ctl_name = &names[loc]; 1051 vfsname[cnt].ctl_type = CTLTYPE_NODE; 1052 size = strlen(vfc.vfc_name) + 1; 1053 loc += size; 1054 } 1055 lastused = loc; 1056 1057 vfsname[0].ctl_name = "mounts"; 1058 vfsname[0].ctl_type = CTLTYPE_NODE; 1059 vfsvars[0].list = vfsname + 1; 1060 vfsvars[0].size = maxtypenum - 1; 1061 1062 secondlevel[CTL_VFS].list = vfsname; 1063 secondlevel[CTL_VFS].size = maxtypenum; 1064 return; 1065} 1066 1067int 1068sysctl_vfsgen(char *string, char **bufpp, int mib[], int flags, int *typep) 1069{ 1070 int indx; 1071 size_t size; 1072 struct vfsconf vfc; 1073 1074 if (*bufpp == NULL) { 1075 listall(string, vfsvars); 1076 return (-1); 1077 } 1078 1079 if ((indx = findname(string, "third", bufpp, vfsvars)) == -1) 1080 return (-1); 1081 1082 mib[1] = VFS_GENERIC; 1083 mib[2] = VFS_CONF; 1084 mib[3] = indx; 1085 size = sizeof vfc; 1086 if (sysctl(mib, 4, &vfc, &size, (void *)0, (size_t)0) < 0) { 1087 if (errno != EOPNOTSUPP) 1088 warn("vfs print"); 1089 return -1; 1090 } 1091 if (flags == 0 && vfc.vfc_refcount == 0) 1092 return -1; 1093 if (!nflag) 1094 fprintf(stdout, "%s has %d mounted instance%s\n", 1095 string, vfc.vfc_refcount, 1096 vfc.vfc_refcount != 1 ? "s" : ""); 1097 else 1098 fprintf(stdout, "%d\n", vfc.vfc_refcount); 1099 1100 return -1; 1101} 1102 1103int 1104sysctl_vfs(char *string, char **bufpp, int mib[], int flags, int *typep) 1105{ 1106 struct list *lp = &vfsvars[mib[1]]; 1107 int indx; 1108 1109 if (lp->list == NULL) { 1110 if (flags) 1111 warnx("No variables defined for file system %s", string); 1112 return(-1); 1113 } 1114 if (*bufpp == NULL) { 1115 listall(string, lp); 1116 return (-1); 1117 } 1118 if ((indx = findname(string, "third", bufpp, lp)) == -1) 1119 return (-1); 1120 1121 mib[1] = vfs_typenums[mib[1]]; 1122 mib[2] = indx; 1123 *typep = lp->list[indx].ctl_type; 1124 return (3); 1125} 1126 1127struct ctlname posixname[] = CTL_FS_POSIX_NAMES; 1128struct list fslist = { posixname, FS_POSIX_MAXID }; 1129 1130/* 1131 * handle file system requests 1132 */ 1133int 1134sysctl_fs(char *string, char **bufpp, int mib[], int flags, int *typep) 1135{ 1136 int indx; 1137 1138 if (*bufpp == NULL) { 1139 listall(string, &fslist); 1140 return(-1); 1141 } 1142 if ((indx = findname(string, "third", bufpp, &fslist)) == -1) 1143 return(-1); 1144 mib[2] = indx; 1145 *typep = fslist.list[indx].ctl_type; 1146 return(3); 1147} 1148 1149#ifdef CPU_BIOS 1150struct ctlname biosname[] = CTL_BIOS_NAMES; 1151struct list bioslist = { biosname, BIOS_MAXID }; 1152 1153/* 1154 * handle BIOS requests 1155 */ 1156int 1157sysctl_bios(char *string, char **bufpp, int mib[], int flags, int *typep) 1158{ 1159 char *name; 1160 int indx; 1161 1162 if (*bufpp == NULL) { 1163 listall(string, &bioslist); 1164 return(-1); 1165 } 1166 if ((indx = findname(string, "third", bufpp, &bioslist)) == -1) 1167 return(-1); 1168 mib[2] = indx; 1169 if (indx == BIOS_DISKINFO) { 1170 if (*bufpp == NULL) { 1171 char name[BUFSIZ]; 1172 1173 /* scan all the bios devices */ 1174 for (indx = 0; indx < 256; indx++) { 1175 snprintf(name, sizeof(name), "%s.%u", 1176 string, indx); 1177 parse(name, 1); 1178 } 1179 return(-1); 1180 } 1181 if ((name = strsep(bufpp, ".")) == NULL) { 1182 warnx("%s: incomplete specification", string); 1183 return(-1); 1184 } 1185 mib[3] = atoi(name); 1186 *typep = CTLTYPE_STRUCT; 1187 return(4); 1188 } else { 1189 *typep = bioslist.list[indx].ctl_type; 1190 return(3); 1191 } 1192} 1193#endif 1194 1195struct ctlname swpencname[] = CTL_SWPENC_NAMES; 1196struct list swpenclist = { swpencname, SWPENC_MAXID }; 1197 1198/* 1199 * handle swap encrypt requests 1200 */ 1201int 1202sysctl_swpenc(char *string, char **bufpp, int mib[], int flags, int *typep) 1203{ 1204 int indx; 1205 1206 if (*bufpp == NULL) { 1207 listall(string, &swpenclist); 1208 return(-1); 1209 } 1210 if ((indx = findname(string, "third", bufpp, &swpenclist)) == -1) 1211 return(-1); 1212 mib[2] = indx; 1213 *typep = swpenclist.list[indx].ctl_type; 1214 return(3); 1215} 1216 1217struct ctlname inetname[] = CTL_IPPROTO_NAMES; 1218struct ctlname ipname[] = IPCTL_NAMES; 1219struct ctlname icmpname[] = ICMPCTL_NAMES; 1220struct ctlname ipipname[] = IPIPCTL_NAMES; 1221struct ctlname tcpname[] = TCPCTL_NAMES; 1222struct ctlname udpname[] = UDPCTL_NAMES; 1223struct ctlname espname[] = ESPCTL_NAMES; 1224struct ctlname ahname[] = AHCTL_NAMES; 1225struct ctlname etheripname[] = ETHERIPCTL_NAMES; 1226struct ctlname grename[] = GRECTL_NAMES; 1227struct ctlname mobileipname[] = MOBILEIPCTL_NAMES; 1228struct ctlname ipcompname[] = IPCOMPCTL_NAMES; 1229struct list inetlist = { inetname, IPPROTO_MAXID }; 1230struct list inetvars[] = { 1231 { ipname, IPCTL_MAXID }, /* ip */ 1232 { icmpname, ICMPCTL_MAXID }, /* icmp */ 1233 { 0, 0 }, /* igmp */ 1234 { 0, 0 }, /* ggmp */ 1235 { ipipname, IPIPCTL_MAXID }, /* ipencap */ 1236 { 0, 0 }, 1237 { tcpname, TCPCTL_MAXID }, /* tcp */ 1238 { 0, 0 }, 1239 { 0, 0 }, /* egp */ 1240 { 0, 0 }, 1241 { 0, 0 }, 1242 { 0, 0 }, 1243 { 0, 0 }, /* pup */ 1244 { 0, 0 }, 1245 { 0, 0 }, 1246 { 0, 0 }, 1247 { 0, 0 }, 1248 { udpname, UDPCTL_MAXID }, /* udp */ 1249 { 0, 0 }, 1250 { 0, 0 }, 1251 { 0, 0 }, 1252 { 0, 0 }, 1253 { 0, 0 }, 1254 { 0, 0 }, 1255 { 0, 0 }, 1256 { 0, 0 }, 1257 { 0, 0 }, 1258 { 0, 0 }, 1259 { 0, 0 }, 1260 { 0, 0 }, 1261 { 0, 0 }, 1262 { 0, 0 }, 1263 { 0, 0 }, 1264 { 0, 0 }, 1265 { 0, 0 }, 1266 { 0, 0 }, 1267 { 0, 0 }, 1268 { 0, 0 }, 1269 { 0, 0 }, 1270 { 0, 0 }, 1271 { 0, 0 }, 1272 { 0, 0 }, 1273 { 0, 0 }, 1274 { 0, 0 }, 1275 { 0, 0 }, 1276 { 0, 0 }, 1277 { 0, 0 }, 1278 { grename, GRECTL_MAXID }, /* GRE */ 1279 { 0, 0 }, 1280 { 0, 0 }, 1281 { espname, ESPCTL_MAXID }, /* esp */ 1282 { ahname, AHCTL_MAXID }, /* ah */ 1283 { 0, 0 }, 1284 { 0, 0 }, 1285 { 0, 0 }, 1286 { mobileipname, MOBILEIPCTL_MAXID }, /* mobileip */ 1287 { 0, 0 }, 1288 { 0, 0 }, 1289 { 0, 0 }, 1290 { 0, 0 }, 1291 { 0, 0 }, 1292 { 0, 0 }, 1293 { 0, 0 }, 1294 { 0, 0 }, 1295 { 0, 0 }, 1296 { 0, 0 }, 1297 { 0, 0 }, 1298 { 0, 0 }, 1299 { 0, 0 }, 1300 { 0, 0 }, 1301 { 0, 0 }, 1302 { 0, 0 }, 1303 { 0, 0 }, 1304 { 0, 0 }, 1305 { 0, 0 }, 1306 { 0, 0 }, 1307 { 0, 0 }, 1308 { 0, 0 }, 1309 { 0, 0 }, 1310 { 0, 0 }, 1311 { 0, 0 }, 1312 { 0, 0 }, 1313 { 0, 0 }, 1314 { 0, 0 }, 1315 { 0, 0 }, 1316 { 0, 0 }, 1317 { 0, 0 }, 1318 { 0, 0 }, 1319 { 0, 0 }, 1320 { 0, 0 }, 1321 { 0, 0 }, 1322 { 0, 0 }, 1323 { 0, 0 }, 1324 { 0, 0 }, 1325 { 0, 0 }, 1326 { 0, 0 }, 1327 { 0, 0 }, 1328 { etheripname, ETHERIPCTL_MAXID }, 1329 { 0, 0 }, 1330 { 0, 0 }, 1331 { 0, 0 }, 1332 { 0, 0 }, 1333 { 0, 0 }, 1334 { 0, 0 }, 1335 { 0, 0 }, 1336 { 0, 0 }, 1337 { 0, 0 }, 1338 { 0, 0 }, 1339 { ipcompname, IPCOMPCTL_MAXID }, 1340}; 1341 1342struct list kernmalloclist = { kernmallocname, KERN_MALLOC_MAXID }; 1343struct list forkstatlist = { forkstatname, KERN_FORKSTAT_MAXID }; 1344struct list nchstatslist = { nchstatsname, KERN_NCHSTATS_MAXID }; 1345struct list ttylist = { ttyname, KERN_TTY_MAXID }; 1346struct list semlist = { semname, KERN_SEMINFO_MAXID }; 1347struct list shmlist = { shmname, KERN_SHMINFO_MAXID }; 1348struct list watchdoglist = { watchdogname, KERN_WATCHDOG_MAXID }; 1349 1350/* 1351 * handle vfs namei cache statistics 1352 */ 1353int 1354sysctl_nchstats(char *string, char **bufpp, int mib[], int flags, int *typep) 1355{ 1356 static struct nchstats nch; 1357 int indx; 1358 size_t size; 1359 static int keepvalue = 0; 1360 1361 if (*bufpp == NULL) { 1362 bzero(&nch, sizeof(struct nchstats)); 1363 listall(string, &nchstatslist); 1364 return(-1); 1365 } 1366 if ((indx = findname(string, "third", bufpp, &nchstatslist)) == -1) 1367 return(-1); 1368 mib[2] = indx; 1369 if (*bufpp != NULL) { 1370 warnx("fourth level name in %s is invalid", string); 1371 return(-1); 1372 } 1373 if (keepvalue == 0) { 1374 size = sizeof(struct nchstats); 1375 if (sysctl(mib, 2, &nch, &size, NULL, 0) < 0) 1376 return(-1); 1377 keepvalue = 1; 1378 } 1379 if (!nflag) 1380 (void)printf("%s = ", string); 1381 switch (indx) { 1382 case KERN_NCHSTATS_GOODHITS: 1383 (void)printf("%ld\n", nch.ncs_goodhits); 1384 break; 1385 case KERN_NCHSTATS_NEGHITS: 1386 (void)printf("%ld\n", nch.ncs_neghits); 1387 break; 1388 case KERN_NCHSTATS_BADHITS: 1389 (void)printf("%ld\n", nch.ncs_badhits); 1390 break; 1391 case KERN_NCHSTATS_FALSEHITS: 1392 (void)printf("%ld\n", nch.ncs_falsehits); 1393 break; 1394 case KERN_NCHSTATS_MISS: 1395 (void)printf("%ld\n", nch.ncs_miss); 1396 break; 1397 case KERN_NCHSTATS_LONG: 1398 (void)printf("%ld\n", nch.ncs_long); 1399 break; 1400 case KERN_NCHSTATS_PASS2: 1401 (void)printf("%ld\n", nch.ncs_pass2); 1402 break; 1403 case KERN_NCHSTATS_2PASSES: 1404 (void)printf("%ld\n", nch.ncs_2passes); 1405 break; 1406 } 1407 return(-1); 1408} 1409 1410/* 1411 * handle tty statistics 1412 */ 1413int 1414sysctl_tty(char *string, char **bufpp, int mib[], int flags, int *typep) 1415{ 1416 int indx; 1417 1418 if (*bufpp == NULL) { 1419 listall(string, &ttylist); 1420 return(-1); 1421 } 1422 if ((indx = findname(string, "third", bufpp, &ttylist)) == -1) 1423 return(-1); 1424 mib[2] = indx; 1425 *typep = CTLTYPE_QUAD; 1426 return(3); 1427} 1428 1429/* 1430 * handle fork statistics 1431 */ 1432int 1433sysctl_forkstat(char *string, char **bufpp, int mib[], int flags, int *typep) 1434{ 1435 static struct forkstat fks; 1436 static int keepvalue = 0; 1437 int indx; 1438 size_t size; 1439 1440 if (*bufpp == NULL) { 1441 bzero(&fks, sizeof(struct forkstat)); 1442 listall(string, &forkstatlist); 1443 return(-1); 1444 } 1445 if ((indx = findname(string, "third", bufpp, &forkstatlist)) == -1) 1446 return(-1); 1447 if (*bufpp != NULL) { 1448 warnx("fourth level name in %s is invalid", string); 1449 return(-1); 1450 } 1451 if (keepvalue == 0) { 1452 size = sizeof(struct forkstat); 1453 if (sysctl(mib, 2, &fks, &size, NULL, 0) < 0) 1454 return(-1); 1455 keepvalue = 1; 1456 } 1457 if (!nflag) 1458 (void)printf("%s = ", string); 1459 switch (indx) { 1460 case KERN_FORKSTAT_FORK: 1461 (void)printf("%d\n", fks.cntfork); 1462 break; 1463 case KERN_FORKSTAT_VFORK: 1464 (void)printf("%d\n", fks.cntvfork); 1465 break; 1466 case KERN_FORKSTAT_RFORK: 1467 (void)printf("%d\n", fks.cntrfork); 1468 break; 1469 case KERN_FORKSTAT_KTHREAD: 1470 (void)printf("%d\n", fks.cntkthread); 1471 break; 1472 case KERN_FORKSTAT_SIZFORK: 1473 (void)printf("%d\n", fks.sizfork); 1474 break; 1475 case KERN_FORKSTAT_SIZVFORK: 1476 (void)printf("%d\n", fks.sizvfork); 1477 break; 1478 case KERN_FORKSTAT_SIZRFORK: 1479 (void)printf("%d\n", fks.sizrfork); 1480 break; 1481 case KERN_FORKSTAT_SIZKTHREAD: 1482 (void)printf("%d\n", fks.sizkthread); 1483 break; 1484 } 1485 return(-1); 1486} 1487 1488/* 1489 * handle malloc statistics 1490 */ 1491int 1492sysctl_malloc(char *string, char **bufpp, int mib[], int flags, int *typep) 1493{ 1494 int indx, stor, i; 1495 char *name, bufp[BUFSIZ], *buf, *ptr; 1496 struct list lp; 1497 size_t size; 1498 1499 if (*bufpp == NULL) { 1500 listall(string, &kernmalloclist); 1501 return(-1); 1502 } 1503 if ((indx = findname(string, "third", bufpp, &kernmalloclist)) == -1) 1504 return(-1); 1505 mib[2] = indx; 1506 if (mib[2] == KERN_MALLOC_BUCKET) { 1507 if ((name = strsep(bufpp, ".")) == NULL) { 1508 size = BUFSIZ; 1509 stor = mib[2]; 1510 mib[2] = KERN_MALLOC_BUCKETS; 1511 buf = bufp; 1512 if (sysctl(mib, 3, buf, &size, NULL, 0) < 0) 1513 return(-1); 1514 mib[2] = stor; 1515 for (stor = 0, i = 0; i < size; i++) 1516 if (buf[i] == ',') 1517 stor++; 1518 lp.list = calloc(stor + 2, sizeof(struct ctlname)); 1519 if (lp.list == NULL) 1520 return(-1); 1521 lp.size = stor + 2; 1522 for (i = 1; 1523 (lp.list[i].ctl_name = strsep(&buf, ",")) != NULL; 1524 i++) { 1525 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1526 } 1527 lp.list[i].ctl_name = buf; 1528 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1529 listall(string, &lp); 1530 free(lp.list); 1531 return(-1); 1532 } 1533 mib[3] = atoi(name); 1534 return(4); 1535 } else if (mib[2] == KERN_MALLOC_BUCKETS) { 1536 *typep = CTLTYPE_STRING; 1537 return(3); 1538 } else if (mib[2] == KERN_MALLOC_KMEMSTATS) { 1539 size = BUFSIZ; 1540 stor = mib[2]; 1541 mib[2] = KERN_MALLOC_KMEMNAMES; 1542 buf = bufp; 1543 if (sysctl(mib, 3, buf, &size, NULL, 0) < 0) 1544 return(-1); 1545 mib[2] = stor; 1546 if ((name = strsep(bufpp, ".")) == NULL) { 1547 for (stor = 0, i = 0; i < size; i++) 1548 if (buf[i] == ',') 1549 stor++; 1550 lp.list = calloc(stor + 2, sizeof(struct ctlname)); 1551 if (lp.list == NULL) 1552 return(-1); 1553 lp.size = stor + 2; 1554 for (i = 1; (lp.list[i].ctl_name = strsep(&buf, ",")) != NULL; i++) { 1555 if (lp.list[i].ctl_name[0] == '\0') { 1556 i--; 1557 continue; 1558 } 1559 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1560 } 1561 lp.list[i].ctl_name = buf; 1562 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1563 listall(string, &lp); 1564 free(lp.list); 1565 return(-1); 1566 } 1567 ptr = strstr(buf, name); 1568 tryagain: 1569 if (ptr == NULL) { 1570 warnx("fourth level name %s in %s is invalid", name, 1571 string); 1572 return(-1); 1573 } 1574 if ((*(ptr + strlen(name)) != ',') && 1575 (*(ptr + strlen(name)) != '\0')) { 1576 ptr = strstr(ptr + 1, name); /* retry */ 1577 goto tryagain; 1578 } 1579 if ((ptr != buf) && (*(ptr - 1) != ',')) { 1580 ptr = strstr(ptr + 1, name); /* retry */ 1581 goto tryagain; 1582 } 1583 for (i = 0, stor = 0; buf + i < ptr; i++) 1584 if (buf[i] == ',') 1585 stor++; 1586 mib[3] = stor; 1587 return(4); 1588 } else if (mib[2] == KERN_MALLOC_KMEMNAMES) { 1589 *typep = CTLTYPE_STRING; 1590 return(3); 1591 } 1592 return(-1); 1593} 1594 1595#ifdef CPU_CHIPSET 1596/* 1597 * handle machdep.chipset requests 1598 */ 1599struct ctlname chipsetname[] = CTL_CHIPSET_NAMES; 1600struct list chipsetlist = { chipsetname, CPU_CHIPSET_MAXID }; 1601 1602int 1603sysctl_chipset(char *string, char **bufpp, int mib[], int flags, int *typep) 1604{ 1605 int indx, bwx; 1606 static void *q; 1607 size_t len; 1608 char *p; 1609 1610 if (*bufpp == NULL) { 1611 listall(string, &chipsetlist); 1612 return (-1); 1613 } 1614 if ((indx = findname(string, "third", bufpp, &chipsetlist)) == -1) 1615 return(-1); 1616 mib[2] = indx; 1617 if (!nflag) 1618 printf("%s = ", string); 1619 switch(mib[2]) { 1620 case CPU_CHIPSET_MEM: 1621 case CPU_CHIPSET_DENSE: 1622 case CPU_CHIPSET_PORTS: 1623 case CPU_CHIPSET_HAE_MASK: 1624 len = sizeof(void *); 1625 if (sysctl(mib, 3, &q, &len, NULL, 0) < 0) 1626 return (-1); 1627 printf("%p\n", q); 1628 break; 1629 case CPU_CHIPSET_BWX: 1630 len = sizeof(int); 1631 if (sysctl(mib, 3, &bwx, &len, NULL, 0) < 0) 1632 return (-1); 1633 printf("%d\n", bwx); 1634 break; 1635 case CPU_CHIPSET_TYPE: 1636 if (sysctl(mib, 3, NULL, &len, NULL, 0) < 0) 1637 return (-1); 1638 p = malloc(len + 1); 1639 if (p == NULL) 1640 return (-1); 1641 if (sysctl(mib, 3, p, &len, NULL, 0) < 0) 1642 return (-1); 1643 p[len] = '\0'; 1644 printf("%s\n", p); 1645 break; 1646 } 1647 return (-1); 1648} 1649#endif 1650/* 1651 * handle internet requests 1652 */ 1653int 1654sysctl_inet(char *string, char **bufpp, int mib[], int flags, int *typep) 1655{ 1656 struct list *lp; 1657 int indx; 1658 1659 if (*bufpp == NULL) { 1660 listall(string, &inetlist); 1661 return(-1); 1662 } 1663 if ((indx = findname(string, "third", bufpp, &inetlist)) == -1) 1664 return(-1); 1665 mib[2] = indx; 1666 if (indx < IPPROTO_MAXID && inetvars[indx].list != NULL) 1667 lp = &inetvars[indx]; 1668 else if (!flags) 1669 return(-1); 1670 else { 1671 warnx("%s: no variables defined for this protocol", string); 1672 return(-1); 1673 } 1674 if (*bufpp == NULL) { 1675 listall(string, lp); 1676 return(-1); 1677 } 1678 if ((indx = findname(string, "fourth", bufpp, lp)) == -1) 1679 return(-1); 1680 mib[3] = indx; 1681 *typep = lp->list[indx].ctl_type; 1682 return(4); 1683} 1684 1685#ifdef INET6 1686struct ctlname inet6name[] = CTL_IPV6PROTO_NAMES; 1687struct ctlname ip6name[] = IPV6CTL_NAMES; 1688struct ctlname icmp6name[] = ICMPV6CTL_NAMES; 1689struct ctlname pim6name[] = PIM6CTL_NAMES; 1690struct list inet6list = { inet6name, IPV6PROTO_MAXID }; 1691struct list inet6vars[] = { 1692/*0*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1693 { 0, 0 }, 1694 { 0, 0 }, 1695 { 0, 0 }, 1696 { 0, 0 }, 1697 { 0, 0 }, 1698/*10*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1699 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1700/*20*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1701 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1702/*30*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1703 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1704/*40*/ { 0, 0 }, 1705 { ip6name, IPV6CTL_MAXID }, /* ipv6 */ 1706 { 0, 0 }, 1707 { 0, 0 }, 1708 { 0, 0 }, 1709 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1710/*50*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1711 { 0, 0 }, 1712 { 0, 0 }, 1713 { 0, 0 }, 1714 { icmp6name, ICMPV6CTL_MAXID }, /* icmp6 */ 1715 { 0, 0 }, 1716/*60*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1717 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1718/*70*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1719 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1720/*80*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1721 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1722/*90*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1723 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 1724/*100*/ { 0, 0 }, 1725 { 0, 0 }, 1726 { 0, 0 }, 1727 { pim6name, PIM6CTL_MAXID }, /* pim6 */ 1728}; 1729 1730/* 1731 * handle internet6 requests 1732 */ 1733int 1734sysctl_inet6(char *string, char **bufpp, int mib[], int flags, int *typep) 1735{ 1736 struct list *lp; 1737 int indx; 1738 1739 if (*bufpp == NULL) { 1740 listall(string, &inet6list); 1741 return(-1); 1742 } 1743 if ((indx = findname(string, "third", bufpp, &inet6list)) == -1) 1744 return(-1); 1745 mib[2] = indx; 1746 if (indx < IPV6PROTO_MAXID && inet6vars[indx].list != NULL) 1747 lp = &inet6vars[indx]; 1748 else if (!flags) 1749 return(-1); 1750 else { 1751 warnx("%s: no variables defined for this protocol", string); 1752 return(-1); 1753 } 1754 if (*bufpp == NULL) { 1755 listall(string, lp); 1756 return(-1); 1757 } 1758 if ((indx = findname(string, "fourth", bufpp, lp)) == -1) 1759 return(-1); 1760 mib[3] = indx; 1761 *typep = lp->list[indx].ctl_type; 1762 return(4); 1763} 1764#endif 1765 1766struct ctlname ipxname[] = CTL_IPXPROTO_NAMES; 1767struct ctlname ipxpname[] = IPXCTL_NAMES; 1768struct ctlname spxpname[] = SPXCTL_NAMES; 1769struct list ipxlist = { ipxname, IPXCTL_MAXID }; 1770struct list ipxvars[] = { 1771 { ipxpname, IPXCTL_MAXID }, /* ipx */ 1772 { 0, 0 }, 1773 { 0, 0 }, 1774 { 0, 0 }, 1775 { 0, 0 }, 1776 { spxpname, SPXCTL_MAXID }, 1777}; 1778 1779/* 1780 * Handle internet requests 1781 */ 1782int 1783sysctl_ipx(char *string, char **bufpp, int mib[], int flags, int *typep) 1784{ 1785 struct list *lp; 1786 int indx; 1787 1788 if (*bufpp == NULL) { 1789 listall(string, &ipxlist); 1790 return(-1); 1791 } 1792 if ((indx = findname(string, "third", bufpp, &ipxlist)) == -1) 1793 return(-1); 1794 mib[2] = indx; 1795 if (indx <= IPXPROTO_SPX && ipxvars[indx].list != NULL) 1796 lp = &ipxvars[indx]; 1797 else if (!flags) 1798 return(-1); 1799 else { 1800 warnx("%s: no variables defined for this protocol", string); 1801 return(-1); 1802 } 1803 if (*bufpp == NULL) { 1804 listall(string, lp); 1805 return(-1); 1806 } 1807 if ((indx = findname(string, "fourth", bufpp, lp)) == -1) 1808 return(-1); 1809 mib[3] = indx; 1810 *typep = lp->list[indx].ctl_type; 1811 return(4); 1812} 1813 1814/* 1815 * Handle SysV semaphore info requests 1816 */ 1817int 1818sysctl_seminfo(string, bufpp, mib, flags, typep) 1819 char *string; 1820 char **bufpp; 1821 int mib[]; 1822 int flags; 1823 int *typep; 1824{ 1825 int indx; 1826 1827 if (*bufpp == NULL) { 1828 listall(string, &semlist); 1829 return(-1); 1830 } 1831 if ((indx = findname(string, "third", bufpp, &semlist)) == -1) 1832 return(-1); 1833 mib[2] = indx; 1834 *typep = CTLTYPE_INT; 1835 return(3); 1836} 1837 1838/* 1839 * Handle SysV shared memory info requests 1840 */ 1841int 1842sysctl_shminfo(string, bufpp, mib, flags, typep) 1843 char *string; 1844 char **bufpp; 1845 int mib[]; 1846 int flags; 1847 int *typep; 1848{ 1849 int indx; 1850 1851 if (*bufpp == NULL) { 1852 listall(string, &shmlist); 1853 return(-1); 1854 } 1855 if ((indx = findname(string, "third", bufpp, &shmlist)) == -1) 1856 return(-1); 1857 mib[2] = indx; 1858 *typep = CTLTYPE_INT; 1859 return(3); 1860} 1861 1862/* 1863 * Handle watchdog support 1864 */ 1865int 1866sysctl_watchdog(char *string, char **bufpp, int mib[], int flags, 1867 int *typep) 1868{ 1869 int indx; 1870 1871 if (*bufpp == NULL) { 1872 listall(string, &watchdoglist); 1873 return(-1); 1874 } 1875 if ((indx = findname(string, "third", bufpp, &watchdoglist)) == -1) 1876 return(-1); 1877 mib[2] = indx; 1878 *typep = watchdoglist.list[indx].ctl_type; 1879 return(3); 1880} 1881 1882/* 1883 * Scan a list of names searching for a particular name. 1884 */ 1885int 1886findname(char *string, char *level, char **bufp, struct list *namelist) 1887{ 1888 char *name; 1889 int i; 1890 1891 if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) { 1892 warnx("%s: incomplete specification", string); 1893 return(-1); 1894 } 1895 for (i = 0; i < namelist->size; i++) 1896 if (namelist->list[i].ctl_name != NULL && 1897 strcmp(name, namelist->list[i].ctl_name) == 0) 1898 break; 1899 if (i == namelist->size) { 1900 warnx("%s level name %s in %s is invalid", level, name, string); 1901 return(-1); 1902 } 1903 return(i); 1904} 1905 1906void 1907usage(void) 1908{ 1909 1910 (void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n\t%s\n", 1911 "sysctl [-n] variable ...", "sysctl [-n] -w variable=value ...", 1912 "sysctl [-n] -a", "sysctl [-n] -A"); 1913 exit(1); 1914} 1915