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