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