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