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