xref: /openbsd-src/sys/kern/kern_sysctl.c (revision 15572fcf8c6bfa0588565cd23f393a5a1499ea57)
1 /*	$OpenBSD: kern_sysctl.c,v 1.383 2020/11/16 06:42:12 gnezdo Exp $	*/
2 /*	$NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $	*/
3 
4 /*-
5  * Copyright (c) 1982, 1986, 1989, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * Mike Karels at Berkeley Software Design, Inc.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)kern_sysctl.c	8.4 (Berkeley) 4/14/94
36  */
37 
38 /*
39  * sysctl system call.
40  */
41 
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/malloc.h>
46 #include <sys/pool.h>
47 #include <sys/proc.h>
48 #include <sys/resourcevar.h>
49 #include <sys/signalvar.h>
50 #include <sys/fcntl.h>
51 #include <sys/file.h>
52 #include <sys/filedesc.h>
53 #include <sys/vnode.h>
54 #include <sys/unistd.h>
55 #include <sys/buf.h>
56 #include <sys/ioctl.h>
57 #include <sys/tty.h>
58 #include <sys/disklabel.h>
59 #include <sys/disk.h>
60 #include <sys/sysctl.h>
61 #include <sys/msgbuf.h>
62 #include <sys/vmmeter.h>
63 #include <sys/namei.h>
64 #include <sys/exec.h>
65 #include <sys/mbuf.h>
66 #include <sys/percpu.h>
67 #include <sys/sensors.h>
68 #include <sys/pipe.h>
69 #include <sys/eventvar.h>
70 #include <sys/socketvar.h>
71 #include <sys/socket.h>
72 #include <sys/domain.h>
73 #include <sys/protosw.h>
74 #include <sys/pledge.h>
75 #include <sys/timetc.h>
76 #include <sys/evcount.h>
77 #include <sys/un.h>
78 #include <sys/unpcb.h>
79 #include <sys/sched.h>
80 #include <sys/mount.h>
81 #include <sys/syscallargs.h>
82 #include <sys/wait.h>
83 #include <sys/witness.h>
84 
85 #include <uvm/uvm_extern.h>
86 
87 #include <dev/cons.h>
88 
89 #include <net/route.h>
90 #include <netinet/in.h>
91 #include <netinet/ip.h>
92 #include <netinet/ip_var.h>
93 #include <netinet/in_pcb.h>
94 #include <netinet/ip6.h>
95 #include <netinet/tcp.h>
96 #include <netinet/tcp_timer.h>
97 #include <netinet/tcp_var.h>
98 #include <netinet/udp.h>
99 #include <netinet/udp_var.h>
100 #include <netinet6/ip6_var.h>
101 
102 #ifdef DDB
103 #include <ddb/db_var.h>
104 #endif
105 
106 #ifdef SYSVMSG
107 #include <sys/msg.h>
108 #endif
109 #ifdef SYSVSEM
110 #include <sys/sem.h>
111 #endif
112 #ifdef SYSVSHM
113 #include <sys/shm.h>
114 #endif
115 
116 #include "audio.h"
117 #include "pf.h"
118 
119 extern struct forkstat forkstat;
120 extern struct nchstats nchstats;
121 extern int nselcoll, fscale;
122 extern struct disklist_head disklist;
123 extern fixpt_t ccpu;
124 extern  long numvnodes;
125 #if NAUDIO > 0
126 extern int audio_record_enable;
127 #endif
128 
129 int allowkmem;
130 int allowdt;
131 
132 int sysctl_diskinit(int, struct proc *);
133 int sysctl_proc_args(int *, u_int, void *, size_t *, struct proc *);
134 int sysctl_proc_cwd(int *, u_int, void *, size_t *, struct proc *);
135 int sysctl_proc_nobroadcastkill(int *, u_int, void *, size_t, void *, size_t *,
136 	struct proc *);
137 int sysctl_proc_vmmap(int *, u_int, void *, size_t *, struct proc *);
138 int sysctl_intrcnt(int *, u_int, void *, size_t *);
139 int sysctl_sensors(int *, u_int, void *, size_t *, void *, size_t);
140 int sysctl_cptime2(int *, u_int, void *, size_t *, void *, size_t);
141 #if NAUDIO > 0
142 int sysctl_audio(int *, u_int, void *, size_t *, void *, size_t);
143 #endif
144 int sysctl_cpustats(int *, u_int, void *, size_t *, void *, size_t);
145 int sysctl_utc_offset(void *, size_t *, void *, size_t);
146 
147 void fill_file(struct kinfo_file *, struct file *, struct filedesc *, int,
148     struct vnode *, struct process *, struct proc *, struct socket *, int);
149 void fill_kproc(struct process *, struct kinfo_proc *, struct proc *, int);
150 
151 int (*cpu_cpuspeed)(int *);
152 
153 /*
154  * Lock to avoid too many processes vslocking a large amount of memory
155  * at the same time.
156  */
157 struct rwlock sysctl_lock = RWLOCK_INITIALIZER("sysctllk");
158 struct rwlock sysctl_disklock = RWLOCK_INITIALIZER("sysctldlk");
159 
160 int
161 sys_sysctl(struct proc *p, void *v, register_t *retval)
162 {
163 	struct sys_sysctl_args /* {
164 		syscallarg(const int *) name;
165 		syscallarg(u_int) namelen;
166 		syscallarg(void *) old;
167 		syscallarg(size_t *) oldlenp;
168 		syscallarg(void *) new;
169 		syscallarg(size_t) newlen;
170 	} */ *uap = v;
171 	int error, dolock = 1;
172 	size_t savelen = 0, oldlen = 0;
173 	sysctlfn *fn;
174 	int name[CTL_MAXNAME];
175 
176 	if (SCARG(uap, new) != NULL &&
177 	    (error = suser(p)))
178 		return (error);
179 	/*
180 	 * all top-level sysctl names are non-terminal
181 	 */
182 	if (SCARG(uap, namelen) > CTL_MAXNAME || SCARG(uap, namelen) < 2)
183 		return (EINVAL);
184 	error = copyin(SCARG(uap, name), name,
185 		       SCARG(uap, namelen) * sizeof(int));
186 	if (error)
187 		return (error);
188 
189 	error = pledge_sysctl(p, SCARG(uap, namelen),
190 	    name, SCARG(uap, new));
191 	if (error)
192 		return (error);
193 
194 	switch (name[0]) {
195 	case CTL_KERN:
196 		fn = kern_sysctl;
197 		break;
198 	case CTL_HW:
199 		fn = hw_sysctl;
200 		break;
201 	case CTL_VM:
202 		fn = uvm_sysctl;
203 		break;
204 	case CTL_NET:
205 		fn = net_sysctl;
206 		break;
207 	case CTL_FS:
208 		fn = fs_sysctl;
209 		break;
210 	case CTL_VFS:
211 		fn = vfs_sysctl;
212 		break;
213 	case CTL_MACHDEP:
214 		fn = cpu_sysctl;
215 		break;
216 #ifdef DEBUG_SYSCTL
217 	case CTL_DEBUG:
218 		fn = debug_sysctl;
219 		break;
220 #endif
221 #ifdef DDB
222 	case CTL_DDB:
223 		fn = ddb_sysctl;
224 		break;
225 #endif
226 	default:
227 		return (EOPNOTSUPP);
228 	}
229 
230 	if (SCARG(uap, oldlenp) &&
231 	    (error = copyin(SCARG(uap, oldlenp), &oldlen, sizeof(oldlen))))
232 		return (error);
233 	if (SCARG(uap, old) != NULL) {
234 		if ((error = rw_enter(&sysctl_lock, RW_WRITE|RW_INTR)) != 0)
235 			return (error);
236 		if (dolock) {
237 			if (atop(oldlen) > uvmexp.wiredmax - uvmexp.wired) {
238 				rw_exit_write(&sysctl_lock);
239 				return (ENOMEM);
240 			}
241 			error = uvm_vslock(p, SCARG(uap, old), oldlen,
242 			    PROT_READ | PROT_WRITE);
243 			if (error) {
244 				rw_exit_write(&sysctl_lock);
245 				return (error);
246 			}
247 		}
248 		savelen = oldlen;
249 	}
250 	error = (*fn)(&name[1], SCARG(uap, namelen) - 1, SCARG(uap, old),
251 	    &oldlen, SCARG(uap, new), SCARG(uap, newlen), p);
252 	if (SCARG(uap, old) != NULL) {
253 		if (dolock)
254 			uvm_vsunlock(p, SCARG(uap, old), savelen);
255 		rw_exit_write(&sysctl_lock);
256 	}
257 	if (error)
258 		return (error);
259 	if (SCARG(uap, oldlenp))
260 		error = copyout(&oldlen, SCARG(uap, oldlenp), sizeof(oldlen));
261 	return (error);
262 }
263 
264 /*
265  * Attributes stored in the kernel.
266  */
267 char hostname[MAXHOSTNAMELEN];
268 int hostnamelen;
269 char domainname[MAXHOSTNAMELEN];
270 int domainnamelen;
271 long hostid;
272 char *disknames = NULL;
273 size_t disknameslen;
274 struct diskstats *diskstats = NULL;
275 size_t diskstatslen;
276 int securelevel;
277 
278 /* morally const values reported by sysctl_bounded_arr */
279 static int arg_max = ARG_MAX;
280 static int openbsd = OpenBSD;
281 static int posix_version = _POSIX_VERSION;
282 static int ngroups_max = NGROUPS_MAX;
283 static int int_zero = 0;
284 static int int_one = 1;
285 static int maxpartitions = MAXPARTITIONS;
286 static int raw_part = RAW_PART;
287 
288 extern int somaxconn, sominconn;
289 extern int nosuidcoredump;
290 extern int maxlocksperuid;
291 extern int uvm_wxabort;
292 extern int global_ptrace;
293 
294 const struct sysctl_bounded_args kern_vars[] = {
295 	{KERN_OSREV, &openbsd, 1, 0},
296 	{KERN_MAXVNODES, &maxvnodes, 0, INT_MAX},
297 	{KERN_MAXPROC, &maxprocess, 0, INT_MAX},
298 	{KERN_MAXFILES, &maxfiles, 0, INT_MAX},
299 	{KERN_NFILES, &numfiles, 1, 0},
300 	{KERN_TTYCOUNT, &tty_count, 1, 0},
301 	{KERN_ARGMAX, &arg_max, 1, 0},
302 	{KERN_NSELCOLL, &nselcoll, 1, 0},
303 	{KERN_POSIX1, &posix_version, 1, 0},
304 	{KERN_NGROUPS, &ngroups_max, 1, 0},
305 	{KERN_JOB_CONTROL, &int_one, 1, 0},
306 	{KERN_SAVED_IDS, &int_one, 1, 0},
307 	{KERN_MAXPARTITIONS, &maxpartitions, 1, 0},
308 	{KERN_RAWPARTITION, &raw_part, 1, 0},
309 	{KERN_MAXTHREAD, &maxthread, 0, INT_MAX},
310 	{KERN_NTHREADS, &nthreads, 1, 0},
311 	{KERN_SOMAXCONN, &somaxconn, 0, SHRT_MAX},
312 	{KERN_SOMINCONN, &sominconn, 0, SHRT_MAX},
313 	{KERN_NOSUIDCOREDUMP, &nosuidcoredump, 0, 3},
314 	{KERN_FSYNC, &int_one, 1, 0},
315 	{KERN_SYSVMSG,
316 #ifdef SYSVMSG
317 	 &int_one,
318 #else
319 	 &int_zero,
320 #endif
321 	 1, 0},
322 	{KERN_SYSVSEM,
323 #ifdef SYSVSEM
324 	 &int_one,
325 #else
326 	 &int_zero,
327 #endif
328 	 1, 0},
329 	{KERN_SYSVSHM,
330 #ifdef SYSVSHM
331 	 &int_one,
332 #else
333 	 &int_zero,
334 #endif
335 	 1, 0},
336 	{KERN_FSCALE, &fscale, 1, 0},
337 	{KERN_CCPU, &ccpu, 1, 0},
338 	{KERN_NPROCS, &nprocesses, 1, 0},
339 	{KERN_SPLASSERT, &splassert_ctl, 0, 3},
340 	{KERN_MAXLOCKSPERUID, &maxlocksperuid, 0, INT_MAX},
341 	{KERN_WXABORT, &uvm_wxabort, 0, 1},
342 	{KERN_NETLIVELOCKS, &int_zero, 1, 0},
343 #ifdef PTRACE
344 	{KERN_GLOBAL_PTRACE, &global_ptrace, 0, 1},
345 #endif
346 };
347 
348 /*
349  * kernel related system variables.
350  */
351 int
352 kern_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
353     size_t newlen, struct proc *p)
354 {
355 	int error, level, inthostid, stackgap;
356 	dev_t dev;
357 	extern int pool_debug;
358 
359 	/* all sysctl names at this level are terminal except a ton of them */
360 	if (namelen != 1) {
361 		switch (name[0]) {
362 		case KERN_PROC:
363 		case KERN_PROF:
364 		case KERN_MALLOCSTATS:
365 		case KERN_TTY:
366 		case KERN_POOL:
367 		case KERN_PROC_ARGS:
368 		case KERN_PROC_CWD:
369 		case KERN_PROC_NOBROADCASTKILL:
370 		case KERN_PROC_VMMAP:
371 		case KERN_SYSVIPC_INFO:
372 		case KERN_SEMINFO:
373 		case KERN_SHMINFO:
374 		case KERN_INTRCNT:
375 		case KERN_WATCHDOG:
376 		case KERN_EVCOUNT:
377 		case KERN_TIMECOUNTER:
378 		case KERN_CPTIME2:
379 		case KERN_FILE:
380 		case KERN_WITNESS:
381 		case KERN_AUDIO:
382 		case KERN_CPUSTATS:
383 			break;
384 		default:
385 			return (ENOTDIR);	/* overloaded */
386 		}
387 	}
388 
389 	switch (name[0]) {
390 	case KERN_OSTYPE:
391 		return (sysctl_rdstring(oldp, oldlenp, newp, ostype));
392 	case KERN_OSRELEASE:
393 		return (sysctl_rdstring(oldp, oldlenp, newp, osrelease));
394 	case KERN_OSVERSION:
395 		return (sysctl_rdstring(oldp, oldlenp, newp, osversion));
396 	case KERN_VERSION:
397 		return (sysctl_rdstring(oldp, oldlenp, newp, version));
398 	case KERN_NUMVNODES:  /* XXX numvnodes is a long */
399 		return (sysctl_rdint(oldp, oldlenp, newp, numvnodes));
400 	case KERN_SECURELVL:
401 		level = securelevel;
402 		if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &level)) ||
403 		    newp == NULL)
404 			return (error);
405 		if ((securelevel > 0 || level < -1) &&
406 		    level < securelevel && p->p_p->ps_pid != 1)
407 			return (EPERM);
408 		securelevel = level;
409 		return (0);
410 	case KERN_ALLOWDT:
411 		if (securelevel > 0)
412 			return (sysctl_rdint(oldp, oldlenp, newp, allowdt));
413 		return (sysctl_int(oldp, oldlenp, newp, newlen,  &allowdt));
414 	case KERN_ALLOWKMEM:
415 		if (securelevel > 0)
416 			return (sysctl_rdint(oldp, oldlenp, newp, allowkmem));
417 		return (sysctl_int(oldp, oldlenp, newp, newlen, &allowkmem));
418 	case KERN_HOSTNAME:
419 		error = sysctl_tstring(oldp, oldlenp, newp, newlen,
420 		    hostname, sizeof(hostname));
421 		if (newp && !error)
422 			hostnamelen = newlen;
423 		return (error);
424 	case KERN_DOMAINNAME:
425 		error = sysctl_tstring(oldp, oldlenp, newp, newlen,
426 		    domainname, sizeof(domainname));
427 		if (newp && !error)
428 			domainnamelen = newlen;
429 		return (error);
430 	case KERN_HOSTID:
431 		inthostid = hostid;  /* XXX assumes sizeof long <= sizeof int */
432 		error =  sysctl_int(oldp, oldlenp, newp, newlen, &inthostid);
433 		hostid = inthostid;
434 		return (error);
435 	case KERN_CLOCKRATE:
436 		return (sysctl_clockrate(oldp, oldlenp, newp));
437 	case KERN_BOOTTIME: {
438 		struct timeval bt;
439 		memset(&bt, 0, sizeof bt);
440 		microboottime(&bt);
441 		return (sysctl_rdstruct(oldp, oldlenp, newp, &bt, sizeof bt));
442 	  }
443 #ifndef SMALL_KERNEL
444 	case KERN_PROC:
445 		return (sysctl_doproc(name + 1, namelen - 1, oldp, oldlenp));
446 	case KERN_PROC_ARGS:
447 		return (sysctl_proc_args(name + 1, namelen - 1, oldp, oldlenp,
448 		     p));
449 	case KERN_PROC_CWD:
450 		return (sysctl_proc_cwd(name + 1, namelen - 1, oldp, oldlenp,
451 		     p));
452 	case KERN_PROC_NOBROADCASTKILL:
453 		return (sysctl_proc_nobroadcastkill(name + 1, namelen - 1,
454 		     newp, newlen, oldp, oldlenp, p));
455 	case KERN_PROC_VMMAP:
456 		return (sysctl_proc_vmmap(name + 1, namelen - 1, oldp, oldlenp,
457 		     p));
458 	case KERN_FILE:
459 		return (sysctl_file(name + 1, namelen - 1, oldp, oldlenp, p));
460 #endif
461 	case KERN_MBSTAT: {
462 		extern struct cpumem *mbstat;
463 		uint64_t counters[MBSTAT_COUNT];
464 		struct mbstat mbs;
465 		unsigned int i;
466 
467 		memset(&mbs, 0, sizeof(mbs));
468 		counters_read(mbstat, counters, MBSTAT_COUNT);
469 		for (i = 0; i < MBSTAT_TYPES; i++)
470 			mbs.m_mtypes[i] = counters[i];
471 
472 		mbs.m_drops = counters[MBSTAT_DROPS];
473 		mbs.m_wait = counters[MBSTAT_WAIT];
474 		mbs.m_drain = counters[MBSTAT_DRAIN];
475 
476 		return (sysctl_rdstruct(oldp, oldlenp, newp,
477 		    &mbs, sizeof(mbs)));
478 	}
479 #if defined(GPROF) || defined(DDBPROF)
480 	case KERN_PROF:
481 		return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp,
482 		    newp, newlen));
483 #endif
484 	case KERN_MSGBUFSIZE:
485 	case KERN_CONSBUFSIZE: {
486 		struct msgbuf *mp;
487 		mp = (name[0] == KERN_MSGBUFSIZE) ? msgbufp : consbufp;
488 		/*
489 		 * deal with cases where the message buffer has
490 		 * become corrupted.
491 		 */
492 		if (!mp || mp->msg_magic != MSG_MAGIC)
493 			return (ENXIO);
494 		return (sysctl_rdint(oldp, oldlenp, newp, mp->msg_bufs));
495 	}
496 	case KERN_CONSBUF:
497 		if ((error = suser(p)))
498 			return (error);
499 		/* FALLTHROUGH */
500 	case KERN_MSGBUF: {
501 		struct msgbuf *mp;
502 		mp = (name[0] == KERN_MSGBUF) ? msgbufp : consbufp;
503 		/* see note above */
504 		if (!mp || mp->msg_magic != MSG_MAGIC)
505 			return (ENXIO);
506 		return (sysctl_rdstruct(oldp, oldlenp, newp, mp,
507 		    mp->msg_bufs + offsetof(struct msgbuf, msg_bufc)));
508 	}
509 	case KERN_MALLOCSTATS:
510 		return (sysctl_malloc(name + 1, namelen - 1, oldp, oldlenp,
511 		    newp, newlen, p));
512 	case KERN_CPTIME:
513 	{
514 		CPU_INFO_ITERATOR cii;
515 		struct cpu_info *ci;
516 		long cp_time[CPUSTATES];
517 		int i, n = 0;
518 
519 		memset(cp_time, 0, sizeof(cp_time));
520 
521 		CPU_INFO_FOREACH(cii, ci) {
522 			if (!cpu_is_online(ci))
523 				continue;
524 			n++;
525 			for (i = 0; i < CPUSTATES; i++)
526 				cp_time[i] += ci->ci_schedstate.spc_cp_time[i];
527 		}
528 
529 		for (i = 0; i < CPUSTATES; i++)
530 			cp_time[i] /= n;
531 
532 		return (sysctl_rdstruct(oldp, oldlenp, newp, &cp_time,
533 		    sizeof(cp_time)));
534 	}
535 	case KERN_NCHSTATS:
536 		return (sysctl_rdstruct(oldp, oldlenp, newp, &nchstats,
537 		    sizeof(struct nchstats)));
538 	case KERN_FORKSTAT:
539 		return (sysctl_rdstruct(oldp, oldlenp, newp, &forkstat,
540 		    sizeof(struct forkstat)));
541 	case KERN_TTY:
542 		return (sysctl_tty(name + 1, namelen - 1, oldp, oldlenp,
543 		    newp, newlen));
544 	case KERN_POOL:
545 		return (sysctl_dopool(name + 1, namelen - 1, oldp, oldlenp));
546 	case KERN_STACKGAPRANDOM:
547 		stackgap = stackgap_random;
548 		error = sysctl_int(oldp, oldlenp, newp, newlen, &stackgap);
549 		if (error)
550 			return (error);
551 		/*
552 		 * Safety harness.
553 		 */
554 		if ((stackgap < ALIGNBYTES && stackgap != 0) ||
555 		    !powerof2(stackgap) || stackgap >= MAXSSIZ)
556 			return (EINVAL);
557 		stackgap_random = stackgap;
558 		return (0);
559 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
560 	case KERN_SYSVIPC_INFO:
561 		return (sysctl_sysvipc(name + 1, namelen - 1, oldp, oldlenp));
562 #endif
563 #ifdef SYSVSEM
564 	case KERN_SEMINFO:
565 		return (sysctl_sysvsem(name + 1, namelen - 1, oldp, oldlenp,
566 		    newp, newlen));
567 #endif
568 #ifdef SYSVSHM
569 	case KERN_SHMINFO:
570 		return (sysctl_sysvshm(name + 1, namelen - 1, oldp, oldlenp,
571 		    newp, newlen));
572 #endif
573 #ifndef SMALL_KERNEL
574 	case KERN_INTRCNT:
575 		return (sysctl_intrcnt(name + 1, namelen - 1, oldp, oldlenp));
576 	case KERN_WATCHDOG:
577 		return (sysctl_wdog(name + 1, namelen - 1, oldp, oldlenp,
578 		    newp, newlen));
579 #endif
580 	case KERN_MAXCLUSTERS: {
581 		int val = nmbclust;
582 		error = sysctl_int(oldp, oldlenp, newp, newlen, &val);
583 		if (error == 0 && val != nmbclust)
584 			error = nmbclust_update(val);
585 		return (error);
586 	}
587 #ifndef SMALL_KERNEL
588 	case KERN_EVCOUNT:
589 		return (evcount_sysctl(name + 1, namelen - 1, oldp, oldlenp,
590 		    newp, newlen));
591 #endif
592 	case KERN_TIMECOUNTER:
593 		return (sysctl_tc(name + 1, namelen - 1, oldp, oldlenp,
594 		    newp, newlen));
595 	case KERN_CPTIME2:
596 		return (sysctl_cptime2(name + 1, namelen -1, oldp, oldlenp,
597 		    newp, newlen));
598 	case KERN_CACHEPCT: {
599 		u_int64_t dmapages;
600 		int opct, pgs;
601 		opct = bufcachepercent;
602 		error = sysctl_int(oldp, oldlenp, newp, newlen,
603 		    &bufcachepercent);
604 		if (error)
605 			return(error);
606 		if (bufcachepercent > 90 || bufcachepercent < 5) {
607 			bufcachepercent = opct;
608 			return (EINVAL);
609 		}
610 		dmapages = uvm_pagecount(&dma_constraint);
611 		if (bufcachepercent != opct) {
612 			pgs = bufcachepercent * dmapages / 100;
613 			bufadjust(pgs); /* adjust bufpages */
614 			bufhighpages = bufpages; /* set high water mark */
615 		}
616 		return(0);
617 	}
618 	case KERN_CONSDEV:
619 		if (cn_tab != NULL)
620 			dev = cn_tab->cn_dev;
621 		else
622 			dev = NODEV;
623 		return sysctl_rdstruct(oldp, oldlenp, newp, &dev, sizeof(dev));
624 	case KERN_POOL_DEBUG: {
625 		int old_pool_debug = pool_debug;
626 
627 		error = sysctl_int(oldp, oldlenp, newp, newlen,
628 		    &pool_debug);
629 		if (error == 0 && pool_debug != old_pool_debug)
630 			pool_reclaim_all();
631 		return (error);
632 	}
633 #ifdef WITNESS
634 	case KERN_WITNESSWATCH:
635 		return witness_sysctl_watch(oldp, oldlenp, newp, newlen);
636 	case KERN_WITNESS:
637 		return witness_sysctl(name + 1, namelen - 1, oldp, oldlenp,
638 		    newp, newlen);
639 #endif
640 #if NAUDIO > 0
641 	case KERN_AUDIO:
642 		return (sysctl_audio(name + 1, namelen - 1, oldp, oldlenp,
643 		    newp, newlen));
644 #endif
645 	case KERN_CPUSTATS:
646 		return (sysctl_cpustats(name + 1, namelen - 1, oldp, oldlenp,
647 		    newp, newlen));
648 #if NPF > 0
649 	case KERN_PFSTATUS:
650 		return (pf_sysctl(oldp, oldlenp, newp, newlen));
651 #endif
652 	case KERN_TIMEOUT_STATS:
653 		return (timeout_sysctl(oldp, oldlenp, newp, newlen));
654 	case KERN_UTC_OFFSET:
655 		return (sysctl_utc_offset(oldp, oldlenp, newp, newlen));
656 	default:
657 		return (sysctl_bounded_arr(kern_vars, nitems(kern_vars), name,
658 		    namelen, oldp, oldlenp, newp, newlen));
659 	}
660 	/* NOTREACHED */
661 }
662 
663 /*
664  * hardware related system variables.
665  */
666 char *hw_vendor, *hw_prod, *hw_uuid, *hw_serial, *hw_ver;
667 int allowpowerdown = 1;
668 
669 /* morally const values reported by sysctl_bounded_arr */
670 static int byte_order = BYTE_ORDER;
671 static int page_size = PAGE_SIZE;
672 
673 const struct sysctl_bounded_args hw_vars[] = {
674 	{HW_NCPU, &ncpus, 1, 0},
675 	{HW_NCPUFOUND, &ncpusfound, 1, 0},
676 	{HW_BYTEORDER, &byte_order, 1, 0},
677 	{HW_PAGESIZE, &page_size, 1, 0},
678 	{HW_DISKCOUNT, &disk_count, 1, 0},
679 };
680 
681 int
682 hw_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
683     size_t newlen, struct proc *p)
684 {
685 	extern char machine[], cpu_model[];
686 	int err, cpuspeed;
687 
688 	/* all sysctl names at this level except sensors are terminal */
689 	if (name[0] != HW_SENSORS && namelen != 1)
690 		return (ENOTDIR);		/* overloaded */
691 
692 	switch (name[0]) {
693 	case HW_MACHINE:
694 		return (sysctl_rdstring(oldp, oldlenp, newp, machine));
695 	case HW_MODEL:
696 		return (sysctl_rdstring(oldp, oldlenp, newp, cpu_model));
697 	case HW_NCPUONLINE:
698 		return (sysctl_rdint(oldp, oldlenp, newp,
699 		    sysctl_hwncpuonline()));
700 	case HW_PHYSMEM:
701 		return (sysctl_rdint(oldp, oldlenp, newp, ptoa(physmem)));
702 	case HW_USERMEM:
703 		return (sysctl_rdint(oldp, oldlenp, newp,
704 		    ptoa(physmem - uvmexp.wired)));
705 	case HW_DISKNAMES:
706 		err = sysctl_diskinit(0, p);
707 		if (err)
708 			return err;
709 		if (disknames)
710 			return (sysctl_rdstring(oldp, oldlenp, newp,
711 			    disknames));
712 		else
713 			return (sysctl_rdstring(oldp, oldlenp, newp, ""));
714 	case HW_DISKSTATS:
715 		err = sysctl_diskinit(1, p);
716 		if (err)
717 			return err;
718 		return (sysctl_rdstruct(oldp, oldlenp, newp, diskstats,
719 		    disk_count * sizeof(struct diskstats)));
720 	case HW_CPUSPEED:
721 		if (!cpu_cpuspeed)
722 			return (EOPNOTSUPP);
723 		err = cpu_cpuspeed(&cpuspeed);
724 		if (err)
725 			return err;
726 		return (sysctl_rdint(oldp, oldlenp, newp, cpuspeed));
727 #ifndef	SMALL_KERNEL
728 	case HW_SENSORS:
729 		return (sysctl_sensors(name + 1, namelen - 1, oldp, oldlenp,
730 		    newp, newlen));
731 	case HW_SETPERF:
732 		return (sysctl_hwsetperf(oldp, oldlenp, newp, newlen));
733 	case HW_PERFPOLICY:
734 		return (sysctl_hwperfpolicy(oldp, oldlenp, newp, newlen));
735 #endif /* !SMALL_KERNEL */
736 	case HW_VENDOR:
737 		if (hw_vendor)
738 			return (sysctl_rdstring(oldp, oldlenp, newp,
739 			    hw_vendor));
740 		else
741 			return (EOPNOTSUPP);
742 	case HW_PRODUCT:
743 		if (hw_prod)
744 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_prod));
745 		else
746 			return (EOPNOTSUPP);
747 	case HW_VERSION:
748 		if (hw_ver)
749 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_ver));
750 		else
751 			return (EOPNOTSUPP);
752 	case HW_SERIALNO:
753 		if (hw_serial)
754 			return (sysctl_rdstring(oldp, oldlenp, newp,
755 			    hw_serial));
756 		else
757 			return (EOPNOTSUPP);
758 	case HW_UUID:
759 		if (hw_uuid)
760 			return (sysctl_rdstring(oldp, oldlenp, newp, hw_uuid));
761 		else
762 			return (EOPNOTSUPP);
763 	case HW_PHYSMEM64:
764 		return (sysctl_rdquad(oldp, oldlenp, newp,
765 		    ptoa((psize_t)physmem)));
766 	case HW_USERMEM64:
767 		return (sysctl_rdquad(oldp, oldlenp, newp,
768 		    ptoa((psize_t)physmem - uvmexp.wired)));
769 	case HW_ALLOWPOWERDOWN:
770 		if (securelevel > 0)
771 			return (sysctl_rdint(oldp, oldlenp, newp,
772 			    allowpowerdown));
773 		return (sysctl_int(oldp, oldlenp, newp, newlen,
774 		    &allowpowerdown));
775 #ifdef __HAVE_CPU_TOPOLOGY
776 	case HW_SMT:
777 		return (sysctl_hwsmt(oldp, oldlenp, newp, newlen));
778 #endif
779 	default:
780 		return sysctl_bounded_arr(hw_vars, nitems(hw_vars), name,
781 		    namelen, oldp, oldlenp, newp, newlen);
782 	}
783 	/* NOTREACHED */
784 }
785 
786 #ifdef DEBUG_SYSCTL
787 /*
788  * Debugging related system variables.
789  */
790 extern struct ctldebug debug_vfs_busyprt;
791 struct ctldebug debug1, debug2, debug3, debug4;
792 struct ctldebug debug5, debug6, debug7, debug8, debug9;
793 struct ctldebug debug10, debug11, debug12, debug13, debug14;
794 struct ctldebug debug15, debug16, debug17, debug18, debug19;
795 static struct ctldebug *debugvars[CTL_DEBUG_MAXID] = {
796 	&debug_vfs_busyprt,
797 	&debug1, &debug2, &debug3, &debug4,
798 	&debug5, &debug6, &debug7, &debug8, &debug9,
799 	&debug10, &debug11, &debug12, &debug13, &debug14,
800 	&debug15, &debug16, &debug17, &debug18, &debug19,
801 };
802 int
803 debug_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
804     size_t newlen, struct proc *p)
805 {
806 	struct ctldebug *cdp;
807 
808 	/* all sysctl names at this level are name and field */
809 	if (namelen != 2)
810 		return (ENOTDIR);		/* overloaded */
811 	if (name[0] < 0 || name[0] >= nitems(debugvars))
812 		return (EOPNOTSUPP);
813 	cdp = debugvars[name[0]];
814 	if (cdp->debugname == 0)
815 		return (EOPNOTSUPP);
816 	switch (name[1]) {
817 	case CTL_DEBUG_NAME:
818 		return (sysctl_rdstring(oldp, oldlenp, newp, cdp->debugname));
819 	case CTL_DEBUG_VALUE:
820 		return (sysctl_int(oldp, oldlenp, newp, newlen, cdp->debugvar));
821 	default:
822 		return (EOPNOTSUPP);
823 	}
824 	/* NOTREACHED */
825 }
826 #endif /* DEBUG_SYSCTL */
827 
828 /*
829  * Reads, or writes that lower the value
830  */
831 int
832 sysctl_int_lower(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
833 {
834 	unsigned int oval = *valp, val = *valp;
835 	int error;
836 
837 	if (newp == NULL)
838 		return (sysctl_rdint(oldp, oldlenp, newp, *valp));
839 
840 	if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)))
841 		return (error);
842 	if (val > oval)
843 		return (EPERM);		/* do not allow raising */
844 	*(unsigned int *)valp = val;
845 	return (0);
846 }
847 
848 /*
849  * Validate parameters and get old / set new parameters
850  * for an integer-valued sysctl function.
851  */
852 int
853 sysctl_int(void *oldp, size_t *oldlenp, void *newp, size_t newlen, int *valp)
854 {
855 	return (sysctl_int_bounded(oldp, oldlenp, newp, newlen, valp, 0, 0));
856 }
857 
858 int
859 sysctl_int_bounded(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
860     int *valp, int minimum, int maximum)
861 {
862 	int error = 0;
863 	int val;
864 
865 	if (oldp && *oldlenp < sizeof(int))
866 		return (ENOMEM);
867 	if (newp && newlen != sizeof(int))
868 		return (EINVAL);
869 	*oldlenp = sizeof(int);
870 	val = *valp;
871 	if (oldp)
872 		error = copyout(&val, oldp, sizeof(int));
873 	if (error == 0 && newp)
874 		error = copyin(newp, &val, sizeof(int));
875 	if (error)
876 		return (error);
877 	if (minimum == maximum || (minimum <= val && val <= maximum))
878 		*valp = val;
879 	else
880 		error = EINVAL;
881 	return (error);
882 }
883 
884 /*
885  * As above, but read-only.
886  */
887 int
888 sysctl_rdint(void *oldp, size_t *oldlenp, void *newp, int val)
889 {
890 	int error = 0;
891 
892 	if (oldp && *oldlenp < sizeof(int))
893 		return (ENOMEM);
894 	if (newp)
895 		return (EPERM);
896 	*oldlenp = sizeof(int);
897 	if (oldp)
898 		error = copyout((caddr_t)&val, oldp, sizeof(int));
899 	return (error);
900 }
901 
902 /*
903  * Array of bounded integer values.
904  */
905 int
906 sysctl_bounded_arr(const struct sysctl_bounded_args *valpp, u_int valplen,
907     int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
908     size_t newlen)
909 {
910 	u_int i;
911 	if (namelen != 1)
912 		return (ENOTDIR);
913 	for (i = 0; i < valplen; ++i) {
914 		if (valpp[i].mib == name[0]) {
915 			if (valpp[i].minimum <= valpp[i].maximum) {
916 				return (sysctl_int_bounded(oldp, oldlenp, newp,
917 				    newlen, valpp[i].var, valpp[i].minimum,
918 				    valpp[i].maximum));
919 			} else {
920 				return (sysctl_rdint(oldp, oldlenp, newp,
921 				    *valpp[i].var));
922 			}
923 		}
924 	}
925 	return (EOPNOTSUPP);
926 }
927 
928 /*
929  * Validate parameters and get old / set new parameters
930  * for an integer-valued sysctl function.
931  */
932 int
933 sysctl_quad(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
934     int64_t *valp)
935 {
936 	int error = 0;
937 
938 	if (oldp && *oldlenp < sizeof(int64_t))
939 		return (ENOMEM);
940 	if (newp && newlen != sizeof(int64_t))
941 		return (EINVAL);
942 	*oldlenp = sizeof(int64_t);
943 	if (oldp)
944 		error = copyout(valp, oldp, sizeof(int64_t));
945 	if (error == 0 && newp)
946 		error = copyin(newp, valp, sizeof(int64_t));
947 	return (error);
948 }
949 
950 /*
951  * As above, but read-only.
952  */
953 int
954 sysctl_rdquad(void *oldp, size_t *oldlenp, void *newp, int64_t val)
955 {
956 	int error = 0;
957 
958 	if (oldp && *oldlenp < sizeof(int64_t))
959 		return (ENOMEM);
960 	if (newp)
961 		return (EPERM);
962 	*oldlenp = sizeof(int64_t);
963 	if (oldp)
964 		error = copyout((caddr_t)&val, oldp, sizeof(int64_t));
965 	return (error);
966 }
967 
968 /*
969  * Validate parameters and get old / set new parameters
970  * for a string-valued sysctl function.
971  */
972 int
973 sysctl_string(void *oldp, size_t *oldlenp, void *newp, size_t newlen, char *str,
974     size_t maxlen)
975 {
976 	return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 0);
977 }
978 
979 int
980 sysctl_tstring(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
981     char *str, size_t maxlen)
982 {
983 	return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 1);
984 }
985 
986 int
987 sysctl__string(void *oldp, size_t *oldlenp, void *newp, size_t newlen,
988     char *str, size_t maxlen, int trunc)
989 {
990 	size_t len;
991 	int error = 0;
992 
993 	len = strlen(str) + 1;
994 	if (oldp && *oldlenp < len) {
995 		if (trunc == 0 || *oldlenp == 0)
996 			return (ENOMEM);
997 	}
998 	if (newp && newlen >= maxlen)
999 		return (EINVAL);
1000 	if (oldp) {
1001 		if (trunc && *oldlenp < len) {
1002 			len = *oldlenp;
1003 			error = copyout(str, oldp, len - 1);
1004 			if (error == 0)
1005 				error = copyout("", (char *)oldp + len - 1, 1);
1006 		} else {
1007 			error = copyout(str, oldp, len);
1008 		}
1009 	}
1010 	*oldlenp = len;
1011 	if (error == 0 && newp) {
1012 		error = copyin(newp, str, newlen);
1013 		str[newlen] = 0;
1014 	}
1015 	return (error);
1016 }
1017 
1018 /*
1019  * As above, but read-only.
1020  */
1021 int
1022 sysctl_rdstring(void *oldp, size_t *oldlenp, void *newp, const char *str)
1023 {
1024 	size_t len;
1025 	int error = 0;
1026 
1027 	len = strlen(str) + 1;
1028 	if (oldp && *oldlenp < len)
1029 		return (ENOMEM);
1030 	if (newp)
1031 		return (EPERM);
1032 	*oldlenp = len;
1033 	if (oldp)
1034 		error = copyout(str, oldp, len);
1035 	return (error);
1036 }
1037 
1038 /*
1039  * Validate parameters and get old / set new parameters
1040  * for a structure oriented sysctl function.
1041  */
1042 int
1043 sysctl_struct(void *oldp, size_t *oldlenp, void *newp, size_t newlen, void *sp,
1044     size_t len)
1045 {
1046 	int error = 0;
1047 
1048 	if (oldp && *oldlenp < len)
1049 		return (ENOMEM);
1050 	if (newp && newlen > len)
1051 		return (EINVAL);
1052 	if (oldp) {
1053 		*oldlenp = len;
1054 		error = copyout(sp, oldp, len);
1055 	}
1056 	if (error == 0 && newp)
1057 		error = copyin(newp, sp, len);
1058 	return (error);
1059 }
1060 
1061 /*
1062  * Validate parameters and get old parameters
1063  * for a structure oriented sysctl function.
1064  */
1065 int
1066 sysctl_rdstruct(void *oldp, size_t *oldlenp, void *newp, const void *sp,
1067     size_t len)
1068 {
1069 	int error = 0;
1070 
1071 	if (oldp && *oldlenp < len)
1072 		return (ENOMEM);
1073 	if (newp)
1074 		return (EPERM);
1075 	*oldlenp = len;
1076 	if (oldp)
1077 		error = copyout(sp, oldp, len);
1078 	return (error);
1079 }
1080 
1081 #ifndef SMALL_KERNEL
1082 void
1083 fill_file(struct kinfo_file *kf, struct file *fp, struct filedesc *fdp,
1084 	  int fd, struct vnode *vp, struct process *pr, struct proc *p,
1085 	  struct socket *so, int show_pointers)
1086 {
1087 	struct vattr va;
1088 
1089 	memset(kf, 0, sizeof(*kf));
1090 
1091 	kf->fd_fd = fd;		/* might not really be an fd */
1092 
1093 	if (fp != NULL) {
1094 		if (show_pointers)
1095 			kf->f_fileaddr = PTRTOINT64(fp);
1096 		kf->f_flag = fp->f_flag;
1097 		kf->f_iflags = fp->f_iflags;
1098 		kf->f_type = fp->f_type;
1099 		kf->f_count = fp->f_count;
1100 		if (show_pointers)
1101 			kf->f_ucred = PTRTOINT64(fp->f_cred);
1102 		kf->f_uid = fp->f_cred->cr_uid;
1103 		kf->f_gid = fp->f_cred->cr_gid;
1104 		if (show_pointers)
1105 			kf->f_ops = PTRTOINT64(fp->f_ops);
1106 		if (show_pointers)
1107 			kf->f_data = PTRTOINT64(fp->f_data);
1108 		kf->f_usecount = 0;
1109 
1110 		if (suser(p) == 0 || p->p_ucred->cr_uid == fp->f_cred->cr_uid) {
1111 			mtx_enter(&fp->f_mtx);
1112 			kf->f_offset = fp->f_offset;
1113 			kf->f_rxfer = fp->f_rxfer;
1114 			kf->f_rwfer = fp->f_wxfer;
1115 			kf->f_seek = fp->f_seek;
1116 			kf->f_rbytes = fp->f_rbytes;
1117 			kf->f_wbytes = fp->f_wbytes;
1118 			mtx_leave(&fp->f_mtx);
1119 		} else
1120 			kf->f_offset = -1;
1121 	} else if (vp != NULL) {
1122 		/* fake it */
1123 		kf->f_type = DTYPE_VNODE;
1124 		kf->f_flag = FREAD;
1125 		if (fd == KERN_FILE_TRACE)
1126 			kf->f_flag |= FWRITE;
1127 	} else if (so != NULL) {
1128 		/* fake it */
1129 		kf->f_type = DTYPE_SOCKET;
1130 	}
1131 
1132 	/* information about the object associated with this file */
1133 	switch (kf->f_type) {
1134 	case DTYPE_VNODE:
1135 		if (fp != NULL)
1136 			vp = (struct vnode *)fp->f_data;
1137 
1138 		if (show_pointers)
1139 			kf->v_un = PTRTOINT64(vp->v_un.vu_socket);
1140 		kf->v_type = vp->v_type;
1141 		kf->v_tag = vp->v_tag;
1142 		kf->v_flag = vp->v_flag;
1143 		if (show_pointers)
1144 			kf->v_data = PTRTOINT64(vp->v_data);
1145 		if (show_pointers)
1146 			kf->v_mount = PTRTOINT64(vp->v_mount);
1147 		if (vp->v_mount)
1148 			strlcpy(kf->f_mntonname,
1149 			    vp->v_mount->mnt_stat.f_mntonname,
1150 			    sizeof(kf->f_mntonname));
1151 
1152 		if (VOP_GETATTR(vp, &va, p->p_ucred, p) == 0) {
1153 			kf->va_fileid = va.va_fileid;
1154 			kf->va_mode = MAKEIMODE(va.va_type, va.va_mode);
1155 			kf->va_size = va.va_size;
1156 			kf->va_rdev = va.va_rdev;
1157 			kf->va_fsid = va.va_fsid & 0xffffffff;
1158 			kf->va_nlink = va.va_nlink;
1159 		}
1160 		break;
1161 
1162 	case DTYPE_SOCKET: {
1163 		int locked = 0;
1164 
1165 		if (so == NULL) {
1166 			so = (struct socket *)fp->f_data;
1167 			/* if so is passed as parameter it is already locked */
1168 			switch (so->so_proto->pr_domain->dom_family) {
1169 			case AF_INET:
1170 			case AF_INET6:
1171 				NET_LOCK();
1172 				locked = 1;
1173 				break;
1174 			}
1175 		}
1176 
1177 		kf->so_type = so->so_type;
1178 		kf->so_state = so->so_state;
1179 		if (show_pointers)
1180 			kf->so_pcb = PTRTOINT64(so->so_pcb);
1181 		else
1182 			kf->so_pcb = -1;
1183 		kf->so_protocol = so->so_proto->pr_protocol;
1184 		kf->so_family = so->so_proto->pr_domain->dom_family;
1185 		kf->so_rcv_cc = so->so_rcv.sb_cc;
1186 		kf->so_snd_cc = so->so_snd.sb_cc;
1187 		if (isspliced(so)) {
1188 			if (show_pointers)
1189 				kf->so_splice =
1190 				    PTRTOINT64(so->so_sp->ssp_socket);
1191 			kf->so_splicelen = so->so_sp->ssp_len;
1192 		} else if (issplicedback(so))
1193 			kf->so_splicelen = -1;
1194 		if (so->so_pcb == NULL) {
1195 			if (locked)
1196 				NET_UNLOCK();
1197 			break;
1198 		}
1199 		switch (kf->so_family) {
1200 		case AF_INET: {
1201 			struct inpcb *inpcb = so->so_pcb;
1202 
1203 			NET_ASSERT_LOCKED();
1204 			if (show_pointers)
1205 				kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb);
1206 			kf->inp_lport = inpcb->inp_lport;
1207 			kf->inp_laddru[0] = inpcb->inp_laddr.s_addr;
1208 			kf->inp_fport = inpcb->inp_fport;
1209 			kf->inp_faddru[0] = inpcb->inp_faddr.s_addr;
1210 			kf->inp_rtableid = inpcb->inp_rtableid;
1211 			if (so->so_type == SOCK_RAW)
1212 				kf->inp_proto = inpcb->inp_ip.ip_p;
1213 			if (so->so_proto->pr_protocol == IPPROTO_TCP) {
1214 				struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb;
1215 				kf->t_rcv_wnd = tcpcb->rcv_wnd;
1216 				kf->t_snd_wnd = tcpcb->snd_wnd;
1217 				kf->t_snd_cwnd = tcpcb->snd_cwnd;
1218 				kf->t_state = tcpcb->t_state;
1219 			}
1220 			break;
1221 		    }
1222 		case AF_INET6: {
1223 			struct inpcb *inpcb = so->so_pcb;
1224 
1225 			NET_ASSERT_LOCKED();
1226 			if (show_pointers)
1227 				kf->inp_ppcb = PTRTOINT64(inpcb->inp_ppcb);
1228 			kf->inp_lport = inpcb->inp_lport;
1229 			kf->inp_laddru[0] = inpcb->inp_laddr6.s6_addr32[0];
1230 			kf->inp_laddru[1] = inpcb->inp_laddr6.s6_addr32[1];
1231 			kf->inp_laddru[2] = inpcb->inp_laddr6.s6_addr32[2];
1232 			kf->inp_laddru[3] = inpcb->inp_laddr6.s6_addr32[3];
1233 			kf->inp_fport = inpcb->inp_fport;
1234 			kf->inp_faddru[0] = inpcb->inp_faddr6.s6_addr32[0];
1235 			kf->inp_faddru[1] = inpcb->inp_faddr6.s6_addr32[1];
1236 			kf->inp_faddru[2] = inpcb->inp_faddr6.s6_addr32[2];
1237 			kf->inp_faddru[3] = inpcb->inp_faddr6.s6_addr32[3];
1238 			kf->inp_rtableid = inpcb->inp_rtableid;
1239 			if (so->so_type == SOCK_RAW)
1240 				kf->inp_proto = inpcb->inp_ipv6.ip6_nxt;
1241 			if (so->so_proto->pr_protocol == IPPROTO_TCP) {
1242 				struct tcpcb *tcpcb = (void *)inpcb->inp_ppcb;
1243 				kf->t_rcv_wnd = tcpcb->rcv_wnd;
1244 				kf->t_snd_wnd = tcpcb->snd_wnd;
1245 				kf->t_state = tcpcb->t_state;
1246 			}
1247 			break;
1248 		    }
1249 		case AF_UNIX: {
1250 			struct unpcb *unpcb = so->so_pcb;
1251 
1252 			kf->f_msgcount = unpcb->unp_msgcount;
1253 			if (show_pointers) {
1254 				kf->unp_conn	= PTRTOINT64(unpcb->unp_conn);
1255 				kf->unp_refs	= PTRTOINT64(
1256 				    SLIST_FIRST(&unpcb->unp_refs));
1257 				kf->unp_nextref	= PTRTOINT64(
1258 				    SLIST_NEXT(unpcb, unp_nextref));
1259 				kf->v_un	= PTRTOINT64(unpcb->unp_vnode);
1260 				kf->unp_addr	= PTRTOINT64(unpcb->unp_addr);
1261 			}
1262 			if (unpcb->unp_addr != NULL) {
1263 				struct sockaddr_un *un = mtod(unpcb->unp_addr,
1264 				    struct sockaddr_un *);
1265 				memcpy(kf->unp_path, un->sun_path, un->sun_len
1266 				    - offsetof(struct sockaddr_un,sun_path));
1267 			}
1268 			break;
1269 		    }
1270 		}
1271 		if (locked)
1272 			NET_UNLOCK();
1273 		break;
1274 	    }
1275 
1276 	case DTYPE_PIPE: {
1277 		struct pipe *pipe = (struct pipe *)fp->f_data;
1278 
1279 		if (show_pointers)
1280 			kf->pipe_peer = PTRTOINT64(pipe->pipe_peer);
1281 		kf->pipe_state = pipe->pipe_state;
1282 		break;
1283 	    }
1284 
1285 	case DTYPE_KQUEUE: {
1286 		struct kqueue *kqi = (struct kqueue *)fp->f_data;
1287 
1288 		kf->kq_count = kqi->kq_count;
1289 		kf->kq_state = kqi->kq_state;
1290 		break;
1291 	    }
1292 	}
1293 
1294 	/* per-process information for KERN_FILE_BY[PU]ID */
1295 	if (pr != NULL) {
1296 		kf->p_pid = pr->ps_pid;
1297 		kf->p_uid = pr->ps_ucred->cr_uid;
1298 		kf->p_gid = pr->ps_ucred->cr_gid;
1299 		kf->p_tid = -1;
1300 		strlcpy(kf->p_comm, pr->ps_comm, sizeof(kf->p_comm));
1301 	}
1302 	if (fdp != NULL) {
1303 		fdplock(fdp);
1304 		kf->fd_ofileflags = fdp->fd_ofileflags[fd];
1305 		fdpunlock(fdp);
1306 	}
1307 }
1308 
1309 /*
1310  * Get file structures.
1311  */
1312 int
1313 sysctl_file(int *name, u_int namelen, char *where, size_t *sizep,
1314     struct proc *p)
1315 {
1316 	struct kinfo_file *kf;
1317 	struct filedesc *fdp;
1318 	struct file *fp;
1319 	struct process *pr;
1320 	size_t buflen, elem_size, elem_count, outsize;
1321 	char *dp = where;
1322 	int arg, i, error = 0, needed = 0, matched;
1323 	u_int op;
1324 	int show_pointers;
1325 
1326 	if (namelen > 4)
1327 		return (ENOTDIR);
1328 	if (namelen < 4 || name[2] > sizeof(*kf))
1329 		return (EINVAL);
1330 
1331 	buflen = where != NULL ? *sizep : 0;
1332 	op = name[0];
1333 	arg = name[1];
1334 	elem_size = name[2];
1335 	elem_count = name[3];
1336 	outsize = MIN(sizeof(*kf), elem_size);
1337 
1338 	if (elem_size < 1)
1339 		return (EINVAL);
1340 
1341 	show_pointers = suser(curproc) == 0;
1342 
1343 	kf = malloc(sizeof(*kf), M_TEMP, M_WAITOK);
1344 
1345 #define FILLIT2(fp, fdp, i, vp, pr, so) do {				\
1346 	if (buflen >= elem_size && elem_count > 0) {			\
1347 		fill_file(kf, fp, fdp, i, vp, pr, p, so, show_pointers);\
1348 		error = copyout(kf, dp, outsize);			\
1349 		if (error)						\
1350 			break;						\
1351 		dp += elem_size;					\
1352 		buflen -= elem_size;					\
1353 		elem_count--;						\
1354 	}								\
1355 	needed += elem_size;						\
1356 } while (0)
1357 #define FILLIT(fp, fdp, i, vp, pr) \
1358 	FILLIT2(fp, fdp, i, vp, pr, NULL)
1359 #define FILLSO(so) \
1360 	FILLIT2(NULL, NULL, 0, NULL, NULL, so)
1361 
1362 	switch (op) {
1363 	case KERN_FILE_BYFILE:
1364 		/* use the inp-tables to pick up closed connections, too */
1365 		if (arg == DTYPE_SOCKET) {
1366 			struct inpcb *inp;
1367 
1368 			NET_LOCK();
1369 			TAILQ_FOREACH(inp, &tcbtable.inpt_queue, inp_queue)
1370 				FILLSO(inp->inp_socket);
1371 			TAILQ_FOREACH(inp, &udbtable.inpt_queue, inp_queue)
1372 				FILLSO(inp->inp_socket);
1373 			TAILQ_FOREACH(inp, &rawcbtable.inpt_queue, inp_queue)
1374 				FILLSO(inp->inp_socket);
1375 #ifdef INET6
1376 			TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue,
1377 			    inp_queue)
1378 				FILLSO(inp->inp_socket);
1379 #endif
1380 			NET_UNLOCK();
1381 		}
1382 		fp = NULL;
1383 		while ((fp = fd_iterfile(fp, p)) != NULL) {
1384 			if ((arg == 0 || fp->f_type == arg)) {
1385 				int af, skip = 0;
1386 				if (arg == DTYPE_SOCKET && fp->f_type == arg) {
1387 					af = ((struct socket *)fp->f_data)->
1388 					    so_proto->pr_domain->dom_family;
1389 					if (af == AF_INET || af == AF_INET6)
1390 						skip = 1;
1391 				}
1392 				if (!skip)
1393 					FILLIT(fp, NULL, 0, NULL, NULL);
1394 			}
1395 		}
1396 		break;
1397 	case KERN_FILE_BYPID:
1398 		/* A arg of -1 indicates all processes */
1399 		if (arg < -1) {
1400 			error = EINVAL;
1401 			break;
1402 		}
1403 		matched = 0;
1404 		LIST_FOREACH(pr, &allprocess, ps_list) {
1405 			/*
1406 			 * skip system, exiting, embryonic and undead
1407 			 * processes
1408 			 */
1409 			if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING))
1410 				continue;
1411 			if (arg > 0 && pr->ps_pid != (pid_t)arg) {
1412 				/* not the pid we are looking for */
1413 				continue;
1414 			}
1415 			matched = 1;
1416 			fdp = pr->ps_fd;
1417 			if (pr->ps_textvp)
1418 				FILLIT(NULL, NULL, KERN_FILE_TEXT, pr->ps_textvp, pr);
1419 			if (fdp->fd_cdir)
1420 				FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr);
1421 			if (fdp->fd_rdir)
1422 				FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr);
1423 			if (pr->ps_tracevp)
1424 				FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr);
1425 			for (i = 0; i < fdp->fd_nfiles; i++) {
1426 				if ((fp = fd_getfile(fdp, i)) == NULL)
1427 					continue;
1428 				FILLIT(fp, fdp, i, NULL, pr);
1429 				FRELE(fp, p);
1430 			}
1431 		}
1432 		if (!matched)
1433 			error = ESRCH;
1434 		break;
1435 	case KERN_FILE_BYUID:
1436 		LIST_FOREACH(pr, &allprocess, ps_list) {
1437 			/*
1438 			 * skip system, exiting, embryonic and undead
1439 			 * processes
1440 			 */
1441 			if (pr->ps_flags & (PS_SYSTEM | PS_EMBRYO | PS_EXITING))
1442 				continue;
1443 			if (arg >= 0 && pr->ps_ucred->cr_uid != (uid_t)arg) {
1444 				/* not the uid we are looking for */
1445 				continue;
1446 			}
1447 			fdp = pr->ps_fd;
1448 			if (fdp->fd_cdir)
1449 				FILLIT(NULL, NULL, KERN_FILE_CDIR, fdp->fd_cdir, pr);
1450 			if (fdp->fd_rdir)
1451 				FILLIT(NULL, NULL, KERN_FILE_RDIR, fdp->fd_rdir, pr);
1452 			if (pr->ps_tracevp)
1453 				FILLIT(NULL, NULL, KERN_FILE_TRACE, pr->ps_tracevp, pr);
1454 			for (i = 0; i < fdp->fd_nfiles; i++) {
1455 				if ((fp = fd_getfile(fdp, i)) == NULL)
1456 					continue;
1457 				FILLIT(fp, fdp, i, NULL, pr);
1458 				FRELE(fp, p);
1459 			}
1460 		}
1461 		break;
1462 	default:
1463 		error = EINVAL;
1464 		break;
1465 	}
1466 	free(kf, M_TEMP, sizeof(*kf));
1467 
1468 	if (!error) {
1469 		if (where == NULL)
1470 			needed += KERN_FILESLOP * elem_size;
1471 		else if (*sizep < needed)
1472 			error = ENOMEM;
1473 		*sizep = needed;
1474 	}
1475 
1476 	return (error);
1477 }
1478 
1479 /*
1480  * try over estimating by 5 procs
1481  */
1482 #define KERN_PROCSLOP	5
1483 
1484 int
1485 sysctl_doproc(int *name, u_int namelen, char *where, size_t *sizep)
1486 {
1487 	struct kinfo_proc *kproc = NULL;
1488 	struct proc *p;
1489 	struct process *pr;
1490 	char *dp;
1491 	int arg, buflen, doingzomb, elem_size, elem_count;
1492 	int error, needed, op;
1493 	int dothreads = 0;
1494 	int show_pointers;
1495 
1496 	dp = where;
1497 	buflen = where != NULL ? *sizep : 0;
1498 	needed = error = 0;
1499 
1500 	if (namelen != 4 || name[2] <= 0 || name[3] < 0 ||
1501 	    name[2] > sizeof(*kproc))
1502 		return (EINVAL);
1503 	op = name[0];
1504 	arg = name[1];
1505 	elem_size = name[2];
1506 	elem_count = name[3];
1507 
1508 	dothreads = op & KERN_PROC_SHOW_THREADS;
1509 	op &= ~KERN_PROC_SHOW_THREADS;
1510 
1511 	show_pointers = suser(curproc) == 0;
1512 
1513 	if (where != NULL)
1514 		kproc = malloc(sizeof(*kproc), M_TEMP, M_WAITOK);
1515 
1516 	pr = LIST_FIRST(&allprocess);
1517 	doingzomb = 0;
1518 again:
1519 	for (; pr != NULL; pr = LIST_NEXT(pr, ps_list)) {
1520 		/* XXX skip processes in the middle of being zapped */
1521 		if (pr->ps_pgrp == NULL)
1522 			continue;
1523 
1524 		/*
1525 		 * Skip embryonic processes.
1526 		 */
1527 		if (pr->ps_flags & PS_EMBRYO)
1528 			continue;
1529 
1530 		/*
1531 		 * TODO - make more efficient (see notes below).
1532 		 */
1533 		switch (op) {
1534 
1535 		case KERN_PROC_PID:
1536 			/* could do this with just a lookup */
1537 			if (pr->ps_pid != (pid_t)arg)
1538 				continue;
1539 			break;
1540 
1541 		case KERN_PROC_PGRP:
1542 			/* could do this by traversing pgrp */
1543 			if (pr->ps_pgrp->pg_id != (pid_t)arg)
1544 				continue;
1545 			break;
1546 
1547 		case KERN_PROC_SESSION:
1548 			if (pr->ps_session->s_leader == NULL ||
1549 			    pr->ps_session->s_leader->ps_pid != (pid_t)arg)
1550 				continue;
1551 			break;
1552 
1553 		case KERN_PROC_TTY:
1554 			if ((pr->ps_flags & PS_CONTROLT) == 0 ||
1555 			    pr->ps_session->s_ttyp == NULL ||
1556 			    pr->ps_session->s_ttyp->t_dev != (dev_t)arg)
1557 				continue;
1558 			break;
1559 
1560 		case KERN_PROC_UID:
1561 			if (pr->ps_ucred->cr_uid != (uid_t)arg)
1562 				continue;
1563 			break;
1564 
1565 		case KERN_PROC_RUID:
1566 			if (pr->ps_ucred->cr_ruid != (uid_t)arg)
1567 				continue;
1568 			break;
1569 
1570 		case KERN_PROC_ALL:
1571 			if (pr->ps_flags & PS_SYSTEM)
1572 				continue;
1573 			break;
1574 
1575 		case KERN_PROC_KTHREAD:
1576 			/* no filtering */
1577 			break;
1578 
1579 		default:
1580 			error = EINVAL;
1581 			goto err;
1582 		}
1583 
1584 		if (buflen >= elem_size && elem_count > 0) {
1585 			fill_kproc(pr, kproc, NULL, show_pointers);
1586 			error = copyout(kproc, dp, elem_size);
1587 			if (error)
1588 				goto err;
1589 			dp += elem_size;
1590 			buflen -= elem_size;
1591 			elem_count--;
1592 		}
1593 		needed += elem_size;
1594 
1595 		/* Skip per-thread entries if not required by op */
1596 		if (!dothreads)
1597 			continue;
1598 
1599 		TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
1600 			if (buflen >= elem_size && elem_count > 0) {
1601 				fill_kproc(pr, kproc, p, show_pointers);
1602 				error = copyout(kproc, dp, elem_size);
1603 				if (error)
1604 					goto err;
1605 				dp += elem_size;
1606 				buflen -= elem_size;
1607 				elem_count--;
1608 			}
1609 			needed += elem_size;
1610 		}
1611 	}
1612 	if (doingzomb == 0) {
1613 		pr = LIST_FIRST(&zombprocess);
1614 		doingzomb++;
1615 		goto again;
1616 	}
1617 	if (where != NULL) {
1618 		*sizep = dp - where;
1619 		if (needed > *sizep) {
1620 			error = ENOMEM;
1621 			goto err;
1622 		}
1623 	} else {
1624 		needed += KERN_PROCSLOP * elem_size;
1625 		*sizep = needed;
1626 	}
1627 err:
1628 	if (kproc)
1629 		free(kproc, M_TEMP, sizeof(*kproc));
1630 	return (error);
1631 }
1632 
1633 /*
1634  * Fill in a kproc structure for the specified process.
1635  */
1636 void
1637 fill_kproc(struct process *pr, struct kinfo_proc *ki, struct proc *p,
1638     int show_pointers)
1639 {
1640 	struct session *s = pr->ps_session;
1641 	struct tty *tp;
1642 	struct vmspace *vm = pr->ps_vmspace;
1643 	struct timespec booted, st, ut, utc;
1644 	int isthread;
1645 
1646 	isthread = p != NULL;
1647 	if (!isthread)
1648 		p = pr->ps_mainproc;		/* XXX */
1649 
1650 	FILL_KPROC(ki, strlcpy, p, pr, pr->ps_ucred, pr->ps_pgrp,
1651 	    p, pr, s, vm, pr->ps_limit, pr->ps_sigacts, isthread,
1652 	    show_pointers);
1653 
1654 	/* stuff that's too painful to generalize into the macros */
1655 	if (pr->ps_pptr)
1656 		ki->p_ppid = pr->ps_pptr->ps_pid;
1657 	if (s->s_leader)
1658 		ki->p_sid = s->s_leader->ps_pid;
1659 
1660 	if ((pr->ps_flags & PS_CONTROLT) && (tp = s->s_ttyp)) {
1661 		ki->p_tdev = tp->t_dev;
1662 		ki->p_tpgid = tp->t_pgrp ? tp->t_pgrp->pg_id : -1;
1663 		if (show_pointers)
1664 			ki->p_tsess = PTRTOINT64(tp->t_session);
1665 	} else {
1666 		ki->p_tdev = NODEV;
1667 		ki->p_tpgid = -1;
1668 	}
1669 
1670 	/* fixups that can only be done in the kernel */
1671 	if ((pr->ps_flags & PS_ZOMBIE) == 0) {
1672 		if ((pr->ps_flags & PS_EMBRYO) == 0 && vm != NULL)
1673 			ki->p_vm_rssize = vm_resident_count(vm);
1674 		calctsru(isthread ? &p->p_tu : &pr->ps_tu, &ut, &st, NULL);
1675 		ki->p_uutime_sec = ut.tv_sec;
1676 		ki->p_uutime_usec = ut.tv_nsec/1000;
1677 		ki->p_ustime_sec = st.tv_sec;
1678 		ki->p_ustime_usec = st.tv_nsec/1000;
1679 
1680 		/* Convert starting uptime to a starting UTC time. */
1681 		nanoboottime(&booted);
1682 		timespecadd(&booted, &pr->ps_start, &utc);
1683 		ki->p_ustart_sec = utc.tv_sec;
1684 		ki->p_ustart_usec = utc.tv_nsec / 1000;
1685 
1686 #ifdef MULTIPROCESSOR
1687 		if (p->p_cpu != NULL)
1688 			ki->p_cpuid = CPU_INFO_UNIT(p->p_cpu);
1689 #endif
1690 	}
1691 
1692 	/* get %cpu and schedule state: just one thread or sum of all? */
1693 	if (isthread) {
1694 		ki->p_pctcpu = p->p_pctcpu;
1695 		ki->p_stat   = p->p_stat;
1696 	} else {
1697 		ki->p_pctcpu = 0;
1698 		ki->p_stat = (pr->ps_flags & PS_ZOMBIE) ? SDEAD : SIDL;
1699 		TAILQ_FOREACH(p, &pr->ps_threads, p_thr_link) {
1700 			ki->p_pctcpu += p->p_pctcpu;
1701 			/* find best state: ONPROC > RUN > STOP > SLEEP > .. */
1702 			if (p->p_stat == SONPROC || ki->p_stat == SONPROC)
1703 				ki->p_stat = SONPROC;
1704 			else if (p->p_stat == SRUN || ki->p_stat == SRUN)
1705 				ki->p_stat = SRUN;
1706 			else if (p->p_stat == SSTOP || ki->p_stat == SSTOP)
1707 				ki->p_stat = SSTOP;
1708 			else if (p->p_stat == SSLEEP)
1709 				ki->p_stat = SSLEEP;
1710 		}
1711 	}
1712 }
1713 
1714 int
1715 sysctl_proc_args(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1716     struct proc *cp)
1717 {
1718 	struct process *vpr;
1719 	pid_t pid;
1720 	struct ps_strings pss;
1721 	struct iovec iov;
1722 	struct uio uio;
1723 	int error, cnt, op;
1724 	size_t limit;
1725 	char **rargv, **vargv;		/* reader vs. victim */
1726 	char *rarg, *varg, *buf;
1727 	struct vmspace *vm;
1728 	vaddr_t ps_strings;
1729 
1730 	if (namelen > 2)
1731 		return (ENOTDIR);
1732 	if (namelen < 2)
1733 		return (EINVAL);
1734 
1735 	pid = name[0];
1736 	op = name[1];
1737 
1738 	switch (op) {
1739 	case KERN_PROC_ARGV:
1740 	case KERN_PROC_NARGV:
1741 	case KERN_PROC_ENV:
1742 	case KERN_PROC_NENV:
1743 		break;
1744 	default:
1745 		return (EOPNOTSUPP);
1746 	}
1747 
1748 	if ((vpr = prfind(pid)) == NULL)
1749 		return (ESRCH);
1750 
1751 	if (oldp == NULL) {
1752 		if (op == KERN_PROC_NARGV || op == KERN_PROC_NENV)
1753 			*oldlenp = sizeof(int);
1754 		else
1755 			*oldlenp = ARG_MAX;	/* XXX XXX XXX */
1756 		return (0);
1757 	}
1758 
1759 	/* Either system process or exiting/zombie */
1760 	if (vpr->ps_flags & (PS_SYSTEM | PS_EXITING))
1761 		return (EINVAL);
1762 
1763 	/* Execing - danger. */
1764 	if ((vpr->ps_flags & PS_INEXEC))
1765 		return (EBUSY);
1766 
1767 	/* Only owner or root can get env */
1768 	if ((op == KERN_PROC_NENV || op == KERN_PROC_ENV) &&
1769 	    (vpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid &&
1770 	    (error = suser(cp)) != 0))
1771 		return (error);
1772 
1773 	ps_strings = vpr->ps_strings;
1774 	vm = vpr->ps_vmspace;
1775 	uvmspace_addref(vm);
1776 	vpr = NULL;
1777 
1778 	buf = malloc(PAGE_SIZE, M_TEMP, M_WAITOK);
1779 
1780 	iov.iov_base = &pss;
1781 	iov.iov_len = sizeof(pss);
1782 	uio.uio_iov = &iov;
1783 	uio.uio_iovcnt = 1;
1784 	uio.uio_offset = (off_t)ps_strings;
1785 	uio.uio_resid = sizeof(pss);
1786 	uio.uio_segflg = UIO_SYSSPACE;
1787 	uio.uio_rw = UIO_READ;
1788 	uio.uio_procp = cp;
1789 
1790 	if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1791 		goto out;
1792 
1793 	if (op == KERN_PROC_NARGV) {
1794 		error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nargvstr);
1795 		goto out;
1796 	}
1797 	if (op == KERN_PROC_NENV) {
1798 		error = sysctl_rdint(oldp, oldlenp, NULL, pss.ps_nenvstr);
1799 		goto out;
1800 	}
1801 
1802 	if (op == KERN_PROC_ARGV) {
1803 		cnt = pss.ps_nargvstr;
1804 		vargv = pss.ps_argvstr;
1805 	} else {
1806 		cnt = pss.ps_nenvstr;
1807 		vargv = pss.ps_envstr;
1808 	}
1809 
1810 	/* -1 to have space for a terminating NUL */
1811 	limit = *oldlenp - 1;
1812 	*oldlenp = 0;
1813 
1814 	rargv = oldp;
1815 
1816 	/*
1817 	 * *oldlenp - number of bytes copied out into readers buffer.
1818 	 * limit - maximal number of bytes allowed into readers buffer.
1819 	 * rarg - pointer into readers buffer where next arg will be stored.
1820 	 * rargv - pointer into readers buffer where the next rarg pointer
1821 	 *  will be stored.
1822 	 * vargv - pointer into victim address space where the next argument
1823 	 *  will be read.
1824 	 */
1825 
1826 	/* space for cnt pointers and a NULL */
1827 	rarg = (char *)(rargv + cnt + 1);
1828 	*oldlenp += (cnt + 1) * sizeof(char **);
1829 
1830 	while (cnt > 0 && *oldlenp < limit) {
1831 		size_t len, vstrlen;
1832 
1833 		/* Write to readers argv */
1834 		if ((error = copyout(&rarg, rargv, sizeof(rarg))) != 0)
1835 			goto out;
1836 
1837 		/* read the victim argv */
1838 		iov.iov_base = &varg;
1839 		iov.iov_len = sizeof(varg);
1840 		uio.uio_iov = &iov;
1841 		uio.uio_iovcnt = 1;
1842 		uio.uio_offset = (off_t)(vaddr_t)vargv;
1843 		uio.uio_resid = sizeof(varg);
1844 		uio.uio_segflg = UIO_SYSSPACE;
1845 		uio.uio_rw = UIO_READ;
1846 		uio.uio_procp = cp;
1847 		if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1848 			goto out;
1849 
1850 		if (varg == NULL)
1851 			break;
1852 
1853 		/*
1854 		 * read the victim arg. We must jump through hoops to avoid
1855 		 * crossing a page boundary too much and returning an error.
1856 		 */
1857 more:
1858 		len = PAGE_SIZE - (((vaddr_t)varg) & PAGE_MASK);
1859 		/* leave space for the terminating NUL */
1860 		iov.iov_base = buf;
1861 		iov.iov_len = len;
1862 		uio.uio_iov = &iov;
1863 		uio.uio_iovcnt = 1;
1864 		uio.uio_offset = (off_t)(vaddr_t)varg;
1865 		uio.uio_resid = len;
1866 		uio.uio_segflg = UIO_SYSSPACE;
1867 		uio.uio_rw = UIO_READ;
1868 		uio.uio_procp = cp;
1869 		if ((error = uvm_io(&vm->vm_map, &uio, 0)) != 0)
1870 			goto out;
1871 
1872 		for (vstrlen = 0; vstrlen < len; vstrlen++) {
1873 			if (buf[vstrlen] == '\0')
1874 				break;
1875 		}
1876 
1877 		/* Don't overflow readers buffer. */
1878 		if (*oldlenp + vstrlen + 1 >= limit) {
1879 			error = ENOMEM;
1880 			goto out;
1881 		}
1882 
1883 		if ((error = copyout(buf, rarg, vstrlen)) != 0)
1884 			goto out;
1885 
1886 		*oldlenp += vstrlen;
1887 		rarg += vstrlen;
1888 
1889 		/* The string didn't end in this page? */
1890 		if (vstrlen == len) {
1891 			varg += vstrlen;
1892 			goto more;
1893 		}
1894 
1895 		/* End of string. Terminate it with a NUL */
1896 		buf[0] = '\0';
1897 		if ((error = copyout(buf, rarg, 1)) != 0)
1898 			goto out;
1899 		*oldlenp += 1;
1900 		rarg += 1;
1901 
1902 		vargv++;
1903 		rargv++;
1904 		cnt--;
1905 	}
1906 
1907 	if (*oldlenp >= limit) {
1908 		error = ENOMEM;
1909 		goto out;
1910 	}
1911 
1912 	/* Write the terminating null */
1913 	rarg = NULL;
1914 	error = copyout(&rarg, rargv, sizeof(rarg));
1915 
1916 out:
1917 	uvmspace_free(vm);
1918 	free(buf, M_TEMP, PAGE_SIZE);
1919 	return (error);
1920 }
1921 
1922 int
1923 sysctl_proc_cwd(int *name, u_int namelen, void *oldp, size_t *oldlenp,
1924     struct proc *cp)
1925 {
1926 	struct process *findpr;
1927 	struct vnode *vp;
1928 	pid_t pid;
1929 	int error;
1930 	size_t lenused, len;
1931 	char *path, *bp, *bend;
1932 
1933 	if (namelen > 1)
1934 		return (ENOTDIR);
1935 	if (namelen < 1)
1936 		return (EINVAL);
1937 
1938 	pid = name[0];
1939 	if ((findpr = prfind(pid)) == NULL)
1940 		return (ESRCH);
1941 
1942 	if (oldp == NULL) {
1943 		*oldlenp = MAXPATHLEN * 4;
1944 		return (0);
1945 	}
1946 
1947 	/* Either system process or exiting/zombie */
1948 	if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING))
1949 		return (EINVAL);
1950 
1951 	/* Only owner or root can get cwd */
1952 	if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid &&
1953 	    (error = suser(cp)) != 0)
1954 		return (error);
1955 
1956 	len = *oldlenp;
1957 	if (len > MAXPATHLEN * 4)
1958 		len = MAXPATHLEN * 4;
1959 	else if (len < 2)
1960 		return (ERANGE);
1961 	*oldlenp = 0;
1962 
1963 	/* snag a reference to the vnode before we can sleep */
1964 	vp = findpr->ps_fd->fd_cdir;
1965 	vref(vp);
1966 
1967 	path = malloc(len, M_TEMP, M_WAITOK);
1968 
1969 	bp = &path[len];
1970 	bend = bp;
1971 	*(--bp) = '\0';
1972 
1973 	/* Same as sys__getcwd */
1974 	error = vfs_getcwd_common(vp, NULL,
1975 	    &bp, path, len / 2, GETCWD_CHECK_ACCESS, cp);
1976 	if (error == 0) {
1977 		*oldlenp = lenused = bend - bp;
1978 		error = copyout(bp, oldp, lenused);
1979 	}
1980 
1981 	vrele(vp);
1982 	free(path, M_TEMP, len);
1983 
1984 	return (error);
1985 }
1986 
1987 int
1988 sysctl_proc_nobroadcastkill(int *name, u_int namelen, void *newp, size_t newlen,
1989     void *oldp, size_t *oldlenp, struct proc *cp)
1990 {
1991 	struct process *findpr;
1992 	pid_t pid;
1993 	int error, flag;
1994 
1995 	if (namelen > 1)
1996 		return (ENOTDIR);
1997 	if (namelen < 1)
1998 		return (EINVAL);
1999 
2000 	pid = name[0];
2001 	if ((findpr = prfind(pid)) == NULL)
2002 		return (ESRCH);
2003 
2004 	/* Either system process or exiting/zombie */
2005 	if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING))
2006 		return (EINVAL);
2007 
2008 	/* Only root can change PS_NOBROADCASTKILL */
2009 	if (newp != 0 && (error = suser(cp)) != 0)
2010 		return (error);
2011 
2012 	/* get the PS_NOBROADCASTKILL flag */
2013 	flag = findpr->ps_flags & PS_NOBROADCASTKILL ? 1 : 0;
2014 
2015 	error = sysctl_int(oldp, oldlenp, newp, newlen, &flag);
2016 	if (error == 0 && newp) {
2017 		if (flag)
2018 			atomic_setbits_int(&findpr->ps_flags,
2019 			    PS_NOBROADCASTKILL);
2020 		else
2021 			atomic_clearbits_int(&findpr->ps_flags,
2022 			    PS_NOBROADCASTKILL);
2023 	}
2024 
2025 	return (error);
2026 }
2027 
2028 /* Arbitrary but reasonable limit for one iteration. */
2029 #define	VMMAP_MAXLEN	MAXPHYS
2030 
2031 int
2032 sysctl_proc_vmmap(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2033     struct proc *cp)
2034 {
2035 	struct process *findpr;
2036 	pid_t pid;
2037 	int error;
2038 	size_t oldlen, len;
2039 	struct kinfo_vmentry *kve, *ukve;
2040 	u_long *ustart, start;
2041 
2042 	if (namelen > 1)
2043 		return (ENOTDIR);
2044 	if (namelen < 1)
2045 		return (EINVAL);
2046 
2047 	/* Provide max buffer length as hint. */
2048 	if (oldp == NULL) {
2049 		if (oldlenp == NULL)
2050 			return (EINVAL);
2051 		else {
2052 			*oldlenp = VMMAP_MAXLEN;
2053 			return (0);
2054 		}
2055 	}
2056 
2057 	pid = name[0];
2058 	if (pid == cp->p_p->ps_pid) {
2059 		/* Self process mapping. */
2060 		findpr = cp->p_p;
2061 	} else if (pid > 0) {
2062 		if ((findpr = prfind(pid)) == NULL)
2063 			return (ESRCH);
2064 
2065 		/* Either system process or exiting/zombie */
2066 		if (findpr->ps_flags & (PS_SYSTEM | PS_EXITING))
2067 			return (EINVAL);
2068 
2069 #if 1
2070 		/* XXX Allow only root for now */
2071 		if ((error = suser(cp)) != 0)
2072 			return (error);
2073 #else
2074 		/* Only owner or root can get vmmap */
2075 		if (findpr->ps_ucred->cr_uid != cp->p_ucred->cr_uid &&
2076 		    (error = suser(cp)) != 0)
2077 			return (error);
2078 #endif
2079 	} else {
2080 		/* Only root can get kernel_map */
2081 		if ((error = suser(cp)) != 0)
2082 			return (error);
2083 		findpr = NULL;
2084 	}
2085 
2086 	/* Check the given size. */
2087 	oldlen = *oldlenp;
2088 	if (oldlen == 0 || oldlen % sizeof(*kve) != 0)
2089 		return (EINVAL);
2090 
2091 	/* Deny huge allocation. */
2092 	if (oldlen > VMMAP_MAXLEN)
2093 		return (EINVAL);
2094 
2095 	/*
2096 	 * Iterate from the given address passed as the first element's
2097 	 * kve_start via oldp.
2098 	 */
2099 	ukve = (struct kinfo_vmentry *)oldp;
2100 	ustart = &ukve->kve_start;
2101 	error = copyin(ustart, &start, sizeof(start));
2102 	if (error != 0)
2103 		return (error);
2104 
2105 	/* Allocate wired memory to not block. */
2106 	kve = malloc(oldlen, M_TEMP, M_WAITOK);
2107 
2108 	/* Set the base address and read entries. */
2109 	kve[0].kve_start = start;
2110 	len = oldlen;
2111 	error = fill_vmmap(findpr, kve, &len);
2112 	if (error != 0 && error != ENOMEM)
2113 		goto done;
2114 	if (len == 0)
2115 		goto done;
2116 
2117 	KASSERT(len <= oldlen);
2118 	KASSERT((len % sizeof(struct kinfo_vmentry)) == 0);
2119 
2120 	error = copyout(kve, oldp, len);
2121 
2122 done:
2123 	*oldlenp = len;
2124 
2125 	free(kve, M_TEMP, oldlen);
2126 
2127 	return (error);
2128 }
2129 #endif
2130 
2131 /*
2132  * Initialize disknames/diskstats for export by sysctl. If update is set,
2133  * then we simply update the disk statistics information.
2134  */
2135 int
2136 sysctl_diskinit(int update, struct proc *p)
2137 {
2138 	struct diskstats *sdk;
2139 	struct disk *dk;
2140 	const char *duid;
2141 	int i, tlen, l;
2142 
2143 	if ((i = rw_enter(&sysctl_disklock, RW_WRITE|RW_INTR)) != 0)
2144 		return i;
2145 
2146 	if (disk_change) {
2147 		for (dk = TAILQ_FIRST(&disklist), tlen = 0; dk;
2148 		    dk = TAILQ_NEXT(dk, dk_link)) {
2149 			if (dk->dk_name)
2150 				tlen += strlen(dk->dk_name);
2151 			tlen += 18;	/* label uid + separators */
2152 		}
2153 		tlen++;
2154 
2155 		if (disknames)
2156 			free(disknames, M_SYSCTL, disknameslen);
2157 		if (diskstats)
2158 			free(diskstats, M_SYSCTL, diskstatslen);
2159 		diskstats = NULL;
2160 		disknames = NULL;
2161 		diskstats = mallocarray(disk_count, sizeof(struct diskstats),
2162 		    M_SYSCTL, M_WAITOK|M_ZERO);
2163 		diskstatslen = disk_count * sizeof(struct diskstats);
2164 		disknames = malloc(tlen, M_SYSCTL, M_WAITOK|M_ZERO);
2165 		disknameslen = tlen;
2166 		disknames[0] = '\0';
2167 
2168 		for (dk = TAILQ_FIRST(&disklist), i = 0, l = 0; dk;
2169 		    dk = TAILQ_NEXT(dk, dk_link), i++) {
2170 			duid = NULL;
2171 			if (dk->dk_label && !duid_iszero(dk->dk_label->d_uid))
2172 				duid = duid_format(dk->dk_label->d_uid);
2173 			snprintf(disknames + l, tlen - l, "%s:%s,",
2174 			    dk->dk_name ? dk->dk_name : "",
2175 			    duid ? duid : "");
2176 			l += strlen(disknames + l);
2177 			sdk = diskstats + i;
2178 			strlcpy(sdk->ds_name, dk->dk_name,
2179 			    sizeof(sdk->ds_name));
2180 			mtx_enter(&dk->dk_mtx);
2181 			sdk->ds_busy = dk->dk_busy;
2182 			sdk->ds_rxfer = dk->dk_rxfer;
2183 			sdk->ds_wxfer = dk->dk_wxfer;
2184 			sdk->ds_seek = dk->dk_seek;
2185 			sdk->ds_rbytes = dk->dk_rbytes;
2186 			sdk->ds_wbytes = dk->dk_wbytes;
2187 			sdk->ds_attachtime = dk->dk_attachtime;
2188 			sdk->ds_timestamp = dk->dk_timestamp;
2189 			sdk->ds_time = dk->dk_time;
2190 			mtx_leave(&dk->dk_mtx);
2191 		}
2192 
2193 		/* Eliminate trailing comma */
2194 		if (l != 0)
2195 			disknames[l - 1] = '\0';
2196 		disk_change = 0;
2197 	} else if (update) {
2198 		/* Just update, number of drives hasn't changed */
2199 		for (dk = TAILQ_FIRST(&disklist), i = 0; dk;
2200 		    dk = TAILQ_NEXT(dk, dk_link), i++) {
2201 			sdk = diskstats + i;
2202 			strlcpy(sdk->ds_name, dk->dk_name,
2203 			    sizeof(sdk->ds_name));
2204 			mtx_enter(&dk->dk_mtx);
2205 			sdk->ds_busy = dk->dk_busy;
2206 			sdk->ds_rxfer = dk->dk_rxfer;
2207 			sdk->ds_wxfer = dk->dk_wxfer;
2208 			sdk->ds_seek = dk->dk_seek;
2209 			sdk->ds_rbytes = dk->dk_rbytes;
2210 			sdk->ds_wbytes = dk->dk_wbytes;
2211 			sdk->ds_attachtime = dk->dk_attachtime;
2212 			sdk->ds_timestamp = dk->dk_timestamp;
2213 			sdk->ds_time = dk->dk_time;
2214 			mtx_leave(&dk->dk_mtx);
2215 		}
2216 	}
2217 	rw_exit_write(&sysctl_disklock);
2218 	return 0;
2219 }
2220 
2221 #if defined(SYSVMSG) || defined(SYSVSEM) || defined(SYSVSHM)
2222 int
2223 sysctl_sysvipc(int *name, u_int namelen, void *where, size_t *sizep)
2224 {
2225 #ifdef SYSVSEM
2226 	struct sem_sysctl_info *semsi;
2227 #endif
2228 #ifdef SYSVSHM
2229 	struct shm_sysctl_info *shmsi;
2230 #endif
2231 	size_t infosize, dssize, tsize, buflen, bufsiz;
2232 	int i, nds, error, ret;
2233 	void *buf;
2234 
2235 	if (namelen != 1)
2236 		return (EINVAL);
2237 
2238 	buflen = *sizep;
2239 
2240 	switch (*name) {
2241 	case KERN_SYSVIPC_MSG_INFO:
2242 #ifdef SYSVMSG
2243 		return (sysctl_sysvmsg(name, namelen, where, sizep));
2244 #else
2245 		return (EOPNOTSUPP);
2246 #endif
2247 	case KERN_SYSVIPC_SEM_INFO:
2248 #ifdef SYSVSEM
2249 		infosize = sizeof(semsi->seminfo);
2250 		nds = seminfo.semmni;
2251 		dssize = sizeof(semsi->semids[0]);
2252 		break;
2253 #else
2254 		return (EOPNOTSUPP);
2255 #endif
2256 	case KERN_SYSVIPC_SHM_INFO:
2257 #ifdef SYSVSHM
2258 		infosize = sizeof(shmsi->shminfo);
2259 		nds = shminfo.shmmni;
2260 		dssize = sizeof(shmsi->shmids[0]);
2261 		break;
2262 #else
2263 		return (EOPNOTSUPP);
2264 #endif
2265 	default:
2266 		return (EINVAL);
2267 	}
2268 	tsize = infosize + (nds * dssize);
2269 
2270 	/* Return just the total size required. */
2271 	if (where == NULL) {
2272 		*sizep = tsize;
2273 		return (0);
2274 	}
2275 
2276 	/* Not enough room for even the info struct. */
2277 	if (buflen < infosize) {
2278 		*sizep = 0;
2279 		return (ENOMEM);
2280 	}
2281 	bufsiz = min(tsize, buflen);
2282 	buf = malloc(bufsiz, M_TEMP, M_WAITOK|M_ZERO);
2283 
2284 	switch (*name) {
2285 #ifdef SYSVSEM
2286 	case KERN_SYSVIPC_SEM_INFO:
2287 		semsi = (struct sem_sysctl_info *)buf;
2288 		semsi->seminfo = seminfo;
2289 		break;
2290 #endif
2291 #ifdef SYSVSHM
2292 	case KERN_SYSVIPC_SHM_INFO:
2293 		shmsi = (struct shm_sysctl_info *)buf;
2294 		shmsi->shminfo = shminfo;
2295 		break;
2296 #endif
2297 	}
2298 	buflen -= infosize;
2299 
2300 	ret = 0;
2301 	if (buflen > 0) {
2302 		/* Fill in the IPC data structures.  */
2303 		for (i = 0; i < nds; i++) {
2304 			if (buflen < dssize) {
2305 				ret = ENOMEM;
2306 				break;
2307 			}
2308 			switch (*name) {
2309 #ifdef SYSVSEM
2310 			case KERN_SYSVIPC_SEM_INFO:
2311 				if (sema[i] != NULL)
2312 					memcpy(&semsi->semids[i], sema[i],
2313 					    dssize);
2314 				else
2315 					memset(&semsi->semids[i], 0, dssize);
2316 				break;
2317 #endif
2318 #ifdef SYSVSHM
2319 			case KERN_SYSVIPC_SHM_INFO:
2320 				if (shmsegs[i] != NULL)
2321 					memcpy(&shmsi->shmids[i], shmsegs[i],
2322 					    dssize);
2323 				else
2324 					memset(&shmsi->shmids[i], 0, dssize);
2325 				break;
2326 #endif
2327 			}
2328 			buflen -= dssize;
2329 		}
2330 	}
2331 	*sizep -= buflen;
2332 	error = copyout(buf, where, *sizep);
2333 	free(buf, M_TEMP, bufsiz);
2334 	/* If copyout succeeded, use return code set earlier. */
2335 	return (error ? error : ret);
2336 }
2337 #endif /* SYSVMSG || SYSVSEM || SYSVSHM */
2338 
2339 #ifndef	SMALL_KERNEL
2340 
2341 int
2342 sysctl_intrcnt(int *name, u_int namelen, void *oldp, size_t *oldlenp)
2343 {
2344 	return (evcount_sysctl(name, namelen, oldp, oldlenp, NULL, 0));
2345 }
2346 
2347 
2348 int
2349 sysctl_sensors(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2350     void *newp, size_t newlen)
2351 {
2352 	struct ksensor *ks;
2353 	struct sensor *us;
2354 	struct ksensordev *ksd;
2355 	struct sensordev *usd;
2356 	int dev, numt, ret;
2357 	enum sensor_type type;
2358 
2359 	if (namelen != 1 && namelen != 3)
2360 		return (ENOTDIR);
2361 
2362 	dev = name[0];
2363 	if (namelen == 1) {
2364 		ret = sensordev_get(dev, &ksd);
2365 		if (ret)
2366 			return (ret);
2367 
2368 		/* Grab a copy, to clear the kernel pointers */
2369 		usd = malloc(sizeof(*usd), M_TEMP, M_WAITOK|M_ZERO);
2370 		usd->num = ksd->num;
2371 		strlcpy(usd->xname, ksd->xname, sizeof(usd->xname));
2372 		memcpy(usd->maxnumt, ksd->maxnumt, sizeof(usd->maxnumt));
2373 		usd->sensors_count = ksd->sensors_count;
2374 
2375 		ret = sysctl_rdstruct(oldp, oldlenp, newp, usd,
2376 		    sizeof(struct sensordev));
2377 
2378 		free(usd, M_TEMP, sizeof(*usd));
2379 		return (ret);
2380 	}
2381 
2382 	type = name[1];
2383 	numt = name[2];
2384 
2385 	ret = sensor_find(dev, type, numt, &ks);
2386 	if (ret)
2387 		return (ret);
2388 
2389 	/* Grab a copy, to clear the kernel pointers */
2390 	us = malloc(sizeof(*us), M_TEMP, M_WAITOK|M_ZERO);
2391 	memcpy(us->desc, ks->desc, sizeof(us->desc));
2392 	us->tv = ks->tv;
2393 	us->value = ks->value;
2394 	us->type = ks->type;
2395 	us->status = ks->status;
2396 	us->numt = ks->numt;
2397 	us->flags = ks->flags;
2398 
2399 	ret = sysctl_rdstruct(oldp, oldlenp, newp, us,
2400 	    sizeof(struct sensor));
2401 	free(us, M_TEMP, sizeof(*us));
2402 	return (ret);
2403 }
2404 #endif	/* SMALL_KERNEL */
2405 
2406 int
2407 sysctl_cptime2(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2408     void *newp, size_t newlen)
2409 {
2410 	CPU_INFO_ITERATOR cii;
2411 	struct cpu_info *ci;
2412 	int found = 0;
2413 
2414 	if (namelen != 1)
2415 		return (ENOTDIR);
2416 
2417 	CPU_INFO_FOREACH(cii, ci) {
2418 		if (name[0] == CPU_INFO_UNIT(ci)) {
2419 			found = 1;
2420 			break;
2421 		}
2422 	}
2423 	if (!found)
2424 		return (ENOENT);
2425 
2426 	return (sysctl_rdstruct(oldp, oldlenp, newp,
2427 	    &ci->ci_schedstate.spc_cp_time,
2428 	    sizeof(ci->ci_schedstate.spc_cp_time)));
2429 }
2430 
2431 #if NAUDIO > 0
2432 int
2433 sysctl_audio(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2434     void *newp, size_t newlen)
2435 {
2436 	if (namelen != 1)
2437 		return (ENOTDIR);
2438 
2439 	if (name[0] != KERN_AUDIO_RECORD)
2440 		return (ENOENT);
2441 
2442 	return (sysctl_int(oldp, oldlenp, newp, newlen, &audio_record_enable));
2443 }
2444 #endif
2445 
2446 int
2447 sysctl_cpustats(int *name, u_int namelen, void *oldp, size_t *oldlenp,
2448     void *newp, size_t newlen)
2449 {
2450 	CPU_INFO_ITERATOR cii;
2451 	struct cpustats cs;
2452 	struct cpu_info *ci;
2453 	int found = 0;
2454 
2455 	if (namelen != 1)
2456 		return (ENOTDIR);
2457 
2458 	CPU_INFO_FOREACH(cii, ci) {
2459 		if (name[0] == CPU_INFO_UNIT(ci)) {
2460 			found = 1;
2461 			break;
2462 		}
2463 	}
2464 	if (!found)
2465 		return (ENOENT);
2466 
2467 	memcpy(&cs.cs_time, &ci->ci_schedstate.spc_cp_time, sizeof(cs.cs_time));
2468 	cs.cs_flags = 0;
2469 	if (cpu_is_online(ci))
2470 		cs.cs_flags |= CPUSTATS_ONLINE;
2471 
2472 	return (sysctl_rdstruct(oldp, oldlenp, newp, &cs, sizeof(cs)));
2473 }
2474 
2475 int
2476 sysctl_utc_offset(void *oldp, size_t *oldlenp, void *newp, size_t newlen)
2477 {
2478 	struct timespec adjusted, now;
2479 	int adjustment_seconds, error, new_offset_minutes, old_offset_minutes;
2480 
2481 	old_offset_minutes = utc_offset / 60;	/* seconds -> minutes */
2482 	if (securelevel > 0)
2483 		return sysctl_rdint(oldp, oldlenp, newp, old_offset_minutes);
2484 
2485 	new_offset_minutes = old_offset_minutes;
2486 	error = sysctl_int(oldp, oldlenp, newp, newlen, &new_offset_minutes);
2487 	if (error)
2488 		return error;
2489 	if (new_offset_minutes < -24 * 60 || new_offset_minutes > 24 * 60)
2490 		return EINVAL;
2491 	if (new_offset_minutes == old_offset_minutes)
2492 		return 0;
2493 
2494 	utc_offset = new_offset_minutes * 60;	/* minutes -> seconds */
2495 	adjustment_seconds = (new_offset_minutes - old_offset_minutes) * 60;
2496 
2497 	nanotime(&now);
2498 	adjusted = now;
2499 	adjusted.tv_sec -= adjustment_seconds;
2500 	tc_setrealtimeclock(&adjusted);
2501 	resettodr();
2502 
2503 	return 0;
2504 }
2505