xref: /csrg-svn/usr.sbin/sysctl/sysctl.c (revision 69323)
158888Smckusick /*
261882Sbostic  * Copyright (c) 1993
361882Sbostic  *	The Regents of the University of California.  All rights reserved.
458888Smckusick  *
558888Smckusick  * %sccs.include.redist.c%
658888Smckusick  */
758888Smckusick 
858888Smckusick #ifndef lint
961882Sbostic static char copyright[] =
1061882Sbostic "@(#) Copyright (c) 1993\n\
1161882Sbostic 	The Regents of the University of California.  All rights reserved.\n";
1258888Smckusick #endif /* not lint */
1358888Smckusick 
1458888Smckusick #ifndef lint
15*69323Smckusick static char sccsid[] = "@(#)sysctl.c	8.5 (Berkeley) 05/09/95";
1658888Smckusick #endif /* not lint */
1758888Smckusick 
1859379Sbostic #include <sys/param.h>
1959658Smckusick #include <sys/gmon.h>
2068906Smckusick #include <sys/mount.h>
2158888Smckusick #include <sys/stat.h>
2258888Smckusick #include <sys/sysctl.h>
2358888Smckusick #include <sys/socket.h>
2458888Smckusick #include <vm/vm_param.h>
2560426Smckusick #include <machine/cpu.h>
2659379Sbostic 
2759140Smckusick #include <netinet/in.h>
2859140Smckusick #include <netinet/in_systm.h>
2959140Smckusick #include <netinet/ip.h>
3059140Smckusick #include <netinet/ip_icmp.h>
3159140Smckusick #include <netinet/icmp_var.h>
3259311Smckusick #include <netinet/ip_var.h>
3359311Smckusick #include <netinet/udp.h>
3459311Smckusick #include <netinet/udp_var.h>
3559379Sbostic 
3658888Smckusick #include <errno.h>
3759379Sbostic #include <stdio.h>
3858888Smckusick #include <stdlib.h>
3958888Smckusick #include <string.h>
4058888Smckusick 
4159140Smckusick struct ctlname topname[] = CTL_NAMES;
4259140Smckusick struct ctlname kernname[] = CTL_KERN_NAMES;
4359140Smckusick struct ctlname vmname[] = CTL_VM_NAMES;
4459140Smckusick struct ctlname netname[] = CTL_NET_NAMES;
4559140Smckusick struct ctlname hwname[] = CTL_HW_NAMES;
4659719Sbostic struct ctlname username[] = CTL_USER_NAMES;
4759159Smckusick struct ctlname debugname[CTL_DEBUG_MAXID];
4868906Smckusick struct ctlname *vfsname;
4960426Smckusick #ifdef CTL_MACHDEP_NAMES
5060426Smckusick struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
5160426Smckusick #endif
5259159Smckusick char names[BUFSIZ];
5368906Smckusick int lastused;
5458888Smckusick 
5558888Smckusick struct list {
5659140Smckusick 	struct	ctlname *list;
5758888Smckusick 	int	size;
5859140Smckusick };
5959140Smckusick struct list toplist = { topname, CTL_MAXID };
6059140Smckusick struct list secondlevel[] = {
6158888Smckusick 	{ 0, 0 },			/* CTL_UNSPEC */
6258888Smckusick 	{ kernname, KERN_MAXID },	/* CTL_KERN */
6358888Smckusick 	{ vmname, VM_MAXID },		/* CTL_VM */
6468906Smckusick 	{ 0, 0 },			/* CTL_VFS */
6558888Smckusick 	{ netname, NET_MAXID },		/* CTL_NET */
6659159Smckusick 	{ 0, CTL_DEBUG_MAXID },		/* CTL_DEBUG */
6758888Smckusick 	{ hwname, HW_MAXID },		/* CTL_HW */
6860426Smckusick #ifdef CTL_MACHDEP_NAMES
6960426Smckusick 	{ machdepname, CPU_MAXID },	/* CTL_MACHDEP */
7060426Smckusick #else
7158888Smckusick 	{ 0, 0 },			/* CTL_MACHDEP */
7260426Smckusick #endif
7359719Sbostic 	{ username, USER_MAXID },	/* CTL_USER_NAMES */
7458888Smckusick };
7558888Smckusick 
7658910Smckusick int	Aflag, aflag, nflag, wflag;
7758888Smckusick 
7860426Smckusick /*
7960426Smckusick  * Variables requiring special processing.
8060426Smckusick  */
8160426Smckusick #define	CLOCK		0x00000001
8260426Smckusick #define	BOOTTIME	0x00000002
8360426Smckusick #define	CONSDEV		0x00000004
8460426Smckusick 
8558888Smckusick int
main(argc,argv)8658888Smckusick main(argc, argv)
8758888Smckusick 	int argc;
8858888Smckusick 	char *argv[];
8958888Smckusick {
9058888Smckusick 	extern char *optarg;
9158888Smckusick 	extern int optind;
9258910Smckusick 	int ch, lvl1;
9358888Smckusick 
9458910Smckusick 	while ((ch = getopt(argc, argv, "Aanw")) != EOF) {
9558888Smckusick 		switch (ch) {
9658888Smckusick 
9758888Smckusick 		case 'A':
9858888Smckusick 			Aflag = 1;
9958888Smckusick 			break;
10058888Smckusick 
10158888Smckusick 		case 'a':
10258888Smckusick 			aflag = 1;
10358888Smckusick 			break;
10458888Smckusick 
10558910Smckusick 		case 'n':
10658910Smckusick 			nflag = 1;
10758910Smckusick 			break;
10858910Smckusick 
10958888Smckusick 		case 'w':
11058888Smckusick 			wflag = 1;
11158888Smckusick 			break;
11258888Smckusick 
11358888Smckusick 		default:
11458888Smckusick 			usage();
11558888Smckusick 		}
11658888Smckusick 	}
11758888Smckusick 	argc -= optind;
11858888Smckusick 	argv += optind;
11958888Smckusick 
120*69323Smckusick 	if (argc == 0 && (Aflag || aflag)) {
12159159Smckusick 		debuginit();
12268906Smckusick 		vfsinit();
12358910Smckusick 		for (lvl1 = 1; lvl1 < CTL_MAXID; lvl1++)
12459140Smckusick 			listall(topname[lvl1].ctl_name, &secondlevel[lvl1]);
12558888Smckusick 		exit(0);
12658888Smckusick 	}
12758888Smckusick 	if (argc == 0)
12858888Smckusick 		usage();
12968917Sbostic 	for (; *argv != NULL; ++argv)
13058888Smckusick 		parse(*argv, 1);
13158888Smckusick 	exit(0);
13258888Smckusick }
13358888Smckusick 
13458888Smckusick /*
13558888Smckusick  * List all variables known to the system.
13658888Smckusick  */
listall(prefix,lp)13759140Smckusick listall(prefix, lp)
13859140Smckusick 	char *prefix;
13959140Smckusick 	struct list *lp;
14058888Smckusick {
14158910Smckusick 	int lvl2;
14258888Smckusick 	char *cp, name[BUFSIZ];
14358888Smckusick 
14458910Smckusick 	if (lp->list == 0)
14558910Smckusick 		return;
14659140Smckusick 	strcpy(name, prefix);
14758910Smckusick 	cp = &name[strlen(name)];
14858910Smckusick 	*cp++ = '.';
14959140Smckusick 	for (lvl2 = 0; lvl2 < lp->size; lvl2++) {
15059140Smckusick 		if (lp->list[lvl2].ctl_name == 0)
15159140Smckusick 			continue;
15259140Smckusick 		strcpy(cp, lp->list[lvl2].ctl_name);
15358910Smckusick 		parse(name, Aflag);
15458888Smckusick 	}
15558888Smckusick }
15658888Smckusick 
15758888Smckusick /*
15858888Smckusick  * Parse a name into a MIB entry.
15958888Smckusick  * Lookup and print out the MIB entry if it exists.
16058888Smckusick  * Set a new value if requested.
16158888Smckusick  */
parse(string,flags)16258888Smckusick parse(string, flags)
16358888Smckusick 	char *string;
16458888Smckusick 	int flags;
16558888Smckusick {
16668906Smckusick 	int indx, type, state, len;
16768906Smckusick 	size_t size;
16860426Smckusick 	int special = 0;
16958888Smckusick 	void *newval = 0;
17058888Smckusick 	int intval, newsize = 0;
17159140Smckusick 	quad_t quadval;
17259140Smckusick 	struct list *lp;
17368906Smckusick 	struct vfsconf vfc;
17458888Smckusick 	int mib[CTL_MAXNAME];
17558888Smckusick 	char *cp, *bufp, buf[BUFSIZ], strval[BUFSIZ];
17658888Smckusick 
17758888Smckusick 	bufp = buf;
17858888Smckusick 	snprintf(buf, BUFSIZ, "%s", string);
17958888Smckusick 	if ((cp = strchr(string, '=')) != NULL) {
18058888Smckusick 		if (!wflag) {
18158888Smckusick 			fprintf(stderr, "Must specify -w to set variables\n");
18258888Smckusick 			exit(2);
18358888Smckusick 		}
18458888Smckusick 		*strchr(buf, '=') = '\0';
18558888Smckusick 		*cp++ = '\0';
18658888Smckusick 		while (isspace(*cp))
18758888Smckusick 			cp++;
18859140Smckusick 		newval = cp;
18959140Smckusick 		newsize = strlen(cp);
19058888Smckusick 	}
19159140Smckusick 	if ((indx = findname(string, "top", &bufp, &toplist)) == -1)
19258888Smckusick 		return;
19358888Smckusick 	mib[0] = indx;
19468906Smckusick 	if (indx == CTL_VFS)
19568906Smckusick 		vfsinit();
19659159Smckusick 	if (indx == CTL_DEBUG)
19759159Smckusick 		debuginit();
19858888Smckusick 	lp = &secondlevel[indx];
19958888Smckusick 	if (lp->list == 0) {
20058888Smckusick 		fprintf(stderr, "%s: class is not implemented\n",
20158888Smckusick 		    topname[indx]);
20258888Smckusick 		return;
20358888Smckusick 	}
20458910Smckusick 	if (bufp == NULL) {
20559140Smckusick 		listall(topname[indx].ctl_name, lp);
20658910Smckusick 		return;
20758910Smckusick 	}
20858888Smckusick 	if ((indx = findname(string, "second", &bufp, lp)) == -1)
20958888Smckusick 		return;
21058888Smckusick 	mib[1] = indx;
21159140Smckusick 	type = lp->list[indx].ctl_type;
21259140Smckusick 	len = 2;
21358888Smckusick 	switch (mib[0]) {
21458888Smckusick 
21558888Smckusick 	case CTL_KERN:
21658888Smckusick 		switch (mib[1]) {
21759658Smckusick 		case KERN_PROF:
21859658Smckusick 			mib[2] = GPROF_STATE;
21959658Smckusick 			size = sizeof state;
22059658Smckusick 			if (sysctl(mib, 3, &state, &size, NULL, 0) < 0) {
22159658Smckusick 				if (flags == 0)
22259658Smckusick 					return;
22359658Smckusick 				if (!nflag)
22459658Smckusick 					fprintf(stdout, "%s: ", string);
22559658Smckusick 				fprintf(stderr,
22659658Smckusick 				    "kernel is not compiled for profiling\n");
22759658Smckusick 				return;
22859658Smckusick 			}
22959658Smckusick 			if (!nflag)
23059658Smckusick 				fprintf(stdout, "%s: %s\n", string,
23159658Smckusick 				    state == GMON_PROF_OFF ? "off" : "running");
23259658Smckusick 			return;
23358888Smckusick 		case KERN_VNODE:
23458888Smckusick 		case KERN_FILE:
23558888Smckusick 			if (flags == 0)
23658888Smckusick 				return;
23758888Smckusick 			fprintf(stderr,
23858888Smckusick 			    "Use pstat to view %s information\n", string);
23958888Smckusick 			return;
24058888Smckusick 		case KERN_PROC:
24158888Smckusick 			if (flags == 0)
24258888Smckusick 				return;
24358888Smckusick 			fprintf(stderr,
24458888Smckusick 			    "Use ps to view %s information\n", string);
24558888Smckusick 			return;
24658888Smckusick 		case KERN_CLOCKRATE:
24760426Smckusick 			special |= CLOCK;
24858888Smckusick 			break;
24960154Smckusick 		case KERN_BOOTTIME:
25060426Smckusick 			special |= BOOTTIME;
25160154Smckusick 			break;
25258888Smckusick 		}
25358888Smckusick 		break;
25458888Smckusick 
25558888Smckusick 	case CTL_HW:
25658888Smckusick 		break;
25758888Smckusick 
25858888Smckusick 	case CTL_VM:
25958888Smckusick 		if (mib[1] == VM_LOADAVG) {
26058888Smckusick 			double loads[3];
26158888Smckusick 
26258888Smckusick 			getloadavg(loads, 3);
26358910Smckusick 			if (!nflag)
26458910Smckusick 				fprintf(stdout, "%s: ", string);
26558910Smckusick 			fprintf(stdout, "%.2f %.2f %.2f\n",
26658888Smckusick 			    loads[0], loads[1], loads[2]);
26758888Smckusick 			return;
26858888Smckusick 		}
26958888Smckusick 		if (flags == 0)
27058888Smckusick 			return;
27158888Smckusick 		fprintf(stderr,
27258888Smckusick 		    "Use vmstat or systat to view %s information\n", string);
27358888Smckusick 		return;
27458888Smckusick 
27558888Smckusick 	case CTL_NET:
27659140Smckusick 		if (mib[1] == PF_INET) {
27759140Smckusick 			len = sysctl_inet(string, &bufp, mib, flags, &type);
27859140Smckusick 			if (len >= 0)
27959140Smckusick 				break;
28059140Smckusick 			return;
28159140Smckusick 		}
28258888Smckusick 		if (flags == 0)
28358888Smckusick 			return;
28458888Smckusick 		fprintf(stderr, "Use netstat to view %s information\n", string);
28558888Smckusick 		return;
28658888Smckusick 
28759159Smckusick 	case CTL_DEBUG:
28859159Smckusick 		mib[2] = CTL_DEBUG_VALUE;
28959159Smckusick 		len = 3;
29059159Smckusick 		break;
29159159Smckusick 
29260426Smckusick 	case CTL_MACHDEP:
29360426Smckusick #ifdef CPU_CONSDEV
29460426Smckusick 		if (mib[1] == CPU_CONSDEV)
29560426Smckusick 			special |= CONSDEV;
29660426Smckusick #endif
29760426Smckusick 		break;
29860426Smckusick 
29968906Smckusick 	case CTL_VFS:
30068906Smckusick 		mib[3] = mib[1];
30168906Smckusick 		mib[1] = VFS_GENERIC;
30268906Smckusick 		mib[2] = VFS_CONF;
30368906Smckusick 		len = 4;
30468906Smckusick 		size = sizeof vfc;
30568906Smckusick 		if (sysctl(mib, 4, &vfc, &size, (void *)0, (size_t)0) < 0) {
30668906Smckusick 			perror("vfs print");
30768906Smckusick 			return;
30868906Smckusick 		}
30968906Smckusick 		if (flags == 0 && vfc.vfc_refcount == 0)
31068906Smckusick 			return;
31168906Smckusick 		if (!nflag)
31268906Smckusick 			fprintf(stdout, "%s has %d mounted instance%s\n",
31368906Smckusick 			    string, vfc.vfc_refcount,
31468906Smckusick 			    vfc.vfc_refcount != 1 ? "s" : "");
31568906Smckusick 		else
31668906Smckusick 			fprintf(stdout, "%d\n", vfc.vfc_refcount);
31768906Smckusick 		return;
31868906Smckusick 
31959719Sbostic 	case CTL_USER:
32058888Smckusick 		break;
32158888Smckusick 
32258888Smckusick 	default:
32358888Smckusick 		fprintf(stderr, "Illegal top level value: %d\n", mib[0]);
32458888Smckusick 		return;
32558888Smckusick 
32658888Smckusick 	}
32759140Smckusick 	if (bufp) {
32859140Smckusick 		fprintf(stderr, "name %s in %s is unknown\n", *bufp, string);
32959140Smckusick 		return;
33059140Smckusick 	}
33159140Smckusick 	if (newsize > 0) {
33259140Smckusick 		switch (type) {
33359140Smckusick 		case CTLTYPE_INT:
33459140Smckusick 			intval = atoi(newval);
33559140Smckusick 			newval = &intval;
33659140Smckusick 			newsize = sizeof intval;
33759140Smckusick 			break;
33858888Smckusick 
33959140Smckusick 		case CTLTYPE_QUAD:
34059140Smckusick 			sscanf(newval, "%qd", &quadval);
34159140Smckusick 			newval = &quadval;
34259140Smckusick 			newsize = sizeof quadval;
34359140Smckusick 			break;
34459140Smckusick 		}
34559140Smckusick 	}
34658888Smckusick 	size = BUFSIZ;
34759140Smckusick 	if (sysctl(mib, len, buf, &size, newsize ? newval : 0, newsize) == -1) {
34858888Smckusick 		if (flags == 0)
34958888Smckusick 			return;
35058888Smckusick 		switch (errno) {
35158888Smckusick 		case EOPNOTSUPP:
35258888Smckusick 			fprintf(stderr, "%s: value is not available\n", string);
35358888Smckusick 			return;
35458888Smckusick 		case ENOTDIR:
35558888Smckusick 			fprintf(stderr, "%s: specification is incomplete\n",
35658888Smckusick 			    string);
35758888Smckusick 			return;
35858888Smckusick 		case ENOMEM:
35958888Smckusick 			fprintf(stderr, "%s: type is unknown to this program\n",
36058888Smckusick 			    string);
36158888Smckusick 			return;
36258888Smckusick 		default:
36358888Smckusick 			perror(string);
36458888Smckusick 			return;
36558888Smckusick 		}
36658888Smckusick 	}
36760426Smckusick 	if (special & CLOCK) {
36858888Smckusick 		struct clockinfo *clkp = (struct clockinfo *)buf;
36958888Smckusick 
37058910Smckusick 		if (!nflag)
37158910Smckusick 			fprintf(stdout, "%s: ", string);
37258888Smckusick 		fprintf(stdout,
37358910Smckusick 		    "hz = %d, tick = %d, profhz = %d, stathz = %d\n",
37458910Smckusick 		    clkp->hz, clkp->tick, clkp->profhz, clkp->stathz);
37558888Smckusick 		return;
37658888Smckusick 	}
37760426Smckusick 	if (special & BOOTTIME) {
37860154Smckusick 		struct timeval *btp = (struct timeval *)buf;
37960154Smckusick 
38060154Smckusick 		if (!nflag)
38160154Smckusick 			fprintf(stdout, "%s = %s\n", string,
38260154Smckusick 			    ctime(&btp->tv_sec));
38360154Smckusick 		else
38460154Smckusick 			fprintf(stdout, "%d\n", btp->tv_sec);
38560154Smckusick 		return;
38660154Smckusick 	}
38760426Smckusick 	if (special & CONSDEV) {
38860426Smckusick 		dev_t dev = *(dev_t *)buf;
38960426Smckusick 
39060426Smckusick 		if (!nflag)
39160426Smckusick 			fprintf(stdout, "%s = %s\n", string,
39260426Smckusick 			    devname(dev, S_IFCHR));
39360426Smckusick 		else
39460426Smckusick 			fprintf(stdout, "0x%x\n", dev);
39560426Smckusick 		return;
39660426Smckusick 	}
39759140Smckusick 	switch (type) {
39859140Smckusick 	case CTLTYPE_INT:
39958910Smckusick 		if (newsize == 0) {
40058910Smckusick 			if (!nflag)
40158910Smckusick 				fprintf(stdout, "%s = ", string);
40258910Smckusick 			fprintf(stdout, "%d\n", *(int *)buf);
40358910Smckusick 		} else {
40458910Smckusick 			if (!nflag)
40558910Smckusick 				fprintf(stdout, "%s: %d -> ", string,
40658910Smckusick 				    *(int *)buf);
40758910Smckusick 			fprintf(stdout, "%d\n", *(int *)newval);
40858910Smckusick 		}
40959140Smckusick 		return;
41059140Smckusick 
41159140Smckusick 	case CTLTYPE_STRING:
41258910Smckusick 		if (newsize == 0) {
41358910Smckusick 			if (!nflag)
41458910Smckusick 				fprintf(stdout, "%s = ", string);
41558910Smckusick 			fprintf(stdout, "%s\n", buf);
41658910Smckusick 		} else {
41758910Smckusick 			if (!nflag)
41858910Smckusick 				fprintf(stdout, "%s: %s -> ", string, buf);
41958910Smckusick 			fprintf(stdout, "%s\n", newval);
42058910Smckusick 		}
42159140Smckusick 		return;
42259140Smckusick 
42359140Smckusick 	case CTLTYPE_QUAD:
42459140Smckusick 		if (newsize == 0) {
42559140Smckusick 			if (!nflag)
42659140Smckusick 				fprintf(stdout, "%s = ", string);
42759140Smckusick 			fprintf(stdout, "%qd\n", *(quad_t *)buf);
42859140Smckusick 		} else {
42959140Smckusick 			if (!nflag)
43059140Smckusick 				fprintf(stdout, "%s: %qd -> ", string,
43159140Smckusick 				    *(quad_t *)buf);
43259140Smckusick 			fprintf(stdout, "%qd\n", *(quad_t *)newval);
43359140Smckusick 		}
43459140Smckusick 		return;
43559140Smckusick 
43659140Smckusick 	case CTLTYPE_STRUCT:
43759140Smckusick 		fprintf(stderr, "%s: unknown structure returned\n",
43859140Smckusick 		    string);
43959140Smckusick 		return;
44059140Smckusick 
44159140Smckusick 	default:
44259140Smckusick 	case CTLTYPE_NODE:
44359140Smckusick 		fprintf(stderr, "%s: unknown type returned\n",
44459140Smckusick 		    string);
44559140Smckusick 		return;
44659140Smckusick 	}
44758888Smckusick }
44858888Smckusick 
44959159Smckusick /*
45059159Smckusick  * Initialize the set of debugging names
45159159Smckusick  */
debuginit()45259159Smckusick debuginit()
45359159Smckusick {
45468951Sbostic 	int mib[3], loc, i;
45568951Sbostic 	size_t size;
45659159Smckusick 
45759159Smckusick 	if (secondlevel[CTL_DEBUG].list != 0)
45859159Smckusick 		return;
45959159Smckusick 	secondlevel[CTL_DEBUG].list = debugname;
46059159Smckusick 	mib[0] = CTL_DEBUG;
46159159Smckusick 	mib[2] = CTL_DEBUG_NAME;
46268906Smckusick 	for (loc = lastused, i = 0; i < CTL_DEBUG_MAXID; i++) {
46359159Smckusick 		mib[1] = i;
46459159Smckusick 		size = BUFSIZ - loc;
46559159Smckusick 		if (sysctl(mib, 3, &names[loc], &size, NULL, 0) == -1)
46659159Smckusick 			continue;
46759159Smckusick 		debugname[i].ctl_name = &names[loc];
46859159Smckusick 		debugname[i].ctl_type = CTLTYPE_INT;
46959159Smckusick 		loc += size;
47059159Smckusick 	}
47168906Smckusick 	lastused = loc;
47259159Smckusick }
47359159Smckusick 
47468906Smckusick /*
47568906Smckusick  * Initialize the set of filesystem names
47668906Smckusick  */
vfsinit()47768906Smckusick vfsinit()
47868906Smckusick {
47968906Smckusick 	int mib[4], maxtypenum, cnt, loc, size;
48068906Smckusick 	struct vfsconf vfc;
48168906Smckusick 	size_t buflen;
48268906Smckusick 
48368906Smckusick 	if (secondlevel[CTL_VFS].list != 0)
48468906Smckusick 		return;
48568906Smckusick 	mib[0] = CTL_VFS;
48668906Smckusick 	mib[1] = VFS_GENERIC;
48768906Smckusick 	mib[2] = VFS_MAXTYPENUM;
48868906Smckusick 	buflen = 4;
48968906Smckusick 	if (sysctl(mib, 3, &maxtypenum, &buflen, (void *)0, (size_t)0) < 0)
49068906Smckusick 		return;
49168906Smckusick 	if ((vfsname = malloc(maxtypenum * sizeof(*vfsname))) == 0)
49268906Smckusick 		return;
49368906Smckusick 	memset(vfsname, 0, maxtypenum * sizeof(*vfsname));
49468906Smckusick 	mib[2] = VFS_CONF;
49568906Smckusick 	buflen = sizeof vfc;
49668906Smckusick 	for (loc = lastused, cnt = 0; cnt < maxtypenum; cnt++) {
49768906Smckusick 		mib[3] = cnt;
49868906Smckusick 		if (sysctl(mib, 4, &vfc, &buflen, (void *)0, (size_t)0) < 0) {
49968906Smckusick 			if (errno == EOPNOTSUPP)
50068906Smckusick 				continue;
50168906Smckusick 			perror("vfsinit");
50268906Smckusick 			free(vfsname);
50368906Smckusick 			return;
50468906Smckusick 		}
50568906Smckusick 		strcat(&names[loc], vfc.vfc_name);
50668906Smckusick 		vfsname[cnt].ctl_name = &names[loc];
50768906Smckusick 		vfsname[cnt].ctl_type = CTLTYPE_INT;
50868906Smckusick 		size = strlen(vfc.vfc_name) + 1;
50968906Smckusick 		loc += size;
51068906Smckusick 	}
51168906Smckusick 	lastused = loc;
51268906Smckusick 	secondlevel[CTL_VFS].list = vfsname;
51368906Smckusick 	secondlevel[CTL_VFS].size = maxtypenum;
51468906Smckusick 	return;
51568906Smckusick }
51668906Smckusick 
51759140Smckusick struct ctlname inetname[] = CTL_IPPROTO_NAMES;
51859140Smckusick struct ctlname ipname[] = IPCTL_NAMES;
51959140Smckusick struct ctlname icmpname[] = ICMPCTL_NAMES;
52059311Smckusick struct ctlname udpname[] = UDPCTL_NAMES;
52159140Smckusick struct list inetlist = { inetname, IPPROTO_MAXID };
52259140Smckusick struct list inetvars[] = {
52359311Smckusick 	{ ipname, IPCTL_MAXID },	/* ip */
52459311Smckusick 	{ icmpname, ICMPCTL_MAXID },	/* icmp */
52559311Smckusick 	{ 0, 0 },			/* igmp */
52659311Smckusick 	{ 0, 0 },			/* ggmp */
52759311Smckusick 	{ 0, 0 },
52859311Smckusick 	{ 0, 0 },
52959311Smckusick 	{ 0, 0 },			/* tcp */
53059311Smckusick 	{ 0, 0 },
53159311Smckusick 	{ 0, 0 },			/* egp */
53259311Smckusick 	{ 0, 0 },
53359311Smckusick 	{ 0, 0 },
53459311Smckusick 	{ 0, 0 },
53559311Smckusick 	{ 0, 0 },			/* pup */
53659311Smckusick 	{ 0, 0 },
53759311Smckusick 	{ 0, 0 },
53859311Smckusick 	{ 0, 0 },
53959311Smckusick 	{ 0, 0 },
54059311Smckusick 	{ udpname, UDPCTL_MAXID },	/* udp */
54159140Smckusick };
54259140Smckusick 
54358888Smckusick /*
54459140Smckusick  * handle internet requests
54559140Smckusick  */
sysctl_inet(string,bufpp,mib,flags,typep)54659140Smckusick sysctl_inet(string, bufpp, mib, flags, typep)
54759140Smckusick 	char *string;
54859140Smckusick 	char **bufpp;
54959140Smckusick 	int mib[];
55059140Smckusick 	int flags;
55159140Smckusick 	int *typep;
55259140Smckusick {
55359140Smckusick 	struct list *lp;
55459140Smckusick 	int indx;
55559140Smckusick 
55659140Smckusick 	if (*bufpp == NULL) {
55759140Smckusick 		listall(string, &inetlist);
55859140Smckusick 		return (-1);
55959140Smckusick 	}
56059140Smckusick 	if ((indx = findname(string, "third", bufpp, &inetlist)) == -1)
56159140Smckusick 		return (-1);
56259140Smckusick 	mib[2] = indx;
56359311Smckusick 	if (indx <= IPPROTO_UDP && inetvars[indx].list != NULL)
56459140Smckusick 		lp = &inetvars[indx];
56559140Smckusick 	else if (!flags)
56659140Smckusick 		return (-1);
56759140Smckusick 	else {
56859140Smckusick 		fprintf(stderr, "%s: no variables defined for this protocol\n",
56959140Smckusick 		    string);
57059140Smckusick 		return (-1);
57159140Smckusick 	}
57259140Smckusick 	if (*bufpp == NULL) {
57359140Smckusick 		listall(string, lp);
57459140Smckusick 		return (-1);
57559140Smckusick 	}
57659140Smckusick 	if ((indx = findname(string, "fourth", bufpp, lp)) == -1)
57759140Smckusick 		return (-1);
57859140Smckusick 	mib[3] = indx;
57959140Smckusick 	*typep = lp->list[indx].ctl_type;
58059140Smckusick 	return (4);
58159140Smckusick }
58259140Smckusick 
58359140Smckusick /*
58458888Smckusick  * Scan a list of names searching for a particular name.
58558888Smckusick  */
findname(string,level,bufp,namelist)58658888Smckusick findname(string, level, bufp, namelist)
58758888Smckusick 	char *string;
58858888Smckusick 	char *level;
58958888Smckusick 	char **bufp;
59058888Smckusick 	struct list *namelist;
59158888Smckusick {
59258888Smckusick 	char *name;
59358888Smckusick 	int i;
59458888Smckusick 
59558888Smckusick 	if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) {
59658888Smckusick 		fprintf(stderr, "%s: incomplete specification\n", string);
59758888Smckusick 		return (-1);
59858888Smckusick 	}
59958888Smckusick 	for (i = 0; i < namelist->size; i++)
60059252Storek 		if (namelist->list[i].ctl_name != NULL &&
60159252Storek 		    strcmp(name, namelist->list[i].ctl_name) == 0)
60258888Smckusick 			break;
60358888Smckusick 	if (i == namelist->size) {
60458888Smckusick 		fprintf(stderr, "%s level name %s in %s is invalid\n",
60558888Smckusick 		    level, name, string);
60658888Smckusick 		return (-1);
60758888Smckusick 	}
60858888Smckusick 	return (i);
60958888Smckusick }
61058888Smckusick 
usage()61158888Smckusick usage()
61258888Smckusick {
61358888Smckusick 
61458911Smckusick 	(void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n\t%s\n",
61558911Smckusick 	    "sysctl [-n] variable ...", "sysctl [-n] -w variable=value ...",
61658911Smckusick 	    "sysctl [-n] -a", "sysctl [-n] -A");
61758888Smckusick 	exit(1);
61858888Smckusick }
619