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