sysctl.c revision 8857
11553Srgrimes/*
21553Srgrimes * Copyright (c) 1993
31553Srgrimes *	The Regents of the University of California.  All rights reserved.
41553Srgrimes *
51553Srgrimes * Redistribution and use in source and binary forms, with or without
61553Srgrimes * modification, are permitted provided that the following conditions
71553Srgrimes * are met:
81553Srgrimes * 1. Redistributions of source code must retain the above copyright
91553Srgrimes *    notice, this list of conditions and the following disclaimer.
101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111553Srgrimes *    notice, this list of conditions and the following disclaimer in the
121553Srgrimes *    documentation and/or other materials provided with the distribution.
131553Srgrimes * 3. All advertising materials mentioning features or use of this software
141553Srgrimes *    must display the following acknowledgement:
151553Srgrimes *	This product includes software developed by the University of
161553Srgrimes *	California, Berkeley and its contributors.
171553Srgrimes * 4. Neither the name of the University nor the names of its contributors
181553Srgrimes *    may be used to endorse or promote products derived from this software
191553Srgrimes *    without specific prior written permission.
201553Srgrimes *
211553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241553Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311553Srgrimes * SUCH DAMAGE.
321553Srgrimes */
331553Srgrimes
341553Srgrimes#ifndef lint
351553Srgrimesstatic char copyright[] =
361553Srgrimes"@(#) Copyright (c) 1993\n\
371553Srgrimes	The Regents of the University of California.  All rights reserved.\n";
381553Srgrimes#endif /* not lint */
391553Srgrimes
401553Srgrimes#ifndef lint
416284Swollman/*static char sccsid[] = "From: @(#)sysctl.c	8.1 (Berkeley) 6/6/93"; */
426284Swollmanstatic const char rcsid[] =
438857Srgrimes	"$Id: sysctl.c,v 1.5 1995/05/12 19:10:56 wollman Exp $";
441553Srgrimes#endif /* not lint */
451553Srgrimes
461553Srgrimes#include <sys/param.h>
471553Srgrimes#include <sys/gmon.h>
481553Srgrimes#include <sys/stat.h>
491553Srgrimes#include <sys/sysctl.h>
501553Srgrimes#include <sys/socket.h>
511553Srgrimes#include <vm/vm_param.h>
521553Srgrimes#include <machine/cpu.h>
531553Srgrimes
541553Srgrimes#include <netinet/in.h>
551553Srgrimes#include <netinet/in_systm.h>
561553Srgrimes#include <netinet/ip.h>
571553Srgrimes#include <netinet/ip_icmp.h>
581553Srgrimes#include <netinet/icmp_var.h>
591553Srgrimes#include <netinet/ip_var.h>
601553Srgrimes#include <netinet/udp.h>
611553Srgrimes#include <netinet/udp_var.h>
626284Swollman#include <netinet/tcp.h>
636284Swollman#include <netinet/tcp_seq.h>
646284Swollman#include <netinet/tcp_timer.h>
656284Swollman#include <netinet/tcp_var.h>
666473Swollman#include <netinet/igmp_var.h>
671553Srgrimes
681553Srgrimes#include <errno.h>
691553Srgrimes#include <stdio.h>
701553Srgrimes#include <stdlib.h>
711553Srgrimes#include <string.h>
721553Srgrimes
731553Srgrimesstruct ctlname topname[] = CTL_NAMES;
741553Srgrimesstruct ctlname kernname[] = CTL_KERN_NAMES;
751553Srgrimesstruct ctlname vmname[] = CTL_VM_NAMES;
761553Srgrimesstruct ctlname netname[] = CTL_NET_NAMES;
771553Srgrimesstruct ctlname hwname[] = CTL_HW_NAMES;
781553Srgrimesstruct ctlname username[] = CTL_USER_NAMES;
791553Srgrimesstruct ctlname debugname[CTL_DEBUG_MAXID];
801553Srgrimes#ifdef CTL_MACHDEP_NAMES
811553Srgrimesstruct ctlname machdepname[] = CTL_MACHDEP_NAMES;
821553Srgrimes#endif
831553Srgrimeschar names[BUFSIZ];
841553Srgrimes
851553Srgrimesstruct list {
861553Srgrimes	struct	ctlname *list;
871553Srgrimes	int	size;
881553Srgrimes};
891553Srgrimesstruct list toplist = { topname, CTL_MAXID };
901553Srgrimesstruct list secondlevel[] = {
911553Srgrimes	{ 0, 0 },			/* CTL_UNSPEC */
921553Srgrimes	{ kernname, KERN_MAXID },	/* CTL_KERN */
931553Srgrimes	{ vmname, VM_MAXID },		/* CTL_VM */
941553Srgrimes	{ 0, 0 },			/* CTL_FS */
951553Srgrimes	{ netname, NET_MAXID },		/* CTL_NET */
961553Srgrimes	{ 0, CTL_DEBUG_MAXID },		/* CTL_DEBUG */
971553Srgrimes	{ hwname, HW_MAXID },		/* CTL_HW */
981553Srgrimes#ifdef CTL_MACHDEP_NAMES
991553Srgrimes	{ machdepname, CPU_MAXID },	/* CTL_MACHDEP */
1001553Srgrimes#else
1011553Srgrimes	{ 0, 0 },			/* CTL_MACHDEP */
1021553Srgrimes#endif
1031553Srgrimes	{ username, USER_MAXID },	/* CTL_USER_NAMES */
1041553Srgrimes};
1051553Srgrimes
1061553Srgrimesint	Aflag, aflag, nflag, wflag;
1071553Srgrimes
1081553Srgrimes/*
1091553Srgrimes * Variables requiring special processing.
1101553Srgrimes */
1111553Srgrimes#define	CLOCK		0x00000001
1121553Srgrimes#define	BOOTTIME	0x00000002
1131553Srgrimes#define	CONSDEV		0x00000004
1148479Swollman#define DUMPDEV		0x00000008
1151553Srgrimes
1161553Srgrimesint
1171553Srgrimesmain(argc, argv)
1181553Srgrimes	int argc;
1191553Srgrimes	char *argv[];
1201553Srgrimes{
1211553Srgrimes	extern char *optarg;
1221553Srgrimes	extern int optind;
1231553Srgrimes	int ch, lvl1;
1241553Srgrimes
1251553Srgrimes	while ((ch = getopt(argc, argv, "Aanw")) != EOF) {
1261553Srgrimes		switch (ch) {
1271553Srgrimes
1281553Srgrimes		case 'A':
1291553Srgrimes			Aflag = 1;
1301553Srgrimes			break;
1311553Srgrimes
1321553Srgrimes		case 'a':
1331553Srgrimes			aflag = 1;
1341553Srgrimes			break;
1351553Srgrimes
1361553Srgrimes		case 'n':
1371553Srgrimes			nflag = 1;
1381553Srgrimes			break;
1391553Srgrimes
1401553Srgrimes		case 'w':
1411553Srgrimes			wflag = 1;
1421553Srgrimes			break;
1431553Srgrimes
1441553Srgrimes		default:
1451553Srgrimes			usage();
1461553Srgrimes		}
1471553Srgrimes	}
1481553Srgrimes	argc -= optind;
1491553Srgrimes	argv += optind;
1501553Srgrimes
1511553Srgrimes	if (Aflag || aflag) {
1521553Srgrimes		debuginit();
1531553Srgrimes		for (lvl1 = 1; lvl1 < CTL_MAXID; lvl1++)
1541553Srgrimes			listall(topname[lvl1].ctl_name, &secondlevel[lvl1]);
1551553Srgrimes		exit(0);
1561553Srgrimes	}
1571553Srgrimes	if (argc == 0)
1581553Srgrimes		usage();
1591553Srgrimes	while (argc-- > 0)
1601553Srgrimes		parse(*argv, 1);
1611553Srgrimes	exit(0);
1621553Srgrimes}
1631553Srgrimes
1641553Srgrimes/*
1651553Srgrimes * List all variables known to the system.
1661553Srgrimes */
1671553Srgrimeslistall(prefix, lp)
1681553Srgrimes	char *prefix;
1691553Srgrimes	struct list *lp;
1701553Srgrimes{
1711553Srgrimes	int lvl2;
1721553Srgrimes	char *cp, name[BUFSIZ];
1731553Srgrimes
1741553Srgrimes	if (lp->list == 0)
1751553Srgrimes		return;
1761553Srgrimes	strcpy(name, prefix);
1771553Srgrimes	cp = &name[strlen(name)];
1781553Srgrimes	*cp++ = '.';
1791553Srgrimes	for (lvl2 = 0; lvl2 < lp->size; lvl2++) {
1801553Srgrimes		if (lp->list[lvl2].ctl_name == 0)
1811553Srgrimes			continue;
1821553Srgrimes		strcpy(cp, lp->list[lvl2].ctl_name);
1831553Srgrimes		parse(name, Aflag);
1841553Srgrimes	}
1851553Srgrimes}
1861553Srgrimes
1871553Srgrimes/*
1881553Srgrimes * Parse a name into a MIB entry.
1891553Srgrimes * Lookup and print out the MIB entry if it exists.
1901553Srgrimes * Set a new value if requested.
1911553Srgrimes */
1921553Srgrimesparse(string, flags)
1931553Srgrimes	char *string;
1941553Srgrimes	int flags;
1951553Srgrimes{
1961553Srgrimes	int indx, type, state, size, len;
1971553Srgrimes	int special = 0;
1981553Srgrimes	void *newval = 0;
1991553Srgrimes	int intval, newsize = 0;
2001553Srgrimes	quad_t quadval;
2011553Srgrimes	struct list *lp;
2021553Srgrimes	int mib[CTL_MAXNAME];
2031553Srgrimes	char *cp, *bufp, buf[BUFSIZ], strval[BUFSIZ];
2041553Srgrimes
2051553Srgrimes	bufp = buf;
2061553Srgrimes	snprintf(buf, BUFSIZ, "%s", string);
2071553Srgrimes	if ((cp = strchr(string, '=')) != NULL) {
2081553Srgrimes		if (!wflag) {
2091553Srgrimes			fprintf(stderr, "Must specify -w to set variables\n");
2101553Srgrimes			exit(2);
2111553Srgrimes		}
2121553Srgrimes		*strchr(buf, '=') = '\0';
2131553Srgrimes		*cp++ = '\0';
2141553Srgrimes		while (isspace(*cp))
2151553Srgrimes			cp++;
2161553Srgrimes		newval = cp;
2171553Srgrimes		newsize = strlen(cp);
2181553Srgrimes	}
2191553Srgrimes	if ((indx = findname(string, "top", &bufp, &toplist)) == -1)
2201553Srgrimes		return;
2211553Srgrimes	mib[0] = indx;
2221553Srgrimes	if (indx == CTL_DEBUG)
2231553Srgrimes		debuginit();
2241553Srgrimes	lp = &secondlevel[indx];
2251553Srgrimes	if (lp->list == 0) {
2261553Srgrimes		fprintf(stderr, "%s: class is not implemented\n",
2271553Srgrimes		    topname[indx]);
2281553Srgrimes		return;
2291553Srgrimes	}
2301553Srgrimes	if (bufp == NULL) {
2311553Srgrimes		listall(topname[indx].ctl_name, lp);
2321553Srgrimes		return;
2331553Srgrimes	}
2341553Srgrimes	if ((indx = findname(string, "second", &bufp, lp)) == -1)
2351553Srgrimes		return;
2361553Srgrimes	mib[1] = indx;
2371553Srgrimes	type = lp->list[indx].ctl_type;
2381553Srgrimes	len = 2;
2391553Srgrimes	switch (mib[0]) {
2401553Srgrimes
2411553Srgrimes	case CTL_KERN:
2421553Srgrimes		switch (mib[1]) {
2431553Srgrimes		case KERN_PROF:
2441553Srgrimes			mib[2] = GPROF_STATE;
2451553Srgrimes			size = sizeof state;
2461553Srgrimes			if (sysctl(mib, 3, &state, &size, NULL, 0) < 0) {
2471553Srgrimes				if (flags == 0)
2481553Srgrimes					return;
2491553Srgrimes				if (!nflag)
2501553Srgrimes					fprintf(stdout, "%s: ", string);
2511553Srgrimes				fprintf(stderr,
2521553Srgrimes				    "kernel is not compiled for profiling\n");
2531553Srgrimes				return;
2541553Srgrimes			}
2551553Srgrimes			if (!nflag)
2561553Srgrimes				fprintf(stdout, "%s: %s\n", string,
2571553Srgrimes				    state == GMON_PROF_OFF ? "off" : "running");
2581553Srgrimes			return;
2591553Srgrimes		case KERN_VNODE:
2601553Srgrimes		case KERN_FILE:
2611553Srgrimes			if (flags == 0)
2621553Srgrimes				return;
2631553Srgrimes			fprintf(stderr,
2641553Srgrimes			    "Use pstat to view %s information\n", string);
2651553Srgrimes			return;
2661553Srgrimes		case KERN_PROC:
2671553Srgrimes			if (flags == 0)
2681553Srgrimes				return;
2691553Srgrimes			fprintf(stderr,
2701553Srgrimes			    "Use ps to view %s information\n", string);
2711553Srgrimes			return;
2721553Srgrimes		case KERN_CLOCKRATE:
2731553Srgrimes			special |= CLOCK;
2741553Srgrimes			break;
2751553Srgrimes		case KERN_BOOTTIME:
2761553Srgrimes			special |= BOOTTIME;
2771553Srgrimes			break;
2788479Swollman		case KERN_DUMPDEV:
2798479Swollman			special |= DUMPDEV;
2808479Swollman			break;
2811553Srgrimes		}
2821553Srgrimes		break;
2831553Srgrimes
2841553Srgrimes	case CTL_HW:
2851553Srgrimes		break;
2861553Srgrimes
2871553Srgrimes	case CTL_VM:
2881553Srgrimes		if (mib[1] == VM_LOADAVG) {
2891553Srgrimes			double loads[3];
2901553Srgrimes
2911553Srgrimes			getloadavg(loads, 3);
2921553Srgrimes			if (!nflag)
2931553Srgrimes				fprintf(stdout, "%s: ", string);
2948857Srgrimes			fprintf(stdout, "%.2f %.2f %.2f\n",
2951553Srgrimes			    loads[0], loads[1], loads[2]);
2961553Srgrimes			return;
2971553Srgrimes		}
2981553Srgrimes		if (flags == 0)
2991553Srgrimes			return;
3001553Srgrimes		fprintf(stderr,
3011553Srgrimes		    "Use vmstat or systat to view %s information\n", string);
3021553Srgrimes		return;
3031553Srgrimes
3041553Srgrimes	case CTL_NET:
3051553Srgrimes		if (mib[1] == PF_INET) {
3066473Swollman			len = sysctl_inet(string, &bufp, mib, flags, &type,
3076473Swollman					  &special);
3081553Srgrimes			if (len >= 0)
3091553Srgrimes				break;
3101553Srgrimes			return;
3111553Srgrimes		}
3121553Srgrimes		if (flags == 0)
3131553Srgrimes			return;
3141553Srgrimes		fprintf(stderr, "Use netstat to view %s information\n", string);
3151553Srgrimes		return;
3161553Srgrimes
3171553Srgrimes	case CTL_DEBUG:
3181553Srgrimes		mib[2] = CTL_DEBUG_VALUE;
3191553Srgrimes		len = 3;
3201553Srgrimes		break;
3211553Srgrimes
3221553Srgrimes	case CTL_MACHDEP:
3231553Srgrimes#ifdef CPU_CONSDEV
3241553Srgrimes		if (mib[1] == CPU_CONSDEV)
3251553Srgrimes			special |= CONSDEV;
3261553Srgrimes#endif
3271553Srgrimes		break;
3281553Srgrimes
3291553Srgrimes	case CTL_FS:
3301553Srgrimes	case CTL_USER:
3311553Srgrimes		break;
3321553Srgrimes
3331553Srgrimes	default:
3341553Srgrimes		fprintf(stderr, "Illegal top level value: %d\n", mib[0]);
3351553Srgrimes		return;
3368857Srgrimes
3371553Srgrimes	}
3381553Srgrimes	if (bufp) {
3391553Srgrimes		fprintf(stderr, "name %s in %s is unknown\n", *bufp, string);
3401553Srgrimes		return;
3411553Srgrimes	}
3421553Srgrimes	if (newsize > 0) {
3431553Srgrimes		switch (type) {
3441553Srgrimes		case CTLTYPE_INT:
3451553Srgrimes			intval = atoi(newval);
3461553Srgrimes			newval = &intval;
3471553Srgrimes			newsize = sizeof intval;
3481553Srgrimes			break;
3491553Srgrimes
3501553Srgrimes		case CTLTYPE_QUAD:
3511553Srgrimes			sscanf(newval, "%qd", &quadval);
3521553Srgrimes			newval = &quadval;
3531553Srgrimes			newsize = sizeof quadval;
3541553Srgrimes			break;
3551553Srgrimes		}
3561553Srgrimes	}
3571553Srgrimes	size = BUFSIZ;
3581553Srgrimes	if (sysctl(mib, len, buf, &size, newsize ? newval : 0, newsize) == -1) {
3591553Srgrimes		if (flags == 0)
3601553Srgrimes			return;
3611553Srgrimes		switch (errno) {
3621553Srgrimes		case EOPNOTSUPP:
3631553Srgrimes			fprintf(stderr, "%s: value is not available\n", string);
3641553Srgrimes			return;
3651553Srgrimes		case ENOTDIR:
3661553Srgrimes			fprintf(stderr, "%s: specification is incomplete\n",
3671553Srgrimes			    string);
3681553Srgrimes			return;
3691553Srgrimes		case ENOMEM:
3701553Srgrimes			fprintf(stderr, "%s: type is unknown to this program\n",
3711553Srgrimes			    string);
3721553Srgrimes			return;
3731553Srgrimes		default:
3741553Srgrimes			perror(string);
3751553Srgrimes			return;
3761553Srgrimes		}
3771553Srgrimes	}
3781553Srgrimes	if (special & CLOCK) {
3791553Srgrimes		struct clockinfo *clkp = (struct clockinfo *)buf;
3801553Srgrimes
3811553Srgrimes		if (!nflag)
3821553Srgrimes			fprintf(stdout, "%s: ", string);
3831553Srgrimes		fprintf(stdout,
3841553Srgrimes		    "hz = %d, tick = %d, profhz = %d, stathz = %d\n",
3851553Srgrimes		    clkp->hz, clkp->tick, clkp->profhz, clkp->stathz);
3861553Srgrimes		return;
3871553Srgrimes	}
3881553Srgrimes	if (special & BOOTTIME) {
3891553Srgrimes		struct timeval *btp = (struct timeval *)buf;
3901553Srgrimes
3911553Srgrimes		if (!nflag)
3921951Swollman			fprintf(stdout, "%s = %s", string,
3931553Srgrimes			    ctime(&btp->tv_sec));
3941553Srgrimes		else
3951553Srgrimes			fprintf(stdout, "%d\n", btp->tv_sec);
3961553Srgrimes		return;
3971553Srgrimes	}
3988479Swollman	if (special & (CONSDEV | DUMPDEV)) {
3991553Srgrimes		dev_t dev = *(dev_t *)buf;
4001553Srgrimes
4018479Swollman		if ((special & DUMPDEV) && dev == NODEV && !nflag) {
4028479Swollman			printf("%s = disabled\n", string);
4038479Swollman			return;
4048479Swollman		}
4051553Srgrimes		if (!nflag)
4061553Srgrimes			fprintf(stdout, "%s = %s\n", string,
4078857Srgrimes			    devname(dev,
4088479Swollman				    (special & CONSDEV) ? S_IFCHR : S_IFBLK));
4091553Srgrimes		else
4101553Srgrimes			fprintf(stdout, "0x%x\n", dev);
4111553Srgrimes		return;
4121553Srgrimes	}
4131553Srgrimes	switch (type) {
4141553Srgrimes	case CTLTYPE_INT:
4151553Srgrimes		if (newsize == 0) {
4161553Srgrimes			if (!nflag)
4171553Srgrimes				fprintf(stdout, "%s = ", string);
4181553Srgrimes			fprintf(stdout, "%d\n", *(int *)buf);
4191553Srgrimes		} else {
4201553Srgrimes			if (!nflag)
4211553Srgrimes				fprintf(stdout, "%s: %d -> ", string,
4221553Srgrimes				    *(int *)buf);
4231553Srgrimes			fprintf(stdout, "%d\n", *(int *)newval);
4241553Srgrimes		}
4251553Srgrimes		return;
4261553Srgrimes
4271553Srgrimes	case CTLTYPE_STRING:
4281553Srgrimes		if (newsize == 0) {
4291553Srgrimes			if (!nflag)
4301553Srgrimes				fprintf(stdout, "%s = ", string);
4311553Srgrimes			fprintf(stdout, "%s\n", buf);
4321553Srgrimes		} else {
4331553Srgrimes			if (!nflag)
4341553Srgrimes				fprintf(stdout, "%s: %s -> ", string, buf);
4351553Srgrimes			fprintf(stdout, "%s\n", newval);
4361553Srgrimes		}
4371553Srgrimes		return;
4381553Srgrimes
4391553Srgrimes	case CTLTYPE_QUAD:
4401553Srgrimes		if (newsize == 0) {
4411553Srgrimes			if (!nflag)
4421553Srgrimes				fprintf(stdout, "%s = ", string);
4431553Srgrimes			fprintf(stdout, "%qd\n", *(quad_t *)buf);
4441553Srgrimes		} else {
4451553Srgrimes			if (!nflag)
4461553Srgrimes				fprintf(stdout, "%s: %qd -> ", string,
4471553Srgrimes				    *(quad_t *)buf);
4481553Srgrimes			fprintf(stdout, "%qd\n", *(quad_t *)newval);
4491553Srgrimes		}
4501553Srgrimes		return;
4511553Srgrimes
4521553Srgrimes	case CTLTYPE_STRUCT:
4531553Srgrimes		fprintf(stderr, "%s: unknown structure returned\n",
4541553Srgrimes		    string);
4551553Srgrimes		return;
4561553Srgrimes
4571553Srgrimes	default:
4581553Srgrimes	case CTLTYPE_NODE:
4591553Srgrimes		fprintf(stderr, "%s: unknown type returned\n",
4601553Srgrimes		    string);
4611553Srgrimes		return;
4621553Srgrimes	}
4631553Srgrimes}
4641553Srgrimes
4651553Srgrimes/*
4661553Srgrimes * Initialize the set of debugging names
4671553Srgrimes */
4681553Srgrimesdebuginit()
4691553Srgrimes{
4701553Srgrimes	int mib[3], size, loc, i;
4711553Srgrimes
4721553Srgrimes	if (secondlevel[CTL_DEBUG].list != 0)
4731553Srgrimes		return;
4741553Srgrimes	secondlevel[CTL_DEBUG].list = debugname;
4751553Srgrimes	mib[0] = CTL_DEBUG;
4761553Srgrimes	mib[2] = CTL_DEBUG_NAME;
4771553Srgrimes	for (loc = 0, i = 0; i < CTL_DEBUG_MAXID; i++) {
4781553Srgrimes		mib[1] = i;
4791553Srgrimes		size = BUFSIZ - loc;
4801553Srgrimes		if (sysctl(mib, 3, &names[loc], &size, NULL, 0) == -1)
4811553Srgrimes			continue;
4821553Srgrimes		debugname[i].ctl_name = &names[loc];
4831553Srgrimes		debugname[i].ctl_type = CTLTYPE_INT;
4841553Srgrimes		loc += size;
4851553Srgrimes	}
4861553Srgrimes}
4871553Srgrimes
4881553Srgrimesstruct ctlname inetname[] = CTL_IPPROTO_NAMES;
4891553Srgrimesstruct ctlname ipname[] = IPCTL_NAMES;
4901553Srgrimesstruct ctlname icmpname[] = ICMPCTL_NAMES;
4911553Srgrimesstruct ctlname udpname[] = UDPCTL_NAMES;
4926284Swollmanstruct ctlname tcpname[] = TCPCTL_NAMES;
4936473Swollmanstruct ctlname igmpname[] = IGMPCTL_NAMES;
4941553Srgrimesstruct list inetlist = { inetname, IPPROTO_MAXID };
4951553Srgrimesstruct list inetvars[] = {
4961553Srgrimes	{ ipname, IPCTL_MAXID },	/* ip */
4971553Srgrimes	{ icmpname, ICMPCTL_MAXID },	/* icmp */
4986473Swollman	{ igmpname, IGMPCTL_MAXID },	/* igmp */
4996473Swollman	{ 0, 0 },			/* ggp */
5006473Swollman	{ 0, 0 },			/* ipencap */
5011553Srgrimes	{ 0, 0 },
5026284Swollman	{ tcpname, TCPCTL_MAXID },	/* tcp */
5031553Srgrimes	{ 0, 0 },
5041553Srgrimes	{ 0, 0 },			/* egp */
5051553Srgrimes	{ 0, 0 },
5061553Srgrimes	{ 0, 0 },
5071553Srgrimes	{ 0, 0 },
5081553Srgrimes	{ 0, 0 },			/* pup */
5091553Srgrimes	{ 0, 0 },
5101553Srgrimes	{ 0, 0 },
5111553Srgrimes	{ 0, 0 },
5121553Srgrimes	{ 0, 0 },
5131553Srgrimes	{ udpname, UDPCTL_MAXID },	/* udp */
5141553Srgrimes};
5151553Srgrimes
5161553Srgrimes/*
5171553Srgrimes * handle internet requests
5181553Srgrimes */
5196473Swollmanint
5206473Swollmansysctl_inet(string, bufpp, mib, flags, typep, specialp)
5211553Srgrimes	char *string;
5221553Srgrimes	char **bufpp;
5231553Srgrimes	int mib[];
5241553Srgrimes	int flags;
5251553Srgrimes	int *typep;
5266473Swollman	int *specialp;
5271553Srgrimes{
5281553Srgrimes	struct list *lp;
5291553Srgrimes	int indx;
5301553Srgrimes
5311553Srgrimes	if (*bufpp == NULL) {
5321553Srgrimes		listall(string, &inetlist);
5331553Srgrimes		return (-1);
5341553Srgrimes	}
5351553Srgrimes	if ((indx = findname(string, "third", bufpp, &inetlist)) == -1)
5361553Srgrimes		return (-1);
5371553Srgrimes	mib[2] = indx;
5381553Srgrimes	if (indx <= IPPROTO_UDP && inetvars[indx].list != NULL)
5391553Srgrimes		lp = &inetvars[indx];
5401553Srgrimes	else if (!flags)
5411553Srgrimes		return (-1);
5421553Srgrimes	else {
5431553Srgrimes		fprintf(stderr, "%s: no variables defined for this protocol\n",
5441553Srgrimes		    string);
5451553Srgrimes		return (-1);
5461553Srgrimes	}
5471553Srgrimes	if (*bufpp == NULL) {
5481553Srgrimes		listall(string, lp);
5491553Srgrimes		return (-1);
5501553Srgrimes	}
5511553Srgrimes	if ((indx = findname(string, "fourth", bufpp, lp)) == -1)
5521553Srgrimes		return (-1);
5531553Srgrimes	mib[3] = indx;
5541553Srgrimes	*typep = lp->list[indx].ctl_type;
5551553Srgrimes	return (4);
5561553Srgrimes}
5571553Srgrimes
5581553Srgrimes/*
5591553Srgrimes * Scan a list of names searching for a particular name.
5601553Srgrimes */
5611553Srgrimesfindname(string, level, bufp, namelist)
5621553Srgrimes	char *string;
5631553Srgrimes	char *level;
5641553Srgrimes	char **bufp;
5651553Srgrimes	struct list *namelist;
5661553Srgrimes{
5671553Srgrimes	char *name;
5681553Srgrimes	int i;
5691553Srgrimes
5701553Srgrimes	if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) {
5711553Srgrimes		fprintf(stderr, "%s: incomplete specification\n", string);
5721553Srgrimes		return (-1);
5731553Srgrimes	}
5741553Srgrimes	for (i = 0; i < namelist->size; i++)
5751553Srgrimes		if (namelist->list[i].ctl_name != NULL &&
5761553Srgrimes		    strcmp(name, namelist->list[i].ctl_name) == 0)
5771553Srgrimes			break;
5781553Srgrimes	if (i == namelist->size) {
5791553Srgrimes		fprintf(stderr, "%s level name %s in %s is invalid\n",
5801553Srgrimes		    level, name, string);
5811553Srgrimes		return (-1);
5821553Srgrimes	}
5831553Srgrimes	return (i);
5841553Srgrimes}
5851553Srgrimes
5861553Srgrimesusage()
5871553Srgrimes{
5881553Srgrimes
5891553Srgrimes	(void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n\t%s\n",
5901553Srgrimes	    "sysctl [-n] variable ...", "sysctl [-n] -w variable=value ...",
5911553Srgrimes	    "sysctl [-n] -a", "sysctl [-n] -A");
5921553Srgrimes	exit(1);
5931553Srgrimes}
594