sysctl.c revision 1.199
1/* $OpenBSD: sysctl.c,v 1.199 2014/01/23 03:00:04 guenther 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. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33#include <sys/param.h> 34#include <sys/gmon.h> 35#include <sys/mount.h> 36#include <sys/sem.h> 37#include <sys/shm.h> 38#include <sys/sysctl.h> 39#include <sys/socket.h> 40#include <sys/malloc.h> 41#include <sys/dkstat.h> 42#include <sys/uio.h> 43#include <sys/tty.h> 44#include <sys/namei.h> 45#include <sys/sensors.h> 46#include <net/route.h> 47#include <net/if.h> 48 49#include <netinet/in.h> 50#include <netinet/in_systm.h> 51#include <netinet/ip.h> 52#include <netinet/in_pcb.h> 53#include <netinet/ip_icmp.h> 54#include <netinet/ip_ipip.h> 55#include <netinet/ip_ether.h> 56#include <netinet/ip_ah.h> 57#include <netinet/ip_esp.h> 58#include <netinet/icmp_var.h> 59#include <netinet/igmp_var.h> 60#include <netinet/ip_var.h> 61#include <netinet/udp.h> 62#include <netinet/udp_var.h> 63#include <netinet/tcp.h> 64#include <netinet/tcp_timer.h> 65#include <netinet/tcp_var.h> 66#include <netinet/ip_gre.h> 67#include <netinet/ip_ipcomp.h> 68#include <netinet/ip_carp.h> 69#include <netinet/ip_divert.h> 70 71#include <net/pfvar.h> 72#include <net/if_pfsync.h> 73#include <net/pipex.h> 74 75#ifdef INET6 76#include <netinet/ip6.h> 77#include <netinet/icmp6.h> 78#include <netinet6/ip6_var.h> 79#include <netinet6/pim6_var.h> 80#include <netinet6/ip6_divert.h> 81#endif 82 83#include <netmpls/mpls.h> 84 85#include <uvm/uvm_swap_encrypt.h> 86 87#include <ufs/ufs/quota.h> 88#include <ufs/ufs/inode.h> 89#include <ufs/ffs/ffs_extern.h> 90 91#include <miscfs/fuse/fusefs.h> 92 93#include <nfs/nfsproto.h> 94#include <nfs/nfs.h> 95 96#include <ddb/db_var.h> 97#include <dev/rndvar.h> 98 99#include <err.h> 100#include <errno.h> 101#include <stdio.h> 102#include <stdlib.h> 103#include <string.h> 104#include <ctype.h> 105#include <unistd.h> 106 107#include <machine/cpu.h> 108 109#ifdef CPU_BIOS 110#include <machine/biosvar.h> 111#endif 112 113struct ctlname topname[] = CTL_NAMES; 114struct ctlname kernname[] = CTL_KERN_NAMES; 115struct ctlname vmname[] = CTL_VM_NAMES; 116struct ctlname fsname[] = CTL_FS_NAMES; 117struct ctlname netname[] = CTL_NET_NAMES; 118struct ctlname hwname[] = CTL_HW_NAMES; 119struct ctlname debugname[CTL_DEBUG_MAXID]; 120struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES; 121struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES; 122struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES; 123struct ctlname ttysname[] = CTL_KERN_TTY_NAMES; 124struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES; 125struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES; 126struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES; 127struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES; 128struct ctlname *vfsname; 129#ifdef CTL_MACHDEP_NAMES 130struct ctlname machdepname[] = CTL_MACHDEP_NAMES; 131#endif 132struct ctlname ddbname[] = CTL_DDB_NAMES; 133char names[BUFSIZ]; 134int lastused; 135 136/* Maximum size object to expect from sysctl(3) */ 137#define SYSCTL_BUFSIZ 8192 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 { 0, 0 }, /* was CTL_USER */ 158 { ddbname, DBCTL_MAXID }, /* CTL_DDB_NAMES */ 159 { 0, 0 }, /* CTL_VFS */ 160}; 161 162int Aflag, aflag, nflag, qflag; 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#define SENSORS 0x00002000 181 182/* prototypes */ 183void debuginit(void); 184void listall(char *, struct list *); 185void parse(char *, int); 186void parse_baddynamic(int *, size_t, char *, void **, size_t *, int, int); 187void usage(void); 188int findname(char *, char *, char **, struct list *); 189int sysctl_inet(char *, char **, int *, int, int *); 190#ifdef INET6 191int sysctl_inet6(char *, char **, int *, int, int *); 192#endif 193int sysctl_bpf(char *, char **, int *, int, int *); 194int sysctl_mpls(char *, char **, int *, int, int *); 195int sysctl_pipex(char *, char **, int *, int, int *); 196int sysctl_fs(char *, char **, int *, int, int *); 197static int sysctl_vfs(char *, char **, int[], int, int *); 198static int sysctl_vfsgen(char *, char **, int[], int, int *); 199int sysctl_bios(char *, char **, int *, int, int *); 200int sysctl_swpenc(char *, char **, int *, int, int *); 201int sysctl_forkstat(char *, char **, int *, int, int *); 202int sysctl_tty(char *, char **, int *, int, int *); 203int sysctl_nchstats(char *, char **, int *, int, int *); 204int sysctl_malloc(char *, char **, int *, int, int *); 205int sysctl_seminfo(char *, char **, int *, int, int *); 206int sysctl_shminfo(char *, char **, int *, int, int *); 207int sysctl_watchdog(char *, char **, int *, int, int *); 208int sysctl_tc(char *, char **, int *, int, int *); 209int sysctl_sensors(char *, char **, int *, int, int *); 210void print_sensordev(char *, int *, u_int, struct sensordev *); 211void print_sensor(struct sensor *); 212int sysctl_emul(char *, char *, int); 213#ifdef CPU_CHIPSET 214int sysctl_chipset(char *, char **, int *, int, int *); 215#endif 216void vfsinit(void); 217 218char *equ = "="; 219 220int 221main(int argc, char *argv[]) 222{ 223 int ch, lvl1; 224 225 while ((ch = getopt(argc, argv, "Aanqw")) != -1) { 226 switch (ch) { 227 228 case 'A': 229 Aflag = 1; 230 break; 231 232 case 'a': 233 aflag = 1; 234 break; 235 236 case 'n': 237 nflag = 1; 238 break; 239 240 case 'q': 241 qflag = 1; 242 break; 243 244 case 'w': 245 /* flag no longer needed; var=value implies write */ 246 break; 247 248 default: 249 usage(); 250 } 251 } 252 argc -= optind; 253 argv += optind; 254 255 if (argc == 0 || (Aflag || aflag)) { 256 debuginit(); 257 vfsinit(); 258 for (lvl1 = 1; lvl1 < CTL_MAXID; lvl1++) 259 listall(topname[lvl1].ctl_name, &secondlevel[lvl1]); 260 return (0); 261 } 262 for (; *argv != NULL; ++argv) 263 parse(*argv, 1); 264 return (0); 265} 266 267/* 268 * List all variables known to the system. 269 */ 270void 271listall(char *prefix, struct list *lp) 272{ 273 char *cp, name[BUFSIZ]; 274 int lvl2, len; 275 276 if (lp->list == NULL) 277 return; 278 if ((len = strlcpy(name, prefix, sizeof(name))) >= sizeof(name)) 279 errx(1, "%s: name too long", prefix); 280 cp = name + len++; 281 *cp++ = '.'; 282 for (lvl2 = 0; lvl2 < lp->size; lvl2++) { 283 if (lp->list[lvl2].ctl_name == NULL) 284 continue; 285 if (strlcpy(cp, lp->list[lvl2].ctl_name, 286 sizeof(name) - len) >= sizeof(name) - len) 287 warn("%s: name too long", lp->list[lvl2].ctl_name); 288 parse(name, Aflag); 289 } 290} 291 292/* 293 * Parse a name into a MIB entry. 294 * Lookup and print out the MIB entry if it exists. 295 * Set a new value if requested. 296 */ 297void 298parse(char *string, int flags) 299{ 300 int indx, type, state, intval, len; 301 size_t size, newsize = 0; 302 int lal = 0, special = 0; 303 void *newval = NULL; 304 int64_t quadval; 305 struct list *lp; 306 int mib[CTL_MAXNAME]; 307 char *cp, *bufp, buf[SYSCTL_BUFSIZ]; 308 309 (void)strlcpy(buf, string, sizeof(buf)); 310 bufp = buf; 311 if ((cp = strchr(string, '=')) != NULL) { 312 *strchr(buf, '=') = '\0'; 313 *cp++ = '\0'; 314 while (isspace((unsigned char)*cp)) 315 cp++; 316 newval = cp; 317 newsize = strlen(cp); 318 } 319 if ((indx = findname(string, "top", &bufp, &toplist)) == -1) 320 return; 321 mib[0] = indx; 322 if (indx == CTL_VFS) 323 vfsinit(); 324 if (indx == CTL_DEBUG) 325 debuginit(); 326 lp = &secondlevel[indx]; 327 if (lp->list == 0) { 328 warnx("%s: class is not implemented", topname[indx].ctl_name); 329 return; 330 } 331 if (bufp == NULL) { 332 listall(topname[indx].ctl_name, lp); 333 return; 334 } 335 if ((indx = findname(string, "second", &bufp, lp)) == -1) 336 return; 337 mib[1] = indx; 338 type = lp->list[indx].ctl_type; 339 len = 2; 340 switch (mib[0]) { 341 342 case CTL_KERN: 343 switch (mib[1]) { 344 case KERN_PROF: 345 mib[2] = GPROF_STATE; 346 size = sizeof(state); 347 if (sysctl(mib, 3, &state, &size, NULL, 0) == -1) { 348 if (flags == 0) 349 return; 350 if (!nflag) 351 (void)printf("%s: ", string); 352 (void)puts("kernel is not compiled for profiling"); 353 return; 354 } 355 if (!nflag) 356 (void)printf("%s = %s\n", string, 357 state == GMON_PROF_OFF ? "off" : "running"); 358 return; 359 case KERN_FORKSTAT: 360 sysctl_forkstat(string, &bufp, mib, flags, &type); 361 return; 362 case KERN_TTY: 363 len = sysctl_tty(string, &bufp, mib, flags, &type); 364 if (len < 0) 365 return; 366 break; 367 case KERN_NCHSTATS: 368 sysctl_nchstats(string, &bufp, mib, flags, &type); 369 return; 370 case KERN_MALLOCSTATS: 371 len = sysctl_malloc(string, &bufp, mib, flags, &type); 372 if (len < 0) 373 return; 374 if (mib[2] == KERN_MALLOC_BUCKET) 375 special |= KMEMBUCKETS; 376 if (mib[2] == KERN_MALLOC_KMEMSTATS) 377 special |= KMEMSTATS; 378 newsize = 0; 379 break; 380 case KERN_MBSTAT: 381 if (flags == 0) 382 return; 383 warnx("use netstat to view %s", string); 384 return; 385 case KERN_MSGBUF: 386 if (flags == 0) 387 return; 388 warnx("use dmesg to view %s", string); 389 return; 390 case KERN_VNODE: 391 if (flags == 0) 392 return; 393 warnx("use pstat to view %s information", string); 394 return; 395 case KERN_PROC: 396 if (flags == 0) 397 return; 398 warnx("use ps 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 case KERN_SEMINFO: 418 len = sysctl_seminfo(string, &bufp, mib, flags, &type); 419 if (len < 0) 420 return; 421 break; 422 case KERN_SHMINFO: 423 len = sysctl_shminfo(string, &bufp, mib, flags, &type); 424 if (len < 0) 425 return; 426 break; 427 case KERN_INTRCNT: 428 if (flags == 0) 429 return; 430 warnx("use vmstat or systat to view %s information", 431 string); 432 return; 433 case KERN_WATCHDOG: 434 len = sysctl_watchdog(string, &bufp, mib, flags, 435 &type); 436 if (len < 0) 437 return; 438 break; 439 case KERN_TIMECOUNTER: 440 len = sysctl_tc(string, &bufp, mib, flags, 441 &type); 442 if (len < 0) 443 return; 444 break; 445 case KERN_EMUL: 446 sysctl_emul(string, newval, flags); 447 return; 448 case KERN_FILE: 449 if (flags == 0) 450 return; 451 warnx("use fstat to view %s information", string); 452 return; 453 case KERN_CONSDEV: 454 special |= CHRDEV; 455 break; 456 case KERN_NETLIVELOCKS: 457 special |= UNSIGNED; 458 break; 459 } 460 break; 461 462 case CTL_HW: 463 switch (mib[1]) { 464 case HW_DISKSTATS: 465 /* 466 * Only complain if someone asks explicitly for this, 467 * otherwise "fail" silently. 468 */ 469 if (flags) 470 warnx("use vmstat to view %s information", 471 string); 472 return; 473 case HW_SENSORS: 474 special |= SENSORS; 475 len = sysctl_sensors(string, &bufp, mib, flags, &type); 476 if (len < 0) 477 return; 478 break; 479 case HW_PHYSMEM: 480 case HW_USERMEM: 481 /* 482 * Don't print these; we'll print the 64-bit 483 * variants instead. 484 */ 485 return; 486 } 487 break; 488 489 case CTL_VM: 490 if (mib[1] == VM_LOADAVG) { 491 double loads[3]; 492 493 getloadavg(loads, 3); 494 if (!nflag) 495 (void)printf("%s%s", string, equ); 496 (void)printf("%.2f %.2f %.2f\n", loads[0], 497 loads[1], loads[2]); 498 return; 499 } else if (mib[1] == VM_PSSTRINGS) { 500 struct _ps_strings _ps; 501 502 size = sizeof(_ps); 503 if (sysctl(mib, 2, &_ps, &size, NULL, 0) == -1) { 504 if (flags == 0) 505 return; 506 if (!nflag) 507 (void)printf("%s: ", string); 508 (void)puts("can't find ps strings"); 509 return; 510 } 511 if (!nflag) 512 (void)printf("%s%s", string, equ); 513 (void)printf("%p\n", _ps.val); 514 return; 515 } else if (mib[1] == VM_SWAPENCRYPT) { 516 len = sysctl_swpenc(string, &bufp, mib, flags, &type); 517 if (len < 0) 518 return; 519 520 break; 521 } else if (mib[1] == VM_NKMEMPAGES || 522 mib[1] == VM_ANONMIN || 523 mib[1] == VM_VTEXTMIN || 524 mib[1] == VM_VNODEMIN) { 525 break; 526 } 527 if (flags == 0) 528 return; 529 warnx("use vmstat or systat to view %s information", string); 530 return; 531 532 break; 533 534 case CTL_NET: 535 if (mib[1] == PF_INET) { 536 len = sysctl_inet(string, &bufp, mib, flags, &type); 537 if (len < 0) 538 return; 539 540 if ((mib[2] == IPPROTO_IP && mib[3] == IPCTL_MRTSTATS) || 541 (mib[2] == IPPROTO_IP && mib[3] == IPCTL_STATS) || 542 (mib[2] == IPPROTO_TCP && mib[3] == TCPCTL_STATS) || 543 (mib[2] == IPPROTO_UDP && mib[3] == UDPCTL_STATS) || 544 (mib[2] == IPPROTO_ESP && mib[3] == ESPCTL_STATS) || 545 (mib[2] == IPPROTO_AH && mib[3] == AHCTL_STATS) || 546 (mib[2] == IPPROTO_IGMP && mib[3] == IGMPCTL_STATS) || 547 (mib[2] == IPPROTO_ETHERIP && mib[3] == ETHERIPCTL_STATS) || 548 (mib[2] == IPPROTO_IPIP && mib[3] == IPIPCTL_STATS) || 549 (mib[2] == IPPROTO_IPCOMP && mib[3] == IPCOMPCTL_STATS) || 550 (mib[2] == IPPROTO_ICMP && mib[3] == ICMPCTL_STATS) || 551 (mib[2] == IPPROTO_CARP && mib[3] == CARPCTL_STATS) || 552 (mib[2] == IPPROTO_PFSYNC && mib[3] == PFSYNCCTL_STATS) || 553 (mib[2] == IPPROTO_DIVERT && mib[3] == DIVERTCTL_STATS)) { 554 if (flags == 0) 555 return; 556 warnx("use netstat to view %s information", 557 string); 558 return; 559 } else if ((mib[2] == IPPROTO_TCP && 560 mib[3] == TCPCTL_BADDYNAMIC) || 561 (mib[2] == IPPROTO_UDP && 562 mib[3] == UDPCTL_BADDYNAMIC)) { 563 564 special |= BADDYNAMIC; 565 566 if (newval != NULL) 567 parse_baddynamic(mib, len, string, 568 &newval, &newsize, flags, nflag); 569 } 570 break; 571 } 572#ifdef INET6 573 if (mib[1] == PF_INET6) { 574 len = sysctl_inet6(string, &bufp, mib, flags, &type); 575 if (len < 0) 576 return; 577 578 if ((mib[2] == IPPROTO_PIM && mib[3] == PIM6CTL_STATS) || 579 (mib[2] == IPPROTO_DIVERT && mib[3] == DIVERT6CTL_STATS)) { 580 if (flags == 0) 581 return; 582 warnx("use netstat to view %s information", 583 string); 584 return; 585 } 586 break; 587 } 588#endif 589 if (mib[1] == PF_BPF) { 590 len = sysctl_bpf(string, &bufp, mib, flags, &type); 591 if (len < 0) 592 return; 593 break; 594 } 595 if (mib[1] == PF_MPLS) { 596 len = sysctl_mpls(string, &bufp, mib, flags, &type); 597 if (len < 0) 598 return; 599 break; 600 } 601 if (mib[1] == PF_PIPEX) { 602 len = sysctl_pipex(string, &bufp, mib, flags, &type); 603 if (len < 0) 604 return; 605 break; 606 } 607 if (flags == 0) 608 return; 609 warnx("use netstat to view %s information", string); 610 return; 611 612 case CTL_DEBUG: 613 mib[2] = CTL_DEBUG_VALUE; 614 len = 3; 615 break; 616 617 case CTL_MACHDEP: 618#ifdef CPU_CONSDEV 619 if (mib[1] == CPU_CONSDEV) 620 special |= CHRDEV; 621#endif 622#ifdef CPU_BLK2CHR 623 if (mib[1] == CPU_BLK2CHR) { 624 if (bufp == NULL) 625 return; 626 mib[2] = makedev(atoi(bufp),0); 627 bufp = NULL; 628 len = 3; 629 special |= CHRDEV; 630 break; 631 } 632#endif 633#ifdef CPU_CHR2BLK 634 if (mib[1] == CPU_CHR2BLK) { 635 if (bufp == NULL) 636 return; 637 mib[2] = makedev(atoi(bufp),0); 638 bufp = NULL; 639 len = 3; 640 special |= BLKDEV; 641 break; 642 } 643#endif 644#ifdef CPU_BIOS 645 if (mib[1] == CPU_BIOS) { 646 len = sysctl_bios(string, &bufp, mib, flags, &type); 647 if (len < 0) 648 return; 649 if (mib[2] == BIOS_DEV) 650 special |= BIOSDEV; 651 if (mib[2] == BIOS_DISKINFO) 652 special |= BIOSGEO; 653 break; 654 } 655#endif 656#ifdef CPU_CHIPSET 657 if (mib[1] == CPU_CHIPSET) { 658 len = sysctl_chipset(string, &bufp, mib, flags, &type); 659 if (len < 0) 660 return; 661 break; 662 } 663#endif 664 break; 665 666 case CTL_FS: 667 len = sysctl_fs(string, &bufp, mib, flags, &type); 668 if (len >= 0) 669 break; 670 return; 671 672 case CTL_VFS: 673 if (mib[1]) 674 len = sysctl_vfs(string, &bufp, mib, flags, &type); 675 else 676 len = sysctl_vfsgen(string, &bufp, mib, flags, &type); 677 if (len >= 0) { 678 if (type == CTLTYPE_STRUCT) { 679 if (flags) 680 warnx("use nfsstat to view %s information", 681 MOUNT_NFS); 682 return; 683 } else 684 break; 685 } 686 return; 687 688 case CTL_DDB: 689 break; 690 691 default: 692 warnx("illegal top level value: %d", mib[0]); 693 return; 694 695 } 696 if (bufp) { 697 warnx("name %s in %s is unknown", bufp, string); 698 return; 699 } 700 if (newsize > 0) { 701 switch (type) { 702 case CTLTYPE_INT: 703 errno = 0; 704 if (special & UNSIGNED) 705 intval = strtoul(newval, &cp, 10); 706 else 707 intval = strtol(newval, &cp, 10); 708 if (*cp != '\0') { 709 warnx("%s: illegal value: %s", string, 710 (char *)newval); 711 return; 712 } 713 if (errno == ERANGE) { 714 warnx("%s: value %s out of range", string, 715 (char *)newval); 716 return; 717 } 718 newval = &intval; 719 newsize = sizeof(intval); 720 break; 721 722 case CTLTYPE_QUAD: 723 /* XXX - assumes sizeof(long long) == sizeof(quad_t) */ 724 (void)sscanf(newval, "%lld", (long long *)&quadval); 725 newval = &quadval; 726 newsize = sizeof(quadval); 727 break; 728 } 729 } 730 size = SYSCTL_BUFSIZ; 731 if (sysctl(mib, len, buf, &size, newval, newsize) == -1) { 732 if (flags == 0) 733 return; 734 switch (errno) { 735 case EOPNOTSUPP: 736 warnx("%s: value is not available", string); 737 return; 738 case ENOTDIR: 739 warnx("%s: specification is incomplete", string); 740 return; 741 case ENOMEM: 742 warnx("%s: type is unknown to this program", string); 743 return; 744 case ENXIO: 745 if (special & BIOSGEO) 746 return; 747 default: 748 warn("%s", string); 749 return; 750 } 751 } 752 if (special & KMEMBUCKETS) { 753 struct kmembuckets *kb = (struct kmembuckets *)buf; 754 if (!nflag) 755 (void)printf("%s%s", string, equ); 756 printf("("); 757 printf("calls = %llu ", (long long)kb->kb_calls); 758 printf("total_allocated = %llu ", (long long)kb->kb_total); 759 printf("total_free = %lld ", (long long)kb->kb_totalfree); 760 printf("elements = %lld ", (long long)kb->kb_elmpercl); 761 printf("high watermark = %lld ", (long long)kb->kb_highwat); 762 printf("could_free = %lld", (long long)kb->kb_couldfree); 763 printf(")\n"); 764 return; 765 } 766 if (special & KMEMSTATS) { 767 struct kmemstats *km = (struct kmemstats *)buf; 768 int j, first = 1; 769 770 if (!nflag) 771 (void)printf("%s%s", string, equ); 772 (void)printf("(inuse = %ld, calls = %ld, memuse = %ldK, " 773 "limblocks = %d, mapblocks = %d, maxused = %ldK, " 774 "limit = %ldK, spare = %ld, sizes = (", 775 km->ks_inuse, km->ks_calls, 776 (km->ks_memuse + 1023) / 1024, km->ks_limblocks, 777 km->ks_mapblocks, (km->ks_maxused + 1023) / 1024, 778 (km->ks_limit + 1023) / 1024, km->ks_spare); 779 for (j = 1 << MINBUCKET; j < 1 << (MINBUCKET + 16); j <<= 1) { 780 if ((km->ks_size & j ) == 0) 781 continue; 782 if (first) 783 (void)printf("%d", j); 784 else 785 (void)printf(",%d", j); 786 first = 0; 787 } 788 if (first) 789 (void)printf("none"); 790 (void)printf("))\n"); 791 return; 792 } 793 if (special & CLOCK) { 794 struct clockinfo *clkp = (struct clockinfo *)buf; 795 796 if (!nflag) 797 (void)printf("%s%s", string, equ); 798 (void)printf( 799 "tick = %d, tickadj = %d, hz = %d, profhz = %d, stathz = %d\n", 800 clkp->tick, clkp->tickadj, clkp->hz, clkp->profhz, clkp->stathz); 801 return; 802 } 803 if (special & BOOTTIME) { 804 struct timeval *btp = (struct timeval *)buf; 805 time_t boottime; 806 807 if (!nflag) { 808 boottime = btp->tv_sec; 809 (void)printf("%s%s%s", string, equ, ctime(&boottime)); 810 } else 811 (void)printf("%lld\n", (long long)btp->tv_sec); 812 return; 813 } 814 if (special & BLKDEV) { 815 dev_t dev = *(dev_t *)buf; 816 817 if (!nflag) 818 (void)printf("%s%s%s\n", string, equ, 819 devname(dev, S_IFBLK)); 820 else 821 (void)printf("0x%x\n", dev); 822 return; 823 } 824 if (special & CHRDEV) { 825 dev_t dev = *(dev_t *)buf; 826 827 if (!nflag) 828 (void)printf("%s%s%s\n", string, equ, 829 devname(dev, S_IFCHR)); 830 else 831 (void)printf("0x%x\n", dev); 832 return; 833 } 834#ifdef CPU_BIOS 835 if (special & BIOSGEO) { 836 bios_diskinfo_t *pdi = (bios_diskinfo_t *)buf; 837 838 if (!nflag) 839 (void)printf("%s%s", string, equ); 840 (void)printf("bootdev = 0x%x, " 841 "cylinders = %u, heads = %u, sectors = %u\n", 842 pdi->bsd_dev, pdi->bios_cylinders, 843 pdi->bios_heads, pdi->bios_sectors); 844 return; 845 } 846 if (special & BIOSDEV) { 847 int dev = *(int*)buf; 848 849 if (!nflag) 850 (void)printf("%s%s", string, equ); 851 (void) printf("0x%02x\n", dev); 852 return; 853 } 854#endif 855 if (special & UNSIGNED) { 856 if (newsize == 0) { 857 if (!nflag) 858 (void)printf("%s%s", string, equ); 859 (void)printf("%u\n", *(u_int *)buf); 860 } else { 861 if (!qflag) { 862 if (!nflag) 863 (void)printf("%s: %u -> ", string, 864 *(u_int *)buf); 865 (void)printf("%u\n", *(u_int *)newval); 866 } 867 } 868 return; 869 } 870 if (special & RNDSTATS) { 871 struct rndstats *rndstats = (struct rndstats *)buf; 872 int i; 873 874 if (!nflag) 875 (void)printf("%s%s", string, equ); 876 printf("tot: %llu used: %llu read: %llu stirs: %llu" 877 " enqs: %llu deqs: %llu drops: %llu ledrops: %llu", 878 rndstats->rnd_total, rndstats->rnd_used, 879 rndstats->arc4_reads, rndstats->arc4_nstirs, 880 rndstats->rnd_enqs, rndstats->rnd_deqs, 881 rndstats->rnd_drops, rndstats->rnd_drople); 882 printf(" ed:"); 883 for (i = 0; 884 i < sizeof(rndstats->rnd_ed)/sizeof(rndstats->rnd_ed[0]); 885 i++) 886 printf(" %llu", (unsigned long long)rndstats->rnd_ed[i]); 887 printf(" sc:"); 888 for (i = 0; 889 i < sizeof(rndstats->rnd_sc)/sizeof(rndstats->rnd_sc[0]); 890 i++) 891 printf(" %llu", (unsigned long long)rndstats->rnd_sc[i]); 892 printf(" sb:"); 893 for (i = 0; 894 i < sizeof(rndstats->rnd_sb)/sizeof(rndstats->rnd_sb[0]); 895 i++) 896 printf(" %llu", (unsigned long long)rndstats->rnd_sb[i]); 897 printf("\n"); 898 return; 899 } 900 if (special & BADDYNAMIC) { 901 u_int port, lastport; 902 u_int32_t *baddynamic = (u_int32_t *)buf; 903 904 if (!qflag) { 905 if (!nflag) 906 (void)printf("%s%s", string, 907 newsize ? ": " : equ); 908 lastport = 0; 909 for (port = 0; port < 65536; port++) 910 if (DP_ISSET(baddynamic, port)) { 911 (void)printf("%s%u", 912 lastport ? "," : "", port); 913 lastport = port; 914 } 915 if (newsize != 0) { 916 if (!nflag) 917 fputs(" -> ", stdout); 918 baddynamic = (u_int32_t *)newval; 919 lastport = 0; 920 for (port = 0; port < 65536; port++) 921 if (DP_ISSET(baddynamic, port)) { 922 (void)printf("%s%u", 923 lastport ? "," : "", port); 924 lastport = port; 925 } 926 } 927 (void)putchar('\n'); 928 } 929 return; 930 } 931 if (special & LONGARRAY) { 932 long *la = (long *)buf; 933 if (!nflag) 934 printf("%s%s", string, equ); 935 while (lal--) 936 printf("%ld%s", *la++, lal? ",":""); 937 putchar('\n'); 938 return; 939 } 940 if (special & SENSORS) { 941 struct sensor *s = (struct sensor *)buf; 942 943 if (size > 0 && (s->flags & SENSOR_FINVALID) == 0) { 944 if (!nflag) 945 printf("%s%s", string, equ); 946 print_sensor(s); 947 printf("\n"); 948 } 949 return; 950 } 951 switch (type) { 952 case CTLTYPE_INT: 953 if (newsize == 0) { 954 if (!nflag) 955 (void)printf("%s%s", string, equ); 956 (void)printf("%d\n", *(int *)buf); 957 } else { 958 if (!qflag) { 959 if (!nflag) 960 (void)printf("%s: %d -> ", string, 961 *(int *)buf); 962 (void)printf("%d\n", *(int *)newval); 963 } 964 } 965 return; 966 967 case CTLTYPE_STRING: 968 if (newval == NULL) { 969 if (!nflag) 970 (void)printf("%s%s", string, equ); 971 (void)puts(buf); 972 } else { 973 if (!qflag) { 974 if (!nflag) 975 (void)printf("%s: %s -> ", string, buf); 976 (void)puts((char *)newval); 977 } 978 } 979 return; 980 981 case CTLTYPE_QUAD: 982 if (newsize == 0) { 983 long long tmp = *(quad_t *)buf; 984 985 if (!nflag) 986 (void)printf("%s%s", string, equ); 987 (void)printf("%lld\n", tmp); 988 } else { 989 long long tmp = *(quad_t *)buf; 990 991 if (!qflag) { 992 if (!nflag) 993 (void)printf("%s: %lld -> ", 994 string, tmp); 995 tmp = *(quad_t *)newval; 996 (void)printf("%qd\n", tmp); 997 } 998 } 999 return; 1000 1001 case CTLTYPE_STRUCT: 1002 warnx("%s: unknown structure returned", string); 1003 return; 1004 1005 default: 1006 case CTLTYPE_NODE: 1007 warnx("%s: unknown type returned", string); 1008 return; 1009 } 1010} 1011 1012static void 1013parse_ports(char *portspec, int *port, int *high_port) 1014{ 1015 char *dash; 1016 const char *errstr; 1017 1018 if ((dash = strchr(portspec, '-')) != NULL) 1019 *dash++ = '\0'; 1020 *port = strtonum(portspec, 0, 65535, &errstr); 1021 if (errstr != NULL) 1022 errx(1, "port is %s: %s", errstr, portspec); 1023 if (dash != NULL) { 1024 *high_port = strtonum(dash, 0, 65535, &errstr); 1025 if (errstr != NULL) 1026 errx(1, "high port is %s: %s", errstr, dash); 1027 if (*high_port < *port) 1028 errx(1, "high port %d is lower than %d", 1029 *high_port, *port); 1030 } else 1031 *high_port = *port; 1032} 1033 1034void 1035parse_baddynamic(int mib[], size_t len, char *string, void **newvalp, 1036 size_t *newsizep, int flags, int nflag) 1037{ 1038 static u_int32_t newbaddynamic[DP_MAPSIZE]; 1039 int port, high_port, baddynamic_loaded = 0, full_list_set = 0; 1040 size_t size; 1041 char action, *cp; 1042 1043 while (*newvalp && (cp = strsep((char **)newvalp, ", \t")) && *cp) { 1044 if (*cp == '+' || *cp == '-') { 1045 if (full_list_set) 1046 errx(1, "cannot mix +/- with full list"); 1047 action = *cp++; 1048 if (!baddynamic_loaded) { 1049 size = sizeof(newbaddynamic); 1050 if (sysctl(mib, len, newbaddynamic, 1051 &size, 0, 0) == -1) { 1052 if (flags == 0) 1053 return; 1054 if (!nflag) 1055 printf("%s: ", string); 1056 puts("kernel does contain bad dynamic " 1057 "port tables"); 1058 return; 1059 } 1060 baddynamic_loaded = 1; 1061 } 1062 parse_ports(cp, &port, &high_port); 1063 for (; port <= high_port; port++) { 1064 if (action == '+') 1065 DP_SET(newbaddynamic, port); 1066 else 1067 DP_CLR(newbaddynamic, port); 1068 } 1069 } else { 1070 if (baddynamic_loaded) 1071 errx(1, "cannot mix +/- with full list"); 1072 if (!full_list_set) { 1073 bzero(newbaddynamic, sizeof(newbaddynamic)); 1074 full_list_set = 1; 1075 } 1076 parse_ports(cp, &port, &high_port); 1077 for (; port <= high_port; port++) 1078 DP_SET(newbaddynamic, port); 1079 } 1080 } 1081 *newvalp = (void *)newbaddynamic; 1082 *newsizep = sizeof(newbaddynamic); 1083} 1084 1085/* 1086 * Initialize the set of debugging names 1087 */ 1088void 1089debuginit(void) 1090{ 1091 int mib[3], loc, i; 1092 size_t size; 1093 1094 if (secondlevel[CTL_DEBUG].list != 0) 1095 return; 1096 secondlevel[CTL_DEBUG].list = debugname; 1097 mib[0] = CTL_DEBUG; 1098 mib[2] = CTL_DEBUG_NAME; 1099 for (loc = lastused, i = 0; i < CTL_DEBUG_MAXID; i++) { 1100 mib[1] = i; 1101 size = BUFSIZ - loc; 1102 if (sysctl(mib, 3, &names[loc], &size, NULL, 0) == -1) 1103 continue; 1104 debugname[i].ctl_name = &names[loc]; 1105 debugname[i].ctl_type = CTLTYPE_INT; 1106 loc += size; 1107 } 1108 lastused = loc; 1109} 1110 1111struct ctlname vfsgennames[] = CTL_VFSGENCTL_NAMES; 1112struct ctlname ffsname[] = FFS_NAMES; 1113struct ctlname nfsname[] = FS_NFS_NAMES; 1114struct ctlname fusefsname[] = FUSEFS_NAMES; 1115struct list *vfsvars; 1116int *vfs_typenums; 1117 1118/* 1119 * Initialize the set of filesystem names 1120 */ 1121void 1122vfsinit(void) 1123{ 1124 int mib[4], maxtypenum, cnt, loc, size; 1125 struct vfsconf vfc; 1126 size_t buflen; 1127 1128 if (secondlevel[CTL_VFS].list != 0) 1129 return; 1130 mib[0] = CTL_VFS; 1131 mib[1] = VFS_GENERIC; 1132 mib[2] = VFS_MAXTYPENUM; 1133 buflen = 4; 1134 if (sysctl(mib, 3, &maxtypenum, &buflen, (void *)0, (size_t)0) < 0) 1135 return; 1136 /* 1137 * We need to do 0..maxtypenum so add one, and then we offset them 1138 * all by (another) one by inserting VFS_GENERIC entries at zero 1139 */ 1140 maxtypenum += 2; 1141 if ((vfs_typenums = calloc(maxtypenum, sizeof(int))) == NULL) 1142 return; 1143 if ((vfsvars = calloc(maxtypenum, sizeof(*vfsvars))) == NULL) { 1144 free(vfs_typenums); 1145 return; 1146 } 1147 if ((vfsname = calloc(maxtypenum, sizeof(*vfsname))) == NULL) { 1148 free(vfs_typenums); 1149 free(vfsvars); 1150 return; 1151 } 1152 mib[2] = VFS_CONF; 1153 buflen = sizeof vfc; 1154 for (loc = lastused, cnt = 1; cnt < maxtypenum; cnt++) { 1155 mib[3] = cnt - 1; 1156 if (sysctl(mib, 4, &vfc, &buflen, (void *)0, (size_t)0) < 0) { 1157 if (errno == EOPNOTSUPP) 1158 continue; 1159 warn("vfsinit"); 1160 free(vfsname); 1161 free(vfsvars); 1162 free(vfs_typenums); 1163 return; 1164 } 1165 if (!strcmp(vfc.vfc_name, MOUNT_FFS)) { 1166 vfsvars[cnt].list = ffsname; 1167 vfsvars[cnt].size = FFS_MAXID; 1168 } 1169 if (!strcmp(vfc.vfc_name, MOUNT_NFS)) { 1170 vfsvars[cnt].list = nfsname; 1171 vfsvars[cnt].size = NFS_MAXID; 1172 } 1173 if (!strcmp(vfc.vfc_name, MOUNT_FUSEFS)) { 1174 vfsvars[cnt].list = fusefsname; 1175 vfsvars[cnt].size = FUSEFS_MAXID; 1176 } 1177 vfs_typenums[cnt] = vfc.vfc_typenum; 1178 strlcat(&names[loc], vfc.vfc_name, sizeof names - loc); 1179 vfsname[cnt].ctl_name = &names[loc]; 1180 vfsname[cnt].ctl_type = CTLTYPE_NODE; 1181 size = strlen(vfc.vfc_name) + 1; 1182 loc += size; 1183 } 1184 lastused = loc; 1185 1186 vfsname[0].ctl_name = "mounts"; 1187 vfsname[0].ctl_type = CTLTYPE_NODE; 1188 vfsvars[0].list = vfsname + 1; 1189 vfsvars[0].size = maxtypenum - 1; 1190 1191 secondlevel[CTL_VFS].list = vfsname; 1192 secondlevel[CTL_VFS].size = maxtypenum; 1193 return; 1194} 1195 1196int 1197sysctl_vfsgen(char *string, char **bufpp, int mib[], int flags, int *typep) 1198{ 1199 int indx; 1200 size_t size; 1201 struct vfsconf vfc; 1202 1203 if (*bufpp == NULL) { 1204 listall(string, vfsvars); 1205 return (-1); 1206 } 1207 1208 if ((indx = findname(string, "third", bufpp, vfsvars)) == -1) 1209 return (-1); 1210 1211 mib[1] = VFS_GENERIC; 1212 mib[2] = VFS_CONF; 1213 mib[3] = indx; 1214 size = sizeof vfc; 1215 if (sysctl(mib, 4, &vfc, &size, (void *)0, (size_t)0) < 0) { 1216 if (errno != EOPNOTSUPP) 1217 warn("vfs print"); 1218 return -1; 1219 } 1220 if (flags == 0 && vfc.vfc_refcount == 0) 1221 return -1; 1222 if (!nflag) 1223 fprintf(stdout, "%s has %d mounted instance%s\n", 1224 string, vfc.vfc_refcount, 1225 vfc.vfc_refcount != 1 ? "s" : ""); 1226 else 1227 fprintf(stdout, "%d\n", vfc.vfc_refcount); 1228 1229 return -1; 1230} 1231 1232int 1233sysctl_vfs(char *string, char **bufpp, int mib[], int flags, int *typep) 1234{ 1235 struct list *lp = &vfsvars[mib[1]]; 1236 int indx; 1237 1238 if (lp->list == NULL) { 1239 if (flags) 1240 warnx("No variables defined for file system %s", string); 1241 return (-1); 1242 } 1243 if (*bufpp == NULL) { 1244 listall(string, lp); 1245 return (-1); 1246 } 1247 if ((indx = findname(string, "third", bufpp, lp)) == -1) 1248 return (-1); 1249 1250 mib[1] = vfs_typenums[mib[1]]; 1251 mib[2] = indx; 1252 *typep = lp->list[indx].ctl_type; 1253 return (3); 1254} 1255 1256struct ctlname posixname[] = CTL_FS_POSIX_NAMES; 1257struct list fslist = { posixname, FS_POSIX_MAXID }; 1258 1259/* 1260 * handle file system requests 1261 */ 1262int 1263sysctl_fs(char *string, char **bufpp, int mib[], int flags, int *typep) 1264{ 1265 int indx; 1266 1267 if (*bufpp == NULL) { 1268 listall(string, &fslist); 1269 return (-1); 1270 } 1271 if ((indx = findname(string, "third", bufpp, &fslist)) == -1) 1272 return (-1); 1273 mib[2] = indx; 1274 *typep = fslist.list[indx].ctl_type; 1275 return (3); 1276} 1277 1278#ifdef CPU_BIOS 1279struct ctlname biosname[] = CTL_BIOS_NAMES; 1280struct list bioslist = { biosname, BIOS_MAXID }; 1281 1282/* 1283 * handle BIOS requests 1284 */ 1285int 1286sysctl_bios(char *string, char **bufpp, int mib[], int flags, int *typep) 1287{ 1288 char *name; 1289 int indx; 1290 1291 if (*bufpp == NULL) { 1292 listall(string, &bioslist); 1293 return (-1); 1294 } 1295 if ((indx = findname(string, "third", bufpp, &bioslist)) == -1) 1296 return (-1); 1297 mib[2] = indx; 1298 if (indx == BIOS_DISKINFO) { 1299 if (*bufpp == NULL) { 1300 char name[BUFSIZ]; 1301 1302 /* scan all the bios devices */ 1303 for (indx = 0; indx < 256; indx++) { 1304 snprintf(name, sizeof(name), "%s.%u", 1305 string, indx); 1306 parse(name, 1); 1307 } 1308 return (-1); 1309 } 1310 if ((name = strsep(bufpp, ".")) == NULL) { 1311 warnx("%s: incomplete specification", string); 1312 return (-1); 1313 } 1314 mib[3] = atoi(name); 1315 *typep = CTLTYPE_STRUCT; 1316 return (4); 1317 } else { 1318 *typep = bioslist.list[indx].ctl_type; 1319 return (3); 1320 } 1321} 1322#endif 1323 1324struct ctlname swpencname[] = CTL_SWPENC_NAMES; 1325struct list swpenclist = { swpencname, SWPENC_MAXID }; 1326 1327/* 1328 * handle swap encrypt requests 1329 */ 1330int 1331sysctl_swpenc(char *string, char **bufpp, int mib[], int flags, int *typep) 1332{ 1333 int indx; 1334 1335 if (*bufpp == NULL) { 1336 listall(string, &swpenclist); 1337 return (-1); 1338 } 1339 if ((indx = findname(string, "third", bufpp, &swpenclist)) == -1) 1340 return (-1); 1341 mib[2] = indx; 1342 *typep = swpenclist.list[indx].ctl_type; 1343 return (3); 1344} 1345 1346struct ctlname inetname[] = CTL_IPPROTO_NAMES; 1347struct ctlname ipname[] = IPCTL_NAMES; 1348struct ctlname icmpname[] = ICMPCTL_NAMES; 1349struct ctlname igmpname[] = IGMPCTL_NAMES; 1350struct ctlname ipipname[] = IPIPCTL_NAMES; 1351struct ctlname tcpname[] = TCPCTL_NAMES; 1352struct ctlname udpname[] = UDPCTL_NAMES; 1353struct ctlname espname[] = ESPCTL_NAMES; 1354struct ctlname ahname[] = AHCTL_NAMES; 1355struct ctlname etheripname[] = ETHERIPCTL_NAMES; 1356struct ctlname grename[] = GRECTL_NAMES; 1357struct ctlname mobileipname[] = MOBILEIPCTL_NAMES; 1358struct ctlname ipcompname[] = IPCOMPCTL_NAMES; 1359struct ctlname carpname[] = CARPCTL_NAMES; 1360struct ctlname pfsyncname[] = PFSYNCCTL_NAMES; 1361struct ctlname divertname[] = DIVERTCTL_NAMES; 1362struct ctlname bpfname[] = CTL_NET_BPF_NAMES; 1363struct ctlname ifqname[] = CTL_IFQ_NAMES; 1364struct ctlname pipexname[] = PIPEXCTL_NAMES; 1365struct list inetlist = { inetname, IPPROTO_MAXID }; 1366struct list inetvars[] = { 1367 { ipname, IPCTL_MAXID }, /* ip */ 1368 { icmpname, ICMPCTL_MAXID }, /* icmp */ 1369 { igmpname, IGMPCTL_MAXID }, /* igmp */ 1370 { 0, 0 }, /* ggmp */ 1371 { ipipname, IPIPCTL_MAXID }, /* ipencap */ 1372 { 0, 0 }, 1373 { tcpname, TCPCTL_MAXID }, /* tcp */ 1374 { 0, 0 }, 1375 { 0, 0 }, /* egp */ 1376 { 0, 0 }, 1377 { 0, 0 }, 1378 { 0, 0 }, 1379 { 0, 0 }, /* pup */ 1380 { 0, 0 }, 1381 { 0, 0 }, 1382 { 0, 0 }, 1383 { 0, 0 }, 1384 { udpname, UDPCTL_MAXID }, /* udp */ 1385 { 0, 0 }, 1386 { 0, 0 }, 1387 { 0, 0 }, 1388 { 0, 0 }, 1389 { 0, 0 }, 1390 { 0, 0 }, 1391 { 0, 0 }, 1392 { 0, 0 }, 1393 { 0, 0 }, 1394 { 0, 0 }, 1395 { 0, 0 }, 1396 { 0, 0 }, 1397 { 0, 0 }, 1398 { 0, 0 }, 1399 { 0, 0 }, 1400 { 0, 0 }, 1401 { 0, 0 }, 1402 { 0, 0 }, 1403 { 0, 0 }, 1404 { 0, 0 }, 1405 { 0, 0 }, 1406 { 0, 0 }, 1407 { 0, 0 }, 1408 { 0, 0 }, 1409 { 0, 0 }, 1410 { 0, 0 }, 1411 { 0, 0 }, 1412 { 0, 0 }, 1413 { 0, 0 }, 1414 { grename, GRECTL_MAXID }, /* gre */ 1415 { 0, 0 }, 1416 { 0, 0 }, 1417 { espname, ESPCTL_MAXID }, /* esp */ 1418 { ahname, AHCTL_MAXID }, /* ah */ 1419 { 0, 0 }, 1420 { 0, 0 }, 1421 { 0, 0 }, 1422 { mobileipname, MOBILEIPCTL_MAXID }, /* mobileip */ 1423 { 0, 0 }, 1424 { 0, 0 }, 1425 { 0, 0 }, 1426 { 0, 0 }, 1427 { 0, 0 }, 1428 { 0, 0 }, 1429 { 0, 0 }, 1430 { 0, 0 }, 1431 { 0, 0 }, 1432 { 0, 0 }, 1433 { 0, 0 }, 1434 { 0, 0 }, 1435 { 0, 0 }, 1436 { 0, 0 }, 1437 { 0, 0 }, 1438 { 0, 0 }, 1439 { 0, 0 }, 1440 { 0, 0 }, 1441 { 0, 0 }, 1442 { 0, 0 }, 1443 { 0, 0 }, 1444 { 0, 0 }, 1445 { 0, 0 }, 1446 { 0, 0 }, 1447 { 0, 0 }, 1448 { 0, 0 }, 1449 { 0, 0 }, 1450 { 0, 0 }, 1451 { 0, 0 }, 1452 { 0, 0 }, 1453 { 0, 0 }, 1454 { 0, 0 }, 1455 { 0, 0 }, 1456 { 0, 0 }, 1457 { 0, 0 }, 1458 { 0, 0 }, 1459 { 0, 0 }, 1460 { 0, 0 }, 1461 { 0, 0 }, 1462 { 0, 0 }, 1463 { 0, 0 }, 1464 { etheripname, ETHERIPCTL_MAXID }, 1465 { 0, 0 }, 1466 { 0, 0 }, 1467 { 0, 0 }, 1468 { 0, 0 }, 1469 { 0, 0 }, 1470 { 0, 0 }, 1471 { 0, 0 }, 1472 { 0, 0 }, 1473 { 0, 0 }, 1474 { 0, 0 }, 1475 { ipcompname, IPCOMPCTL_MAXID }, 1476 { 0, 0 }, 1477 { 0, 0 }, 1478 { 0, 0 }, 1479 { carpname, CARPCTL_MAXID }, 1480 { 0, 0 }, 1481 { 0, 0 }, 1482 { 0, 0 }, 1483 { 0, 0 }, 1484 { 0, 0 }, 1485 { 0, 0 }, 1486 { 0, 0 }, 1487 { 0, 0 }, 1488 { 0, 0 }, 1489 { 0, 0 }, 1490 { 0, 0 }, 1491 { 0, 0 }, 1492 { 0, 0 }, 1493 { 0, 0 }, 1494 { 0, 0 }, 1495 { 0, 0 }, 1496 { 0, 0 }, 1497 { 0, 0 }, 1498 { 0, 0 }, 1499 { 0, 0 }, 1500 { 0, 0 }, 1501 { 0, 0 }, 1502 { 0, 0 }, 1503 { 0, 0 }, 1504 { 0, 0 }, 1505 { 0, 0 }, 1506 { 0, 0 }, 1507 { 0, 0 }, 1508 { 0, 0 }, 1509 { 0, 0 }, 1510 { 0, 0 }, 1511 { 0, 0 }, 1512 { 0, 0 }, 1513 { 0, 0 }, 1514 { 0, 0 }, 1515 { 0, 0 }, 1516 { 0, 0 }, 1517 { 0, 0 }, 1518 { 0, 0 }, 1519 { 0, 0 }, 1520 { 0, 0 }, 1521 { 0, 0 }, 1522 { 0, 0 }, 1523 { 0, 0 }, 1524 { 0, 0 }, 1525 { 0, 0 }, 1526 { 0, 0 }, 1527 { 0, 0 }, 1528 { 0, 0 }, 1529 { 0, 0 }, 1530 { 0, 0 }, 1531 { 0, 0 }, 1532 { 0, 0 }, 1533 { 0, 0 }, 1534 { 0, 0 }, 1535 { 0, 0 }, 1536 { 0, 0 }, 1537 { 0, 0 }, 1538 { 0, 0 }, 1539 { 0, 0 }, 1540 { 0, 0 }, 1541 { 0, 0 }, 1542 { 0, 0 }, 1543 { 0, 0 }, 1544 { 0, 0 }, 1545 { 0, 0 }, 1546 { 0, 0 }, 1547 { 0, 0 }, 1548 { 0, 0 }, 1549 { 0, 0 }, 1550 { 0, 0 }, 1551 { 0, 0 }, 1552 { 0, 0 }, 1553 { 0, 0 }, 1554 { 0, 0 }, 1555 { 0, 0 }, 1556 { 0, 0 }, 1557 { 0, 0 }, 1558 { 0, 0 }, 1559 { 0, 0 }, 1560 { 0, 0 }, 1561 { 0, 0 }, 1562 { 0, 0 }, 1563 { 0, 0 }, 1564 { 0, 0 }, 1565 { 0, 0 }, 1566 { 0, 0 }, 1567 { 0, 0 }, 1568 { 0, 0 }, 1569 { 0, 0 }, 1570 { 0, 0 }, 1571 { 0, 0 }, 1572 { 0, 0 }, 1573 { 0, 0 }, 1574 { 0, 0 }, 1575 { 0, 0 }, 1576 { 0, 0 }, 1577 { 0, 0 }, 1578 { 0, 0 }, 1579 { 0, 0 }, 1580 { 0, 0 }, 1581 { 0, 0 }, 1582 { 0, 0 }, 1583 { 0, 0 }, 1584 { 0, 0 }, 1585 { 0, 0 }, 1586 { 0, 0 }, 1587 { 0, 0 }, 1588 { 0, 0 }, 1589 { 0, 0 }, 1590 { 0, 0 }, 1591 { 0, 0 }, 1592 { 0, 0 }, 1593 { 0, 0 }, 1594 { 0, 0 }, 1595 { 0, 0 }, 1596 { 0, 0 }, 1597 { 0, 0 }, 1598 { 0, 0 }, 1599 { 0, 0 }, 1600 { 0, 0 }, 1601 { 0, 0 }, 1602 { 0, 0 }, 1603 { 0, 0 }, 1604 { 0, 0 }, 1605 { 0, 0 }, 1606 { 0, 0 }, 1607 { 0, 0 }, 1608 { 0, 0 }, 1609 { 0, 0 }, 1610 { 0, 0 }, 1611 { 0, 0 }, 1612 { 0, 0 }, 1613 { 0, 0 }, 1614 { 0, 0 }, 1615 { 0, 0 }, 1616 { pfsyncname, PFSYNCCTL_MAXID }, 1617 { 0, 0 }, 1618 { 0, 0 }, 1619 { 0, 0 }, 1620 { 0, 0 }, 1621 { 0, 0 }, 1622 { 0, 0 }, 1623 { 0, 0 }, 1624 { 0, 0 }, 1625 { divertname, DIVERTCTL_MAXID }, 1626}; 1627struct list bpflist = { bpfname, NET_BPF_MAXID }; 1628struct list ifqlist = { ifqname, IFQCTL_MAXID }; 1629struct list pipexlist = { pipexname, PIPEXCTL_MAXID }; 1630 1631struct list kernmalloclist = { kernmallocname, KERN_MALLOC_MAXID }; 1632struct list forkstatlist = { forkstatname, KERN_FORKSTAT_MAXID }; 1633struct list nchstatslist = { nchstatsname, KERN_NCHSTATS_MAXID }; 1634struct list ttylist = { ttysname, KERN_TTY_MAXID }; 1635struct list semlist = { semname, KERN_SEMINFO_MAXID }; 1636struct list shmlist = { shmname, KERN_SHMINFO_MAXID }; 1637struct list watchdoglist = { watchdogname, KERN_WATCHDOG_MAXID }; 1638struct list tclist = { tcname, KERN_TIMECOUNTER_MAXID }; 1639 1640/* 1641 * handle vfs namei cache statistics 1642 */ 1643int 1644sysctl_nchstats(char *string, char **bufpp, int mib[], int flags, int *typep) 1645{ 1646 static struct nchstats nch; 1647 int indx; 1648 size_t size; 1649 static int keepvalue = 0; 1650 1651 if (*bufpp == NULL) { 1652 bzero(&nch, sizeof(struct nchstats)); 1653 listall(string, &nchstatslist); 1654 return (-1); 1655 } 1656 if ((indx = findname(string, "third", bufpp, &nchstatslist)) == -1) 1657 return (-1); 1658 mib[2] = indx; 1659 if (*bufpp != NULL) { 1660 warnx("fourth level name in %s is invalid", string); 1661 return (-1); 1662 } 1663 if (keepvalue == 0) { 1664 size = sizeof(struct nchstats); 1665 if (sysctl(mib, 2, &nch, &size, NULL, 0) < 0) 1666 return (-1); 1667 keepvalue = 1; 1668 } 1669 if (!nflag) 1670 (void)printf("%s%s", string, equ); 1671 switch (indx) { 1672 case KERN_NCHSTATS_GOODHITS: 1673 (void)printf("%llu\n", nch.ncs_goodhits); 1674 break; 1675 case KERN_NCHSTATS_NEGHITS: 1676 (void)printf("%llu\n", nch.ncs_neghits); 1677 break; 1678 case KERN_NCHSTATS_BADHITS: 1679 (void)printf("%llu\n", nch.ncs_badhits); 1680 break; 1681 case KERN_NCHSTATS_FALSEHITS: 1682 (void)printf("%llu\n", nch.ncs_falsehits); 1683 break; 1684 case KERN_NCHSTATS_MISS: 1685 (void)printf("%llu\n", nch.ncs_miss); 1686 break; 1687 case KERN_NCHSTATS_LONG: 1688 (void)printf("%llu\n", nch.ncs_long); 1689 break; 1690 case KERN_NCHSTATS_PASS2: 1691 (void)printf("%llu\n", nch.ncs_pass2); 1692 break; 1693 case KERN_NCHSTATS_2PASSES: 1694 (void)printf("%llu\n", nch.ncs_2passes); 1695 break; 1696 case KERN_NCHSTATS_REVHITS: 1697 (void)printf("%llu\n", nch.ncs_revhits); 1698 break; 1699 case KERN_NCHSTATS_REVMISS: 1700 (void)printf("%llu\n", nch.ncs_revmiss); 1701 break; 1702 case KERN_NCHSTATS_DOTHITS: 1703 (void)printf("%llu\n", nch.ncs_dothits); 1704 break; 1705 case KERN_NCHSTATS_DOTDOTHITS: 1706 (void)printf("%llu\n", nch.ncs_dotdothits); 1707 break; 1708 } 1709 return (-1); 1710} 1711 1712/* 1713 * handle tty statistics 1714 */ 1715int 1716sysctl_tty(char *string, char **bufpp, int mib[], int flags, int *typep) 1717{ 1718 int indx; 1719 1720 if (*bufpp == NULL) { 1721 listall(string, &ttylist); 1722 return (-1); 1723 } 1724 if ((indx = findname(string, "third", bufpp, &ttylist)) == -1) 1725 return (-1); 1726 mib[2] = indx; 1727 1728 if ((*typep = ttylist.list[indx].ctl_type) == CTLTYPE_STRUCT) { 1729 if (flags) 1730 warnx("use pstat -t to view %s information", 1731 string); 1732 return (-1); 1733 } 1734 return (3); 1735} 1736 1737/* 1738 * handle fork statistics 1739 */ 1740int 1741sysctl_forkstat(char *string, char **bufpp, int mib[], int flags, int *typep) 1742{ 1743 static struct forkstat fks; 1744 static int keepvalue = 0; 1745 int indx; 1746 size_t size; 1747 1748 if (*bufpp == NULL) { 1749 bzero(&fks, sizeof(struct forkstat)); 1750 listall(string, &forkstatlist); 1751 return (-1); 1752 } 1753 if ((indx = findname(string, "third", bufpp, &forkstatlist)) == -1) 1754 return (-1); 1755 if (*bufpp != NULL) { 1756 warnx("fourth level name in %s is invalid", string); 1757 return (-1); 1758 } 1759 if (keepvalue == 0) { 1760 size = sizeof(struct forkstat); 1761 if (sysctl(mib, 2, &fks, &size, NULL, 0) < 0) 1762 return (-1); 1763 keepvalue = 1; 1764 } 1765 if (!nflag) 1766 (void)printf("%s%s", string, equ); 1767 switch (indx) { 1768 case KERN_FORKSTAT_FORK: 1769 (void)printf("%d\n", fks.cntfork); 1770 break; 1771 case KERN_FORKSTAT_VFORK: 1772 (void)printf("%d\n", fks.cntvfork); 1773 break; 1774 case KERN_FORKSTAT_TFORK: 1775 (void)printf("%d\n", fks.cnttfork); 1776 break; 1777 case KERN_FORKSTAT_KTHREAD: 1778 (void)printf("%d\n", fks.cntkthread); 1779 break; 1780 case KERN_FORKSTAT_SIZFORK: 1781 (void)printf("%d\n", fks.sizfork); 1782 break; 1783 case KERN_FORKSTAT_SIZVFORK: 1784 (void)printf("%d\n", fks.sizvfork); 1785 break; 1786 case KERN_FORKSTAT_SIZTFORK: 1787 (void)printf("%d\n", fks.siztfork); 1788 break; 1789 case KERN_FORKSTAT_SIZKTHREAD: 1790 (void)printf("%d\n", fks.sizkthread); 1791 break; 1792 } 1793 return (-1); 1794} 1795 1796/* 1797 * handle malloc statistics 1798 */ 1799int 1800sysctl_malloc(char *string, char **bufpp, int mib[], int flags, int *typep) 1801{ 1802 int indx, stor, i; 1803 char *name, bufp[SYSCTL_BUFSIZ], *buf, *ptr; 1804 struct list lp; 1805 size_t size; 1806 1807 if (*bufpp == NULL) { 1808 listall(string, &kernmalloclist); 1809 return (-1); 1810 } 1811 if ((indx = findname(string, "third", bufpp, &kernmalloclist)) == -1) 1812 return (-1); 1813 mib[2] = indx; 1814 if (mib[2] == KERN_MALLOC_BUCKET) { 1815 if ((name = strsep(bufpp, ".")) == NULL) { 1816 size = SYSCTL_BUFSIZ; 1817 stor = mib[2]; 1818 mib[2] = KERN_MALLOC_BUCKETS; 1819 buf = bufp; 1820 if (sysctl(mib, 3, buf, &size, NULL, 0) < 0) 1821 return (-1); 1822 mib[2] = stor; 1823 for (stor = 0, i = 0; i < size; i++) 1824 if (buf[i] == ',') 1825 stor++; 1826 lp.list = calloc(stor + 2, sizeof(struct ctlname)); 1827 if (lp.list == NULL) 1828 return (-1); 1829 lp.size = stor + 2; 1830 for (i = 1; 1831 (lp.list[i].ctl_name = strsep(&buf, ",")) != NULL; 1832 i++) { 1833 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1834 } 1835 lp.list[i].ctl_name = buf; 1836 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1837 listall(string, &lp); 1838 free(lp.list); 1839 return (-1); 1840 } 1841 mib[3] = atoi(name); 1842 return (4); 1843 } else if (mib[2] == KERN_MALLOC_BUCKETS) { 1844 *typep = CTLTYPE_STRING; 1845 return (3); 1846 } else if (mib[2] == KERN_MALLOC_KMEMSTATS) { 1847 size = SYSCTL_BUFSIZ; 1848 stor = mib[2]; 1849 mib[2] = KERN_MALLOC_KMEMNAMES; 1850 buf = bufp; 1851 if (sysctl(mib, 3, buf, &size, NULL, 0) < 0) 1852 return (-1); 1853 mib[2] = stor; 1854 if ((name = strsep(bufpp, ".")) == NULL) { 1855 for (stor = 0, i = 0; i < size; i++) 1856 if (buf[i] == ',') 1857 stor++; 1858 lp.list = calloc(stor + 2, sizeof(struct ctlname)); 1859 if (lp.list == NULL) 1860 return (-1); 1861 lp.size = stor + 2; 1862 for (i = 1; 1863 (lp.list[i].ctl_name = strsep(&buf, ",")) != NULL; 1864 i++) { 1865 if (lp.list[i].ctl_name[0] == '\0') { 1866 i--; 1867 continue; 1868 } 1869 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1870 } 1871 lp.list[i].ctl_name = buf; 1872 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1873 listall(string, &lp); 1874 free(lp.list); 1875 return (-1); 1876 } 1877 ptr = strstr(buf, name); 1878 tryagain: 1879 if (ptr == NULL) { 1880 warnx("fourth level name %s in %s is invalid", name, 1881 string); 1882 return (-1); 1883 } 1884 if ((*(ptr + strlen(name)) != ',') && 1885 (*(ptr + strlen(name)) != '\0')) { 1886 ptr = strstr(ptr + 1, name); /* retry */ 1887 goto tryagain; 1888 } 1889 if ((ptr != buf) && (*(ptr - 1) != ',')) { 1890 ptr = strstr(ptr + 1, name); /* retry */ 1891 goto tryagain; 1892 } 1893 for (i = 0, stor = 0; buf + i < ptr; i++) 1894 if (buf[i] == ',') 1895 stor++; 1896 mib[3] = stor; 1897 return (4); 1898 } else if (mib[2] == KERN_MALLOC_KMEMNAMES) { 1899 *typep = CTLTYPE_STRING; 1900 return (3); 1901 } 1902 return (-1); 1903} 1904 1905#ifdef CPU_CHIPSET 1906/* 1907 * handle machdep.chipset requests 1908 */ 1909struct ctlname chipsetname[] = CTL_CHIPSET_NAMES; 1910struct list chipsetlist = { chipsetname, CPU_CHIPSET_MAXID }; 1911 1912int 1913sysctl_chipset(char *string, char **bufpp, int mib[], int flags, int *typep) 1914{ 1915 int indx, bwx; 1916 static void *q; 1917 size_t len; 1918 char *p; 1919 1920 if (*bufpp == NULL) { 1921 listall(string, &chipsetlist); 1922 return (-1); 1923 } 1924 if ((indx = findname(string, "third", bufpp, &chipsetlist)) == -1) 1925 return (-1); 1926 mib[2] = indx; 1927 if (!nflag) 1928 printf("%s%s", string, equ); 1929 switch(mib[2]) { 1930 case CPU_CHIPSET_MEM: 1931 case CPU_CHIPSET_DENSE: 1932 case CPU_CHIPSET_PORTS: 1933 case CPU_CHIPSET_HAE_MASK: 1934 len = sizeof(void *); 1935 if (sysctl(mib, 3, &q, &len, NULL, 0) < 0) 1936 goto done; 1937 printf("%p", q); 1938 break; 1939 case CPU_CHIPSET_BWX: 1940 len = sizeof(int); 1941 if (sysctl(mib, 3, &bwx, &len, NULL, 0) < 0) 1942 goto done; 1943 printf("%d", bwx); 1944 break; 1945 case CPU_CHIPSET_TYPE: 1946 if (sysctl(mib, 3, NULL, &len, NULL, 0) < 0) 1947 goto done; 1948 p = malloc(len + 1); 1949 if (p == NULL) 1950 goto done; 1951 if (sysctl(mib, 3, p, &len, NULL, 0) < 0) { 1952 free(p); 1953 goto done; 1954 } 1955 p[len] = '\0'; 1956 printf("%s", p); 1957 free(p); 1958 break; 1959 } 1960done: 1961 printf("\n"); 1962 return (-1); 1963} 1964#endif 1965/* 1966 * handle internet requests 1967 */ 1968int 1969sysctl_inet(char *string, char **bufpp, int mib[], int flags, int *typep) 1970{ 1971 struct list *lp; 1972 int indx; 1973 1974 if (*bufpp == NULL) { 1975 listall(string, &inetlist); 1976 return (-1); 1977 } 1978 if ((indx = findname(string, "third", bufpp, &inetlist)) == -1) 1979 return (-1); 1980 mib[2] = indx; 1981 if (indx < IPPROTO_MAXID && inetvars[indx].list != NULL) 1982 lp = &inetvars[indx]; 1983 else if (!flags) 1984 return (-1); 1985 else { 1986 warnx("%s: no variables defined for this protocol", string); 1987 return (-1); 1988 } 1989 if (*bufpp == NULL) { 1990 listall(string, lp); 1991 return (-1); 1992 } 1993 if ((indx = findname(string, "fourth", bufpp, lp)) == -1) 1994 return (-1); 1995 mib[3] = indx; 1996 *typep = lp->list[indx].ctl_type; 1997 if (*typep == CTLTYPE_NODE) { 1998 int tindx; 1999 2000 if (*bufpp == NULL) { 2001 listall(string, &ifqlist); 2002 return(-1); 2003 } 2004 lp = &ifqlist; 2005 if ((tindx = findname(string, "fifth", bufpp, lp)) == -1) 2006 return (-1); 2007 mib[4] = tindx; 2008 *typep = lp->list[tindx].ctl_type; 2009 return(5); 2010 } 2011 return (4); 2012} 2013 2014#ifdef INET6 2015struct ctlname inet6name[] = CTL_IPV6PROTO_NAMES; 2016struct ctlname ip6name[] = IPV6CTL_NAMES; 2017struct ctlname icmp6name[] = ICMPV6CTL_NAMES; 2018struct ctlname pim6name[] = PIM6CTL_NAMES; 2019struct ctlname divert6name[] = DIVERT6CTL_NAMES; 2020struct list inet6list = { inet6name, IPV6PROTO_MAXID }; 2021struct list inet6vars[] = { 2022/*0*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2023 { 0, 0 }, 2024 { 0, 0 }, 2025 { 0, 0 }, 2026 { 0, 0 }, 2027 { 0, 0 }, 2028/*10*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2029 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2030/*20*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2031 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2032/*30*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2033 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2034/*40*/ { 0, 0 }, 2035 { ip6name, IPV6CTL_MAXID }, /* ipv6 */ 2036 { 0, 0 }, 2037 { 0, 0 }, 2038 { 0, 0 }, 2039 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2040/*50*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2041 { 0, 0 }, 2042 { 0, 0 }, 2043 { 0, 0 }, 2044 { icmp6name, ICMPV6CTL_MAXID }, /* icmp6 */ 2045 { 0, 0 }, 2046/*60*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2047 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2048/*70*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2049 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2050/*80*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2051 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2052/*90*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2053 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2054/*100*/ { 0, 0 }, 2055 { 0, 0 }, 2056 { 0, 0 }, 2057 { pim6name, PIM6CTL_MAXID }, /* pim6 */ 2058 { 0, 0 }, 2059 { 0, 0 }, 2060 { 0, 0 }, 2061 { 0, 0 }, 2062 { 0, 0 }, 2063 { 0, 0 }, 2064/*110*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2065 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2066/*120*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2067 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2068/*130*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2069 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2070/*140*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2071 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2072/*150*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2073 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2074/*160*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2075 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2076/*170*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2077 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2078/*180*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2079 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2080/*190*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2081 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2082/*200*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2083 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2084/*210*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2085 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2086/*220*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2087 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2088/*230*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2089 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2090/*240*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2091 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2092/*250*/ { 0, 0 }, 2093 { 0, 0 }, 2094 { 0, 0 }, 2095 { 0, 0 }, 2096 { 0, 0 }, 2097 { 0, 0 }, 2098 { 0, 0 }, 2099 { 0, 0 }, 2100 { divert6name, DIVERT6CTL_MAXID }, 2101}; 2102 2103/* 2104 * handle internet6 requests 2105 */ 2106int 2107sysctl_inet6(char *string, char **bufpp, int mib[], int flags, int *typep) 2108{ 2109 struct list *lp; 2110 int indx; 2111 2112 if (*bufpp == NULL) { 2113 listall(string, &inet6list); 2114 return (-1); 2115 } 2116 if ((indx = findname(string, "third", bufpp, &inet6list)) == -1) 2117 return (-1); 2118 mib[2] = indx; 2119 if (indx < IPV6PROTO_MAXID && inet6vars[indx].list != NULL) 2120 lp = &inet6vars[indx]; 2121 else if (!flags) 2122 return (-1); 2123 else { 2124 warnx("%s: no variables defined for this protocol", string); 2125 return (-1); 2126 } 2127 if (*bufpp == NULL) { 2128 listall(string, lp); 2129 return (-1); 2130 } 2131 if ((indx = findname(string, "fourth", bufpp, lp)) == -1) 2132 return (-1); 2133 mib[3] = indx; 2134 *typep = lp->list[indx].ctl_type; 2135 return (4); 2136} 2137#endif 2138 2139/* handle bpf requests */ 2140int 2141sysctl_bpf(char *string, char **bufpp, int mib[], int flags, int *typep) 2142{ 2143 int indx; 2144 2145 if (*bufpp == NULL) { 2146 listall(string, &bpflist); 2147 return (-1); 2148 } 2149 if ((indx = findname(string, "third", bufpp, &bpflist)) == -1) 2150 return (-1); 2151 mib[2] = indx; 2152 *typep = CTLTYPE_INT; 2153 return (3); 2154} 2155 2156struct ctlname mplsname[] = MPLSCTL_NAMES; 2157struct list mplslist = { mplsname, MPLSCTL_MAXID }; 2158 2159/* handle MPLS requests */ 2160int 2161sysctl_mpls(char *string, char **bufpp, int mib[], int flags, int *typep) 2162{ 2163 struct list *lp; 2164 int indx; 2165 2166 if (*bufpp == NULL) { 2167 listall(string, &mplslist); 2168 return (-1); 2169 } 2170 if ((indx = findname(string, "third", bufpp, &mplslist)) == -1) 2171 return (-1); 2172 mib[2] = indx; 2173 *typep = mplslist.list[indx].ctl_type; 2174 if (*typep == CTLTYPE_NODE) { 2175 int tindx; 2176 2177 if (*bufpp == NULL) { 2178 listall(string, &ifqlist); 2179 return(-1); 2180 } 2181 lp = &ifqlist; 2182 if ((tindx = findname(string, "fourth", bufpp, lp)) == -1) 2183 return (-1); 2184 mib[3] = tindx; 2185 *typep = lp->list[tindx].ctl_type; 2186 return(4); 2187 } 2188 return (3); 2189} 2190 2191/* handle PIPEX requests */ 2192int 2193sysctl_pipex(char *string, char **bufpp, int mib[], int flags, int *typep) 2194{ 2195 struct list *lp; 2196 int indx; 2197 2198 if (*bufpp == NULL) { 2199 listall(string, &pipexlist); 2200 return (-1); 2201 } 2202 if ((indx = findname(string, "third", bufpp, &pipexlist)) == -1) 2203 return (-1); 2204 mib[2] = indx; 2205 *typep = pipexlist.list[indx].ctl_type; 2206 if (*typep == CTLTYPE_NODE) { 2207 int tindx; 2208 2209 if (*bufpp == NULL) { 2210 listall(string, &ifqlist); 2211 return(-1); 2212 } 2213 lp = &ifqlist; 2214 if ((tindx = findname(string, "fourth", bufpp, lp)) == -1) 2215 return (-1); 2216 mib[3] = tindx; 2217 *typep = lp->list[tindx].ctl_type; 2218 return(4); 2219 } 2220 return (3); 2221} 2222 2223/* 2224 * Handle SysV semaphore info requests 2225 */ 2226int 2227sysctl_seminfo(string, bufpp, mib, flags, typep) 2228 char *string; 2229 char **bufpp; 2230 int mib[]; 2231 int flags; 2232 int *typep; 2233{ 2234 int indx; 2235 2236 if (*bufpp == NULL) { 2237 listall(string, &semlist); 2238 return (-1); 2239 } 2240 if ((indx = findname(string, "third", bufpp, &semlist)) == -1) 2241 return (-1); 2242 mib[2] = indx; 2243 *typep = CTLTYPE_INT; 2244 return (3); 2245} 2246 2247/* 2248 * Handle SysV shared memory info requests 2249 */ 2250int 2251sysctl_shminfo(string, bufpp, mib, flags, typep) 2252 char *string; 2253 char **bufpp; 2254 int mib[]; 2255 int flags; 2256 int *typep; 2257{ 2258 int indx; 2259 2260 if (*bufpp == NULL) { 2261 listall(string, &shmlist); 2262 return (-1); 2263 } 2264 if ((indx = findname(string, "third", bufpp, &shmlist)) == -1) 2265 return (-1); 2266 mib[2] = indx; 2267 *typep = CTLTYPE_INT; 2268 return (3); 2269} 2270 2271/* 2272 * Handle watchdog support 2273 */ 2274int 2275sysctl_watchdog(char *string, char **bufpp, int mib[], int flags, 2276 int *typep) 2277{ 2278 int indx; 2279 2280 if (*bufpp == NULL) { 2281 listall(string, &watchdoglist); 2282 return (-1); 2283 } 2284 if ((indx = findname(string, "third", bufpp, &watchdoglist)) == -1) 2285 return (-1); 2286 mib[2] = indx; 2287 *typep = watchdoglist.list[indx].ctl_type; 2288 return (3); 2289} 2290 2291/* 2292 * Handle timecounter support 2293 */ 2294int 2295sysctl_tc(char *string, char **bufpp, int mib[], int flags, 2296 int *typep) 2297{ 2298 int indx; 2299 2300 if (*bufpp == NULL) { 2301 listall(string, &tclist); 2302 return (-1); 2303 } 2304 if ((indx = findname(string, "third", bufpp, &tclist)) == -1) 2305 return (-1); 2306 mib[2] = indx; 2307 *typep = tclist.list[indx].ctl_type; 2308 return (3); 2309} 2310 2311/* 2312 * Handle hardware monitoring sensors support 2313 */ 2314int 2315sysctl_sensors(char *string, char **bufpp, int mib[], int flags, int *typep) 2316{ 2317 char *devname, *typename; 2318 int dev, numt, i; 2319 enum sensor_type type; 2320 struct sensordev snsrdev; 2321 size_t sdlen = sizeof(snsrdev); 2322 2323 if (*bufpp == NULL) { 2324 char buf[SYSCTL_BUFSIZ]; 2325 2326 /* scan all sensor devices */ 2327 for (dev = 0; ; dev++) { 2328 mib[2] = dev; 2329 if (sysctl(mib, 3, &snsrdev, &sdlen, NULL, 0) == -1) { 2330 if (errno == ENXIO) 2331 continue; 2332 if (errno == ENOENT) 2333 break; 2334 } 2335 snprintf(buf, sizeof(buf), "%s.%s", 2336 string, snsrdev.xname); 2337 print_sensordev(buf, mib, 3, &snsrdev); 2338 } 2339 return (-1); 2340 } 2341 2342 /* 2343 * If we get this far, it means that some arguments were 2344 * provided below hw.sensors tree. 2345 * The first branch of hw.sensors tree is the device name. 2346 */ 2347 if ((devname = strsep(bufpp, ".")) == NULL) { 2348 warnx("%s: incomplete specification", string); 2349 return (-1); 2350 } 2351 /* convert sensor device string to an integer */ 2352 for (dev = 0; ; dev++) { 2353 mib[2] = dev; 2354 if (sysctl(mib, 3, &snsrdev, &sdlen, NULL, 0) == -1) { 2355 if (errno == ENXIO) 2356 continue; 2357 if (errno == ENOENT) 2358 break; 2359 } 2360 if (strcmp(devname, snsrdev.xname) == 0) 2361 break; 2362 } 2363 if (strcmp(devname, snsrdev.xname) != 0) { 2364 warnx("%s: sensor device not found: %s", string, devname); 2365 return (-1); 2366 } 2367 if (*bufpp == NULL) { 2368 /* only device name was provided -- let's print all sensors 2369 * that are attached to the specified device 2370 */ 2371 print_sensordev(string, mib, 3, &snsrdev); 2372 return (-1); 2373 } 2374 2375 /* 2376 * At this point we have identified the sensor device, 2377 * now let's go further and identify sensor type. 2378 */ 2379 if ((typename = strsep(bufpp, ".")) == NULL) { 2380 warnx("%s: incomplete specification", string); 2381 return (-1); 2382 } 2383 numt = -1; 2384 for (i = 0; typename[i] != '\0'; i++) 2385 if (isdigit((unsigned char)typename[i])) { 2386 numt = atoi(&typename[i]); 2387 typename[i] = '\0'; 2388 break; 2389 } 2390 for (type = 0; type < SENSOR_MAX_TYPES; type++) 2391 if (strcmp(typename, sensor_type_s[type]) == 0) 2392 break; 2393 if (type == SENSOR_MAX_TYPES) { 2394 warnx("%s: sensor type not recognised: %s", string, typename); 2395 return (-1); 2396 } 2397 mib[3] = type; 2398 2399 /* 2400 * If no integer was provided after sensor_type, let's 2401 * print all sensors of the specified type. 2402 */ 2403 if (numt == -1) { 2404 print_sensordev(string, mib, 4, &snsrdev); 2405 return (-1); 2406 } 2407 2408 /* 2409 * At this point we know that we have received a direct request 2410 * via command-line for a specific sensor. Let's have the parse() 2411 * function deal with it further, and report any errors if such 2412 * sensor node does not exist. 2413 */ 2414 mib[4] = numt; 2415 *typep = CTLTYPE_STRUCT; 2416 return (5); 2417} 2418 2419/* 2420 * Print sensors from the specified device. 2421 */ 2422 2423void 2424print_sensordev(char *string, int mib[], u_int mlen, struct sensordev *snsrdev) 2425{ 2426 char buf[SYSCTL_BUFSIZ]; 2427 enum sensor_type type; 2428 2429 if (mlen == 3) { 2430 for (type = 0; type < SENSOR_MAX_TYPES; type++) { 2431 mib[3] = type; 2432 snprintf(buf, sizeof(buf), "%s.%s", 2433 string, sensor_type_s[type]); 2434 print_sensordev(buf, mib, mlen+1, snsrdev); 2435 } 2436 return; 2437 } 2438 2439 if (mlen == 4) { 2440 int numt; 2441 2442 type = mib[3]; 2443 for (numt = 0; numt < snsrdev->maxnumt[type]; numt++) { 2444 mib[4] = numt; 2445 snprintf(buf, sizeof(buf), "%s%u", string, numt); 2446 print_sensordev(buf, mib, mlen+1, snsrdev); 2447 } 2448 return; 2449 } 2450 2451 if (mlen == 5) { 2452 struct sensor snsr; 2453 size_t slen = sizeof(snsr); 2454 2455 /* this function is only printing sensors in bulk, so we 2456 * do not return any error messages if the requested sensor 2457 * is not found by sysctl(3) 2458 */ 2459 if (sysctl(mib, 5, &snsr, &slen, NULL, 0) == -1) 2460 return; 2461 2462 if (slen > 0 && (snsr.flags & SENSOR_FINVALID) == 0) { 2463 if (!nflag) 2464 printf("%s%s", string, equ); 2465 print_sensor(&snsr); 2466 printf("\n"); 2467 } 2468 return; 2469 } 2470} 2471 2472void 2473print_sensor(struct sensor *s) 2474{ 2475 const char *name; 2476 2477 if (s->flags & SENSOR_FUNKNOWN) 2478 printf("unknown"); 2479 else { 2480 switch (s->type) { 2481 case SENSOR_TEMP: 2482 printf("%.2f degC", 2483 (s->value - 273150000) / 1000000.0); 2484 break; 2485 case SENSOR_FANRPM: 2486 printf("%lld RPM", s->value); 2487 break; 2488 case SENSOR_VOLTS_DC: 2489 printf("%.2f VDC", s->value / 1000000.0); 2490 break; 2491 case SENSOR_VOLTS_AC: 2492 printf("%.2f VAC", s->value / 1000000.0); 2493 break; 2494 case SENSOR_OHMS: 2495 printf("%lld ohm", s->value); 2496 break; 2497 case SENSOR_WATTS: 2498 printf("%.2f W", s->value / 1000000.0); 2499 break; 2500 case SENSOR_AMPS: 2501 printf("%.2f A", s->value / 1000000.0); 2502 break; 2503 case SENSOR_WATTHOUR: 2504 printf("%.2f Wh", s->value / 1000000.0); 2505 break; 2506 case SENSOR_AMPHOUR: 2507 printf("%.2f Ah", s->value / 1000000.0); 2508 break; 2509 case SENSOR_INDICATOR: 2510 printf("%s", s->value ? "On" : "Off"); 2511 break; 2512 case SENSOR_INTEGER: 2513 printf("%lld", s->value); 2514 break; 2515 case SENSOR_PERCENT: 2516 printf("%.2f%%", s->value / 1000.0); 2517 break; 2518 case SENSOR_LUX: 2519 printf("%.2f lx", s->value / 1000000.0); 2520 break; 2521 case SENSOR_DRIVE: 2522 switch (s->value) { 2523 case SENSOR_DRIVE_EMPTY: 2524 name = "empty"; 2525 break; 2526 case SENSOR_DRIVE_READY: 2527 name = "ready"; 2528 break; 2529 case SENSOR_DRIVE_POWERUP: 2530 name = "powering up"; 2531 break; 2532 case SENSOR_DRIVE_ONLINE: 2533 name = "online"; 2534 break; 2535 case SENSOR_DRIVE_IDLE: 2536 name = "idle"; 2537 break; 2538 case SENSOR_DRIVE_ACTIVE: 2539 name = "active"; 2540 break; 2541 case SENSOR_DRIVE_REBUILD: 2542 name = "rebuilding"; 2543 break; 2544 case SENSOR_DRIVE_POWERDOWN: 2545 name = "powering down"; 2546 break; 2547 case SENSOR_DRIVE_FAIL: 2548 name = "failed"; 2549 break; 2550 case SENSOR_DRIVE_PFAIL: 2551 name = "degraded"; 2552 break; 2553 default: 2554 name = "unknown"; 2555 break; 2556 } 2557 printf(name); 2558 break; 2559 case SENSOR_TIMEDELTA: 2560 printf("%.6f secs", s->value / 1000000000.0); 2561 break; 2562 case SENSOR_HUMIDITY: 2563 printf("%.2f%%", s->value / 1000.0); 2564 break; 2565 case SENSOR_FREQ: 2566 printf("%.2f Hz", s->value / 1000000.0); 2567 break; 2568 case SENSOR_ANGLE: 2569 printf("%3.4f degrees", s->value / 1000000.0); 2570 break; 2571 case SENSOR_DISTANCE: 2572 printf("%.2f mm", s->value / 1000.0); 2573 break; 2574 case SENSOR_PRESSURE: 2575 printf("%.2f Pa", s->value / 1000.0); 2576 break; 2577 case SENSOR_ACCEL: 2578 printf("%2.4f m/s^2", s->value / 1000000.0); 2579 break; 2580 default: 2581 printf("unknown"); 2582 } 2583 } 2584 2585 if (s->desc[0] != '\0') 2586 printf(" (%s)", s->desc); 2587 2588 switch (s->status) { 2589 case SENSOR_S_UNSPEC: 2590 break; 2591 case SENSOR_S_OK: 2592 printf(", OK"); 2593 break; 2594 case SENSOR_S_WARN: 2595 printf(", WARNING"); 2596 break; 2597 case SENSOR_S_CRIT: 2598 printf(", CRITICAL"); 2599 break; 2600 case SENSOR_S_UNKNOWN: 2601 printf(", UNKNOWN"); 2602 break; 2603 } 2604 2605 if (s->tv.tv_sec) { 2606 time_t t = s->tv.tv_sec; 2607 char ct[26]; 2608 2609 ctime_r(&t, ct); 2610 ct[19] = '\0'; 2611 printf(", %s.%03ld", ct, s->tv.tv_usec / 1000); 2612 } 2613} 2614 2615struct emulname { 2616 char *name; 2617 int index; 2618} *emul_names; 2619int emul_num, nemuls; 2620int emul_init(void); 2621 2622int 2623sysctl_emul(char *string, char *newval, int flags) 2624{ 2625 int mib[4], enabled, i, old, print, found = 0; 2626 char *head, *target; 2627 size_t len; 2628 2629 if (emul_init() == -1) { 2630 warnx("emul_init: out of memory"); 2631 return (1); 2632 } 2633 2634 mib[0] = CTL_KERN; 2635 mib[1] = KERN_EMUL; 2636 mib[3] = KERN_EMUL_ENABLED; 2637 head = "kern.emul."; 2638 2639 if (aflag || strcmp(string, "kern.emul") == 0) { 2640 if (newval) { 2641 warnx("%s: specification is incomplete", string); 2642 return (1); 2643 } 2644 if (nflag) 2645 printf("%d\n", nemuls); 2646 else 2647 printf("%snemuls%s%d\n", head, equ, nemuls); 2648 for (i = 0; i < emul_num; i++) { 2649 if (emul_names[i].name == NULL) 2650 break; 2651 if (i > 0 && strcmp(emul_names[i].name, 2652 emul_names[i-1].name) == 0) 2653 continue; 2654 mib[2] = emul_names[i].index; 2655 len = sizeof(int); 2656 if (sysctl(mib, 4, &enabled, &len, NULL, 0) == -1) { 2657 warn("%s", string); 2658 continue; 2659 } 2660 if (nflag) 2661 printf("%d\n", enabled); 2662 else 2663 printf("%s%s%s%d\n", head, emul_names[i].name, 2664 equ, enabled); 2665 } 2666 return (0); 2667 } 2668 /* User specified a third level name */ 2669 target = strrchr(string, '.'); 2670 target++; 2671 if (strcmp(target, "nemuls") == 0) { 2672 if (newval) { 2673 warnx("Operation not permitted"); 2674 return (1); 2675 } 2676 if (nflag) 2677 printf("%d\n", nemuls); 2678 else 2679 printf("%snemuls = %d\n", head, nemuls); 2680 return (0); 2681 } 2682 print = 1; 2683 for (i = 0; i < emul_num; i++) { 2684 if (!emul_names[i].name || (strcmp(target, emul_names[i].name))) 2685 continue; 2686 found = 1; 2687 mib[2] = emul_names[i].index; 2688 len = sizeof(int); 2689 if (newval) { 2690 enabled = atoi(newval); 2691 if (sysctl(mib, 4, &old, &len, &enabled, len) == -1) { 2692 warn("%s", string); 2693 print = 0; 2694 continue; 2695 } 2696 if (print) { 2697 if (nflag) 2698 printf("%d\n", enabled); 2699 else 2700 printf("%s%s: %d -> %d\n", head, 2701 target, old, enabled); 2702 } 2703 } else { 2704 if (sysctl(mib, 4, &enabled, &len, NULL, 0) == -1) { 2705 warn("%s", string); 2706 continue; 2707 } 2708 if (print) { 2709 if (nflag) 2710 printf("%d\n", enabled); 2711 else 2712 printf("%s%s = %d\n", head, target, 2713 enabled); 2714 } 2715 } 2716 print = 0; 2717 } 2718 if (!found) 2719 warnx("third level name %s in kern.emul is invalid", 2720 string); 2721 return (0); 2722 2723 2724} 2725 2726static int 2727emulcmp(const void *m, const void *n) 2728{ 2729 const struct emulname *a = m, *b = n; 2730 2731 if (!a || !a->name) 2732 return 1; 2733 if (!b || !b->name) 2734 return -1; 2735 return (strcmp(a->name, b->name)); 2736} 2737 2738int 2739emul_init(void) 2740{ 2741 static int done; 2742 char string[16]; 2743 int mib[4], i; 2744 size_t len; 2745 2746 if (done) 2747 return (0); 2748 done = 1; 2749 2750 mib[0] = CTL_KERN; 2751 mib[1] = KERN_EMUL; 2752 mib[2] = KERN_EMUL_NUM; 2753 len = sizeof(int); 2754 if (sysctl(mib, 3, &emul_num, &len, NULL, 0) == -1) 2755 return (-1); 2756 2757 emul_names = calloc(emul_num, sizeof(*emul_names)); 2758 if (emul_names == NULL) 2759 return (-1); 2760 2761 nemuls = emul_num; 2762 for (i = 0; i < emul_num; i++) { 2763 emul_names[i].index = mib[2] = i + 1; 2764 mib[3] = KERN_EMUL_NAME; 2765 len = sizeof(string); 2766 if (sysctl(mib, 4, string, &len, NULL, 0) == -1) 2767 continue; 2768 if (strcmp(string, "native") == 0) 2769 continue; 2770 emul_names[i].name = strdup(string); 2771 if (emul_names[i].name == NULL) { 2772 free(emul_names); 2773 return (-1); 2774 } 2775 } 2776 qsort(emul_names, nemuls, sizeof(*emul_names), emulcmp); 2777 for (i = 0; i < emul_num; i++) { 2778 if (!emul_names[i].name || (i > 0 && 2779 strcmp(emul_names[i].name, emul_names[i - 1].name) == 0)) 2780 nemuls--; 2781 } 2782 return (0); 2783} 2784 2785/* 2786 * Scan a list of names searching for a particular name. 2787 */ 2788int 2789findname(char *string, char *level, char **bufp, struct list *namelist) 2790{ 2791 char *name; 2792 int i; 2793 2794 if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) { 2795 warnx("%s: incomplete specification", string); 2796 return (-1); 2797 } 2798 for (i = 0; i < namelist->size; i++) 2799 if (namelist->list[i].ctl_name != NULL && 2800 strcmp(name, namelist->list[i].ctl_name) == 0) 2801 break; 2802 if (i == namelist->size) { 2803 warnx("%s level name %s in %s is invalid", level, name, string); 2804 return (-1); 2805 } 2806 return (i); 2807} 2808 2809void 2810usage(void) 2811{ 2812 2813 (void)fprintf(stderr, 2814 "usage: sysctl [-Aan]\n" 2815 " sysctl [-n] name ...\n" 2816 " sysctl [-nq] name=value ...\n"); 2817 exit(1); 2818} 2819