sysctl.c revision 1.260
1/* $OpenBSD: sysctl.c,v 1.260 2024/02/11 21:29:12 bluhm 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 boottime = btp->tv_sec; 941 (void)printf("%s%s%s", string, equ, ctime(&boottime)); 942 } else 943 (void)printf("%lld\n", (long long)btp->tv_sec); 944 return; 945 } 946 if (special & BLKDEV) { 947 dev_t dev = *(dev_t *)buf; 948 949 if (!nflag) 950 (void)printf("%s%s%s\n", string, equ, 951 devname(dev, S_IFBLK)); 952 else 953 (void)printf("0x%x\n", dev); 954 return; 955 } 956 if (special & CHRDEV) { 957 dev_t dev = *(dev_t *)buf; 958 959 if (!nflag) 960 (void)printf("%s%s%s\n", string, equ, 961 devname(dev, S_IFCHR)); 962 else 963 (void)printf("0x%x\n", dev); 964 return; 965 } 966#ifdef CPU_BIOS 967 if (special & BIOSGEO) { 968 bios_diskinfo_t *pdi = (bios_diskinfo_t *)buf; 969 970 if (!nflag) 971 (void)printf("%s%s", string, equ); 972 (void)printf("bootdev = 0x%x, " 973 "cylinders = %u, heads = %u, sectors = %u\n", 974 pdi->bsd_dev, pdi->bios_cylinders, 975 pdi->bios_heads, pdi->bios_sectors); 976 return; 977 } 978 if (special & BIOSDEV) { 979 int dev = *(int*)buf; 980 981 if (!nflag) 982 (void)printf("%s%s", string, equ); 983 (void) printf("0x%02x\n", dev); 984 return; 985 } 986#endif 987 if (special & UNSIGNED) { 988 if (newsize == 0) { 989 if (!nflag) 990 (void)printf("%s%s", string, equ); 991 (void)printf("%u\n", *(u_int *)buf); 992 } else { 993 if (!qflag) { 994 if (!nflag) 995 (void)printf("%s: %u -> ", string, 996 *(u_int *)buf); 997 (void)printf("%u\n", *(u_int *)newval); 998 } 999 } 1000 return; 1001 } 1002 if (special & BADDYNAMIC) { 1003 u_int port, lastport; 1004 u_int32_t *baddynamic = (u_int32_t *)buf; 1005 1006 if (!qflag) { 1007 if (!nflag) 1008 (void)printf("%s%s", string, 1009 newsize ? ": " : equ); 1010 lastport = 0; 1011 for (port = 0; port < 65536; port++) 1012 if (DP_ISSET(baddynamic, port)) { 1013 (void)printf("%s%u", 1014 lastport ? "," : "", port); 1015 lastport = port; 1016 } 1017 if (newsize != 0) { 1018 if (!nflag) 1019 fputs(" -> ", stdout); 1020 baddynamic = (u_int32_t *)newval; 1021 lastport = 0; 1022 for (port = 0; port < 65536; port++) 1023 if (DP_ISSET(baddynamic, port)) { 1024 (void)printf("%s%u", 1025 lastport ? "," : "", port); 1026 lastport = port; 1027 } 1028 } 1029 (void)putchar('\n'); 1030 } 1031 return; 1032 } 1033 if (special & LONGARRAY) { 1034 long *la = (long *)buf; 1035 if (!nflag) 1036 printf("%s%s", string, equ); 1037 while (lal--) 1038 printf("%ld%s", *la++, lal? ",":""); 1039 putchar('\n'); 1040 return; 1041 } 1042 if (special & SENSORS) { 1043 struct sensor *s = (struct sensor *)buf; 1044 1045 if (size > 0 && (s->flags & SENSOR_FINVALID) == 0) { 1046 if (!nflag) 1047 printf("%s%s", string, equ); 1048 print_sensor(s); 1049 printf("\n"); 1050 } 1051 return; 1052 } 1053 if (special & TIMEOUT) { 1054 struct timeoutstat *tstat = (struct timeoutstat *)buf; 1055 1056 if (!nflag) 1057 printf("%s%s", string, equ); 1058 printf("added = %llu, cancelled = %llu, deleted = %llu, " 1059 "late = %llu, pending = %llu, readded = %llu, " 1060 "scheduled = %llu, rescheduled = %llu, " 1061 "run_softclock = %llu, run_thread = %llu, " 1062 "softclocks = %llu, thread_wakeups = %llu\n", 1063 tstat->tos_added, tstat->tos_cancelled, tstat->tos_deleted, 1064 tstat->tos_late, tstat->tos_pending, tstat->tos_readded, 1065 tstat->tos_scheduled, tstat->tos_rescheduled, 1066 tstat->tos_run_softclock, tstat->tos_run_thread, 1067 tstat->tos_softclocks, tstat->tos_thread_wakeups); 1068 return; 1069 } 1070 switch (type) { 1071 case CTLTYPE_INT: 1072 if (newsize == 0) { 1073 if (!nflag) 1074 (void)printf("%s%s", string, equ); 1075 if (special & HEX) 1076 (void)printf("0x%x\n", *(int *)buf); 1077 else 1078 (void)printf("%d\n", *(int *)buf); 1079 } else { 1080 if (!qflag) { 1081 if (!nflag) 1082 (void)printf("%s: %d -> ", string, 1083 *(int *)buf); 1084 if (special & HEX) 1085 (void)printf("0x%x\n", *(int *)newval); 1086 else 1087 (void)printf("%d\n", *(int *)newval); 1088 } 1089 } 1090 return; 1091 1092 case CTLTYPE_STRING: 1093 if (newval == NULL) { 1094 if (!nflag) 1095 (void)printf("%s%s", string, equ); 1096 if (special & HEX) { 1097 size_t i; 1098 for (i = 0; i < size; i++) { 1099 (void)printf("%02x", 1100 (unsigned char)buf[i]); 1101 } 1102 (void)printf("\n"); 1103 } else 1104 (void)puts(buf); 1105 } else if (!qflag) { 1106 if (!nflag) { 1107 (void)printf("%s: ", string); 1108 if (special & HEX) { 1109 size_t i; 1110 for (i = 0; i < size; i++) { 1111 (void)printf("%02x", 1112 (unsigned char)buf[i]); 1113 } 1114 } else 1115 (void)printf("%s", buf); 1116 1117 (void)printf(" -> "); 1118 } 1119 (void)puts(cp); 1120 } 1121 return; 1122 1123 case CTLTYPE_QUAD: 1124 if (newsize == 0) { 1125 int64_t tmp; 1126 1127 memcpy(&tmp, buf, sizeof tmp); 1128 if (!nflag) 1129 (void)printf("%s%s", string, equ); 1130 (void)printf("%lld\n", tmp); 1131 } else { 1132 int64_t tmp; 1133 1134 memcpy(&tmp, buf, sizeof tmp); 1135 if (!qflag) { 1136 if (!nflag) 1137 (void)printf("%s: %lld -> ", 1138 string, tmp); 1139 memcpy(&tmp, newval, sizeof tmp); 1140 (void)printf("%lld\n", tmp); 1141 } 1142 } 1143 return; 1144 1145 case CTLTYPE_STRUCT: 1146 warnx("%s: unknown structure returned", string); 1147 return; 1148 1149 default: 1150 case CTLTYPE_NODE: 1151 warnx("%s: unknown type returned", string); 1152 return; 1153 } 1154} 1155 1156static void 1157parse_ports(char *portspec, int *port, int *high_port) 1158{ 1159 char *dash; 1160 const char *errstr; 1161 1162 if ((dash = strchr(portspec, '-')) != NULL) 1163 *dash++ = '\0'; 1164 *port = strtonum(portspec, 0, 65535, &errstr); 1165 if (errstr != NULL) 1166 errx(1, "port is %s: %s", errstr, portspec); 1167 if (dash != NULL) { 1168 *high_port = strtonum(dash, 0, 65535, &errstr); 1169 if (errstr != NULL) 1170 errx(1, "high port is %s: %s", errstr, dash); 1171 if (*high_port < *port) 1172 errx(1, "high port %d is lower than %d", 1173 *high_port, *port); 1174 } else 1175 *high_port = *port; 1176} 1177 1178void 1179parse_baddynamic(int mib[], size_t len, char *string, void **newvalp, 1180 size_t *newsizep, int flags, int nflag) 1181{ 1182 static u_int32_t newbaddynamic[DP_MAPSIZE]; 1183 int port, high_port, baddynamic_loaded = 0, full_list_set = 0; 1184 size_t size; 1185 char action, *cp; 1186 1187 while (*newvalp && (cp = strsep((char **)newvalp, ", \t")) && *cp) { 1188 if (*cp == '+' || *cp == '-') { 1189 if (full_list_set) 1190 errx(1, "cannot mix +/- with full list"); 1191 action = *cp++; 1192 if (!baddynamic_loaded) { 1193 size = sizeof(newbaddynamic); 1194 if (sysctl(mib, len, newbaddynamic, 1195 &size, 0, 0) == -1) { 1196 if (flags == 0) 1197 return; 1198 if (!nflag) 1199 printf("%s: ", string); 1200 puts("kernel does not contain bad " 1201 "dynamic port tables"); 1202 return; 1203 } 1204 baddynamic_loaded = 1; 1205 } 1206 parse_ports(cp, &port, &high_port); 1207 for (; port <= high_port; port++) { 1208 if (action == '+') 1209 DP_SET(newbaddynamic, port); 1210 else 1211 DP_CLR(newbaddynamic, port); 1212 } 1213 } else { 1214 if (baddynamic_loaded) 1215 errx(1, "cannot mix +/- with full list"); 1216 if (!full_list_set) { 1217 bzero(newbaddynamic, sizeof(newbaddynamic)); 1218 full_list_set = 1; 1219 } 1220 parse_ports(cp, &port, &high_port); 1221 for (; port <= high_port; port++) 1222 DP_SET(newbaddynamic, port); 1223 } 1224 } 1225 *newvalp = (void *)newbaddynamic; 1226 *newsizep = sizeof(newbaddynamic); 1227} 1228 1229/* 1230 * Initialize the set of debugging names 1231 */ 1232void 1233debuginit(void) 1234{ 1235 int mib[3], loc, i; 1236 size_t size; 1237 1238 if (secondlevel[CTL_DEBUG].list != 0) 1239 return; 1240 secondlevel[CTL_DEBUG].list = debugname; 1241 mib[0] = CTL_DEBUG; 1242 mib[2] = CTL_DEBUG_NAME; 1243 for (loc = lastused, i = 0; i < CTL_DEBUG_MAXID; i++) { 1244 mib[1] = i; 1245 size = BUFSIZ - loc; 1246 if (sysctl(mib, 3, &names[loc], &size, NULL, 0) == -1) 1247 continue; 1248 debugname[i].ctl_name = &names[loc]; 1249 debugname[i].ctl_type = CTLTYPE_INT; 1250 loc += size; 1251 } 1252 lastused = loc; 1253} 1254 1255struct ctlname vfsgennames[] = CTL_VFSGENCTL_NAMES; 1256struct ctlname ffsname[] = FFS_NAMES; 1257struct ctlname nfsname[] = FS_NFS_NAMES; 1258struct ctlname fusefsname[] = FUSEFS_NAMES; 1259struct list *vfsvars; 1260int *vfs_typenums; 1261 1262/* 1263 * Initialize the set of filesystem names 1264 */ 1265void 1266vfsinit(void) 1267{ 1268 int mib[4], maxtypenum, cnt, loc, size; 1269 struct vfsconf vfc; 1270 size_t buflen; 1271 1272 if (secondlevel[CTL_VFS].list != 0) 1273 return; 1274 mib[0] = CTL_VFS; 1275 mib[1] = VFS_GENERIC; 1276 mib[2] = VFS_MAXTYPENUM; 1277 buflen = 4; 1278 if (sysctl(mib, 3, &maxtypenum, &buflen, NULL, 0) == -1) 1279 return; 1280 /* 1281 * We need to do 0..maxtypenum so add one, and then we offset them 1282 * all by (another) one by inserting VFS_GENERIC entries at zero 1283 */ 1284 maxtypenum += 2; 1285 if ((vfs_typenums = calloc(maxtypenum, sizeof(int))) == NULL) 1286 return; 1287 if ((vfsvars = calloc(maxtypenum, sizeof(*vfsvars))) == NULL) { 1288 free(vfs_typenums); 1289 return; 1290 } 1291 if ((vfsname = calloc(maxtypenum, sizeof(*vfsname))) == NULL) { 1292 free(vfs_typenums); 1293 free(vfsvars); 1294 return; 1295 } 1296 mib[2] = VFS_CONF; 1297 buflen = sizeof vfc; 1298 for (loc = lastused, cnt = 1; cnt < maxtypenum; cnt++) { 1299 mib[3] = cnt - 1; 1300 if (sysctl(mib, 4, &vfc, &buflen, NULL, 0) == -1) { 1301 if (errno == EOPNOTSUPP) 1302 continue; 1303 warn("vfsinit"); 1304 free(vfsname); 1305 free(vfsvars); 1306 free(vfs_typenums); 1307 return; 1308 } 1309 if (!strcmp(vfc.vfc_name, MOUNT_FFS)) { 1310 vfsvars[cnt].list = ffsname; 1311 vfsvars[cnt].size = FFS_MAXID; 1312 } 1313 if (!strcmp(vfc.vfc_name, MOUNT_NFS)) { 1314 vfsvars[cnt].list = nfsname; 1315 vfsvars[cnt].size = NFS_MAXID; 1316 } 1317 if (!strcmp(vfc.vfc_name, MOUNT_FUSEFS)) { 1318 vfsvars[cnt].list = fusefsname; 1319 vfsvars[cnt].size = FUSEFS_MAXID; 1320 } 1321 vfs_typenums[cnt] = vfc.vfc_typenum; 1322 strlcat(&names[loc], vfc.vfc_name, sizeof names - loc); 1323 vfsname[cnt].ctl_name = &names[loc]; 1324 vfsname[cnt].ctl_type = CTLTYPE_NODE; 1325 size = strlen(vfc.vfc_name) + 1; 1326 loc += size; 1327 } 1328 lastused = loc; 1329 1330 vfsname[0].ctl_name = "mounts"; 1331 vfsname[0].ctl_type = CTLTYPE_NODE; 1332 vfsvars[0].list = vfsname + 1; 1333 vfsvars[0].size = maxtypenum - 1; 1334 1335 secondlevel[CTL_VFS].list = vfsname; 1336 secondlevel[CTL_VFS].size = maxtypenum; 1337 return; 1338} 1339 1340int 1341sysctl_vfsgen(char *string, char **bufpp, int mib[], int flags, int *typep) 1342{ 1343 int indx; 1344 size_t size; 1345 struct vfsconf vfc; 1346 1347 if (*bufpp == NULL) { 1348 listall(string, vfsvars); 1349 return (-1); 1350 } 1351 1352 if ((indx = findname(string, "third", bufpp, vfsvars)) == -1) 1353 return (-1); 1354 1355 mib[1] = VFS_GENERIC; 1356 mib[2] = VFS_CONF; 1357 mib[3] = indx; 1358 size = sizeof vfc; 1359 if (sysctl(mib, 4, &vfc, &size, NULL, 0) == -1) { 1360 if (errno != EOPNOTSUPP) 1361 warn("vfs print"); 1362 return -1; 1363 } 1364 if (flags == 0 && vfc.vfc_refcount == 0) 1365 return -1; 1366 if (!nflag) 1367 fprintf(stdout, "%s has %u mounted instance%s\n", 1368 string, vfc.vfc_refcount, 1369 vfc.vfc_refcount != 1 ? "s" : ""); 1370 else 1371 fprintf(stdout, "%u\n", vfc.vfc_refcount); 1372 1373 return -1; 1374} 1375 1376int 1377sysctl_vfs(char *string, char **bufpp, int mib[], int flags, int *typep) 1378{ 1379 struct list *lp = &vfsvars[mib[1]]; 1380 int indx; 1381 1382 if (lp->list == NULL) { 1383 if (flags) 1384 warnx("No variables defined for file system %s", string); 1385 return (-1); 1386 } 1387 if (*bufpp == NULL) { 1388 listall(string, lp); 1389 return (-1); 1390 } 1391 if ((indx = findname(string, "third", bufpp, lp)) == -1) 1392 return (-1); 1393 1394 mib[1] = vfs_typenums[mib[1]]; 1395 mib[2] = indx; 1396 *typep = lp->list[indx].ctl_type; 1397 return (3); 1398} 1399 1400struct ctlname posixname[] = CTL_FS_POSIX_NAMES; 1401struct list fslist = { posixname, FS_POSIX_MAXID }; 1402 1403/* 1404 * handle file system requests 1405 */ 1406int 1407sysctl_fs(char *string, char **bufpp, int mib[], int flags, int *typep) 1408{ 1409 int indx; 1410 1411 if (*bufpp == NULL) { 1412 listall(string, &fslist); 1413 return (-1); 1414 } 1415 if ((indx = findname(string, "third", bufpp, &fslist)) == -1) 1416 return (-1); 1417 mib[2] = indx; 1418 *typep = fslist.list[indx].ctl_type; 1419 return (3); 1420} 1421 1422#ifdef CPU_BIOS 1423struct ctlname biosname[] = CTL_BIOS_NAMES; 1424struct list bioslist = { biosname, BIOS_MAXID }; 1425 1426/* 1427 * handle BIOS requests 1428 */ 1429int 1430sysctl_bios(char *string, char **bufpp, int mib[], int flags, int *typep) 1431{ 1432 char *name; 1433 int indx; 1434 1435 if (*bufpp == NULL) { 1436 listall(string, &bioslist); 1437 return (-1); 1438 } 1439 if ((indx = findname(string, "third", bufpp, &bioslist)) == -1) 1440 return (-1); 1441 mib[2] = indx; 1442 if (indx == BIOS_DISKINFO) { 1443 const char *errstr; 1444 1445 if (*bufpp == NULL) { 1446 char name[BUFSIZ]; 1447 1448 /* scan all the bios devices */ 1449 for (indx = 0; indx < 256; indx++) { 1450 snprintf(name, sizeof(name), "%s.%u", 1451 string, indx); 1452 parse(name, 1); 1453 } 1454 return (-1); 1455 } 1456 if ((name = strsep(bufpp, ".")) == NULL) { 1457 warnx("%s: incomplete specification", string); 1458 return (-1); 1459 } 1460 mib[3] = strtonum(name, 0, INT_MAX, &errstr); 1461 if (errstr) { 1462 warnx("%s: %s", string, errstr); 1463 return (-1); 1464 } 1465 *typep = CTLTYPE_STRUCT; 1466 return (4); 1467 } else { 1468 *typep = bioslist.list[indx].ctl_type; 1469 return (3); 1470 } 1471} 1472#endif 1473 1474struct ctlname swpencname[] = CTL_SWPENC_NAMES; 1475struct list swpenclist = { swpencname, SWPENC_MAXID }; 1476 1477/* 1478 * handle swap encrypt requests 1479 */ 1480int 1481sysctl_swpenc(char *string, char **bufpp, int mib[], int flags, int *typep) 1482{ 1483 int indx; 1484 1485 if (*bufpp == NULL) { 1486 listall(string, &swpenclist); 1487 return (-1); 1488 } 1489 if ((indx = findname(string, "third", bufpp, &swpenclist)) == -1) 1490 return (-1); 1491 mib[2] = indx; 1492 *typep = swpenclist.list[indx].ctl_type; 1493 return (3); 1494} 1495 1496struct ctlname inetname[] = CTL_IPPROTO_NAMES; 1497struct ctlname ipname[] = IPCTL_NAMES; 1498struct ctlname icmpname[] = ICMPCTL_NAMES; 1499struct ctlname igmpname[] = IGMPCTL_NAMES; 1500struct ctlname ipipname[] = IPIPCTL_NAMES; 1501struct ctlname tcpname[] = TCPCTL_NAMES; 1502struct ctlname udpname[] = UDPCTL_NAMES; 1503struct ctlname espname[] = ESPCTL_NAMES; 1504struct ctlname ahname[] = AHCTL_NAMES; 1505struct ctlname etheripname[] = ETHERIPCTL_NAMES; 1506struct ctlname grename[] = GRECTL_NAMES; 1507struct ctlname ipcompname[] = IPCOMPCTL_NAMES; 1508struct ctlname carpname[] = CARPCTL_NAMES; 1509struct ctlname pfsyncname[] = PFSYNCCTL_NAMES; 1510struct ctlname divertname[] = DIVERTCTL_NAMES; 1511struct ctlname bpfname[] = CTL_NET_BPF_NAMES; 1512struct ctlname ifqname[] = CTL_IFQ_NAMES; 1513struct ctlname pipexname[] = PIPEXCTL_NAMES; 1514struct list inetlist = { inetname, IPPROTO_MAXID }; 1515struct list inetvars[] = { 1516 { ipname, IPCTL_MAXID }, /* ip */ 1517 { icmpname, ICMPCTL_MAXID }, /* icmp */ 1518 { igmpname, IGMPCTL_MAXID }, /* igmp */ 1519 { 0, 0 }, /* ggmp */ 1520 { ipipname, IPIPCTL_MAXID }, /* ipencap */ 1521 { 0, 0 }, 1522 { tcpname, TCPCTL_MAXID }, /* tcp */ 1523 { 0, 0 }, 1524 { 0, 0 }, /* egp */ 1525 { 0, 0 }, 1526 { 0, 0 }, 1527 { 0, 0 }, 1528 { 0, 0 }, /* pup */ 1529 { 0, 0 }, 1530 { 0, 0 }, 1531 { 0, 0 }, 1532 { 0, 0 }, 1533 { udpname, UDPCTL_MAXID }, /* udp */ 1534 { 0, 0 }, 1535 { 0, 0 }, 1536 { 0, 0 }, 1537 { 0, 0 }, 1538 { 0, 0 }, 1539 { 0, 0 }, 1540 { 0, 0 }, 1541 { 0, 0 }, 1542 { 0, 0 }, 1543 { 0, 0 }, 1544 { 0, 0 }, 1545 { 0, 0 }, 1546 { 0, 0 }, 1547 { 0, 0 }, 1548 { 0, 0 }, 1549 { 0, 0 }, 1550 { 0, 0 }, 1551 { 0, 0 }, 1552 { 0, 0 }, 1553 { 0, 0 }, 1554 { 0, 0 }, 1555 { 0, 0 }, 1556 { 0, 0 }, 1557 { 0, 0 }, 1558 { 0, 0 }, 1559 { 0, 0 }, 1560 { 0, 0 }, 1561 { 0, 0 }, 1562 { 0, 0 }, 1563 { grename, GRECTL_MAXID }, /* gre */ 1564 { 0, 0 }, 1565 { 0, 0 }, 1566 { espname, ESPCTL_MAXID }, /* esp */ 1567 { ahname, AHCTL_MAXID }, /* ah */ 1568 { 0, 0 }, 1569 { 0, 0 }, 1570 { 0, 0 }, 1571 { 0, 0 }, 1572 { 0, 0 }, 1573 { 0, 0 }, 1574 { 0, 0 }, 1575 { 0, 0 }, 1576 { 0, 0 }, 1577 { 0, 0 }, 1578 { 0, 0 }, 1579 { 0, 0 }, 1580 { 0, 0 }, 1581 { 0, 0 }, 1582 { 0, 0 }, 1583 { 0, 0 }, 1584 { 0, 0 }, 1585 { 0, 0 }, 1586 { 0, 0 }, 1587 { 0, 0 }, 1588 { 0, 0 }, 1589 { 0, 0 }, 1590 { 0, 0 }, 1591 { 0, 0 }, 1592 { 0, 0 }, 1593 { 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 { etheripname, ETHERIPCTL_MAXID }, 1614 { 0, 0 }, 1615 { 0, 0 }, 1616 { 0, 0 }, 1617 { 0, 0 }, 1618 { 0, 0 }, 1619 { 0, 0 }, 1620 { 0, 0 }, 1621 { 0, 0 }, 1622 { 0, 0 }, 1623 { 0, 0 }, 1624 { ipcompname, IPCOMPCTL_MAXID }, 1625 { 0, 0 }, 1626 { 0, 0 }, 1627 { 0, 0 }, 1628 { carpname, CARPCTL_MAXID }, 1629 { 0, 0 }, 1630 { 0, 0 }, 1631 { 0, 0 }, 1632 { 0, 0 }, 1633 { 0, 0 }, 1634 { 0, 0 }, 1635 { 0, 0 }, 1636 { 0, 0 }, 1637 { 0, 0 }, 1638 { 0, 0 }, 1639 { 0, 0 }, 1640 { 0, 0 }, 1641 { 0, 0 }, 1642 { 0, 0 }, 1643 { 0, 0 }, 1644 { 0, 0 }, 1645 { 0, 0 }, 1646 { 0, 0 }, 1647 { 0, 0 }, 1648 { 0, 0 }, 1649 { 0, 0 }, 1650 { 0, 0 }, 1651 { 0, 0 }, 1652 { 0, 0 }, 1653 { 0, 0 }, 1654 { 0, 0 }, 1655 { 0, 0 }, 1656 { 0, 0 }, 1657 { 0, 0 }, 1658 { 0, 0 }, 1659 { 0, 0 }, 1660 { 0, 0 }, 1661 { 0, 0 }, 1662 { 0, 0 }, 1663 { 0, 0 }, 1664 { 0, 0 }, 1665 { 0, 0 }, 1666 { 0, 0 }, 1667 { 0, 0 }, 1668 { 0, 0 }, 1669 { 0, 0 }, 1670 { 0, 0 }, 1671 { 0, 0 }, 1672 { 0, 0 }, 1673 { 0, 0 }, 1674 { 0, 0 }, 1675 { 0, 0 }, 1676 { 0, 0 }, 1677 { 0, 0 }, 1678 { 0, 0 }, 1679 { 0, 0 }, 1680 { 0, 0 }, 1681 { 0, 0 }, 1682 { 0, 0 }, 1683 { 0, 0 }, 1684 { 0, 0 }, 1685 { 0, 0 }, 1686 { 0, 0 }, 1687 { 0, 0 }, 1688 { 0, 0 }, 1689 { 0, 0 }, 1690 { 0, 0 }, 1691 { 0, 0 }, 1692 { 0, 0 }, 1693 { 0, 0 }, 1694 { 0, 0 }, 1695 { 0, 0 }, 1696 { 0, 0 }, 1697 { 0, 0 }, 1698 { 0, 0 }, 1699 { 0, 0 }, 1700 { 0, 0 }, 1701 { 0, 0 }, 1702 { 0, 0 }, 1703 { 0, 0 }, 1704 { 0, 0 }, 1705 { 0, 0 }, 1706 { 0, 0 }, 1707 { 0, 0 }, 1708 { 0, 0 }, 1709 { 0, 0 }, 1710 { 0, 0 }, 1711 { 0, 0 }, 1712 { 0, 0 }, 1713 { 0, 0 }, 1714 { 0, 0 }, 1715 { 0, 0 }, 1716 { 0, 0 }, 1717 { 0, 0 }, 1718 { 0, 0 }, 1719 { 0, 0 }, 1720 { 0, 0 }, 1721 { 0, 0 }, 1722 { 0, 0 }, 1723 { 0, 0 }, 1724 { 0, 0 }, 1725 { 0, 0 }, 1726 { 0, 0 }, 1727 { 0, 0 }, 1728 { 0, 0 }, 1729 { 0, 0 }, 1730 { 0, 0 }, 1731 { 0, 0 }, 1732 { 0, 0 }, 1733 { 0, 0 }, 1734 { 0, 0 }, 1735 { 0, 0 }, 1736 { 0, 0 }, 1737 { 0, 0 }, 1738 { 0, 0 }, 1739 { 0, 0 }, 1740 { 0, 0 }, 1741 { 0, 0 }, 1742 { 0, 0 }, 1743 { 0, 0 }, 1744 { 0, 0 }, 1745 { 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 { pfsyncname, PFSYNCCTL_MAXID }, 1766 { 0, 0 }, 1767 { 0, 0 }, 1768 { 0, 0 }, 1769 { 0, 0 }, 1770 { 0, 0 }, 1771 { 0, 0 }, 1772 { 0, 0 }, 1773 { 0, 0 }, 1774 { divertname, DIVERTCTL_MAXID }, 1775}; 1776struct list bpflist = { bpfname, NET_BPF_MAXID }; 1777struct list ifqlist = { ifqname, IFQCTL_MAXID }; 1778struct list pipexlist = { pipexname, PIPEXCTL_MAXID }; 1779 1780struct list kernmalloclist = { kernmallocname, KERN_MALLOC_MAXID }; 1781struct list forkstatlist = { forkstatname, KERN_FORKSTAT_MAXID }; 1782struct list nchstatslist = { nchstatsname, KERN_NCHSTATS_MAXID }; 1783struct list ttylist = { ttysname, KERN_TTY_MAXID }; 1784struct list semlist = { semname, KERN_SEMINFO_MAXID }; 1785struct list shmlist = { shmname, KERN_SHMINFO_MAXID }; 1786struct list watchdoglist = { watchdogname, KERN_WATCHDOG_MAXID }; 1787struct list tclist = { tcname, KERN_TIMECOUNTER_MAXID }; 1788struct list audiolist = { audioname, KERN_AUDIO_MAXID }; 1789struct list videolist = { videoname, KERN_VIDEO_MAXID }; 1790struct list witnesslist = { witnessname, KERN_WITNESS_MAXID }; 1791struct list batterylist = { batteryname, HW_BATTERY_MAXID }; 1792 1793/* 1794 * handle vfs namei cache statistics 1795 */ 1796int 1797sysctl_nchstats(char *string, char **bufpp, int mib[], int flags, int *typep) 1798{ 1799 static struct nchstats nch; 1800 int indx; 1801 size_t size; 1802 static int keepvalue = 0; 1803 1804 if (*bufpp == NULL) { 1805 bzero(&nch, sizeof(struct nchstats)); 1806 listall(string, &nchstatslist); 1807 return (-1); 1808 } 1809 if ((indx = findname(string, "third", bufpp, &nchstatslist)) == -1) 1810 return (-1); 1811 mib[2] = indx; 1812 if (*bufpp != NULL) { 1813 warnx("fourth level name in %s is invalid", string); 1814 return (-1); 1815 } 1816 if (keepvalue == 0) { 1817 size = sizeof(struct nchstats); 1818 if (sysctl(mib, 2, &nch, &size, NULL, 0) == -1) 1819 return (-1); 1820 keepvalue = 1; 1821 } 1822 if (!nflag) 1823 (void)printf("%s%s", string, equ); 1824 switch (indx) { 1825 case KERN_NCHSTATS_GOODHITS: 1826 (void)printf("%llu\n", nch.ncs_goodhits); 1827 break; 1828 case KERN_NCHSTATS_NEGHITS: 1829 (void)printf("%llu\n", nch.ncs_neghits); 1830 break; 1831 case KERN_NCHSTATS_BADHITS: 1832 (void)printf("%llu\n", nch.ncs_badhits); 1833 break; 1834 case KERN_NCHSTATS_FALSEHITS: 1835 (void)printf("%llu\n", nch.ncs_falsehits); 1836 break; 1837 case KERN_NCHSTATS_MISS: 1838 (void)printf("%llu\n", nch.ncs_miss); 1839 break; 1840 case KERN_NCHSTATS_LONG: 1841 (void)printf("%llu\n", nch.ncs_long); 1842 break; 1843 case KERN_NCHSTATS_PASS2: 1844 (void)printf("%llu\n", nch.ncs_pass2); 1845 break; 1846 case KERN_NCHSTATS_2PASSES: 1847 (void)printf("%llu\n", nch.ncs_2passes); 1848 break; 1849 case KERN_NCHSTATS_REVHITS: 1850 (void)printf("%llu\n", nch.ncs_revhits); 1851 break; 1852 case KERN_NCHSTATS_REVMISS: 1853 (void)printf("%llu\n", nch.ncs_revmiss); 1854 break; 1855 case KERN_NCHSTATS_DOTHITS: 1856 (void)printf("%llu\n", nch.ncs_dothits); 1857 break; 1858 case KERN_NCHSTATS_DOTDOTHITS: 1859 (void)printf("%llu\n", nch.ncs_dotdothits); 1860 break; 1861 } 1862 return (-1); 1863} 1864 1865/* 1866 * handle tty statistics 1867 */ 1868int 1869sysctl_tty(char *string, char **bufpp, int mib[], int flags, int *typep) 1870{ 1871 int indx; 1872 1873 if (*bufpp == NULL) { 1874 listall(string, &ttylist); 1875 return (-1); 1876 } 1877 if ((indx = findname(string, "third", bufpp, &ttylist)) == -1) 1878 return (-1); 1879 mib[2] = indx; 1880 1881 if ((*typep = ttylist.list[indx].ctl_type) == CTLTYPE_STRUCT) { 1882 if (flags) 1883 warnx("use pstat -t to view %s information", 1884 string); 1885 return (-1); 1886 } 1887 return (3); 1888} 1889 1890/* 1891 * handle fork statistics 1892 */ 1893int 1894sysctl_forkstat(char *string, char **bufpp, int mib[], int flags, int *typep) 1895{ 1896 static struct forkstat fks; 1897 static int keepvalue = 0; 1898 int indx; 1899 size_t size; 1900 1901 if (*bufpp == NULL) { 1902 bzero(&fks, sizeof(struct forkstat)); 1903 listall(string, &forkstatlist); 1904 return (-1); 1905 } 1906 if ((indx = findname(string, "third", bufpp, &forkstatlist)) == -1) 1907 return (-1); 1908 if (*bufpp != NULL) { 1909 warnx("fourth level name in %s is invalid", string); 1910 return (-1); 1911 } 1912 if (keepvalue == 0) { 1913 size = sizeof(struct forkstat); 1914 if (sysctl(mib, 2, &fks, &size, NULL, 0) == -1) 1915 return (-1); 1916 keepvalue = 1; 1917 } 1918 if (!nflag) 1919 (void)printf("%s%s", string, equ); 1920 switch (indx) { 1921 case KERN_FORKSTAT_FORK: 1922 (void)printf("%u\n", fks.cntfork); 1923 break; 1924 case KERN_FORKSTAT_VFORK: 1925 (void)printf("%u\n", fks.cntvfork); 1926 break; 1927 case KERN_FORKSTAT_TFORK: 1928 (void)printf("%u\n", fks.cnttfork); 1929 break; 1930 case KERN_FORKSTAT_KTHREAD: 1931 (void)printf("%u\n", fks.cntkthread); 1932 break; 1933 case KERN_FORKSTAT_SIZFORK: 1934 (void)printf("%llu\n", fks.sizfork); 1935 break; 1936 case KERN_FORKSTAT_SIZVFORK: 1937 (void)printf("%llu\n", fks.sizvfork); 1938 break; 1939 case KERN_FORKSTAT_SIZTFORK: 1940 (void)printf("%llu\n", fks.siztfork); 1941 break; 1942 case KERN_FORKSTAT_SIZKTHREAD: 1943 (void)printf("%llu\n", fks.sizkthread); 1944 break; 1945 } 1946 return (-1); 1947} 1948 1949/* 1950 * handle malloc statistics 1951 */ 1952int 1953sysctl_malloc(char *string, char **bufpp, int mib[], int flags, int *typep) 1954{ 1955 int indx, stor, i; 1956 char *name, bufp[SYSCTL_BUFSIZ], *buf, *ptr; 1957 const char *errstr; 1958 struct list lp; 1959 size_t size; 1960 1961 if (*bufpp == NULL) { 1962 listall(string, &kernmalloclist); 1963 return (-1); 1964 } 1965 if ((indx = findname(string, "third", bufpp, &kernmalloclist)) == -1) 1966 return (-1); 1967 mib[2] = indx; 1968 if (mib[2] == KERN_MALLOC_BUCKET) { 1969 if ((name = strsep(bufpp, ".")) == NULL) { 1970 size = SYSCTL_BUFSIZ; 1971 stor = mib[2]; 1972 mib[2] = KERN_MALLOC_BUCKETS; 1973 buf = bufp; 1974 if (sysctl(mib, 3, buf, &size, NULL, 0) == -1) 1975 return (-1); 1976 mib[2] = stor; 1977 for (stor = 0, i = 0; i < size; i++) 1978 if (buf[i] == ',') 1979 stor++; 1980 lp.list = calloc(stor + 2, sizeof(struct ctlname)); 1981 if (lp.list == NULL) 1982 return (-1); 1983 lp.size = stor + 2; 1984 for (i = 1; (ptr = strsep(&buf, ",")) != NULL; i++) { 1985 lp.list[i].ctl_name = ptr; 1986 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1987 } 1988 listall(string, &lp); 1989 free(lp.list); 1990 return (-1); 1991 } 1992 mib[3] = strtonum(name, 0, INT_MAX, &errstr); 1993 if (errstr) 1994 return -1; 1995 return (4); 1996 } else if (mib[2] == KERN_MALLOC_BUCKETS) { 1997 *typep = CTLTYPE_STRING; 1998 return (3); 1999 } else if (mib[2] == KERN_MALLOC_KMEMSTATS) { 2000 size = SYSCTL_BUFSIZ; 2001 stor = mib[2]; 2002 mib[2] = KERN_MALLOC_KMEMNAMES; 2003 buf = bufp; 2004 if (sysctl(mib, 3, buf, &size, NULL, 0) == -1) 2005 return (-1); 2006 mib[2] = stor; 2007 if ((name = strsep(bufpp, ".")) == NULL) { 2008 for (stor = 0, i = 0; i < size; i++) 2009 if (buf[i] == ',') 2010 stor++; 2011 lp.list = calloc(stor + 2, sizeof(struct ctlname)); 2012 if (lp.list == NULL) 2013 return (-1); 2014 lp.size = stor + 2; 2015 for (i = 1; (ptr = strsep(&buf, ",")) != NULL; i++) { 2016 if (ptr[0] == '\0') { 2017 i--; 2018 continue; 2019 } 2020 lp.list[i].ctl_name = ptr; 2021 lp.list[i].ctl_type = CTLTYPE_STRUCT; 2022 } 2023 listall(string, &lp); 2024 free(lp.list); 2025 return (-1); 2026 } 2027 ptr = strstr(buf, name); 2028 tryagain: 2029 if (ptr == NULL) { 2030 warnx("fourth level name %s in %s is invalid", name, 2031 string); 2032 return (-1); 2033 } 2034 if ((*(ptr + strlen(name)) != ',') && 2035 (*(ptr + strlen(name)) != '\0')) { 2036 ptr = strstr(ptr + 1, name); /* retry */ 2037 goto tryagain; 2038 } 2039 if ((ptr != buf) && (*(ptr - 1) != ',')) { 2040 ptr = strstr(ptr + 1, name); /* retry */ 2041 goto tryagain; 2042 } 2043 for (i = 0, stor = 0; buf + i < ptr; i++) 2044 if (buf[i] == ',') 2045 stor++; 2046 mib[3] = stor; 2047 return (4); 2048 } else if (mib[2] == KERN_MALLOC_KMEMNAMES) { 2049 *typep = CTLTYPE_STRING; 2050 return (3); 2051 } 2052 return (-1); 2053} 2054 2055#ifdef CPU_CHIPSET 2056/* 2057 * handle machdep.chipset requests 2058 */ 2059struct ctlname chipsetname[] = CTL_CHIPSET_NAMES; 2060struct list chipsetlist = { chipsetname, CPU_CHIPSET_MAXID }; 2061 2062int 2063sysctl_chipset(char *string, char **bufpp, int mib[], int flags, int *typep) 2064{ 2065 int indx, bwx; 2066 static void *q; 2067 size_t len; 2068 char *p; 2069 2070 if (*bufpp == NULL) { 2071 listall(string, &chipsetlist); 2072 return (-1); 2073 } 2074 if ((indx = findname(string, "third", bufpp, &chipsetlist)) == -1) 2075 return (-1); 2076 mib[2] = indx; 2077 if (!nflag) 2078 printf("%s%s", string, equ); 2079 switch(mib[2]) { 2080 case CPU_CHIPSET_MEM: 2081 case CPU_CHIPSET_DENSE: 2082 case CPU_CHIPSET_PORTS: 2083 case CPU_CHIPSET_HAE_MASK: 2084 len = sizeof(void *); 2085 if (sysctl(mib, 3, &q, &len, NULL, 0) == -1) 2086 goto done; 2087 printf("%p", q); 2088 break; 2089 case CPU_CHIPSET_BWX: 2090 len = sizeof(int); 2091 if (sysctl(mib, 3, &bwx, &len, NULL, 0) == -1) 2092 goto done; 2093 printf("%d", bwx); 2094 break; 2095 case CPU_CHIPSET_TYPE: 2096 if (sysctl(mib, 3, NULL, &len, NULL, 0) == -1) 2097 goto done; 2098 p = malloc(len + 1); 2099 if (p == NULL) 2100 goto done; 2101 if (sysctl(mib, 3, p, &len, NULL, 0) == -1) { 2102 free(p); 2103 goto done; 2104 } 2105 p[len] = '\0'; 2106 printf("%s", p); 2107 free(p); 2108 break; 2109 } 2110done: 2111 printf("\n"); 2112 return (-1); 2113} 2114#endif 2115/* 2116 * handle internet requests 2117 */ 2118int 2119sysctl_inet(char *string, char **bufpp, int mib[], int flags, int *typep) 2120{ 2121 struct list *lp; 2122 int indx; 2123 2124 if (*bufpp == NULL) { 2125 listall(string, &inetlist); 2126 return (-1); 2127 } 2128 if ((indx = findname(string, "third", bufpp, &inetlist)) == -1) 2129 return (-1); 2130 mib[2] = indx; 2131 if (indx < IPPROTO_MAXID && inetvars[indx].list != NULL) 2132 lp = &inetvars[indx]; 2133 else if (!flags) 2134 return (-1); 2135 else { 2136 warnx("%s: no variables defined for this protocol", string); 2137 return (-1); 2138 } 2139 if (*bufpp == NULL) { 2140 listall(string, lp); 2141 return (-1); 2142 } 2143 if ((indx = findname(string, "fourth", bufpp, lp)) == -1) 2144 return (-1); 2145 mib[3] = indx; 2146 *typep = lp->list[indx].ctl_type; 2147 if (*typep == CTLTYPE_NODE) { 2148 int tindx; 2149 2150 if (*bufpp == NULL) { 2151 listall(string, &ifqlist); 2152 return(-1); 2153 } 2154 lp = &ifqlist; 2155 if ((tindx = findname(string, "fifth", bufpp, lp)) == -1) 2156 return (-1); 2157 mib[4] = tindx; 2158 *typep = lp->list[tindx].ctl_type; 2159 return(5); 2160 } 2161 return (4); 2162} 2163 2164struct ctlname inet6name[] = CTL_IPV6PROTO_NAMES; 2165struct ctlname ip6name[] = IPV6CTL_NAMES; 2166struct ctlname icmp6name[] = ICMPV6CTL_NAMES; 2167struct ctlname divert6name[] = DIVERT6CTL_NAMES; 2168struct list inet6list = { inet6name, IPV6PROTO_MAXID }; 2169struct list inet6vars[] = { 2170/*0*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2171 { 0, 0 }, 2172 { 0, 0 }, 2173 { 0, 0 }, 2174 { 0, 0 }, 2175 { 0, 0 }, 2176/*10*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2177 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2178/*20*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2179 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2180/*30*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2181 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2182/*40*/ { 0, 0 }, 2183 { ip6name, IPV6CTL_MAXID }, /* ipv6 */ 2184 { 0, 0 }, 2185 { 0, 0 }, 2186 { 0, 0 }, 2187 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2188/*50*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2189 { 0, 0 }, 2190 { 0, 0 }, 2191 { 0, 0 }, 2192 { icmp6name, ICMPV6CTL_MAXID }, /* icmp6 */ 2193 { 0, 0 }, 2194/*60*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2195 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2196/*70*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2197 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2198/*80*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2199 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2200/*90*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2201 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2202/*100*/ { 0, 0 }, 2203 { 0, 0 }, 2204 { 0, 0 }, 2205 { 0, 0 }, /* pim6 */ 2206 { 0, 0 }, 2207 { 0, 0 }, 2208 { 0, 0 }, 2209 { 0, 0 }, 2210 { 0, 0 }, 2211 { 0, 0 }, 2212/*110*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2213 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2214/*120*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2215 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2216/*130*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2217 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2218/*140*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2219 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2220/*150*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2221 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2222/*160*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2223 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2224/*170*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2225 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2226/*180*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2227 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2228/*190*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2229 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2230/*200*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2231 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2232/*210*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2233 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2234/*220*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2235 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2236/*230*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2237 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2238/*240*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2239 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2240/*250*/ { 0, 0 }, 2241 { 0, 0 }, 2242 { 0, 0 }, 2243 { 0, 0 }, 2244 { 0, 0 }, 2245 { 0, 0 }, 2246 { 0, 0 }, 2247 { 0, 0 }, 2248 { divert6name, DIVERT6CTL_MAXID }, 2249}; 2250 2251/* 2252 * handle internet6 requests 2253 */ 2254int 2255sysctl_inet6(char *string, char **bufpp, int mib[], int flags, int *typep) 2256{ 2257 struct list *lp; 2258 int indx; 2259 2260 if (*bufpp == NULL) { 2261 listall(string, &inet6list); 2262 return (-1); 2263 } 2264 if ((indx = findname(string, "third", bufpp, &inet6list)) == -1) 2265 return (-1); 2266 mib[2] = indx; 2267 if (indx < IPV6PROTO_MAXID && inet6vars[indx].list != NULL) 2268 lp = &inet6vars[indx]; 2269 else if (!flags) 2270 return (-1); 2271 else { 2272 warnx("%s: no variables defined for this protocol", string); 2273 return (-1); 2274 } 2275 if (*bufpp == NULL) { 2276 listall(string, lp); 2277 return (-1); 2278 } 2279 if ((indx = findname(string, "fourth", bufpp, lp)) == -1) 2280 return (-1); 2281 mib[3] = indx; 2282 *typep = lp->list[indx].ctl_type; 2283 if (*typep == CTLTYPE_NODE) { 2284 int tindx; 2285 2286 if (*bufpp == NULL) { 2287 listall(string, &ifqlist); 2288 return(-1); 2289 } 2290 lp = &ifqlist; 2291 if ((tindx = findname(string, "fifth", bufpp, lp)) == -1) 2292 return (-1); 2293 mib[4] = tindx; 2294 *typep = lp->list[tindx].ctl_type; 2295 return(5); 2296 } 2297 return (4); 2298} 2299 2300/* handle net.unix requests */ 2301struct ctlname netunixname[] = CTL_NET_UNIX_NAMES; 2302struct ctlname netunixprotoname[] = CTL_NET_UNIX_PROTO_NAMES; 2303struct list netunixlist = { netunixname, NET_UNIX_MAXID }; 2304struct list netunixvars[] = { 2305 [SOCK_STREAM] = { netunixprotoname, NET_UNIX_PROTO_MAXID }, 2306 [SOCK_DGRAM] = { netunixprotoname, NET_UNIX_PROTO_MAXID }, 2307 [SOCK_SEQPACKET] = { netunixprotoname, NET_UNIX_PROTO_MAXID }, 2308 [NET_UNIX_MAXID] = { 0, 0 }, 2309}; 2310 2311int 2312sysctl_unix(char *string, char **bufpp, int mib[], int flags, int *typep) 2313{ 2314 struct list *lp; 2315 int indx; 2316 2317 if (*bufpp == NULL) { 2318 listall(string, &netunixlist); 2319 return (-1); 2320 } 2321 if ((indx = findname(string, "third", bufpp, &netunixlist)) == -1) 2322 return (-1); 2323 mib[2] = indx; 2324 *typep = netunixname[indx].ctl_type; 2325 2326 if (indx < NET_UNIX_MAXID && netunixvars[indx].list != NULL) 2327 lp = &netunixvars[indx]; 2328 else 2329 return (3); 2330 2331 if (*bufpp == NULL) { 2332 listall(string, lp); 2333 return (-1); 2334 } 2335 if ((indx = findname(string, "fourth", bufpp, lp)) == -1) 2336 return (-1); 2337 mib[3] = indx; 2338 *typep = lp->list[indx].ctl_type; 2339 return (4); 2340} 2341 2342/* handle net.link requests */ 2343struct ctlname netlinkname[] = CTL_NET_LINK_NAMES; 2344struct ctlname ifrxqname[] = CTL_NET_LINK_IFRXQ_NAMES; 2345struct list netlinklist = { netlinkname, NET_LINK_MAXID }; 2346struct list netlinkvars[] = { 2347 [NET_LINK_IFRXQ] = { ifrxqname, NET_LINK_IFRXQ_MAXID }, 2348}; 2349 2350int 2351sysctl_link(char *string, char **bufpp, int mib[], int flags, int *typep) 2352{ 2353 struct list *lp; 2354 int indx; 2355 2356 if (*bufpp == NULL) { 2357 listall(string, &netlinklist); 2358 return (-1); 2359 } 2360 if ((indx = findname(string, "third", bufpp, &netlinklist)) == -1) 2361 return (-1); 2362 mib[2] = indx; 2363 if (indx < NET_LINK_MAXID && netlinkvars[indx].list != NULL) 2364 lp = &netlinkvars[indx]; 2365 else if (!flags) 2366 return (-1); 2367 else { 2368 warnx("%s: no variables defined for this protocol", string); 2369 return (-1); 2370 } 2371 if (*bufpp == NULL) { 2372 listall(string, lp); 2373 return (-1); 2374 } 2375 if ((indx = findname(string, "fourth", bufpp, lp)) == -1) 2376 return (-1); 2377 mib[3] = indx; 2378 *typep = lp->list[indx].ctl_type; 2379 return (4); 2380} 2381 2382/* handle bpf requests */ 2383int 2384sysctl_bpf(char *string, char **bufpp, int mib[], int flags, int *typep) 2385{ 2386 int indx; 2387 2388 if (*bufpp == NULL) { 2389 listall(string, &bpflist); 2390 return (-1); 2391 } 2392 if ((indx = findname(string, "third", bufpp, &bpflist)) == -1) 2393 return (-1); 2394 mib[2] = indx; 2395 *typep = CTLTYPE_INT; 2396 return (3); 2397} 2398 2399struct ctlname mplsname[] = MPLSCTL_NAMES; 2400struct list mplslist = { mplsname, MPLSCTL_MAXID }; 2401 2402/* handle MPLS requests */ 2403int 2404sysctl_mpls(char *string, char **bufpp, int mib[], int flags, int *typep) 2405{ 2406 struct list *lp; 2407 int indx; 2408 2409 if (*bufpp == NULL) { 2410 listall(string, &mplslist); 2411 return (-1); 2412 } 2413 if ((indx = findname(string, "third", bufpp, &mplslist)) == -1) 2414 return (-1); 2415 mib[2] = indx; 2416 *typep = mplslist.list[indx].ctl_type; 2417 if (*typep == CTLTYPE_NODE) { 2418 int tindx; 2419 2420 if (*bufpp == NULL) { 2421 listall(string, &ifqlist); 2422 return(-1); 2423 } 2424 lp = &ifqlist; 2425 if ((tindx = findname(string, "fourth", bufpp, lp)) == -1) 2426 return (-1); 2427 mib[3] = tindx; 2428 *typep = lp->list[tindx].ctl_type; 2429 return(4); 2430 } 2431 return (3); 2432} 2433 2434/* handle PIPEX requests */ 2435int 2436sysctl_pipex(char *string, char **bufpp, int mib[], int flags, int *typep) 2437{ 2438 struct list *lp; 2439 int indx; 2440 2441 if (*bufpp == NULL) { 2442 listall(string, &pipexlist); 2443 return (-1); 2444 } 2445 if ((indx = findname(string, "third", bufpp, &pipexlist)) == -1) 2446 return (-1); 2447 mib[2] = indx; 2448 *typep = pipexlist.list[indx].ctl_type; 2449 if (*typep == CTLTYPE_NODE) { 2450 int tindx; 2451 2452 if (*bufpp == NULL) { 2453 listall(string, &ifqlist); 2454 return(-1); 2455 } 2456 lp = &ifqlist; 2457 if ((tindx = findname(string, "fourth", bufpp, lp)) == -1) 2458 return (-1); 2459 mib[3] = tindx; 2460 *typep = lp->list[tindx].ctl_type; 2461 return(4); 2462 } 2463 return (3); 2464} 2465 2466/* 2467 * Handle SysV semaphore info requests 2468 */ 2469int 2470sysctl_seminfo(char *string, char **bufpp, int mib[], int flags, int *typep) 2471{ 2472 int indx; 2473 2474 if (*bufpp == NULL) { 2475 listall(string, &semlist); 2476 return (-1); 2477 } 2478 if ((indx = findname(string, "third", bufpp, &semlist)) == -1) 2479 return (-1); 2480 mib[2] = indx; 2481 *typep = CTLTYPE_INT; 2482 return (3); 2483} 2484 2485/* 2486 * Handle SysV shared memory info requests 2487 */ 2488int 2489sysctl_shminfo(char *string, char **bufpp, int mib[], int flags, int *typep) 2490{ 2491 int indx; 2492 2493 if (*bufpp == NULL) { 2494 listall(string, &shmlist); 2495 return (-1); 2496 } 2497 if ((indx = findname(string, "third", bufpp, &shmlist)) == -1) 2498 return (-1); 2499 mib[2] = indx; 2500 *typep = CTLTYPE_INT; 2501 return (3); 2502} 2503 2504/* 2505 * Handle watchdog support 2506 */ 2507int 2508sysctl_watchdog(char *string, char **bufpp, int mib[], int flags, 2509 int *typep) 2510{ 2511 int indx; 2512 2513 if (*bufpp == NULL) { 2514 listall(string, &watchdoglist); 2515 return (-1); 2516 } 2517 if ((indx = findname(string, "third", bufpp, &watchdoglist)) == -1) 2518 return (-1); 2519 mib[2] = indx; 2520 *typep = watchdoglist.list[indx].ctl_type; 2521 return (3); 2522} 2523 2524/* 2525 * Handle timecounter support 2526 */ 2527int 2528sysctl_tc(char *string, char **bufpp, int mib[], int flags, 2529 int *typep) 2530{ 2531 int indx; 2532 2533 if (*bufpp == NULL) { 2534 listall(string, &tclist); 2535 return (-1); 2536 } 2537 if ((indx = findname(string, "third", bufpp, &tclist)) == -1) 2538 return (-1); 2539 mib[2] = indx; 2540 *typep = tclist.list[indx].ctl_type; 2541 return (3); 2542} 2543 2544/* 2545 * Handle hardware monitoring sensors support 2546 */ 2547int 2548sysctl_sensors(char *string, char **bufpp, int mib[], int flags, int *typep) 2549{ 2550 char *devname, *typename; 2551 int dev, numt, i; 2552 enum sensor_type type; 2553 struct sensordev snsrdev; 2554 size_t sdlen = sizeof(snsrdev); 2555 2556 if (*bufpp == NULL) { 2557 char buf[SYSCTL_BUFSIZ]; 2558 2559 /* scan all sensor devices */ 2560 for (dev = 0; ; dev++) { 2561 mib[2] = dev; 2562 if (sysctl(mib, 3, &snsrdev, &sdlen, NULL, 0) == -1) { 2563 if (errno == ENXIO) 2564 continue; 2565 if (errno == ENOENT) 2566 break; 2567 warn("sensors dev %d", dev); 2568 return (-1); 2569 } 2570 snprintf(buf, sizeof(buf), "%s.%s", 2571 string, snsrdev.xname); 2572 print_sensordev(buf, mib, 3, &snsrdev); 2573 } 2574 return (-1); 2575 } 2576 2577 /* 2578 * If we get this far, it means that some arguments were 2579 * provided below hw.sensors tree. 2580 * The first branch of hw.sensors tree is the device name. 2581 */ 2582 if ((devname = strsep(bufpp, ".")) == NULL) { 2583 warnx("%s: incomplete specification", string); 2584 return (-1); 2585 } 2586 /* convert sensor device string to an integer */ 2587 for (dev = 0; ; dev++) { 2588 mib[2] = dev; 2589 if (sysctl(mib, 3, &snsrdev, &sdlen, NULL, 0) == -1) { 2590 if (errno == ENXIO) 2591 continue; 2592 if (errno == ENOENT) 2593 break; 2594 warn("sensors dev %d", dev); 2595 return (-1); 2596 } 2597 if (strcmp(devname, snsrdev.xname) == 0) 2598 break; 2599 } 2600 if (strcmp(devname, snsrdev.xname) != 0) { 2601 warnx("%s: sensor device not found: %s", string, devname); 2602 return (-1); 2603 } 2604 if (*bufpp == NULL) { 2605 /* only device name was provided -- let's print all sensors 2606 * that are attached to the specified device 2607 */ 2608 print_sensordev(string, mib, 3, &snsrdev); 2609 return (-1); 2610 } 2611 2612 /* 2613 * At this point we have identified the sensor device, 2614 * now let's go further and identify sensor type. 2615 */ 2616 if ((typename = strsep(bufpp, ".")) == NULL) { 2617 warnx("%s: incomplete specification", string); 2618 return (-1); 2619 } 2620 numt = -1; 2621 for (i = 0; typename[i] != '\0'; i++) 2622 if (isdigit((unsigned char)typename[i])) { 2623 const char *errstr; 2624 2625 numt = strtonum(&typename[i], 0, INT_MAX, &errstr); 2626 if (errstr) { 2627 warnx("%s: %s", string, errstr); 2628 return (-1); 2629 } 2630 typename[i] = '\0'; 2631 break; 2632 } 2633 for (type = 0; type < SENSOR_MAX_TYPES; type++) 2634 if (strcmp(typename, sensor_type_s[type]) == 0) 2635 break; 2636 if (type == SENSOR_MAX_TYPES) { 2637 warnx("%s: sensor type not recognised: %s", string, typename); 2638 return (-1); 2639 } 2640 mib[3] = type; 2641 2642 /* 2643 * If no integer was provided after sensor_type, let's 2644 * print all sensors of the specified type. 2645 */ 2646 if (numt == -1) { 2647 print_sensordev(string, mib, 4, &snsrdev); 2648 return (-1); 2649 } 2650 2651 /* 2652 * At this point we know that we have received a direct request 2653 * via command-line for a specific sensor. Let's have the parse() 2654 * function deal with it further, and report any errors if such 2655 * sensor node does not exist. 2656 */ 2657 mib[4] = numt; 2658 *typep = CTLTYPE_STRUCT; 2659 return (5); 2660} 2661 2662/* 2663 * Print sensors from the specified device. 2664 */ 2665 2666void 2667print_sensordev(char *string, int mib[], u_int mlen, struct sensordev *snsrdev) 2668{ 2669 char buf[SYSCTL_BUFSIZ]; 2670 enum sensor_type type; 2671 2672 if (mlen == 3) { 2673 for (type = 0; type < SENSOR_MAX_TYPES; type++) { 2674 mib[3] = type; 2675 snprintf(buf, sizeof(buf), "%s.%s", 2676 string, sensor_type_s[type]); 2677 print_sensordev(buf, mib, mlen+1, snsrdev); 2678 } 2679 return; 2680 } 2681 2682 if (mlen == 4) { 2683 int numt; 2684 2685 type = mib[3]; 2686 for (numt = 0; numt < snsrdev->maxnumt[type]; numt++) { 2687 mib[4] = numt; 2688 snprintf(buf, sizeof(buf), "%s%u", string, numt); 2689 print_sensordev(buf, mib, mlen+1, snsrdev); 2690 } 2691 return; 2692 } 2693 2694 if (mlen == 5) { 2695 struct sensor snsr; 2696 size_t slen = sizeof(snsr); 2697 2698 /* this function is only printing sensors in bulk, so we 2699 * do not return any error messages if the requested sensor 2700 * is not found by sysctl(3) 2701 */ 2702 if (sysctl(mib, 5, &snsr, &slen, NULL, 0) == -1) 2703 return; 2704 2705 if (slen > 0 && (snsr.flags & SENSOR_FINVALID) == 0) { 2706 if (!nflag) 2707 printf("%s%s", string, equ); 2708 print_sensor(&snsr); 2709 printf("\n"); 2710 } 2711 return; 2712 } 2713} 2714 2715void 2716print_sensor(struct sensor *s) 2717{ 2718 const char *name; 2719 2720 if (s->flags & SENSOR_FUNKNOWN) 2721 printf("unknown"); 2722 else { 2723 switch (s->type) { 2724 case SENSOR_TEMP: 2725 printf("%.2f degC", 2726 (s->value - 273150000) / 1000000.0); 2727 break; 2728 case SENSOR_FANRPM: 2729 printf("%lld RPM", s->value); 2730 break; 2731 case SENSOR_VOLTS_DC: 2732 printf("%.2f VDC", s->value / 1000000.0); 2733 break; 2734 case SENSOR_VOLTS_AC: 2735 printf("%.2f VAC", s->value / 1000000.0); 2736 break; 2737 case SENSOR_OHMS: 2738 printf("%lld ohm", s->value); 2739 break; 2740 case SENSOR_WATTS: 2741 printf("%.2f W", s->value / 1000000.0); 2742 break; 2743 case SENSOR_AMPS: 2744 printf("%.2f A", s->value / 1000000.0); 2745 break; 2746 case SENSOR_WATTHOUR: 2747 printf("%.2f Wh", s->value / 1000000.0); 2748 break; 2749 case SENSOR_AMPHOUR: 2750 printf("%.2f Ah", s->value / 1000000.0); 2751 break; 2752 case SENSOR_INDICATOR: 2753 printf("%s", s->value ? "On" : "Off"); 2754 break; 2755 case SENSOR_INTEGER: 2756 printf("%lld", s->value); 2757 break; 2758 case SENSOR_PERCENT: 2759 printf("%.2f%%", s->value / 1000.0); 2760 break; 2761 case SENSOR_LUX: 2762 printf("%.2f lx", s->value / 1000000.0); 2763 break; 2764 case SENSOR_DRIVE: 2765 switch (s->value) { 2766 case SENSOR_DRIVE_EMPTY: 2767 name = "empty"; 2768 break; 2769 case SENSOR_DRIVE_READY: 2770 name = "ready"; 2771 break; 2772 case SENSOR_DRIVE_POWERUP: 2773 name = "powering up"; 2774 break; 2775 case SENSOR_DRIVE_ONLINE: 2776 name = "online"; 2777 break; 2778 case SENSOR_DRIVE_IDLE: 2779 name = "idle"; 2780 break; 2781 case SENSOR_DRIVE_ACTIVE: 2782 name = "active"; 2783 break; 2784 case SENSOR_DRIVE_REBUILD: 2785 name = "rebuilding"; 2786 break; 2787 case SENSOR_DRIVE_POWERDOWN: 2788 name = "powering down"; 2789 break; 2790 case SENSOR_DRIVE_FAIL: 2791 name = "failed"; 2792 break; 2793 case SENSOR_DRIVE_PFAIL: 2794 name = "degraded"; 2795 break; 2796 default: 2797 name = "unknown"; 2798 break; 2799 } 2800 printf("%s", name); 2801 break; 2802 case SENSOR_TIMEDELTA: 2803 printf("%.6f secs", s->value / 1000000000.0); 2804 break; 2805 case SENSOR_HUMIDITY: 2806 printf("%.2f%%", s->value / 1000.0); 2807 break; 2808 case SENSOR_FREQ: 2809 printf("%.2f Hz", s->value / 1000000.0); 2810 break; 2811 case SENSOR_ANGLE: 2812 printf("%3.4f degrees", s->value / 1000000.0); 2813 break; 2814 case SENSOR_DISTANCE: 2815 printf("%.3f m", s->value / 1000000.0); 2816 break; 2817 case SENSOR_PRESSURE: 2818 printf("%.2f Pa", s->value / 1000.0); 2819 break; 2820 case SENSOR_ACCEL: 2821 printf("%2.4f m/s^2", s->value / 1000000.0); 2822 break; 2823 case SENSOR_VELOCITY: 2824 printf("%4.3f m/s", s->value / 1000000.0); 2825 break; 2826 case SENSOR_ENERGY: 2827 printf("%.2f J", s->value / 1000000.0); 2828 break; 2829 default: 2830 printf("unknown"); 2831 } 2832 } 2833 2834 if (s->desc[0] != '\0') 2835 printf(" (%s)", s->desc); 2836 2837 switch (s->status) { 2838 case SENSOR_S_UNSPEC: 2839 break; 2840 case SENSOR_S_OK: 2841 printf(", OK"); 2842 break; 2843 case SENSOR_S_WARN: 2844 printf(", WARNING"); 2845 break; 2846 case SENSOR_S_CRIT: 2847 printf(", CRITICAL"); 2848 break; 2849 case SENSOR_S_UNKNOWN: 2850 printf(", UNKNOWN"); 2851 break; 2852 } 2853 2854 if (s->tv.tv_sec) { 2855 time_t t = s->tv.tv_sec; 2856 char ct[26]; 2857 2858 ctime_r(&t, ct); 2859 ct[19] = '\0'; 2860 printf(", %s.%03ld", ct, s->tv.tv_usec / 1000); 2861 } 2862} 2863 2864/* 2865 * Handle audio support 2866 */ 2867int 2868sysctl_audio(char *string, char **bufpp, int mib[], int flags, int *typep) 2869{ 2870 int indx; 2871 2872 if (*bufpp == NULL) { 2873 listall(string, &audiolist); 2874 return (-1); 2875 } 2876 if ((indx = findname(string, "third", bufpp, &audiolist)) == -1) 2877 return (-1); 2878 mib[2] = indx; 2879 *typep = audiolist.list[indx].ctl_type; 2880 return (3); 2881} 2882 2883/* 2884 * Handle video support 2885 */ 2886int 2887sysctl_video(char *string, char **bufpp, int mib[], int flags, int *typep) 2888{ 2889 int indx; 2890 2891 if (*bufpp == NULL) { 2892 listall(string, &videolist); 2893 return (-1); 2894 } 2895 if ((indx = findname(string, "third", bufpp, &videolist)) == -1) 2896 return (-1); 2897 mib[2] = indx; 2898 *typep = videolist.list[indx].ctl_type; 2899 return (3); 2900} 2901 2902/* 2903 * Handle witness support 2904 */ 2905int 2906sysctl_witness(char *string, char **bufpp, int mib[], int flags, int *typep) 2907{ 2908 int indx; 2909 2910 if (*bufpp == NULL) { 2911 listall(string, &witnesslist); 2912 return (-1); 2913 } 2914 if ((indx = findname(string, "third", bufpp, &witnesslist)) == -1) 2915 return (-1); 2916 mib[2] = indx; 2917 *typep = witnesslist.list[indx].ctl_type; 2918 return (3); 2919} 2920 2921/* 2922 * Handle battery support 2923 */ 2924int 2925sysctl_battery(char *string, char **bufpp, int mib[], int flags, 2926 int *typep) 2927{ 2928 int indx; 2929 2930 if (*bufpp == NULL) { 2931 listall(string, &batterylist); 2932 return (-1); 2933 } 2934 if ((indx = findname(string, "third", bufpp, &batterylist)) == -1) 2935 return (-1); 2936 mib[2] = indx; 2937 *typep = batterylist.list[indx].ctl_type; 2938 return (3); 2939} 2940 2941/* 2942 * Scan a list of names searching for a particular name. 2943 */ 2944int 2945findname(char *string, char *level, char **bufp, struct list *namelist) 2946{ 2947 char *name; 2948 int i; 2949 2950 if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) { 2951 warnx("%s: incomplete specification", string); 2952 return (-1); 2953 } 2954 for (i = 0; i < namelist->size; i++) 2955 if (namelist->list[i].ctl_name != NULL && 2956 strcmp(name, namelist->list[i].ctl_name) == 0) 2957 break; 2958 if (i == namelist->size) { 2959 warnx("%s level name %s in %s is invalid", level, name, string); 2960 return (-1); 2961 } 2962 return (i); 2963} 2964 2965void 2966usage(void) 2967{ 2968 2969 (void)fprintf(stderr, 2970 "usage: sysctl [-Aanq] [name[=value]]\n"); 2971 exit(1); 2972} 2973