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