1: /*
   2:  * Copyright (c) 1993
   3:  *	The Regents of the University of California.  All rights reserved.
   4:  *
   5:  * Redistribution and use in source and binary forms, with or without
   6:  * modification, are permitted provided that the following conditions
   7:  * are met:
   8:  * 1. Redistributions of source code must retain the above copyright
   9:  *    notice, this list of conditions and the following disclaimer.
  10:  * 2. Redistributions in binary form must reproduce the above copyright
  11:  *    notice, this list of conditions and the following disclaimer in the
  12:  *    documentation and/or other materials provided with the distribution.
  13:  * 3. All advertising materials mentioning features or use of this software
  14:  *    must display the following acknowledgement:
  15:  *	This product includes software developed by the University of
  16:  *	California, Berkeley and its contributors.
  17:  * 4. Neither the name of the University nor the names of its contributors
  18:  *    may be used to endorse or promote products derived from this software
  19:  *    without specific prior written permission.
  20:  *
  21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31:  * SUCH DAMAGE.
  32:  */
  33: 
  34: #if !defined(lint) && defined(DOSCCS)
  35: static char copyright[] =
  36: "@(#) Copyright (c) 1993\n\
  37: 	The Regents of the University of California.  All rights reserved.\n";
  38: 
  39: static char sccsid[] = "@(#)sysctl.c	8.1.4 (2.11BSD GTE) 1998/4/3";
  40: #endif /* not lint */
  41: 
  42: #include <sys/param.h>
  43: #include <sys/stat.h>
  44: #include <sys/sysctl.h>
  45: #include <sys/socket.h>
  46: #include <machine/cpu.h>
  47: 
  48: #include <netinet/in.h>
  49: #include <netinet/in_systm.h>
  50: #include <netinet/ip.h>
  51: #include <netinet/ip_icmp.h>
  52: #include <netinet/icmp_var.h>
  53: #include <netinet/ip_var.h>
  54: #include <netinet/udp.h>
  55: #include <netinet/udp_var.h>
  56: 
  57: #include <errno.h>
  58: #include <stdio.h>
  59: #include <string.h>
  60: #include <ctype.h>
  61: 
  62: struct ctlname topname[] = CTL_NAMES;
  63: struct ctlname kernname[] = CTL_KERN_NAMES;
  64: struct ctlname vmname[] = CTL_VM_NAMES;
  65: #ifdef  CTL_NET_NAMES
  66: struct ctlname netname[] = CTL_NET_NAMES;
  67: #endif
  68: struct ctlname hwname[] = CTL_HW_NAMES;
  69: struct ctlname username[] = CTL_USER_NAMES;
  70: struct ctlname debugname[CTL_DEBUG_MAXID];
  71: struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
  72: char names[BUFSIZ];
  73: 
  74: struct list {
  75:     struct  ctlname *list;
  76:     int size;
  77: };
  78: struct list toplist = { topname, CTL_MAXID };
  79: struct list secondlevel[] = {
  80:     { 0, 0 },           /* CTL_UNSPEC */
  81:     { kernname, KERN_MAXID },   /* CTL_KERN */
  82:     { vmname, VM_MAXID },       /* CTL_VM */
  83:     { 0, 0 },           /* CTL_FS */
  84: #ifdef  CTL_NET_NAMES
  85:     { netname, NET_MAXID },     /* CTL_NET */
  86: #else
  87:     { 0, 0 },
  88: #endif
  89:     { 0, CTL_DEBUG_MAXID },     /* CTL_DEBUG */
  90:     { hwname, HW_MAXID },       /* CTL_HW */
  91:     { machdepname, CPU_MAXID }, /* CTL_MACHDEP */
  92:     { username, USER_MAXID },   /* CTL_USER_NAMES */
  93: };
  94: 
  95: int Aflag, aflag, nflag, wflag;
  96: 
  97: extern char *optarg;
  98: extern int optind, errno;
  99: 
 100: /*
 101:  * Variables requiring special processing.
 102:  */
 103: #define CLOCK       0x0001
 104: #define BOOTTIME    0x0002
 105: #define CONSDEV     0x0004
 106: 
 107: int
 108: main(argc, argv)
 109:     int argc;
 110:     char *argv[];
 111: {
 112:     int ch, lvl1;
 113: 
 114:     while ((ch = getopt(argc, argv, "Aanw")) != EOF) {
 115:         switch (ch) {
 116: 
 117:         case 'A':
 118:             Aflag = 1;
 119:             break;
 120: 
 121:         case 'a':
 122:             aflag = 1;
 123:             break;
 124: 
 125:         case 'n':
 126:             nflag = 1;
 127:             break;
 128: 
 129:         case 'w':
 130:             wflag = 1;
 131:             break;
 132: 
 133:         default:
 134:             usage();
 135:         }
 136:     }
 137:     argc -= optind;
 138:     argv += optind;
 139: 
 140:     if (Aflag || aflag) {
 141:         debuginit();
 142:         for (lvl1 = 1; lvl1 < CTL_MAXID; lvl1++)
 143:             listall(topname[lvl1].ctl_name, &secondlevel[lvl1]);
 144:         exit(0);
 145:     }
 146:     if (argc == 0)
 147:         usage();
 148:     while (argc-- > 0)
 149:         parse(*argv, 1);
 150:     exit(0);
 151: }
 152: 
 153: /*
 154:  * List all variables known to the system.
 155:  */
 156: listall(prefix, lp)
 157:     char *prefix;
 158:     struct list *lp;
 159: {
 160:     int lvl2;
 161:     char *cp, name[BUFSIZ];
 162: 
 163:     if (lp->list == 0)
 164:         return;
 165:     strcpy(name, prefix);
 166:     cp = &name[strlen(name)];
 167:     *cp++ = '.';
 168:     for (lvl2 = 0; lvl2 < lp->size; lvl2++) {
 169:         if (lp->list[lvl2].ctl_name == 0)
 170:             continue;
 171:         strcpy(cp, lp->list[lvl2].ctl_name);
 172:         parse(name, Aflag);
 173:     }
 174: }
 175: 
 176: /*
 177:  * Parse a name into a MIB entry.
 178:  * Lookup and print out the MIB entry if it exists.
 179:  * Set a new value if requested.
 180:  */
 181: parse(string, flags)
 182:     char *string;
 183:     int flags;
 184: {
 185:     int indx, type, state, size, len;
 186:     int special = 0;
 187:     void *newval = (void *)0;
 188:     int intval, newsize = 0;
 189:     long longval;
 190:     struct list *lp;
 191:     int mib[CTL_MAXNAME];
 192:     char *cp, *bufp, buf[BUFSIZ], strval[BUFSIZ];
 193: 
 194:     bufp = buf;
 195:     strcpy(buf, string);
 196:     if ((cp = strchr(string, '=')) != NULL) {
 197:         if (!wflag) {
 198:             fprintf(stderr, "Must specify -w to set variables\n");
 199:             exit(2);
 200:         }
 201:         *strchr(buf, '=') = '\0';
 202:         *cp++ = '\0';
 203:         while (isspace(*cp))
 204:             cp++;
 205:         newval = (void *)cp;
 206:         newsize = strlen(cp);
 207:     }
 208:     if ((indx = findname(string, "top", &bufp, &toplist)) == -1)
 209:         return;
 210:     mib[0] = indx;
 211:     if (indx == CTL_DEBUG)
 212:         debuginit();
 213:     lp = &secondlevel[indx];
 214:     if (lp->list == 0) {
 215:         fprintf(stderr, "%s: class is not implemented\n",
 216:             topname[indx]);
 217:         return;
 218:     }
 219:     if (bufp == NULL) {
 220:         listall(topname[indx].ctl_name, lp);
 221:         return;
 222:     }
 223:     if ((indx = findname(string, "second", &bufp, lp)) == -1)
 224:         return;
 225:     mib[1] = indx;
 226:     type = lp->list[indx].ctl_type;
 227:     len = 2;
 228:     switch (mib[0]) {
 229: 
 230:     case CTL_KERN:
 231:         switch (mib[1]) {
 232:         case KERN_PROF:
 233:             fprintf(stderr,
 234:                 "kern.prof =  not supported in 2.11BSD\n");
 235:             return;
 236:         case KERN_INODE:
 237:         case KERN_FILE:
 238:         case KERN_TEXT:
 239:             if (flags == 0)
 240:                 return;
 241:             fprintf(stderr,
 242:                 "Use pstat to view %s information\n", string);
 243:             return;
 244:         case KERN_PROC:
 245:             if (flags == 0)
 246:                 return;
 247:             fprintf(stderr,
 248:                 "Use ps to view %s information\n", string);
 249:             return;
 250:         case KERN_CLOCKRATE:
 251:             special |= CLOCK;
 252:             break;
 253:         case KERN_BOOTTIME:
 254:             special |= BOOTTIME;
 255:             break;
 256:         }
 257:         break;
 258: 
 259:     case CTL_HW:
 260:         break;
 261: 
 262:     case CTL_VM:
 263:         if (mib[1] == VM_LOADAVG) {
 264:             double loads[3];
 265: 
 266:             getloadavg(loads, 3);
 267:             if (!nflag)
 268:                 fprintf(stdout, "%s: ", string);
 269:             fprintf(stdout, "%.2f %.2f %.2f\n",
 270:                 loads[0], loads[1], loads[2]);
 271:             return;
 272:         }
 273:         if (flags == 0)
 274:             return;
 275:         fprintf(stderr,
 276:             "Use vmstat or pstat to view %s information\n", string);
 277:         return;
 278: 
 279:     case CTL_NET:
 280:         if (mib[1] == PF_INET) {
 281:             len = sysctl_inet(string, &bufp, mib, flags, &type);
 282:             if (len >= 0)
 283:                 break;
 284:             return;
 285:         }
 286:         if (flags == 0)
 287:             return;
 288:         fprintf(stderr, "Use netstat to view %s information\n", string);
 289:         return;
 290: 
 291:     case CTL_DEBUG:
 292:         mib[2] = CTL_DEBUG_VALUE;
 293:         len = 3;
 294:         break;
 295: 
 296:     case CTL_MACHDEP:
 297:         if (mib[1] == CPU_CONSDEV)
 298:             special |= CONSDEV;
 299:         if (mib[1] == CPU_TMSCP) {
 300:             len = sysctl_tmscp(string, &bufp, mib, flags, &type);
 301:             if (len >= 0)
 302:                 goto doit;
 303:             return;
 304:         }
 305:         if (mib[1] == CPU_MSCP) {
 306:             len = sysctl_mscp(string, &bufp, mib, flags, &type);
 307:             if (len >= 0)
 308:                 goto doit;
 309:             return;
 310:         }
 311:         break;
 312: 
 313:     case CTL_FS:
 314:     case CTL_USER:
 315:         break;
 316: 
 317:     default:
 318:         fprintf(stderr, "Illegal top level value: %d\n", mib[0]);
 319:         return;
 320: 
 321:     }
 322: doit:
 323:     if (bufp) {
 324:         fprintf(stderr, "name %s in %s is unknown\n", *bufp, string);
 325:         return;
 326:     }
 327:     if (newsize > 0) {
 328:         switch (type) {
 329:         case CTLTYPE_INT:
 330:             intval = atoi(newval);
 331:             newval = (void *)&intval;
 332:             newsize = sizeof intval;
 333:             break;
 334: 
 335:         case CTLTYPE_LONG:
 336:             sscanf(newval, "%ld", &longval);
 337:             newval = (void *)&longval;
 338:             newsize = sizeof longval;
 339:             break;
 340:         }
 341:     }
 342:     size = BUFSIZ;
 343:     if (sysctl(mib, len, buf, &size, newsize ? newval : (void *)0, newsize) == -1) {
 344:         if (flags == 0)
 345:             return;
 346:         switch (errno) {
 347:         case EOPNOTSUPP:
 348:             fprintf(stderr, "%s: value is not available\n", string);
 349:             return;
 350:         case ENOTDIR:
 351:             fprintf(stderr, "%s: specification is incomplete\n",
 352:                 string);
 353:             return;
 354:         case ENOMEM:
 355:             fprintf(stderr, "%s: type is unknown to this program\n",
 356:                 string);
 357:             return;
 358:         default:
 359:             perror(string);
 360:             return;
 361:         }
 362:     }
 363:     if (special & CLOCK) {
 364:         struct clockinfo *clkp = (struct clockinfo *)buf;
 365: 
 366:         if (!nflag)
 367:             fprintf(stdout, "%s: ", string);
 368:         fprintf(stdout,
 369:             "hz = %d, tick = %d, profhz = %d, stathz = %d\n",
 370:             clkp->hz, clkp->tick, clkp->profhz, clkp->stathz);
 371:         return;
 372:     }
 373:     if (special & BOOTTIME) {
 374:         struct timeval *btp = (struct timeval *)buf;
 375: 
 376:         if (!nflag)
 377:             fprintf(stdout, "%s = %s", string,
 378:                 ctime(&btp->tv_sec));
 379:         else
 380:             fprintf(stdout, "%d\n", btp->tv_sec);
 381:         return;
 382:     }
 383:     if (special & CONSDEV) {
 384:         dev_t dev = *(dev_t *)buf;
 385: 
 386:         if (!nflag)
 387:             fprintf(stdout, "%s = %s\n", string,
 388:                 devname(dev, S_IFCHR));
 389:         else
 390:             fprintf(stdout, "0x%x\n", dev);
 391:         return;
 392:     }
 393:     switch (type) {
 394:     case CTLTYPE_INT:
 395:         if (newsize == 0) {
 396:             if (!nflag)
 397:                 fprintf(stdout, "%s = ", string);
 398:             fprintf(stdout, "%d\n", *(int *)buf);
 399:         } else {
 400:             if (!nflag)
 401:                 fprintf(stdout, "%s: %d -> ", string,
 402:                     *(int *)buf);
 403:             fprintf(stdout, "%d\n", *(int *)newval);
 404:         }
 405:         return;
 406: 
 407:     case CTLTYPE_STRING:
 408:         if (newsize == 0) {
 409:             if (!nflag)
 410:                 fprintf(stdout, "%s = ", string);
 411:             fprintf(stdout, "%s\n", buf);
 412:         } else {
 413:             if (!nflag)
 414:                 fprintf(stdout, "%s: %s -> ", string, buf);
 415:             fprintf(stdout, "%s\n", newval);
 416:         }
 417:         return;
 418: 
 419:     case CTLTYPE_LONG:
 420:         if (newsize == 0) {
 421:             if (!nflag)
 422:                 fprintf(stdout, "%s = ", string);
 423:             fprintf(stdout, "%ld\n", *(long *)buf);
 424:         } else {
 425:             if (!nflag)
 426:                 fprintf(stdout, "%s: %ld -> ", string,
 427:                     *(long *)buf);
 428:             fprintf(stdout, "%ld\n", *(long *)newval);
 429:         }
 430:         return;
 431: 
 432:     case CTLTYPE_STRUCT:
 433:         fprintf(stderr, "%s: unknown structure returned\n",
 434:             string);
 435:         return;
 436: 
 437:     default:
 438:     case CTLTYPE_NODE:
 439:         fprintf(stderr, "%s: unknown type returned\n",
 440:             string);
 441:         return;
 442:     }
 443: }
 444: 
 445: struct  ctlname tmscpname[]  = TMSCP_NAMES;
 446: struct  list tmscplist = { tmscpname, TMSCP_MAXID };
 447: 
 448: struct  ctlname mscpname[]  = MSCP_NAMES;
 449: struct  list mscplist = { mscpname, MSCP_MAXID };
 450: 
 451: /*
 452:  * Handle machdep.tmscp.x
 453: */
 454: sysctl_tmscp(string, bufpp, mib, flags, typep)
 455:     char *string;
 456:     char **bufpp;
 457:     int mib[];
 458:     int flags;
 459:     int *typep;
 460: {
 461:     int indx;
 462: 
 463:     if (*bufpp == NULL) {
 464:         listall(string, &tmscplist);
 465:         return (-1);
 466:     }
 467:     if ((indx = findname(string, "third", bufpp, &tmscplist)) == -1)
 468:         return (-1);
 469:     mib[2] = indx;
 470:     *typep = tmscpname[indx].ctl_type;
 471:     return (3);
 472: }
 473: 
 474: /*
 475:  * Handle machdep.mscp.x
 476: */
 477: sysctl_mscp(string, bufpp, mib, flags, typep)
 478:     char *string;
 479:     char **bufpp;
 480:     int mib[];
 481:     int flags;
 482:     int *typep;
 483: {
 484:     int indx;
 485: 
 486:     if (*bufpp == NULL) {
 487:         listall(string, &mscplist);
 488:         return (-1);
 489:     }
 490:     if ((indx = findname(string, "third", bufpp, &mscplist)) == -1)
 491:         return (-1);
 492:     mib[2] = indx;
 493:     *typep = mscpname[indx].ctl_type;
 494:     return (3);
 495: }
 496: 
 497: /*
 498:  * Initialize the set of debugging names
 499:  */
 500: debuginit()
 501: {
 502:     int mib[3], size, loc, i;
 503: 
 504:     if (secondlevel[CTL_DEBUG].list != 0)
 505:         return;
 506:     secondlevel[CTL_DEBUG].list = debugname;
 507:     mib[0] = CTL_DEBUG;
 508:     mib[2] = CTL_DEBUG_NAME;
 509:     for (loc = 0, i = 0; i < CTL_DEBUG_MAXID; i++) {
 510:         mib[1] = i;
 511:         size = BUFSIZ - loc;
 512:         if (sysctl(mib, 3, &names[loc], &size, NULL, 0) == -1)
 513:             continue;
 514:         debugname[i].ctl_name = &names[loc];
 515:         debugname[i].ctl_type = CTLTYPE_INT;
 516:         loc += size;
 517:     }
 518: }
 519: 
 520: struct ctlname inetname[] = CTL_IPPROTO_NAMES;
 521: struct ctlname ipname[] = IPCTL_NAMES;
 522: struct ctlname icmpname[] = ICMPCTL_NAMES;
 523: struct ctlname udpname[] = UDPCTL_NAMES;
 524: struct list inetlist = { inetname, IPPROTO_MAXID };
 525: struct list inetvars[] = {
 526:     { ipname, IPCTL_MAXID },    /* ip */
 527:     { icmpname, ICMPCTL_MAXID },    /* icmp */
 528:     { 0, 0 },           /* igmp */
 529:     { 0, 0 },           /* ggmp */
 530:     { 0, 0 },
 531:     { 0, 0 },
 532:     { 0, 0 },           /* tcp */
 533:     { 0, 0 },
 534:     { 0, 0 },           /* egp */
 535:     { 0, 0 },
 536:     { 0, 0 },
 537:     { 0, 0 },
 538:     { 0, 0 },           /* pup */
 539:     { 0, 0 },
 540:     { 0, 0 },
 541:     { 0, 0 },
 542:     { 0, 0 },
 543:     { udpname, UDPCTL_MAXID },  /* udp */
 544: };
 545: 
 546: /*
 547:  * handle internet requests
 548:  */
 549: sysctl_inet(string, bufpp, mib, flags, typep)
 550:     char *string;
 551:     char **bufpp;
 552:     int mib[];
 553:     int flags;
 554:     int *typep;
 555: {
 556:     struct list *lp;
 557:     int indx;
 558: 
 559:     if (*bufpp == NULL) {
 560:         listall(string, &inetlist);
 561:         return (-1);
 562:     }
 563:     if ((indx = findname(string, "third", bufpp, &inetlist)) == -1)
 564:         return (-1);
 565:     mib[2] = indx;
 566:     if (indx <= IPPROTO_UDP && inetvars[indx].list != NULL)
 567:         lp = &inetvars[indx];
 568:     else if (!flags)
 569:         return (-1);
 570:     else {
 571:         fprintf(stderr, "%s: no variables defined for this protocol\n",
 572:             string);
 573:         return (-1);
 574:     }
 575:     if (*bufpp == NULL) {
 576:         listall(string, lp);
 577:         return (-1);
 578:     }
 579:     if ((indx = findname(string, "fourth", bufpp, lp)) == -1)
 580:         return (-1);
 581:     mib[3] = indx;
 582:     *typep = lp->list[indx].ctl_type;
 583:     return (4);
 584: }
 585: 
 586: /*
 587:  * Scan a list of names searching for a particular name.
 588:  */
 589: findname(string, level, bufp, namelist)
 590:     char *string;
 591:     char *level;
 592:     char **bufp;
 593:     struct list *namelist;
 594: {
 595:     char *name;
 596:     int i;
 597: 
 598:     if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) {
 599:         fprintf(stderr, "%s: incomplete specification\n", string);
 600:         return (-1);
 601:     }
 602:     for (i = 0; i < namelist->size; i++)
 603:         if (namelist->list[i].ctl_name != NULL &&
 604:             strcmp(name, namelist->list[i].ctl_name) == 0)
 605:             break;
 606:     if (i == namelist->size) {
 607:         fprintf(stderr, "%s level name %s in %s is invalid\n",
 608:             level, name, string);
 609:         return (-1);
 610:     }
 611:     return (i);
 612: }
 613: 
 614: usage()
 615: {
 616: 
 617:     (void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n\t%s\n",
 618:         "sysctl [-n] variable ...", "sysctl [-n] -w variable=value ...",
 619:         "sysctl [-n] -a", "sysctl [-n] -A");
 620:     exit(1);
 621: }

Defined functions

debuginit defined in line 500; used 2 times
findname defined in line 589; used 6 times
listall defined in line 156; used 6 times
main defined in line 107; never used
parse defined in line 181; used 2 times
sysctl_inet defined in line 549; used 1 times
sysctl_mscp defined in line 477; used 1 times
sysctl_tmscp defined in line 454; used 1 times
usage defined in line 614; used 2 times

Defined variables

Aflag defined in line 95; used 3 times
aflag defined in line 95; used 2 times
copyright defined in line 35; never used
debugname defined in line 70; used 3 times
hwname defined in line 68; used 1 times
  • in line 90
icmpname defined in line 522; used 1 times
inetlist defined in line 524; used 2 times
inetname defined in line 520; used 1 times
inetvars defined in line 525; used 2 times
ipname defined in line 521; used 1 times
kernname defined in line 63; used 1 times
  • in line 81
machdepname defined in line 71; used 1 times
  • in line 91
mscplist defined in line 449; used 2 times
mscpname defined in line 448; used 2 times
names defined in line 72; used 2 times
netname defined in line 66; used 1 times
  • in line 85
nflag defined in line 95; used 11 times
sccsid defined in line 39; never used
secondlevel defined in line 79; used 4 times
tmscplist defined in line 446; used 2 times
tmscpname defined in line 445; used 2 times
toplist defined in line 78; used 1 times
topname defined in line 62; used 4 times
udpname defined in line 523; used 1 times
username defined in line 69; used 1 times
  • in line 92
vmname defined in line 64; used 1 times
  • in line 82
wflag defined in line 95; used 2 times

Defined struct's

list defined in line 74; used 20 times

Defined macros

BOOTTIME defined in line 104; used 2 times
CLOCK defined in line 103; used 2 times
CONSDEV defined in line 105; used 2 times
Last modified: 1998-04-04
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5512
Valid CSS Valid XHTML 1.0 Strict