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