sysctl.c revision 1.190
1/* $OpenBSD: sysctl.c,v 1.190 2013/06/08 14:24:39 yasuoka 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/param.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/dkstat.h> 42#include <sys/uio.h> 43#include <sys/tty.h> 44#include <sys/namei.h> 45#include <sys/sensors.h> 46#include <net/route.h> 47#include <net/if.h> 48 49#include <netinet/in.h> 50#include <netinet/in_systm.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 <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 104#include <machine/cpu.h> 105 106#ifdef CPU_BIOS 107#include <machine/biosvar.h> 108#endif 109 110struct ctlname topname[] = CTL_NAMES; 111struct ctlname kernname[] = CTL_KERN_NAMES; 112struct ctlname vmname[] = CTL_VM_NAMES; 113struct ctlname fsname[] = CTL_FS_NAMES; 114struct ctlname netname[] = CTL_NET_NAMES; 115struct ctlname hwname[] = CTL_HW_NAMES; 116struct ctlname debugname[CTL_DEBUG_MAXID]; 117struct ctlname kernmallocname[] = CTL_KERN_MALLOC_NAMES; 118struct ctlname forkstatname[] = CTL_KERN_FORKSTAT_NAMES; 119struct ctlname nchstatsname[] = CTL_KERN_NCHSTATS_NAMES; 120struct ctlname ttysname[] = CTL_KERN_TTY_NAMES; 121struct ctlname semname[] = CTL_KERN_SEMINFO_NAMES; 122struct ctlname shmname[] = CTL_KERN_SHMINFO_NAMES; 123struct ctlname watchdogname[] = CTL_KERN_WATCHDOG_NAMES; 124struct ctlname tcname[] = CTL_KERN_TIMECOUNTER_NAMES; 125struct ctlname *vfsname; 126#ifdef CTL_MACHDEP_NAMES 127struct ctlname machdepname[] = CTL_MACHDEP_NAMES; 128#endif 129struct ctlname ddbname[] = CTL_DDB_NAMES; 130char names[BUFSIZ]; 131int lastused; 132 133/* Maximum size object to expect from sysctl(3) */ 134#define SYSCTL_BUFSIZ 8192 135 136struct list { 137 struct ctlname *list; 138 int size; 139}; 140struct list toplist = { topname, CTL_MAXID }; 141struct list secondlevel[] = { 142 { 0, 0 }, /* CTL_UNSPEC */ 143 { kernname, KERN_MAXID }, /* CTL_KERN */ 144 { vmname, VM_MAXID }, /* CTL_VM */ 145 { fsname, FS_MAXID }, /* CTL_FS */ 146 { netname, NET_MAXID }, /* CTL_NET */ 147 { 0, CTL_DEBUG_MAXID }, /* CTL_DEBUG */ 148 { hwname, HW_MAXID }, /* CTL_HW */ 149#ifdef CTL_MACHDEP_NAMES 150 { machdepname, CPU_MAXID }, /* CTL_MACHDEP */ 151#else 152 { 0, 0 }, /* CTL_MACHDEP */ 153#endif 154 { 0, 0 }, /* was CTL_USER */ 155 { ddbname, DBCTL_MAXID }, /* CTL_DDB_NAMES */ 156 { 0, 0 }, /* CTL_VFS */ 157}; 158 159int Aflag, aflag, nflag, qflag; 160 161/* 162 * Variables requiring special processing. 163 */ 164#define CLOCK 0x00000001 165#define BOOTTIME 0x00000002 166#define CHRDEV 0x00000004 167#define BLKDEV 0x00000008 168#define RNDSTATS 0x00000010 169#define BADDYNAMIC 0x00000020 170#define BIOSGEO 0x00000040 171#define BIOSDEV 0x00000080 172#define MAJ2DEV 0x00000100 173#define UNSIGNED 0x00000200 174#define KMEMBUCKETS 0x00000400 175#define LONGARRAY 0x00000800 176#define KMEMSTATS 0x00001000 177#define SENSORS 0x00002000 178 179/* prototypes */ 180void debuginit(void); 181void listall(char *, struct list *); 182void parse(char *, int); 183void parse_baddynamic(int *, size_t, char *, void **, size_t *, int, int); 184void usage(void); 185int findname(char *, char *, char **, struct list *); 186int sysctl_inet(char *, char **, int *, int, int *); 187#ifdef INET6 188int sysctl_inet6(char *, char **, int *, int, int *); 189#endif 190int sysctl_bpf(char *, char **, int *, int, int *); 191int sysctl_mpls(char *, char **, int *, int, int *); 192int sysctl_pipex(char *, char **, int *, int, int *); 193int sysctl_fs(char *, char **, int *, int, int *); 194static int sysctl_vfs(char *, char **, int[], int, int *); 195static int sysctl_vfsgen(char *, char **, int[], int, int *); 196int sysctl_bios(char *, char **, int *, int, int *); 197int sysctl_swpenc(char *, char **, int *, int, int *); 198int sysctl_forkstat(char *, char **, int *, int, int *); 199int sysctl_tty(char *, char **, int *, int, int *); 200int sysctl_nchstats(char *, char **, int *, int, int *); 201int sysctl_malloc(char *, char **, int *, int, int *); 202int sysctl_seminfo(char *, char **, int *, int, int *); 203int sysctl_shminfo(char *, char **, int *, int, int *); 204int sysctl_watchdog(char *, char **, int *, int, int *); 205int sysctl_tc(char *, char **, int *, int, int *); 206int sysctl_sensors(char *, char **, int *, int, int *); 207void print_sensordev(char *, int *, u_int, struct sensordev *); 208void print_sensor(struct sensor *); 209int sysctl_emul(char *, char *, int); 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(*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_VNODE: 388 case KERN_FILE: 389 if (flags == 0) 390 return; 391 warnx("use pstat to view %s information", string); 392 return; 393 case KERN_PROC: 394 if (flags == 0) 395 return; 396 warnx("use ps to view %s information", string); 397 return; 398 case KERN_CLOCKRATE: 399 special |= CLOCK; 400 break; 401 case KERN_BOOTTIME: 402 special |= BOOTTIME; 403 break; 404 case KERN_RND: 405 special |= RNDSTATS; 406 break; 407 case KERN_HOSTID: 408 case KERN_ARND: 409 special |= UNSIGNED; 410 break; 411 case KERN_CPTIME: 412 special |= LONGARRAY; 413 lal = CPUSTATES; 414 break; 415 case KERN_SEMINFO: 416 len = sysctl_seminfo(string, &bufp, mib, flags, &type); 417 if (len < 0) 418 return; 419 break; 420 case KERN_SHMINFO: 421 len = sysctl_shminfo(string, &bufp, mib, flags, &type); 422 if (len < 0) 423 return; 424 break; 425 case KERN_WATCHDOG: 426 len = sysctl_watchdog(string, &bufp, mib, flags, 427 &type); 428 if (len < 0) 429 return; 430 break; 431 case KERN_TIMECOUNTER: 432 len = sysctl_tc(string, &bufp, mib, flags, 433 &type); 434 if (len < 0) 435 return; 436 break; 437 case KERN_EMUL: 438 sysctl_emul(string, newval, flags); 439 return; 440 case KERN_FILE2: 441 if (flags == 0) 442 return; 443 warnx("use fstat to view %s information", string); 444 return; 445 case KERN_CONSDEV: 446 special |= CHRDEV; 447 break; 448 case KERN_NETLIVELOCKS: 449 special |= UNSIGNED; 450 break; 451 } 452 break; 453 454 case CTL_HW: 455 switch (mib[1]) { 456 case HW_DISKSTATS: 457 /* 458 * Only complain if someone asks explicitly for this, 459 * otherwise "fail" silently. 460 */ 461 if (flags) 462 warnx("use vmstat to view %s information", 463 string); 464 return; 465 case HW_SENSORS: 466 special |= SENSORS; 467 len = sysctl_sensors(string, &bufp, mib, flags, &type); 468 if (len < 0) 469 return; 470 break; 471 case HW_PHYSMEM: 472 case HW_USERMEM: 473 /* 474 * Don't print these; we'll print the 64-bit 475 * variants instead. 476 */ 477 return; 478 } 479 break; 480 481 case CTL_VM: 482 if (mib[1] == VM_LOADAVG) { 483 double loads[3]; 484 485 getloadavg(loads, 3); 486 if (!nflag) 487 (void)printf("%s%s", string, equ); 488 (void)printf("%.2f %.2f %.2f\n", loads[0], 489 loads[1], loads[2]); 490 return; 491 } else if (mib[1] == VM_PSSTRINGS) { 492 struct _ps_strings _ps; 493 494 size = sizeof(_ps); 495 if (sysctl(mib, 2, &_ps, &size, NULL, 0) == -1) { 496 if (flags == 0) 497 return; 498 if (!nflag) 499 (void)printf("%s: ", string); 500 (void)puts("can't find ps strings"); 501 return; 502 } 503 if (!nflag) 504 (void)printf("%s%s", string, equ); 505 (void)printf("%p\n", _ps.val); 506 return; 507 } else if (mib[1] == VM_SWAPENCRYPT) { 508 len = sysctl_swpenc(string, &bufp, mib, flags, &type); 509 if (len < 0) 510 return; 511 512 break; 513 } else if (mib[1] == VM_NKMEMPAGES || 514 mib[1] == VM_ANONMIN || 515 mib[1] == VM_VTEXTMIN || 516 mib[1] == VM_VNODEMIN) { 517 break; 518 } 519 if (flags == 0) 520 return; 521 warnx("use vmstat or systat to view %s information", string); 522 return; 523 524 break; 525 526 case CTL_NET: 527 if (mib[1] == PF_INET) { 528 len = sysctl_inet(string, &bufp, mib, flags, &type); 529 if (len < 0) 530 return; 531 532 if ((mib[2] == IPPROTO_IP && mib[3] == IPCTL_MRTSTATS) || 533 (mib[2] == IPPROTO_IP && mib[3] == IPCTL_STATS) || 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#ifdef INET6 565 if (mib[1] == PF_INET6) { 566 len = sysctl_inet6(string, &bufp, mib, flags, &type); 567 if (len < 0) 568 return; 569 570 if ((mib[2] == IPPROTO_PIM && mib[3] == PIM6CTL_STATS) || 571 (mib[2] == IPPROTO_DIVERT && mib[3] == DIVERT6CTL_STATS)) { 572 if (flags == 0) 573 return; 574 warnx("use netstat to view %s information", 575 string); 576 return; 577 } 578 break; 579 } 580#endif 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 = 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 contain bad dynamic " 1049 "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 list *vfsvars; 1107int *vfs_typenums; 1108 1109/* 1110 * Initialize the set of filesystem names 1111 */ 1112void 1113vfsinit(void) 1114{ 1115 int mib[4], maxtypenum, cnt, loc, size; 1116 struct vfsconf vfc; 1117 size_t buflen; 1118 1119 if (secondlevel[CTL_VFS].list != 0) 1120 return; 1121 mib[0] = CTL_VFS; 1122 mib[1] = VFS_GENERIC; 1123 mib[2] = VFS_MAXTYPENUM; 1124 buflen = 4; 1125 if (sysctl(mib, 3, &maxtypenum, &buflen, (void *)0, (size_t)0) < 0) 1126 return; 1127 maxtypenum++; /* + generic */ 1128 if ((vfs_typenums = calloc(maxtypenum, sizeof(int))) == NULL) 1129 return; 1130 if ((vfsvars = calloc(maxtypenum, sizeof(*vfsvars))) == NULL) { 1131 free(vfs_typenums); 1132 return; 1133 } 1134 if ((vfsname = calloc(maxtypenum, sizeof(*vfsname))) == NULL) { 1135 free(vfs_typenums); 1136 free(vfsvars); 1137 return; 1138 } 1139 mib[2] = VFS_CONF; 1140 buflen = sizeof vfc; 1141 for (loc = lastused, cnt = 1; cnt < maxtypenum; cnt++) { 1142 mib[3] = cnt - 1; 1143 if (sysctl(mib, 4, &vfc, &buflen, (void *)0, (size_t)0) < 0) { 1144 if (errno == EOPNOTSUPP) 1145 continue; 1146 warn("vfsinit"); 1147 free(vfsname); 1148 free(vfsvars); 1149 free(vfs_typenums); 1150 return; 1151 } 1152 if (!strcmp(vfc.vfc_name, MOUNT_FFS)) { 1153 vfsvars[cnt].list = ffsname; 1154 vfsvars[cnt].size = FFS_MAXID; 1155 } 1156 if (!strcmp(vfc.vfc_name, MOUNT_NFS)) { 1157 vfsvars[cnt].list = nfsname; 1158 vfsvars[cnt].size = NFS_MAXID; 1159 } 1160 vfs_typenums[cnt] = vfc.vfc_typenum; 1161 strlcat(&names[loc], vfc.vfc_name, sizeof names - loc); 1162 vfsname[cnt].ctl_name = &names[loc]; 1163 vfsname[cnt].ctl_type = CTLTYPE_NODE; 1164 size = strlen(vfc.vfc_name) + 1; 1165 loc += size; 1166 } 1167 lastused = loc; 1168 1169 vfsname[0].ctl_name = "mounts"; 1170 vfsname[0].ctl_type = CTLTYPE_NODE; 1171 vfsvars[0].list = vfsname + 1; 1172 vfsvars[0].size = maxtypenum - 1; 1173 1174 secondlevel[CTL_VFS].list = vfsname; 1175 secondlevel[CTL_VFS].size = maxtypenum; 1176 return; 1177} 1178 1179int 1180sysctl_vfsgen(char *string, char **bufpp, int mib[], int flags, int *typep) 1181{ 1182 int indx; 1183 size_t size; 1184 struct vfsconf vfc; 1185 1186 if (*bufpp == NULL) { 1187 listall(string, vfsvars); 1188 return (-1); 1189 } 1190 1191 if ((indx = findname(string, "third", bufpp, vfsvars)) == -1) 1192 return (-1); 1193 1194 mib[1] = VFS_GENERIC; 1195 mib[2] = VFS_CONF; 1196 mib[3] = indx; 1197 size = sizeof vfc; 1198 if (sysctl(mib, 4, &vfc, &size, (void *)0, (size_t)0) < 0) { 1199 if (errno != EOPNOTSUPP) 1200 warn("vfs print"); 1201 return -1; 1202 } 1203 if (flags == 0 && vfc.vfc_refcount == 0) 1204 return -1; 1205 if (!nflag) 1206 fprintf(stdout, "%s has %d mounted instance%s\n", 1207 string, vfc.vfc_refcount, 1208 vfc.vfc_refcount != 1 ? "s" : ""); 1209 else 1210 fprintf(stdout, "%d\n", vfc.vfc_refcount); 1211 1212 return -1; 1213} 1214 1215int 1216sysctl_vfs(char *string, char **bufpp, int mib[], int flags, int *typep) 1217{ 1218 struct list *lp = &vfsvars[mib[1]]; 1219 int indx; 1220 1221 if (lp->list == NULL) { 1222 if (flags) 1223 warnx("No variables defined for file system %s", string); 1224 return (-1); 1225 } 1226 if (*bufpp == NULL) { 1227 listall(string, lp); 1228 return (-1); 1229 } 1230 if ((indx = findname(string, "third", bufpp, lp)) == -1) 1231 return (-1); 1232 1233 mib[1] = vfs_typenums[mib[1]]; 1234 mib[2] = indx; 1235 *typep = lp->list[indx].ctl_type; 1236 return (3); 1237} 1238 1239struct ctlname posixname[] = CTL_FS_POSIX_NAMES; 1240struct list fslist = { posixname, FS_POSIX_MAXID }; 1241 1242/* 1243 * handle file system requests 1244 */ 1245int 1246sysctl_fs(char *string, char **bufpp, int mib[], int flags, int *typep) 1247{ 1248 int indx; 1249 1250 if (*bufpp == NULL) { 1251 listall(string, &fslist); 1252 return (-1); 1253 } 1254 if ((indx = findname(string, "third", bufpp, &fslist)) == -1) 1255 return (-1); 1256 mib[2] = indx; 1257 *typep = fslist.list[indx].ctl_type; 1258 return (3); 1259} 1260 1261#ifdef CPU_BIOS 1262struct ctlname biosname[] = CTL_BIOS_NAMES; 1263struct list bioslist = { biosname, BIOS_MAXID }; 1264 1265/* 1266 * handle BIOS requests 1267 */ 1268int 1269sysctl_bios(char *string, char **bufpp, int mib[], int flags, int *typep) 1270{ 1271 char *name; 1272 int indx; 1273 1274 if (*bufpp == NULL) { 1275 listall(string, &bioslist); 1276 return (-1); 1277 } 1278 if ((indx = findname(string, "third", bufpp, &bioslist)) == -1) 1279 return (-1); 1280 mib[2] = indx; 1281 if (indx == BIOS_DISKINFO) { 1282 if (*bufpp == NULL) { 1283 char name[BUFSIZ]; 1284 1285 /* scan all the bios devices */ 1286 for (indx = 0; indx < 256; indx++) { 1287 snprintf(name, sizeof(name), "%s.%u", 1288 string, indx); 1289 parse(name, 1); 1290 } 1291 return (-1); 1292 } 1293 if ((name = strsep(bufpp, ".")) == NULL) { 1294 warnx("%s: incomplete specification", string); 1295 return (-1); 1296 } 1297 mib[3] = atoi(name); 1298 *typep = CTLTYPE_STRUCT; 1299 return (4); 1300 } else { 1301 *typep = bioslist.list[indx].ctl_type; 1302 return (3); 1303 } 1304} 1305#endif 1306 1307struct ctlname swpencname[] = CTL_SWPENC_NAMES; 1308struct list swpenclist = { swpencname, SWPENC_MAXID }; 1309 1310/* 1311 * handle swap encrypt requests 1312 */ 1313int 1314sysctl_swpenc(char *string, char **bufpp, int mib[], int flags, int *typep) 1315{ 1316 int indx; 1317 1318 if (*bufpp == NULL) { 1319 listall(string, &swpenclist); 1320 return (-1); 1321 } 1322 if ((indx = findname(string, "third", bufpp, &swpenclist)) == -1) 1323 return (-1); 1324 mib[2] = indx; 1325 *typep = swpenclist.list[indx].ctl_type; 1326 return (3); 1327} 1328 1329struct ctlname inetname[] = CTL_IPPROTO_NAMES; 1330struct ctlname ipname[] = IPCTL_NAMES; 1331struct ctlname icmpname[] = ICMPCTL_NAMES; 1332struct ctlname igmpname[] = IGMPCTL_NAMES; 1333struct ctlname ipipname[] = IPIPCTL_NAMES; 1334struct ctlname tcpname[] = TCPCTL_NAMES; 1335struct ctlname udpname[] = UDPCTL_NAMES; 1336struct ctlname espname[] = ESPCTL_NAMES; 1337struct ctlname ahname[] = AHCTL_NAMES; 1338struct ctlname etheripname[] = ETHERIPCTL_NAMES; 1339struct ctlname grename[] = GRECTL_NAMES; 1340struct ctlname mobileipname[] = MOBILEIPCTL_NAMES; 1341struct ctlname ipcompname[] = IPCOMPCTL_NAMES; 1342struct ctlname carpname[] = CARPCTL_NAMES; 1343struct ctlname pfsyncname[] = PFSYNCCTL_NAMES; 1344struct ctlname divertname[] = DIVERTCTL_NAMES; 1345struct ctlname bpfname[] = CTL_NET_BPF_NAMES; 1346struct ctlname ifqname[] = CTL_IFQ_NAMES; 1347struct ctlname pipexname[] = PIPEXCTL_NAMES; 1348struct list inetlist = { inetname, IPPROTO_MAXID }; 1349struct list inetvars[] = { 1350 { ipname, IPCTL_MAXID }, /* ip */ 1351 { icmpname, ICMPCTL_MAXID }, /* icmp */ 1352 { igmpname, IGMPCTL_MAXID }, /* igmp */ 1353 { 0, 0 }, /* ggmp */ 1354 { ipipname, IPIPCTL_MAXID }, /* ipencap */ 1355 { 0, 0 }, 1356 { tcpname, TCPCTL_MAXID }, /* tcp */ 1357 { 0, 0 }, 1358 { 0, 0 }, /* egp */ 1359 { 0, 0 }, 1360 { 0, 0 }, 1361 { 0, 0 }, 1362 { 0, 0 }, /* pup */ 1363 { 0, 0 }, 1364 { 0, 0 }, 1365 { 0, 0 }, 1366 { 0, 0 }, 1367 { udpname, UDPCTL_MAXID }, /* udp */ 1368 { 0, 0 }, 1369 { 0, 0 }, 1370 { 0, 0 }, 1371 { 0, 0 }, 1372 { 0, 0 }, 1373 { 0, 0 }, 1374 { 0, 0 }, 1375 { 0, 0 }, 1376 { 0, 0 }, 1377 { 0, 0 }, 1378 { 0, 0 }, 1379 { 0, 0 }, 1380 { 0, 0 }, 1381 { 0, 0 }, 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 { grename, GRECTL_MAXID }, /* gre */ 1398 { 0, 0 }, 1399 { 0, 0 }, 1400 { espname, ESPCTL_MAXID }, /* esp */ 1401 { ahname, AHCTL_MAXID }, /* ah */ 1402 { 0, 0 }, 1403 { 0, 0 }, 1404 { 0, 0 }, 1405 { mobileipname, MOBILEIPCTL_MAXID }, /* mobileip */ 1406 { 0, 0 }, 1407 { 0, 0 }, 1408 { 0, 0 }, 1409 { 0, 0 }, 1410 { 0, 0 }, 1411 { 0, 0 }, 1412 { 0, 0 }, 1413 { 0, 0 }, 1414 { 0, 0 }, 1415 { 0, 0 }, 1416 { 0, 0 }, 1417 { 0, 0 }, 1418 { 0, 0 }, 1419 { 0, 0 }, 1420 { 0, 0 }, 1421 { 0, 0 }, 1422 { 0, 0 }, 1423 { 0, 0 }, 1424 { 0, 0 }, 1425 { 0, 0 }, 1426 { 0, 0 }, 1427 { 0, 0 }, 1428 { 0, 0 }, 1429 { 0, 0 }, 1430 { 0, 0 }, 1431 { 0, 0 }, 1432 { 0, 0 }, 1433 { 0, 0 }, 1434 { 0, 0 }, 1435 { 0, 0 }, 1436 { 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 { etheripname, ETHERIPCTL_MAXID }, 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 { ipcompname, IPCOMPCTL_MAXID }, 1459 { 0, 0 }, 1460 { 0, 0 }, 1461 { 0, 0 }, 1462 { carpname, CARPCTL_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 { 0, 0 }, 1474 { 0, 0 }, 1475 { 0, 0 }, 1476 { 0, 0 }, 1477 { 0, 0 }, 1478 { 0, 0 }, 1479 { 0, 0 }, 1480 { 0, 0 }, 1481 { 0, 0 }, 1482 { 0, 0 }, 1483 { 0, 0 }, 1484 { 0, 0 }, 1485 { 0, 0 }, 1486 { 0, 0 }, 1487 { 0, 0 }, 1488 { 0, 0 }, 1489 { 0, 0 }, 1490 { 0, 0 }, 1491 { 0, 0 }, 1492 { 0, 0 }, 1493 { 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 { pfsyncname, PFSYNCCTL_MAXID }, 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 { divertname, DIVERTCTL_MAXID }, 1609}; 1610struct list bpflist = { bpfname, NET_BPF_MAXID }; 1611struct list ifqlist = { ifqname, IFQCTL_MAXID }; 1612struct list pipexlist = { pipexname, PIPEXCTL_MAXID }; 1613 1614struct list kernmalloclist = { kernmallocname, KERN_MALLOC_MAXID }; 1615struct list forkstatlist = { forkstatname, KERN_FORKSTAT_MAXID }; 1616struct list nchstatslist = { nchstatsname, KERN_NCHSTATS_MAXID }; 1617struct list ttylist = { ttysname, KERN_TTY_MAXID }; 1618struct list semlist = { semname, KERN_SEMINFO_MAXID }; 1619struct list shmlist = { shmname, KERN_SHMINFO_MAXID }; 1620struct list watchdoglist = { watchdogname, KERN_WATCHDOG_MAXID }; 1621struct list tclist = { tcname, KERN_TIMECOUNTER_MAXID }; 1622 1623/* 1624 * handle vfs namei cache statistics 1625 */ 1626int 1627sysctl_nchstats(char *string, char **bufpp, int mib[], int flags, int *typep) 1628{ 1629 static struct nchstats nch; 1630 int indx; 1631 size_t size; 1632 static int keepvalue = 0; 1633 1634 if (*bufpp == NULL) { 1635 bzero(&nch, sizeof(struct nchstats)); 1636 listall(string, &nchstatslist); 1637 return (-1); 1638 } 1639 if ((indx = findname(string, "third", bufpp, &nchstatslist)) == -1) 1640 return (-1); 1641 mib[2] = indx; 1642 if (*bufpp != NULL) { 1643 warnx("fourth level name in %s is invalid", string); 1644 return (-1); 1645 } 1646 if (keepvalue == 0) { 1647 size = sizeof(struct nchstats); 1648 if (sysctl(mib, 2, &nch, &size, NULL, 0) < 0) 1649 return (-1); 1650 keepvalue = 1; 1651 } 1652 if (!nflag) 1653 (void)printf("%s%s", string, equ); 1654 switch (indx) { 1655 case KERN_NCHSTATS_GOODHITS: 1656 (void)printf("%llu\n", nch.ncs_goodhits); 1657 break; 1658 case KERN_NCHSTATS_NEGHITS: 1659 (void)printf("%llu\n", nch.ncs_neghits); 1660 break; 1661 case KERN_NCHSTATS_BADHITS: 1662 (void)printf("%llu\n", nch.ncs_badhits); 1663 break; 1664 case KERN_NCHSTATS_FALSEHITS: 1665 (void)printf("%llu\n", nch.ncs_falsehits); 1666 break; 1667 case KERN_NCHSTATS_MISS: 1668 (void)printf("%llu\n", nch.ncs_miss); 1669 break; 1670 case KERN_NCHSTATS_LONG: 1671 (void)printf("%llu\n", nch.ncs_long); 1672 break; 1673 case KERN_NCHSTATS_PASS2: 1674 (void)printf("%llu\n", nch.ncs_pass2); 1675 break; 1676 case KERN_NCHSTATS_2PASSES: 1677 (void)printf("%llu\n", nch.ncs_2passes); 1678 break; 1679 case KERN_NCHSTATS_REVHITS: 1680 (void)printf("%llu\n", nch.ncs_revhits); 1681 break; 1682 case KERN_NCHSTATS_REVMISS: 1683 (void)printf("%llu\n", nch.ncs_revmiss); 1684 break; 1685 case KERN_NCHSTATS_DOTHITS: 1686 (void)printf("%llu\n", nch.ncs_dothits); 1687 break; 1688 case KERN_NCHSTATS_DOTDOTHITS: 1689 (void)printf("%llu\n", nch.ncs_dotdothits); 1690 break; 1691 } 1692 return (-1); 1693} 1694 1695/* 1696 * handle tty statistics 1697 */ 1698int 1699sysctl_tty(char *string, char **bufpp, int mib[], int flags, int *typep) 1700{ 1701 int indx; 1702 1703 if (*bufpp == NULL) { 1704 listall(string, &ttylist); 1705 return (-1); 1706 } 1707 if ((indx = findname(string, "third", bufpp, &ttylist)) == -1) 1708 return (-1); 1709 mib[2] = indx; 1710 1711 if ((*typep = ttylist.list[indx].ctl_type) == CTLTYPE_STRUCT) { 1712 if (flags) 1713 warnx("use pstat -t to view %s information", 1714 string); 1715 return (-1); 1716 } 1717 return (3); 1718} 1719 1720/* 1721 * handle fork statistics 1722 */ 1723int 1724sysctl_forkstat(char *string, char **bufpp, int mib[], int flags, int *typep) 1725{ 1726 static struct forkstat fks; 1727 static int keepvalue = 0; 1728 int indx; 1729 size_t size; 1730 1731 if (*bufpp == NULL) { 1732 bzero(&fks, sizeof(struct forkstat)); 1733 listall(string, &forkstatlist); 1734 return (-1); 1735 } 1736 if ((indx = findname(string, "third", bufpp, &forkstatlist)) == -1) 1737 return (-1); 1738 if (*bufpp != NULL) { 1739 warnx("fourth level name in %s is invalid", string); 1740 return (-1); 1741 } 1742 if (keepvalue == 0) { 1743 size = sizeof(struct forkstat); 1744 if (sysctl(mib, 2, &fks, &size, NULL, 0) < 0) 1745 return (-1); 1746 keepvalue = 1; 1747 } 1748 if (!nflag) 1749 (void)printf("%s%s", string, equ); 1750 switch (indx) { 1751 case KERN_FORKSTAT_FORK: 1752 (void)printf("%d\n", fks.cntfork); 1753 break; 1754 case KERN_FORKSTAT_VFORK: 1755 (void)printf("%d\n", fks.cntvfork); 1756 break; 1757 case KERN_FORKSTAT_TFORK: 1758 (void)printf("%d\n", fks.cnttfork); 1759 break; 1760 case KERN_FORKSTAT_KTHREAD: 1761 (void)printf("%d\n", fks.cntkthread); 1762 break; 1763 case KERN_FORKSTAT_SIZFORK: 1764 (void)printf("%d\n", fks.sizfork); 1765 break; 1766 case KERN_FORKSTAT_SIZVFORK: 1767 (void)printf("%d\n", fks.sizvfork); 1768 break; 1769 case KERN_FORKSTAT_SIZTFORK: 1770 (void)printf("%d\n", fks.siztfork); 1771 break; 1772 case KERN_FORKSTAT_SIZKTHREAD: 1773 (void)printf("%d\n", fks.sizkthread); 1774 break; 1775 } 1776 return (-1); 1777} 1778 1779/* 1780 * handle malloc statistics 1781 */ 1782int 1783sysctl_malloc(char *string, char **bufpp, int mib[], int flags, int *typep) 1784{ 1785 int indx, stor, i; 1786 char *name, bufp[SYSCTL_BUFSIZ], *buf, *ptr; 1787 struct list lp; 1788 size_t size; 1789 1790 if (*bufpp == NULL) { 1791 listall(string, &kernmalloclist); 1792 return (-1); 1793 } 1794 if ((indx = findname(string, "third", bufpp, &kernmalloclist)) == -1) 1795 return (-1); 1796 mib[2] = indx; 1797 if (mib[2] == KERN_MALLOC_BUCKET) { 1798 if ((name = strsep(bufpp, ".")) == NULL) { 1799 size = SYSCTL_BUFSIZ; 1800 stor = mib[2]; 1801 mib[2] = KERN_MALLOC_BUCKETS; 1802 buf = bufp; 1803 if (sysctl(mib, 3, buf, &size, NULL, 0) < 0) 1804 return (-1); 1805 mib[2] = stor; 1806 for (stor = 0, i = 0; i < size; i++) 1807 if (buf[i] == ',') 1808 stor++; 1809 lp.list = calloc(stor + 2, sizeof(struct ctlname)); 1810 if (lp.list == NULL) 1811 return (-1); 1812 lp.size = stor + 2; 1813 for (i = 1; 1814 (lp.list[i].ctl_name = strsep(&buf, ",")) != NULL; 1815 i++) { 1816 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1817 } 1818 lp.list[i].ctl_name = buf; 1819 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1820 listall(string, &lp); 1821 free(lp.list); 1822 return (-1); 1823 } 1824 mib[3] = atoi(name); 1825 return (4); 1826 } else if (mib[2] == KERN_MALLOC_BUCKETS) { 1827 *typep = CTLTYPE_STRING; 1828 return (3); 1829 } else if (mib[2] == KERN_MALLOC_KMEMSTATS) { 1830 size = SYSCTL_BUFSIZ; 1831 stor = mib[2]; 1832 mib[2] = KERN_MALLOC_KMEMNAMES; 1833 buf = bufp; 1834 if (sysctl(mib, 3, buf, &size, NULL, 0) < 0) 1835 return (-1); 1836 mib[2] = stor; 1837 if ((name = strsep(bufpp, ".")) == NULL) { 1838 for (stor = 0, i = 0; i < size; i++) 1839 if (buf[i] == ',') 1840 stor++; 1841 lp.list = calloc(stor + 2, sizeof(struct ctlname)); 1842 if (lp.list == NULL) 1843 return (-1); 1844 lp.size = stor + 2; 1845 for (i = 1; 1846 (lp.list[i].ctl_name = strsep(&buf, ",")) != NULL; 1847 i++) { 1848 if (lp.list[i].ctl_name[0] == '\0') { 1849 i--; 1850 continue; 1851 } 1852 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1853 } 1854 lp.list[i].ctl_name = buf; 1855 lp.list[i].ctl_type = CTLTYPE_STRUCT; 1856 listall(string, &lp); 1857 free(lp.list); 1858 return (-1); 1859 } 1860 ptr = strstr(buf, name); 1861 tryagain: 1862 if (ptr == NULL) { 1863 warnx("fourth level name %s in %s is invalid", name, 1864 string); 1865 return (-1); 1866 } 1867 if ((*(ptr + strlen(name)) != ',') && 1868 (*(ptr + strlen(name)) != '\0')) { 1869 ptr = strstr(ptr + 1, name); /* retry */ 1870 goto tryagain; 1871 } 1872 if ((ptr != buf) && (*(ptr - 1) != ',')) { 1873 ptr = strstr(ptr + 1, name); /* retry */ 1874 goto tryagain; 1875 } 1876 for (i = 0, stor = 0; buf + i < ptr; i++) 1877 if (buf[i] == ',') 1878 stor++; 1879 mib[3] = stor; 1880 return (4); 1881 } else if (mib[2] == KERN_MALLOC_KMEMNAMES) { 1882 *typep = CTLTYPE_STRING; 1883 return (3); 1884 } 1885 return (-1); 1886} 1887 1888#ifdef CPU_CHIPSET 1889/* 1890 * handle machdep.chipset requests 1891 */ 1892struct ctlname chipsetname[] = CTL_CHIPSET_NAMES; 1893struct list chipsetlist = { chipsetname, CPU_CHIPSET_MAXID }; 1894 1895int 1896sysctl_chipset(char *string, char **bufpp, int mib[], int flags, int *typep) 1897{ 1898 int indx, bwx; 1899 static void *q; 1900 size_t len; 1901 char *p; 1902 1903 if (*bufpp == NULL) { 1904 listall(string, &chipsetlist); 1905 return (-1); 1906 } 1907 if ((indx = findname(string, "third", bufpp, &chipsetlist)) == -1) 1908 return (-1); 1909 mib[2] = indx; 1910 if (!nflag) 1911 printf("%s%s", string, equ); 1912 switch(mib[2]) { 1913 case CPU_CHIPSET_MEM: 1914 case CPU_CHIPSET_DENSE: 1915 case CPU_CHIPSET_PORTS: 1916 case CPU_CHIPSET_HAE_MASK: 1917 len = sizeof(void *); 1918 if (sysctl(mib, 3, &q, &len, NULL, 0) < 0) 1919 goto done; 1920 printf("%p", q); 1921 break; 1922 case CPU_CHIPSET_BWX: 1923 len = sizeof(int); 1924 if (sysctl(mib, 3, &bwx, &len, NULL, 0) < 0) 1925 goto done; 1926 printf("%d", bwx); 1927 break; 1928 case CPU_CHIPSET_TYPE: 1929 if (sysctl(mib, 3, NULL, &len, NULL, 0) < 0) 1930 goto done; 1931 p = malloc(len + 1); 1932 if (p == NULL) 1933 goto done; 1934 if (sysctl(mib, 3, p, &len, NULL, 0) < 0) { 1935 free(p); 1936 goto done; 1937 } 1938 p[len] = '\0'; 1939 printf("%s", p); 1940 free(p); 1941 break; 1942 } 1943done: 1944 printf("\n"); 1945 return (-1); 1946} 1947#endif 1948/* 1949 * handle internet requests 1950 */ 1951int 1952sysctl_inet(char *string, char **bufpp, int mib[], int flags, int *typep) 1953{ 1954 struct list *lp; 1955 int indx; 1956 1957 if (*bufpp == NULL) { 1958 listall(string, &inetlist); 1959 return (-1); 1960 } 1961 if ((indx = findname(string, "third", bufpp, &inetlist)) == -1) 1962 return (-1); 1963 mib[2] = indx; 1964 if (indx < IPPROTO_MAXID && inetvars[indx].list != NULL) 1965 lp = &inetvars[indx]; 1966 else if (!flags) 1967 return (-1); 1968 else { 1969 warnx("%s: no variables defined for this protocol", string); 1970 return (-1); 1971 } 1972 if (*bufpp == NULL) { 1973 listall(string, lp); 1974 return (-1); 1975 } 1976 if ((indx = findname(string, "fourth", bufpp, lp)) == -1) 1977 return (-1); 1978 mib[3] = indx; 1979 *typep = lp->list[indx].ctl_type; 1980 if (*typep == CTLTYPE_NODE) { 1981 int tindx; 1982 1983 if (*bufpp == NULL) { 1984 listall(string, &ifqlist); 1985 return(-1); 1986 } 1987 lp = &ifqlist; 1988 if ((tindx = findname(string, "fifth", bufpp, lp)) == -1) 1989 return (-1); 1990 mib[4] = tindx; 1991 *typep = lp->list[tindx].ctl_type; 1992 return(5); 1993 } 1994 return (4); 1995} 1996 1997#ifdef INET6 1998struct ctlname inet6name[] = CTL_IPV6PROTO_NAMES; 1999struct ctlname ip6name[] = IPV6CTL_NAMES; 2000struct ctlname icmp6name[] = ICMPV6CTL_NAMES; 2001struct ctlname pim6name[] = PIM6CTL_NAMES; 2002struct ctlname divert6name[] = DIVERT6CTL_NAMES; 2003struct list inet6list = { inet6name, IPV6PROTO_MAXID }; 2004struct list inet6vars[] = { 2005/*0*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2006 { 0, 0 }, 2007 { 0, 0 }, 2008 { 0, 0 }, 2009 { 0, 0 }, 2010 { 0, 0 }, 2011/*10*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2012 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2013/*20*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2014 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2015/*30*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2016 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2017/*40*/ { 0, 0 }, 2018 { ip6name, IPV6CTL_MAXID }, /* ipv6 */ 2019 { 0, 0 }, 2020 { 0, 0 }, 2021 { 0, 0 }, 2022 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2023/*50*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2024 { 0, 0 }, 2025 { 0, 0 }, 2026 { 0, 0 }, 2027 { icmp6name, ICMPV6CTL_MAXID }, /* icmp6 */ 2028 { 0, 0 }, 2029/*60*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2030 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2031/*70*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2032 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2033/*80*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2034 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2035/*90*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2036 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2037/*100*/ { 0, 0 }, 2038 { 0, 0 }, 2039 { 0, 0 }, 2040 { pim6name, PIM6CTL_MAXID }, /* pim6 */ 2041 { 0, 0 }, 2042 { 0, 0 }, 2043 { 0, 0 }, 2044 { 0, 0 }, 2045 { 0, 0 }, 2046 { 0, 0 }, 2047/*110*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2048 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2049/*120*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2050 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2051/*130*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2052 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2053/*140*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2054 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2055/*150*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2056 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2057/*160*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2058 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2059/*170*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2060 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2061/*180*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2062 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2063/*190*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2064 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2065/*200*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2066 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2067/*210*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2068 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2069/*220*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2070 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2071/*230*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2072 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2073/*240*/ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2074 { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, 2075/*250*/ { 0, 0 }, 2076 { 0, 0 }, 2077 { 0, 0 }, 2078 { 0, 0 }, 2079 { 0, 0 }, 2080 { 0, 0 }, 2081 { 0, 0 }, 2082 { 0, 0 }, 2083 { divert6name, DIVERT6CTL_MAXID }, 2084}; 2085 2086/* 2087 * handle internet6 requests 2088 */ 2089int 2090sysctl_inet6(char *string, char **bufpp, int mib[], int flags, int *typep) 2091{ 2092 struct list *lp; 2093 int indx; 2094 2095 if (*bufpp == NULL) { 2096 listall(string, &inet6list); 2097 return (-1); 2098 } 2099 if ((indx = findname(string, "third", bufpp, &inet6list)) == -1) 2100 return (-1); 2101 mib[2] = indx; 2102 if (indx < IPV6PROTO_MAXID && inet6vars[indx].list != NULL) 2103 lp = &inet6vars[indx]; 2104 else if (!flags) 2105 return (-1); 2106 else { 2107 warnx("%s: no variables defined for this protocol", string); 2108 return (-1); 2109 } 2110 if (*bufpp == NULL) { 2111 listall(string, lp); 2112 return (-1); 2113 } 2114 if ((indx = findname(string, "fourth", bufpp, lp)) == -1) 2115 return (-1); 2116 mib[3] = indx; 2117 *typep = lp->list[indx].ctl_type; 2118 return (4); 2119} 2120#endif 2121 2122/* handle bpf requests */ 2123int 2124sysctl_bpf(char *string, char **bufpp, int mib[], int flags, int *typep) 2125{ 2126 int indx; 2127 2128 if (*bufpp == NULL) { 2129 listall(string, &bpflist); 2130 return (-1); 2131 } 2132 if ((indx = findname(string, "third", bufpp, &bpflist)) == -1) 2133 return (-1); 2134 mib[2] = indx; 2135 *typep = CTLTYPE_INT; 2136 return (3); 2137} 2138 2139struct ctlname mplsname[] = MPLSCTL_NAMES; 2140struct list mplslist = { mplsname, MPLSCTL_MAXID }; 2141 2142/* handle MPLS requests */ 2143int 2144sysctl_mpls(char *string, char **bufpp, int mib[], int flags, int *typep) 2145{ 2146 struct list *lp; 2147 int indx; 2148 2149 if (*bufpp == NULL) { 2150 listall(string, &mplslist); 2151 return (-1); 2152 } 2153 if ((indx = findname(string, "third", bufpp, &mplslist)) == -1) 2154 return (-1); 2155 mib[2] = indx; 2156 *typep = mplslist.list[indx].ctl_type; 2157 if (*typep == CTLTYPE_NODE) { 2158 int tindx; 2159 2160 if (*bufpp == NULL) { 2161 listall(string, &ifqlist); 2162 return(-1); 2163 } 2164 lp = &ifqlist; 2165 if ((tindx = findname(string, "fourth", bufpp, lp)) == -1) 2166 return (-1); 2167 mib[3] = tindx; 2168 *typep = lp->list[tindx].ctl_type; 2169 return(4); 2170 } 2171 return (3); 2172} 2173 2174/* handle PIPEX requests */ 2175int 2176sysctl_pipex(char *string, char **bufpp, int mib[], int flags, int *typep) 2177{ 2178 struct list *lp; 2179 int indx; 2180 2181 if (*bufpp == NULL) { 2182 listall(string, &pipexlist); 2183 return (-1); 2184 } 2185 if ((indx = findname(string, "third", bufpp, &pipexlist)) == -1) 2186 return (-1); 2187 mib[2] = indx; 2188 *typep = pipexlist.list[indx].ctl_type; 2189 if (*typep == CTLTYPE_NODE) { 2190 int tindx; 2191 2192 if (*bufpp == NULL) { 2193 listall(string, &ifqlist); 2194 return(-1); 2195 } 2196 lp = &ifqlist; 2197 if ((tindx = findname(string, "fourth", bufpp, lp)) == -1) 2198 return (-1); 2199 mib[3] = tindx; 2200 *typep = lp->list[tindx].ctl_type; 2201 return(4); 2202 } 2203 return (3); 2204} 2205 2206/* 2207 * Handle SysV semaphore info requests 2208 */ 2209int 2210sysctl_seminfo(string, bufpp, mib, flags, typep) 2211 char *string; 2212 char **bufpp; 2213 int mib[]; 2214 int flags; 2215 int *typep; 2216{ 2217 int indx; 2218 2219 if (*bufpp == NULL) { 2220 listall(string, &semlist); 2221 return (-1); 2222 } 2223 if ((indx = findname(string, "third", bufpp, &semlist)) == -1) 2224 return (-1); 2225 mib[2] = indx; 2226 *typep = CTLTYPE_INT; 2227 return (3); 2228} 2229 2230/* 2231 * Handle SysV shared memory info requests 2232 */ 2233int 2234sysctl_shminfo(string, bufpp, mib, flags, typep) 2235 char *string; 2236 char **bufpp; 2237 int mib[]; 2238 int flags; 2239 int *typep; 2240{ 2241 int indx; 2242 2243 if (*bufpp == NULL) { 2244 listall(string, &shmlist); 2245 return (-1); 2246 } 2247 if ((indx = findname(string, "third", bufpp, &shmlist)) == -1) 2248 return (-1); 2249 mib[2] = indx; 2250 *typep = CTLTYPE_INT; 2251 return (3); 2252} 2253 2254/* 2255 * Handle watchdog support 2256 */ 2257int 2258sysctl_watchdog(char *string, char **bufpp, int mib[], int flags, 2259 int *typep) 2260{ 2261 int indx; 2262 2263 if (*bufpp == NULL) { 2264 listall(string, &watchdoglist); 2265 return (-1); 2266 } 2267 if ((indx = findname(string, "third", bufpp, &watchdoglist)) == -1) 2268 return (-1); 2269 mib[2] = indx; 2270 *typep = watchdoglist.list[indx].ctl_type; 2271 return (3); 2272} 2273 2274/* 2275 * Handle timecounter support 2276 */ 2277int 2278sysctl_tc(char *string, char **bufpp, int mib[], int flags, 2279 int *typep) 2280{ 2281 int indx; 2282 2283 if (*bufpp == NULL) { 2284 listall(string, &tclist); 2285 return (-1); 2286 } 2287 if ((indx = findname(string, "third", bufpp, &tclist)) == -1) 2288 return (-1); 2289 mib[2] = indx; 2290 *typep = tclist.list[indx].ctl_type; 2291 return (3); 2292} 2293 2294/* 2295 * Handle hardware monitoring sensors support 2296 */ 2297int 2298sysctl_sensors(char *string, char **bufpp, int mib[], int flags, int *typep) 2299{ 2300 char *devname, *typename; 2301 int dev, numt, i; 2302 enum sensor_type type; 2303 struct sensordev snsrdev; 2304 size_t sdlen = sizeof(snsrdev); 2305 2306 if (*bufpp == NULL) { 2307 char buf[SYSCTL_BUFSIZ]; 2308 2309 /* scan all sensor devices */ 2310 for (dev = 0; ; dev++) { 2311 mib[2] = dev; 2312 if (sysctl(mib, 3, &snsrdev, &sdlen, NULL, 0) == -1) { 2313 if (errno == ENXIO) 2314 continue; 2315 if (errno == ENOENT) 2316 break; 2317 } 2318 snprintf(buf, sizeof(buf), "%s.%s", 2319 string, snsrdev.xname); 2320 print_sensordev(buf, mib, 3, &snsrdev); 2321 } 2322 return (-1); 2323 } 2324 2325 /* 2326 * If we get this far, it means that some arguments were 2327 * provided below hw.sensors tree. 2328 * The first branch of hw.sensors tree is the device name. 2329 */ 2330 if ((devname = strsep(bufpp, ".")) == NULL) { 2331 warnx("%s: incomplete specification", string); 2332 return (-1); 2333 } 2334 /* convert sensor device string to an integer */ 2335 for (dev = 0; ; dev++) { 2336 mib[2] = dev; 2337 if (sysctl(mib, 3, &snsrdev, &sdlen, NULL, 0) == -1) { 2338 if (errno == ENXIO) 2339 continue; 2340 if (errno == ENOENT) 2341 break; 2342 } 2343 if (strcmp(devname, snsrdev.xname) == 0) 2344 break; 2345 } 2346 if (strcmp(devname, snsrdev.xname) != 0) { 2347 warnx("%s: sensor device not found: %s", string, devname); 2348 return (-1); 2349 } 2350 if (*bufpp == NULL) { 2351 /* only device name was provided -- let's print all sensors 2352 * that are attached to the specified device 2353 */ 2354 print_sensordev(string, mib, 3, &snsrdev); 2355 return (-1); 2356 } 2357 2358 /* 2359 * At this point we have identified the sensor device, 2360 * now let's go further and identify sensor type. 2361 */ 2362 if ((typename = strsep(bufpp, ".")) == NULL) { 2363 warnx("%s: incomplete specification", string); 2364 return (-1); 2365 } 2366 numt = -1; 2367 for (i = 0; typename[i] != '\0'; i++) 2368 if (isdigit(typename[i])) { 2369 numt = atoi(&typename[i]); 2370 typename[i] = '\0'; 2371 break; 2372 } 2373 for (type = 0; type < SENSOR_MAX_TYPES; type++) 2374 if (strcmp(typename, sensor_type_s[type]) == 0) 2375 break; 2376 if (type == SENSOR_MAX_TYPES) { 2377 warnx("%s: sensor type not recognised: %s", string, typename); 2378 return (-1); 2379 } 2380 mib[3] = type; 2381 2382 /* 2383 * If no integer was provided after sensor_type, let's 2384 * print all sensors of the specified type. 2385 */ 2386 if (numt == -1) { 2387 print_sensordev(string, mib, 4, &snsrdev); 2388 return (-1); 2389 } 2390 2391 /* 2392 * At this point we know that we have received a direct request 2393 * via command-line for a specific sensor. Let's have the parse() 2394 * function deal with it further, and report any errors if such 2395 * sensor node does not exist. 2396 */ 2397 mib[4] = numt; 2398 *typep = CTLTYPE_STRUCT; 2399 return (5); 2400} 2401 2402/* 2403 * Print sensors from the specified device. 2404 */ 2405 2406void 2407print_sensordev(char *string, int mib[], u_int mlen, struct sensordev *snsrdev) 2408{ 2409 char buf[SYSCTL_BUFSIZ]; 2410 enum sensor_type type; 2411 2412 if (mlen == 3) { 2413 for (type = 0; type < SENSOR_MAX_TYPES; type++) { 2414 mib[3] = type; 2415 snprintf(buf, sizeof(buf), "%s.%s", 2416 string, sensor_type_s[type]); 2417 print_sensordev(buf, mib, mlen+1, snsrdev); 2418 } 2419 return; 2420 } 2421 2422 if (mlen == 4) { 2423 int numt; 2424 2425 type = mib[3]; 2426 for (numt = 0; numt < snsrdev->maxnumt[type]; numt++) { 2427 mib[4] = numt; 2428 snprintf(buf, sizeof(buf), "%s%u", string, numt); 2429 print_sensordev(buf, mib, mlen+1, snsrdev); 2430 } 2431 return; 2432 } 2433 2434 if (mlen == 5) { 2435 struct sensor snsr; 2436 size_t slen = sizeof(snsr); 2437 2438 /* this function is only printing sensors in bulk, so we 2439 * do not return any error messages if the requested sensor 2440 * is not found by sysctl(3) 2441 */ 2442 if (sysctl(mib, 5, &snsr, &slen, NULL, 0) == -1) 2443 return; 2444 2445 if (slen > 0 && (snsr.flags & SENSOR_FINVALID) == 0) { 2446 if (!nflag) 2447 printf("%s%s", string, equ); 2448 print_sensor(&snsr); 2449 printf("\n"); 2450 } 2451 return; 2452 } 2453} 2454 2455void 2456print_sensor(struct sensor *s) 2457{ 2458 const char *name; 2459 2460 if (s->flags & SENSOR_FUNKNOWN) 2461 printf("unknown"); 2462 else { 2463 switch (s->type) { 2464 case SENSOR_TEMP: 2465 printf("%.2f degC", 2466 (s->value - 273150000) / 1000000.0); 2467 break; 2468 case SENSOR_FANRPM: 2469 printf("%lld RPM", s->value); 2470 break; 2471 case SENSOR_VOLTS_DC: 2472 printf("%.2f VDC", s->value / 1000000.0); 2473 break; 2474 case SENSOR_VOLTS_AC: 2475 printf("%.2f VAC", s->value / 1000000.0); 2476 break; 2477 case SENSOR_OHMS: 2478 printf("%lld ohm", s->value); 2479 break; 2480 case SENSOR_WATTS: 2481 printf("%.2f W", s->value / 1000000.0); 2482 break; 2483 case SENSOR_AMPS: 2484 printf("%.2f A", s->value / 1000000.0); 2485 break; 2486 case SENSOR_WATTHOUR: 2487 printf("%.2f Wh", s->value / 1000000.0); 2488 break; 2489 case SENSOR_AMPHOUR: 2490 printf("%.2f Ah", s->value / 1000000.0); 2491 break; 2492 case SENSOR_INDICATOR: 2493 printf("%s", s->value ? "On" : "Off"); 2494 break; 2495 case SENSOR_INTEGER: 2496 printf("%lld", s->value); 2497 break; 2498 case SENSOR_PERCENT: 2499 printf("%.2f%%", s->value / 1000.0); 2500 break; 2501 case SENSOR_LUX: 2502 printf("%.2f lx", s->value / 1000000.0); 2503 break; 2504 case SENSOR_DRIVE: 2505 switch (s->value) { 2506 case SENSOR_DRIVE_EMPTY: 2507 name = "empty"; 2508 break; 2509 case SENSOR_DRIVE_READY: 2510 name = "ready"; 2511 break; 2512 case SENSOR_DRIVE_POWERUP: 2513 name = "powering up"; 2514 break; 2515 case SENSOR_DRIVE_ONLINE: 2516 name = "online"; 2517 break; 2518 case SENSOR_DRIVE_IDLE: 2519 name = "idle"; 2520 break; 2521 case SENSOR_DRIVE_ACTIVE: 2522 name = "active"; 2523 break; 2524 case SENSOR_DRIVE_REBUILD: 2525 name = "rebuilding"; 2526 break; 2527 case SENSOR_DRIVE_POWERDOWN: 2528 name = "powering down"; 2529 break; 2530 case SENSOR_DRIVE_FAIL: 2531 name = "failed"; 2532 break; 2533 case SENSOR_DRIVE_PFAIL: 2534 name = "degraded"; 2535 break; 2536 default: 2537 name = "unknown"; 2538 break; 2539 } 2540 printf(name); 2541 break; 2542 case SENSOR_TIMEDELTA: 2543 printf("%.6f secs", s->value / 1000000000.0); 2544 break; 2545 case SENSOR_HUMIDITY: 2546 printf("%.2f%%", s->value / 1000.0); 2547 break; 2548 case SENSOR_FREQ: 2549 printf("%.2f Hz", s->value / 1000000.0); 2550 break; 2551 case SENSOR_ANGLE: 2552 printf("%3.4f degrees", s->value / 1000000.0); 2553 break; 2554 case SENSOR_DISTANCE: 2555 printf("%.2f mm", s->value / 1000.0); 2556 break; 2557 case SENSOR_PRESSURE: 2558 printf("%.2f Pa", s->value / 1000.0); 2559 break; 2560 case SENSOR_ACCEL: 2561 printf("%2.4f m/s^2", s->value / 1000000.0); 2562 break; 2563 default: 2564 printf("unknown"); 2565 } 2566 } 2567 2568 if (s->desc[0] != '\0') 2569 printf(" (%s)", s->desc); 2570 2571 switch (s->status) { 2572 case SENSOR_S_UNSPEC: 2573 break; 2574 case SENSOR_S_OK: 2575 printf(", OK"); 2576 break; 2577 case SENSOR_S_WARN: 2578 printf(", WARNING"); 2579 break; 2580 case SENSOR_S_CRIT: 2581 printf(", CRITICAL"); 2582 break; 2583 case SENSOR_S_UNKNOWN: 2584 printf(", UNKNOWN"); 2585 break; 2586 } 2587 2588 if (s->tv.tv_sec) { 2589 time_t t = s->tv.tv_sec; 2590 char ct[26]; 2591 2592 ctime_r(&t, ct); 2593 ct[19] = '\0'; 2594 printf(", %s.%03ld", ct, s->tv.tv_usec / 1000); 2595 } 2596} 2597 2598struct emulname { 2599 char *name; 2600 int index; 2601} *emul_names; 2602int emul_num, nemuls; 2603int emul_init(void); 2604 2605int 2606sysctl_emul(char *string, char *newval, int flags) 2607{ 2608 int mib[4], enabled, i, old, print, found = 0; 2609 char *head, *target; 2610 size_t len; 2611 2612 if (emul_init() == -1) { 2613 warnx("emul_init: out of memory"); 2614 return (1); 2615 } 2616 2617 mib[0] = CTL_KERN; 2618 mib[1] = KERN_EMUL; 2619 mib[3] = KERN_EMUL_ENABLED; 2620 head = "kern.emul."; 2621 2622 if (aflag || strcmp(string, "kern.emul") == 0) { 2623 if (newval) { 2624 warnx("%s: specification is incomplete", string); 2625 return (1); 2626 } 2627 if (nflag) 2628 printf("%d\n", nemuls); 2629 else 2630 printf("%snemuls%s%d\n", head, equ, nemuls); 2631 for (i = 0; i < emul_num; i++) { 2632 if (emul_names[i].name == NULL) 2633 break; 2634 if (i > 0 && strcmp(emul_names[i].name, 2635 emul_names[i-1].name) == 0) 2636 continue; 2637 mib[2] = emul_names[i].index; 2638 len = sizeof(int); 2639 if (sysctl(mib, 4, &enabled, &len, NULL, 0) == -1) { 2640 warn("%s", string); 2641 continue; 2642 } 2643 if (nflag) 2644 printf("%d\n", enabled); 2645 else 2646 printf("%s%s%s%d\n", head, emul_names[i].name, 2647 equ, enabled); 2648 } 2649 return (0); 2650 } 2651 /* User specified a third level name */ 2652 target = strrchr(string, '.'); 2653 target++; 2654 if (strcmp(target, "nemuls") == 0) { 2655 if (newval) { 2656 warnx("Operation not permitted"); 2657 return (1); 2658 } 2659 if (nflag) 2660 printf("%d\n", nemuls); 2661 else 2662 printf("%snemuls = %d\n", head, nemuls); 2663 return (0); 2664 } 2665 print = 1; 2666 for (i = 0; i < emul_num; i++) { 2667 if (!emul_names[i].name || (strcmp(target, emul_names[i].name))) 2668 continue; 2669 found = 1; 2670 mib[2] = emul_names[i].index; 2671 len = sizeof(int); 2672 if (newval) { 2673 enabled = atoi(newval); 2674 if (sysctl(mib, 4, &old, &len, &enabled, len) == -1) { 2675 warn("%s", string); 2676 print = 0; 2677 continue; 2678 } 2679 if (print) { 2680 if (nflag) 2681 printf("%d\n", enabled); 2682 else 2683 printf("%s%s: %d -> %d\n", head, 2684 target, old, enabled); 2685 } 2686 } else { 2687 if (sysctl(mib, 4, &enabled, &len, NULL, 0) == -1) { 2688 warn("%s", string); 2689 continue; 2690 } 2691 if (print) { 2692 if (nflag) 2693 printf("%d\n", enabled); 2694 else 2695 printf("%s%s = %d\n", head, target, 2696 enabled); 2697 } 2698 } 2699 print = 0; 2700 } 2701 if (!found) 2702 warnx("third level name %s in kern.emul is invalid", 2703 string); 2704 return (0); 2705 2706 2707} 2708 2709int 2710emulcmp(const void *m, const void *n) 2711{ 2712 const struct emulname *a = m, *b = n; 2713 2714 if (!a || !a->name) 2715 return 1; 2716 if (!b || !b->name) 2717 return -1; 2718 return (strcmp(a->name, b->name)); 2719} 2720 2721int 2722emul_init(void) 2723{ 2724 static int done; 2725 char string[16]; 2726 int mib[4], i; 2727 size_t len; 2728 2729 if (done) 2730 return (0); 2731 done = 1; 2732 2733 mib[0] = CTL_KERN; 2734 mib[1] = KERN_EMUL; 2735 mib[2] = KERN_EMUL_NUM; 2736 len = sizeof(int); 2737 if (sysctl(mib, 3, &emul_num, &len, NULL, 0) == -1) 2738 return (-1); 2739 2740 emul_names = calloc(emul_num, sizeof(*emul_names)); 2741 if (emul_names == NULL) 2742 return (-1); 2743 2744 nemuls = emul_num; 2745 for (i = 0; i < emul_num; i++) { 2746 emul_names[i].index = mib[2] = i + 1; 2747 mib[3] = KERN_EMUL_NAME; 2748 len = sizeof(string); 2749 if (sysctl(mib, 4, string, &len, NULL, 0) == -1) 2750 continue; 2751 if (strcmp(string, "native") == 0) 2752 continue; 2753 emul_names[i].name = strdup(string); 2754 if (emul_names[i].name == NULL) { 2755 free(emul_names); 2756 return (-1); 2757 } 2758 } 2759 qsort(emul_names, nemuls, sizeof(*emul_names), emulcmp); 2760 for (i = 0; i < emul_num; i++) { 2761 if (!emul_names[i].name || (i > 0 && 2762 strcmp(emul_names[i].name, emul_names[i - 1].name) == 0)) 2763 nemuls--; 2764 } 2765 return (0); 2766} 2767 2768/* 2769 * Scan a list of names searching for a particular name. 2770 */ 2771int 2772findname(char *string, char *level, char **bufp, struct list *namelist) 2773{ 2774 char *name; 2775 int i; 2776 2777 if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) { 2778 warnx("%s: incomplete specification", string); 2779 return (-1); 2780 } 2781 for (i = 0; i < namelist->size; i++) 2782 if (namelist->list[i].ctl_name != NULL && 2783 strcmp(name, namelist->list[i].ctl_name) == 0) 2784 break; 2785 if (i == namelist->size) { 2786 warnx("%s level name %s in %s is invalid", level, name, string); 2787 return (-1); 2788 } 2789 return (i); 2790} 2791 2792void 2793usage(void) 2794{ 2795 2796 (void)fprintf(stderr, 2797 "usage: sysctl [-Aan]\n" 2798 " sysctl [-n] name ...\n" 2799 " sysctl [-nq] name=value ...\n"); 2800 exit(1); 2801} 2802