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