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