148356cf6Smckusick /*
276f30379Sbostic * Copyright (c) 1993
376f30379Sbostic * The Regents of the University of California. All rights reserved.
448356cf6Smckusick *
548356cf6Smckusick * %sccs.include.redist.c%
648356cf6Smckusick */
748356cf6Smckusick
848356cf6Smckusick #ifndef lint
976f30379Sbostic static char copyright[] =
1076f30379Sbostic "@(#) Copyright (c) 1993\n\
1176f30379Sbostic The Regents of the University of California. All rights reserved.\n";
1248356cf6Smckusick #endif /* not lint */
1348356cf6Smckusick
1448356cf6Smckusick #ifndef lint
15*4444460aSmckusick static char sccsid[] = "@(#)sysctl.c 8.5 (Berkeley) 05/09/95";
1648356cf6Smckusick #endif /* not lint */
1748356cf6Smckusick
18ffe81a7bSbostic #include <sys/param.h>
197d6a41feSmckusick #include <sys/gmon.h>
2038187f89Smckusick #include <sys/mount.h>
2148356cf6Smckusick #include <sys/stat.h>
2248356cf6Smckusick #include <sys/sysctl.h>
2348356cf6Smckusick #include <sys/socket.h>
2448356cf6Smckusick #include <vm/vm_param.h>
25205717e4Smckusick #include <machine/cpu.h>
26ffe81a7bSbostic
27a3a5e311Smckusick #include <netinet/in.h>
28a3a5e311Smckusick #include <netinet/in_systm.h>
29a3a5e311Smckusick #include <netinet/ip.h>
30a3a5e311Smckusick #include <netinet/ip_icmp.h>
31a3a5e311Smckusick #include <netinet/icmp_var.h>
324310f570Smckusick #include <netinet/ip_var.h>
334310f570Smckusick #include <netinet/udp.h>
344310f570Smckusick #include <netinet/udp_var.h>
35ffe81a7bSbostic
3648356cf6Smckusick #include <errno.h>
37ffe81a7bSbostic #include <stdio.h>
3848356cf6Smckusick #include <stdlib.h>
3948356cf6Smckusick #include <string.h>
4048356cf6Smckusick
41a3a5e311Smckusick struct ctlname topname[] = CTL_NAMES;
42a3a5e311Smckusick struct ctlname kernname[] = CTL_KERN_NAMES;
43a3a5e311Smckusick struct ctlname vmname[] = CTL_VM_NAMES;
44a3a5e311Smckusick struct ctlname netname[] = CTL_NET_NAMES;
45a3a5e311Smckusick struct ctlname hwname[] = CTL_HW_NAMES;
465c1800e7Sbostic struct ctlname username[] = CTL_USER_NAMES;
47314e6e3aSmckusick struct ctlname debugname[CTL_DEBUG_MAXID];
4838187f89Smckusick struct ctlname *vfsname;
49205717e4Smckusick #ifdef CTL_MACHDEP_NAMES
50205717e4Smckusick struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
51205717e4Smckusick #endif
52314e6e3aSmckusick char names[BUFSIZ];
5338187f89Smckusick int lastused;
5448356cf6Smckusick
5548356cf6Smckusick struct list {
56a3a5e311Smckusick struct ctlname *list;
5748356cf6Smckusick int size;
58a3a5e311Smckusick };
59a3a5e311Smckusick struct list toplist = { topname, CTL_MAXID };
60a3a5e311Smckusick struct list secondlevel[] = {
6148356cf6Smckusick { 0, 0 }, /* CTL_UNSPEC */
6248356cf6Smckusick { kernname, KERN_MAXID }, /* CTL_KERN */
6348356cf6Smckusick { vmname, VM_MAXID }, /* CTL_VM */
6438187f89Smckusick { 0, 0 }, /* CTL_VFS */
6548356cf6Smckusick { netname, NET_MAXID }, /* CTL_NET */
66314e6e3aSmckusick { 0, CTL_DEBUG_MAXID }, /* CTL_DEBUG */
6748356cf6Smckusick { hwname, HW_MAXID }, /* CTL_HW */
68205717e4Smckusick #ifdef CTL_MACHDEP_NAMES
69205717e4Smckusick { machdepname, CPU_MAXID }, /* CTL_MACHDEP */
70205717e4Smckusick #else
7148356cf6Smckusick { 0, 0 }, /* CTL_MACHDEP */
72205717e4Smckusick #endif
735c1800e7Sbostic { username, USER_MAXID }, /* CTL_USER_NAMES */
7448356cf6Smckusick };
7548356cf6Smckusick
76c42d362fSmckusick int Aflag, aflag, nflag, wflag;
7748356cf6Smckusick
78205717e4Smckusick /*
79205717e4Smckusick * Variables requiring special processing.
80205717e4Smckusick */
81205717e4Smckusick #define CLOCK 0x00000001
82205717e4Smckusick #define BOOTTIME 0x00000002
83205717e4Smckusick #define CONSDEV 0x00000004
84205717e4Smckusick
8548356cf6Smckusick int
main(argc,argv)8648356cf6Smckusick main(argc, argv)
8748356cf6Smckusick int argc;
8848356cf6Smckusick char *argv[];
8948356cf6Smckusick {
9048356cf6Smckusick extern char *optarg;
9148356cf6Smckusick extern int optind;
92c42d362fSmckusick int ch, lvl1;
9348356cf6Smckusick
94c42d362fSmckusick while ((ch = getopt(argc, argv, "Aanw")) != EOF) {
9548356cf6Smckusick switch (ch) {
9648356cf6Smckusick
9748356cf6Smckusick case 'A':
9848356cf6Smckusick Aflag = 1;
9948356cf6Smckusick break;
10048356cf6Smckusick
10148356cf6Smckusick case 'a':
10248356cf6Smckusick aflag = 1;
10348356cf6Smckusick break;
10448356cf6Smckusick
105c42d362fSmckusick case 'n':
106c42d362fSmckusick nflag = 1;
107c42d362fSmckusick break;
108c42d362fSmckusick
10948356cf6Smckusick case 'w':
11048356cf6Smckusick wflag = 1;
11148356cf6Smckusick break;
11248356cf6Smckusick
11348356cf6Smckusick default:
11448356cf6Smckusick usage();
11548356cf6Smckusick }
11648356cf6Smckusick }
11748356cf6Smckusick argc -= optind;
11848356cf6Smckusick argv += optind;
11948356cf6Smckusick
120*4444460aSmckusick if (argc == 0 && (Aflag || aflag)) {
121314e6e3aSmckusick debuginit();
12238187f89Smckusick vfsinit();
123c42d362fSmckusick for (lvl1 = 1; lvl1 < CTL_MAXID; lvl1++)
124a3a5e311Smckusick listall(topname[lvl1].ctl_name, &secondlevel[lvl1]);
12548356cf6Smckusick exit(0);
12648356cf6Smckusick }
12748356cf6Smckusick if (argc == 0)
12848356cf6Smckusick usage();
129407fae98Sbostic for (; *argv != NULL; ++argv)
13048356cf6Smckusick parse(*argv, 1);
13148356cf6Smckusick exit(0);
13248356cf6Smckusick }
13348356cf6Smckusick
13448356cf6Smckusick /*
13548356cf6Smckusick * List all variables known to the system.
13648356cf6Smckusick */
listall(prefix,lp)137a3a5e311Smckusick listall(prefix, lp)
138a3a5e311Smckusick char *prefix;
13948356cf6Smckusick struct list *lp;
140a3a5e311Smckusick {
141c42d362fSmckusick int lvl2;
14248356cf6Smckusick char *cp, name[BUFSIZ];
14348356cf6Smckusick
14448356cf6Smckusick if (lp->list == 0)
145c42d362fSmckusick return;
146a3a5e311Smckusick strcpy(name, prefix);
14748356cf6Smckusick cp = &name[strlen(name)];
14848356cf6Smckusick *cp++ = '.';
149a3a5e311Smckusick for (lvl2 = 0; lvl2 < lp->size; lvl2++) {
150a3a5e311Smckusick if (lp->list[lvl2].ctl_name == 0)
151a3a5e311Smckusick continue;
152a3a5e311Smckusick strcpy(cp, lp->list[lvl2].ctl_name);
15348356cf6Smckusick parse(name, Aflag);
15448356cf6Smckusick }
15548356cf6Smckusick }
15648356cf6Smckusick
15748356cf6Smckusick /*
15848356cf6Smckusick * Parse a name into a MIB entry.
15948356cf6Smckusick * Lookup and print out the MIB entry if it exists.
16048356cf6Smckusick * Set a new value if requested.
16148356cf6Smckusick */
parse(string,flags)16248356cf6Smckusick parse(string, flags)
16348356cf6Smckusick char *string;
16448356cf6Smckusick int flags;
16548356cf6Smckusick {
16638187f89Smckusick int indx, type, state, len;
16738187f89Smckusick size_t size;
168205717e4Smckusick int special = 0;
16948356cf6Smckusick void *newval = 0;
17048356cf6Smckusick int intval, newsize = 0;
171a3a5e311Smckusick quad_t quadval;
172a3a5e311Smckusick struct list *lp;
17338187f89Smckusick struct vfsconf vfc;
17448356cf6Smckusick int mib[CTL_MAXNAME];
17548356cf6Smckusick char *cp, *bufp, buf[BUFSIZ], strval[BUFSIZ];
17648356cf6Smckusick
17748356cf6Smckusick bufp = buf;
17848356cf6Smckusick snprintf(buf, BUFSIZ, "%s", string);
17948356cf6Smckusick if ((cp = strchr(string, '=')) != NULL) {
18048356cf6Smckusick if (!wflag) {
18148356cf6Smckusick fprintf(stderr, "Must specify -w to set variables\n");
18248356cf6Smckusick exit(2);
18348356cf6Smckusick }
18448356cf6Smckusick *strchr(buf, '=') = '\0';
18548356cf6Smckusick *cp++ = '\0';
18648356cf6Smckusick while (isspace(*cp))
18748356cf6Smckusick cp++;
18848356cf6Smckusick newval = cp;
18948356cf6Smckusick newsize = strlen(cp);
19048356cf6Smckusick }
191a3a5e311Smckusick if ((indx = findname(string, "top", &bufp, &toplist)) == -1)
19248356cf6Smckusick return;
19348356cf6Smckusick mib[0] = indx;
19438187f89Smckusick if (indx == CTL_VFS)
19538187f89Smckusick vfsinit();
196314e6e3aSmckusick if (indx == CTL_DEBUG)
197314e6e3aSmckusick debuginit();
19848356cf6Smckusick lp = &secondlevel[indx];
19948356cf6Smckusick if (lp->list == 0) {
20048356cf6Smckusick fprintf(stderr, "%s: class is not implemented\n",
20148356cf6Smckusick topname[indx]);
20248356cf6Smckusick return;
20348356cf6Smckusick }
204c42d362fSmckusick if (bufp == NULL) {
205a3a5e311Smckusick listall(topname[indx].ctl_name, lp);
206c42d362fSmckusick return;
207c42d362fSmckusick }
20848356cf6Smckusick if ((indx = findname(string, "second", &bufp, lp)) == -1)
20948356cf6Smckusick return;
21048356cf6Smckusick mib[1] = indx;
211a3a5e311Smckusick type = lp->list[indx].ctl_type;
212a3a5e311Smckusick len = 2;
21348356cf6Smckusick switch (mib[0]) {
21448356cf6Smckusick
21548356cf6Smckusick case CTL_KERN:
21648356cf6Smckusick switch (mib[1]) {
2177d6a41feSmckusick case KERN_PROF:
2187d6a41feSmckusick mib[2] = GPROF_STATE;
2197d6a41feSmckusick size = sizeof state;
2207d6a41feSmckusick if (sysctl(mib, 3, &state, &size, NULL, 0) < 0) {
2217d6a41feSmckusick if (flags == 0)
2227d6a41feSmckusick return;
2237d6a41feSmckusick if (!nflag)
2247d6a41feSmckusick fprintf(stdout, "%s: ", string);
2257d6a41feSmckusick fprintf(stderr,
2267d6a41feSmckusick "kernel is not compiled for profiling\n");
2277d6a41feSmckusick return;
2287d6a41feSmckusick }
2297d6a41feSmckusick if (!nflag)
2307d6a41feSmckusick fprintf(stdout, "%s: %s\n", string,
2317d6a41feSmckusick state == GMON_PROF_OFF ? "off" : "running");
2327d6a41feSmckusick return;
23348356cf6Smckusick case KERN_VNODE:
23448356cf6Smckusick case KERN_FILE:
23548356cf6Smckusick if (flags == 0)
23648356cf6Smckusick return;
23748356cf6Smckusick fprintf(stderr,
23848356cf6Smckusick "Use pstat to view %s information\n", string);
23948356cf6Smckusick return;
24048356cf6Smckusick case KERN_PROC:
24148356cf6Smckusick if (flags == 0)
24248356cf6Smckusick return;
24348356cf6Smckusick fprintf(stderr,
24448356cf6Smckusick "Use ps to view %s information\n", string);
24548356cf6Smckusick return;
24648356cf6Smckusick case KERN_CLOCKRATE:
247205717e4Smckusick special |= CLOCK;
24848356cf6Smckusick break;
2496e12f17fSmckusick case KERN_BOOTTIME:
250205717e4Smckusick special |= BOOTTIME;
2516e12f17fSmckusick break;
25248356cf6Smckusick }
25348356cf6Smckusick break;
25448356cf6Smckusick
25548356cf6Smckusick case CTL_HW:
25648356cf6Smckusick break;
25748356cf6Smckusick
25848356cf6Smckusick case CTL_VM:
25948356cf6Smckusick if (mib[1] == VM_LOADAVG) {
26048356cf6Smckusick double loads[3];
26148356cf6Smckusick
26248356cf6Smckusick getloadavg(loads, 3);
263c42d362fSmckusick if (!nflag)
264c42d362fSmckusick fprintf(stdout, "%s: ", string);
265c42d362fSmckusick fprintf(stdout, "%.2f %.2f %.2f\n",
26648356cf6Smckusick loads[0], loads[1], loads[2]);
26748356cf6Smckusick return;
26848356cf6Smckusick }
26948356cf6Smckusick if (flags == 0)
27048356cf6Smckusick return;
27148356cf6Smckusick fprintf(stderr,
27248356cf6Smckusick "Use vmstat or systat to view %s information\n", string);
27348356cf6Smckusick return;
27448356cf6Smckusick
27548356cf6Smckusick case CTL_NET:
276a3a5e311Smckusick if (mib[1] == PF_INET) {
277a3a5e311Smckusick len = sysctl_inet(string, &bufp, mib, flags, &type);
278a3a5e311Smckusick if (len >= 0)
279a3a5e311Smckusick break;
280a3a5e311Smckusick return;
281a3a5e311Smckusick }
28248356cf6Smckusick if (flags == 0)
28348356cf6Smckusick return;
28448356cf6Smckusick fprintf(stderr, "Use netstat to view %s information\n", string);
28548356cf6Smckusick return;
28648356cf6Smckusick
28748356cf6Smckusick case CTL_DEBUG:
288314e6e3aSmckusick mib[2] = CTL_DEBUG_VALUE;
289314e6e3aSmckusick len = 3;
290314e6e3aSmckusick break;
291314e6e3aSmckusick
29248356cf6Smckusick case CTL_MACHDEP:
293205717e4Smckusick #ifdef CPU_CONSDEV
294205717e4Smckusick if (mib[1] == CPU_CONSDEV)
295205717e4Smckusick special |= CONSDEV;
296205717e4Smckusick #endif
297205717e4Smckusick break;
298205717e4Smckusick
29938187f89Smckusick case CTL_VFS:
30038187f89Smckusick mib[3] = mib[1];
30138187f89Smckusick mib[1] = VFS_GENERIC;
30238187f89Smckusick mib[2] = VFS_CONF;
30338187f89Smckusick len = 4;
30438187f89Smckusick size = sizeof vfc;
30538187f89Smckusick if (sysctl(mib, 4, &vfc, &size, (void *)0, (size_t)0) < 0) {
30638187f89Smckusick perror("vfs print");
30738187f89Smckusick return;
30838187f89Smckusick }
30938187f89Smckusick if (flags == 0 && vfc.vfc_refcount == 0)
31038187f89Smckusick return;
31138187f89Smckusick if (!nflag)
31238187f89Smckusick fprintf(stdout, "%s has %d mounted instance%s\n",
31338187f89Smckusick string, vfc.vfc_refcount,
31438187f89Smckusick vfc.vfc_refcount != 1 ? "s" : "");
31538187f89Smckusick else
31638187f89Smckusick fprintf(stdout, "%d\n", vfc.vfc_refcount);
31738187f89Smckusick return;
31838187f89Smckusick
3195c1800e7Sbostic case CTL_USER:
32048356cf6Smckusick break;
32148356cf6Smckusick
32248356cf6Smckusick default:
32348356cf6Smckusick fprintf(stderr, "Illegal top level value: %d\n", mib[0]);
32448356cf6Smckusick return;
32548356cf6Smckusick
32648356cf6Smckusick }
327a3a5e311Smckusick if (bufp) {
328a3a5e311Smckusick fprintf(stderr, "name %s in %s is unknown\n", *bufp, string);
329a3a5e311Smckusick return;
330a3a5e311Smckusick }
331a3a5e311Smckusick if (newsize > 0) {
332a3a5e311Smckusick switch (type) {
333a3a5e311Smckusick case CTLTYPE_INT:
334a3a5e311Smckusick intval = atoi(newval);
335a3a5e311Smckusick newval = &intval;
336a3a5e311Smckusick newsize = sizeof intval;
337a3a5e311Smckusick break;
33848356cf6Smckusick
339a3a5e311Smckusick case CTLTYPE_QUAD:
340a3a5e311Smckusick sscanf(newval, "%qd", &quadval);
341a3a5e311Smckusick newval = &quadval;
342a3a5e311Smckusick newsize = sizeof quadval;
343a3a5e311Smckusick break;
344a3a5e311Smckusick }
345a3a5e311Smckusick }
34648356cf6Smckusick size = BUFSIZ;
347a3a5e311Smckusick if (sysctl(mib, len, buf, &size, newsize ? newval : 0, newsize) == -1) {
34848356cf6Smckusick if (flags == 0)
34948356cf6Smckusick return;
35048356cf6Smckusick switch (errno) {
35148356cf6Smckusick case EOPNOTSUPP:
35248356cf6Smckusick fprintf(stderr, "%s: value is not available\n", string);
35348356cf6Smckusick return;
35448356cf6Smckusick case ENOTDIR:
35548356cf6Smckusick fprintf(stderr, "%s: specification is incomplete\n",
35648356cf6Smckusick string);
35748356cf6Smckusick return;
35848356cf6Smckusick case ENOMEM:
35948356cf6Smckusick fprintf(stderr, "%s: type is unknown to this program\n",
36048356cf6Smckusick string);
36148356cf6Smckusick return;
36248356cf6Smckusick default:
36348356cf6Smckusick perror(string);
36448356cf6Smckusick return;
36548356cf6Smckusick }
36648356cf6Smckusick }
367205717e4Smckusick if (special & CLOCK) {
36848356cf6Smckusick struct clockinfo *clkp = (struct clockinfo *)buf;
36948356cf6Smckusick
370c42d362fSmckusick if (!nflag)
371c42d362fSmckusick fprintf(stdout, "%s: ", string);
37248356cf6Smckusick fprintf(stdout,
373c42d362fSmckusick "hz = %d, tick = %d, profhz = %d, stathz = %d\n",
374c42d362fSmckusick clkp->hz, clkp->tick, clkp->profhz, clkp->stathz);
37548356cf6Smckusick return;
37648356cf6Smckusick }
377205717e4Smckusick if (special & BOOTTIME) {
3786e12f17fSmckusick struct timeval *btp = (struct timeval *)buf;
3796e12f17fSmckusick
3806e12f17fSmckusick if (!nflag)
3816e12f17fSmckusick fprintf(stdout, "%s = %s\n", string,
3826e12f17fSmckusick ctime(&btp->tv_sec));
3836e12f17fSmckusick else
3846e12f17fSmckusick fprintf(stdout, "%d\n", btp->tv_sec);
3856e12f17fSmckusick return;
3866e12f17fSmckusick }
387205717e4Smckusick if (special & CONSDEV) {
388205717e4Smckusick dev_t dev = *(dev_t *)buf;
389205717e4Smckusick
390205717e4Smckusick if (!nflag)
391205717e4Smckusick fprintf(stdout, "%s = %s\n", string,
392205717e4Smckusick devname(dev, S_IFCHR));
393205717e4Smckusick else
394205717e4Smckusick fprintf(stdout, "0x%x\n", dev);
395205717e4Smckusick return;
396205717e4Smckusick }
397a3a5e311Smckusick switch (type) {
398a3a5e311Smckusick case CTLTYPE_INT:
399c42d362fSmckusick if (newsize == 0) {
400c42d362fSmckusick if (!nflag)
401c42d362fSmckusick fprintf(stdout, "%s = ", string);
402c42d362fSmckusick fprintf(stdout, "%d\n", *(int *)buf);
403c42d362fSmckusick } else {
404c42d362fSmckusick if (!nflag)
405c42d362fSmckusick fprintf(stdout, "%s: %d -> ", string,
406c42d362fSmckusick *(int *)buf);
407c42d362fSmckusick fprintf(stdout, "%d\n", *(int *)newval);
408c42d362fSmckusick }
409a3a5e311Smckusick return;
410a3a5e311Smckusick
411a3a5e311Smckusick case CTLTYPE_STRING:
412c42d362fSmckusick if (newsize == 0) {
413c42d362fSmckusick if (!nflag)
414c42d362fSmckusick fprintf(stdout, "%s = ", string);
415c42d362fSmckusick fprintf(stdout, "%s\n", buf);
416c42d362fSmckusick } else {
417c42d362fSmckusick if (!nflag)
418c42d362fSmckusick fprintf(stdout, "%s: %s -> ", string, buf);
419c42d362fSmckusick fprintf(stdout, "%s\n", newval);
420c42d362fSmckusick }
42148356cf6Smckusick return;
422a3a5e311Smckusick
423a3a5e311Smckusick case CTLTYPE_QUAD:
424a3a5e311Smckusick if (newsize == 0) {
425a3a5e311Smckusick if (!nflag)
426a3a5e311Smckusick fprintf(stdout, "%s = ", string);
427a3a5e311Smckusick fprintf(stdout, "%qd\n", *(quad_t *)buf);
428a3a5e311Smckusick } else {
429a3a5e311Smckusick if (!nflag)
430a3a5e311Smckusick fprintf(stdout, "%s: %qd -> ", string,
431a3a5e311Smckusick *(quad_t *)buf);
432a3a5e311Smckusick fprintf(stdout, "%qd\n", *(quad_t *)newval);
433a3a5e311Smckusick }
434a3a5e311Smckusick return;
435a3a5e311Smckusick
436a3a5e311Smckusick case CTLTYPE_STRUCT:
437a3a5e311Smckusick fprintf(stderr, "%s: unknown structure returned\n",
438a3a5e311Smckusick string);
439a3a5e311Smckusick return;
440a3a5e311Smckusick
441a3a5e311Smckusick default:
442a3a5e311Smckusick case CTLTYPE_NODE:
443a3a5e311Smckusick fprintf(stderr, "%s: unknown type returned\n",
444a3a5e311Smckusick string);
445a3a5e311Smckusick return;
446a3a5e311Smckusick }
447a3a5e311Smckusick }
448a3a5e311Smckusick
449314e6e3aSmckusick /*
450314e6e3aSmckusick * Initialize the set of debugging names
451314e6e3aSmckusick */
debuginit()452314e6e3aSmckusick debuginit()
453314e6e3aSmckusick {
4547cd463d7Sbostic int mib[3], loc, i;
4557cd463d7Sbostic size_t size;
456314e6e3aSmckusick
457314e6e3aSmckusick if (secondlevel[CTL_DEBUG].list != 0)
458314e6e3aSmckusick return;
459314e6e3aSmckusick secondlevel[CTL_DEBUG].list = debugname;
460314e6e3aSmckusick mib[0] = CTL_DEBUG;
461314e6e3aSmckusick mib[2] = CTL_DEBUG_NAME;
46238187f89Smckusick for (loc = lastused, i = 0; i < CTL_DEBUG_MAXID; i++) {
463314e6e3aSmckusick mib[1] = i;
464314e6e3aSmckusick size = BUFSIZ - loc;
465314e6e3aSmckusick if (sysctl(mib, 3, &names[loc], &size, NULL, 0) == -1)
466314e6e3aSmckusick continue;
467314e6e3aSmckusick debugname[i].ctl_name = &names[loc];
468314e6e3aSmckusick debugname[i].ctl_type = CTLTYPE_INT;
469314e6e3aSmckusick loc += size;
470314e6e3aSmckusick }
47138187f89Smckusick lastused = loc;
47238187f89Smckusick }
47338187f89Smckusick
47438187f89Smckusick /*
47538187f89Smckusick * Initialize the set of filesystem names
47638187f89Smckusick */
vfsinit()47738187f89Smckusick vfsinit()
47838187f89Smckusick {
47938187f89Smckusick int mib[4], maxtypenum, cnt, loc, size;
48038187f89Smckusick struct vfsconf vfc;
48138187f89Smckusick size_t buflen;
48238187f89Smckusick
48338187f89Smckusick if (secondlevel[CTL_VFS].list != 0)
48438187f89Smckusick return;
48538187f89Smckusick mib[0] = CTL_VFS;
48638187f89Smckusick mib[1] = VFS_GENERIC;
48738187f89Smckusick mib[2] = VFS_MAXTYPENUM;
48838187f89Smckusick buflen = 4;
48938187f89Smckusick if (sysctl(mib, 3, &maxtypenum, &buflen, (void *)0, (size_t)0) < 0)
49038187f89Smckusick return;
49138187f89Smckusick if ((vfsname = malloc(maxtypenum * sizeof(*vfsname))) == 0)
49238187f89Smckusick return;
49338187f89Smckusick memset(vfsname, 0, maxtypenum * sizeof(*vfsname));
49438187f89Smckusick mib[2] = VFS_CONF;
49538187f89Smckusick buflen = sizeof vfc;
49638187f89Smckusick for (loc = lastused, cnt = 0; cnt < maxtypenum; cnt++) {
49738187f89Smckusick mib[3] = cnt;
49838187f89Smckusick if (sysctl(mib, 4, &vfc, &buflen, (void *)0, (size_t)0) < 0) {
49938187f89Smckusick if (errno == EOPNOTSUPP)
50038187f89Smckusick continue;
50138187f89Smckusick perror("vfsinit");
50238187f89Smckusick free(vfsname);
50338187f89Smckusick return;
50438187f89Smckusick }
50538187f89Smckusick strcat(&names[loc], vfc.vfc_name);
50638187f89Smckusick vfsname[cnt].ctl_name = &names[loc];
50738187f89Smckusick vfsname[cnt].ctl_type = CTLTYPE_INT;
50838187f89Smckusick size = strlen(vfc.vfc_name) + 1;
50938187f89Smckusick loc += size;
51038187f89Smckusick }
51138187f89Smckusick lastused = loc;
51238187f89Smckusick secondlevel[CTL_VFS].list = vfsname;
51338187f89Smckusick secondlevel[CTL_VFS].size = maxtypenum;
51438187f89Smckusick return;
515314e6e3aSmckusick }
516314e6e3aSmckusick
517a3a5e311Smckusick struct ctlname inetname[] = CTL_IPPROTO_NAMES;
518a3a5e311Smckusick struct ctlname ipname[] = IPCTL_NAMES;
519a3a5e311Smckusick struct ctlname icmpname[] = ICMPCTL_NAMES;
5204310f570Smckusick struct ctlname udpname[] = UDPCTL_NAMES;
521a3a5e311Smckusick struct list inetlist = { inetname, IPPROTO_MAXID };
522a3a5e311Smckusick struct list inetvars[] = {
5234310f570Smckusick { ipname, IPCTL_MAXID }, /* ip */
5244310f570Smckusick { icmpname, ICMPCTL_MAXID }, /* icmp */
5254310f570Smckusick { 0, 0 }, /* igmp */
5264310f570Smckusick { 0, 0 }, /* ggmp */
5274310f570Smckusick { 0, 0 },
5284310f570Smckusick { 0, 0 },
5294310f570Smckusick { 0, 0 }, /* tcp */
5304310f570Smckusick { 0, 0 },
5314310f570Smckusick { 0, 0 }, /* egp */
5324310f570Smckusick { 0, 0 },
5334310f570Smckusick { 0, 0 },
5344310f570Smckusick { 0, 0 },
5354310f570Smckusick { 0, 0 }, /* pup */
5364310f570Smckusick { 0, 0 },
5374310f570Smckusick { 0, 0 },
5384310f570Smckusick { 0, 0 },
5394310f570Smckusick { 0, 0 },
5404310f570Smckusick { udpname, UDPCTL_MAXID }, /* udp */
541a3a5e311Smckusick };
542a3a5e311Smckusick
543a3a5e311Smckusick /*
544a3a5e311Smckusick * handle internet requests
545a3a5e311Smckusick */
sysctl_inet(string,bufpp,mib,flags,typep)546a3a5e311Smckusick sysctl_inet(string, bufpp, mib, flags, typep)
547a3a5e311Smckusick char *string;
548a3a5e311Smckusick char **bufpp;
549a3a5e311Smckusick int mib[];
550a3a5e311Smckusick int flags;
551a3a5e311Smckusick int *typep;
552a3a5e311Smckusick {
553a3a5e311Smckusick struct list *lp;
554a3a5e311Smckusick int indx;
555a3a5e311Smckusick
556a3a5e311Smckusick if (*bufpp == NULL) {
557a3a5e311Smckusick listall(string, &inetlist);
558a3a5e311Smckusick return (-1);
559a3a5e311Smckusick }
560a3a5e311Smckusick if ((indx = findname(string, "third", bufpp, &inetlist)) == -1)
561a3a5e311Smckusick return (-1);
562a3a5e311Smckusick mib[2] = indx;
5634310f570Smckusick if (indx <= IPPROTO_UDP && inetvars[indx].list != NULL)
564a3a5e311Smckusick lp = &inetvars[indx];
565a3a5e311Smckusick else if (!flags)
566a3a5e311Smckusick return (-1);
567a3a5e311Smckusick else {
568a3a5e311Smckusick fprintf(stderr, "%s: no variables defined for this protocol\n",
569a3a5e311Smckusick string);
570a3a5e311Smckusick return (-1);
571a3a5e311Smckusick }
572a3a5e311Smckusick if (*bufpp == NULL) {
573a3a5e311Smckusick listall(string, lp);
574a3a5e311Smckusick return (-1);
575a3a5e311Smckusick }
576a3a5e311Smckusick if ((indx = findname(string, "fourth", bufpp, lp)) == -1)
577a3a5e311Smckusick return (-1);
578a3a5e311Smckusick mib[3] = indx;
579a3a5e311Smckusick *typep = lp->list[indx].ctl_type;
580a3a5e311Smckusick return (4);
58148356cf6Smckusick }
58248356cf6Smckusick
58348356cf6Smckusick /*
58448356cf6Smckusick * Scan a list of names searching for a particular name.
58548356cf6Smckusick */
findname(string,level,bufp,namelist)58648356cf6Smckusick findname(string, level, bufp, namelist)
58748356cf6Smckusick char *string;
58848356cf6Smckusick char *level;
58948356cf6Smckusick char **bufp;
59048356cf6Smckusick struct list *namelist;
59148356cf6Smckusick {
59248356cf6Smckusick char *name;
59348356cf6Smckusick int i;
59448356cf6Smckusick
59548356cf6Smckusick if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) {
59648356cf6Smckusick fprintf(stderr, "%s: incomplete specification\n", string);
59748356cf6Smckusick return (-1);
59848356cf6Smckusick }
59948356cf6Smckusick for (i = 0; i < namelist->size; i++)
60022798014Storek if (namelist->list[i].ctl_name != NULL &&
60122798014Storek strcmp(name, namelist->list[i].ctl_name) == 0)
60248356cf6Smckusick break;
60348356cf6Smckusick if (i == namelist->size) {
60448356cf6Smckusick fprintf(stderr, "%s level name %s in %s is invalid\n",
60548356cf6Smckusick level, name, string);
60648356cf6Smckusick return (-1);
60748356cf6Smckusick }
60848356cf6Smckusick return (i);
60948356cf6Smckusick }
61048356cf6Smckusick
usage()61148356cf6Smckusick usage()
61248356cf6Smckusick {
61348356cf6Smckusick
614733b6633Smckusick (void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n\t%s\n",
615733b6633Smckusick "sysctl [-n] variable ...", "sysctl [-n] -w variable=value ...",
616733b6633Smckusick "sysctl [-n] -a", "sysctl [-n] -A");
61748356cf6Smckusick exit(1);
61848356cf6Smckusick }
619