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