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