1 /**	$MirOS: src/sys/compat/common/kern_info_43.c,v 1.2 2005/03/06 21:27:29 tg Exp $ */
2 /*	$OpenBSD: kern_info_43.c,v 1.15 2003/08/15 20:32:15 tedu Exp $	*/
3 /*	$NetBSD: kern_info_43.c,v 1.5 1996/02/04 02:02:22 christos Exp $	*/
4 
5 /*
6  * Copyright (c) 1982, 1986, 1991, 1993
7  *	The Regents of the University of California.  All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	@(#)subr_xxx.c	8.1 (Berkeley) 6/10/93
34  */
35 
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/filedesc.h>
39 #include <sys/kernel.h>
40 #include <sys/vnode.h>
41 #include <sys/proc.h>
42 #include <sys/file.h>
43 #include <sys/socket.h>
44 #include <sys/socketvar.h>
45 #include <sys/stat.h>
46 #include <sys/ioctl.h>
47 #include <sys/fcntl.h>
48 #include <sys/malloc.h>
49 #include <sys/syslog.h>
50 #include <sys/unistd.h>
51 #include <sys/resourcevar.h>
52 #include <uvm/uvm_extern.h>
53 #include <sys/sysctl.h>
54 
55 #include <sys/mount.h>
56 #include <sys/syscallargs.h>
57 
58 #if defined(COMPAT_OPENBSD)
59 
60 int
compat_43_sys_getdtablesize(p,v,retval)61 compat_43_sys_getdtablesize(p, v, retval)
62 	struct proc *p;
63 	void *v;
64 	register_t *retval;
65 {
66 	*retval = min((int)p->p_rlimit[RLIMIT_NOFILE].rlim_cur, maxfiles);
67 	return (0);
68 }
69 
70 
71 /* ARGSUSED */
72 int
compat_43_sys_gethostid(p,v,retval)73 compat_43_sys_gethostid(p, v, retval)
74 	struct proc *p;
75 	void *v;
76 	register_t *retval;
77 {
78 	*(int32_t *)retval = hostid;
79 	return (0);
80 }
81 
82 
83 /*ARGSUSED*/
84 int
compat_43_sys_gethostname(p,v,retval)85 compat_43_sys_gethostname(p, v, retval)
86 	struct proc *p;
87 	void *v;
88 	register_t *retval;
89 {
90 	struct compat_43_sys_gethostname_args /* {
91 		syscallarg(char *) hostname;
92 		syscallarg(u_int) len;
93 	} */ *uap = v;
94 	int name;
95 	size_t sz;
96 
97 	name = KERN_HOSTNAME;
98 	sz = SCARG(uap, len);
99 	return (kern_sysctl(&name, 1, SCARG(uap, hostname), &sz, 0, 0, p));
100 }
101 
102 #define	KINFO_PROC		(0<<8)
103 #define	KINFO_RT		(1<<8)
104 #define	KINFO_VNODE		(2<<8)
105 #define	KINFO_FILE		(3<<8)
106 #define	KINFO_METER		(4<<8)
107 #define	KINFO_LOADAVG		(5<<8)
108 #define	KINFO_CLOCKRATE		(6<<8)
109 #define	KINFO_BSDI_SYSINFO	(101<<8)
110 
111 
112 /*
113  * The string data is appended to the end of the bsdi_si structure during
114  * copyout. The "char *" offsets in the bsdi_si struct are relative to the
115  * base of the bsdi_si struct.
116  */
117 struct bsdi_si {
118         char    *machine;
119         char    *cpu_model;
120         long    ncpu;
121         long    cpuspeed;
122         long    hwflags;
123         u_long  physmem;
124         u_long  usermem;
125         u_long  pagesize;
126 
127         char    *ostype;
128         char    *osrelease;
129         long    os_revision;
130         long    posix1_version;
131         char    *version;
132 
133         long    hz;
134         long    profhz;
135         int     ngroups_max;
136         long    arg_max;
137         long    open_max;
138         long    child_max;
139 
140         struct  timeval boottime;
141         char    *hostname;
142 };
143 
144 /* Non-standard BSDI extension - only present on their 4.3 net-2 releases */
145 #define       KINFO_BSDI_SYSINFO      (101<<8)
146 
147 /*
148  * XXX this is bloat, but I hope it's better here than on the potentially
149  * limited kernel stack...  -Peter
150  */
151 
152 struct {
153 	char    *bsdi_machine;          /* "i386" on BSD/386 */
154 	char    *pad0;
155 	long    pad1;
156 	long    pad2;
157 	long    pad3;
158 	u_long  pad4;
159 	u_long  pad5;
160 	u_long  pad6;
161 
162 	char    *bsdi_ostype;           /* "BSD/386" on BSD/386 */
163 	char    *bsdi_osrelease;        /* "1.1" on BSD/386 */
164 	long    pad7;
165 	long    pad8;
166 	char    *pad9;
167 
168 	long    pad10;
169 	long    pad11;
170 	int     pad12;
171 	long    pad13;
172 	quad_t  pad14;
173 	long    pad15;
174 
175 	struct  timeval pad16;
176 	/* we dont set this, because BSDI's uname used gethostname() instead */
177 	char    *bsdi_hostname;         /* hostname on BSD/386 */
178 
179 	/* the actual string data is appended here */
180 
181 } bsdi_si;
182 /*
183  * this data is appended to the end of the bsdi_si structure during copyout.
184  * The "char *" offsets are relative to the base of the bsdi_si struct.
185  * This contains "OpenBSD\01.2-BUILT-nnnnnn\0i386\0", and these strings
186  * should not exceed the length of the buffer here... (or else!! :-)
187  */
188 char bsdi_strings[80];        /* It had better be less than this! */
189 
190 int
compat_43_sys_getkerninfo(p,v,retval)191 compat_43_sys_getkerninfo(p, v, retval)
192 	struct proc *p;
193 	void *v;
194 	register_t *retval;
195 {
196 	register struct compat_43_sys_getkerninfo_args /* {
197 		syscallarg(int) op;
198 		syscallarg(char *) where;
199 		syscallarg(int *) size;
200 		syscallarg(int) arg;
201 	} */ *uap = v;
202 	int error, name[5];
203 	size_t size;
204 
205 	extern char machine[];
206 
207 	if (SCARG(uap, size) && (error = copyin((caddr_t)SCARG(uap, size),
208 	    (caddr_t)&size, sizeof(size))))
209 		return (error);
210 
211 	switch (SCARG(uap, op) & 0xff00) {
212 
213 	case KINFO_RT:
214 		name[0] = PF_ROUTE;
215 		name[1] = 0;
216 		name[2] = (SCARG(uap, op) & 0xff0000) >> 16;
217 		name[3] = SCARG(uap, op) & 0xff;
218 		name[4] = SCARG(uap, arg);
219 		error =
220 		    net_sysctl(name, 5, SCARG(uap, where), &size, NULL, 0, p);
221 		break;
222 
223 	case KINFO_VNODE:
224 		name[0] = KERN_VNODE;
225 		error =
226 		    kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p);
227 		break;
228 
229 	case KINFO_PROC:
230 		name[0] = KERN_PROC;
231 		name[1] = SCARG(uap, op) & 0xff;
232 		name[2] = SCARG(uap, arg);
233 		error =
234 		    kern_sysctl(name, 3, SCARG(uap, where), &size, NULL, 0, p);
235 		break;
236 
237 	case KINFO_FILE:
238 		name[0] = KERN_FILE;
239 		error =
240 		    kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p);
241 		break;
242 
243 	case KINFO_METER:
244 		name[0] = VM_METER;
245 		error =
246 		    uvm_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p);
247 		break;
248 
249 	case KINFO_LOADAVG:
250 		name[0] = VM_LOADAVG;
251 		error =
252 		    uvm_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p);
253 		break;
254 
255 	case KINFO_CLOCKRATE:
256 		name[0] = KERN_CLOCKRATE;
257 		error =
258 		    kern_sysctl(name, 1, SCARG(uap, where), &size, NULL, 0, p);
259 		break;
260 
261 	case KINFO_BSDI_SYSINFO: {
262 		/*
263 		 * this is pretty crude, but it's just enough for uname()
264 		 * from BSDI's 1.x libc to work.
265 		 */
266 
267 		u_int needed;
268 		u_int left;
269 		char *s;
270 
271 		bzero((char *)&bsdi_si, sizeof(bsdi_si));
272 		bzero(bsdi_strings, sizeof(bsdi_strings));
273 
274 		s = bsdi_strings;
275 
276 		bsdi_si.bsdi_ostype = ((char *)(s - bsdi_strings)) +
277 				       sizeof(bsdi_si);
278 		strlcpy(s, ostype, bsdi_strings + sizeof bsdi_strings - s);
279 		s += strlen(s) + 1;
280 
281 		bsdi_si.bsdi_osrelease = ((char *)(s - bsdi_strings)) +
282 					  sizeof(bsdi_si);
283 		strlcpy(s, osrelease, bsdi_strings + sizeof bsdi_strings - s);
284 		s += strlen(s) + 1;
285 
286 		bsdi_si.bsdi_machine = ((char *)(s - bsdi_strings)) +
287 					sizeof(bsdi_si);
288 		strlcpy(s, machine, bsdi_strings + sizeof bsdi_strings - s);
289 		s += strlen(s) + 1;
290 
291 		needed = sizeof(bsdi_si) + (s - bsdi_strings);
292 
293 		if (SCARG(uap, where) == NULL) {
294 			/* process is asking how much buffer to supply.. */
295 			size = needed;
296 			error = 0;
297 			break;
298 		}
299 
300 		/* if too much buffer supplied, trim it down */
301 		if (size > needed)
302 			size = needed;
303 
304 		/* how much of the buffer is remaining */
305 		left = size;
306 
307 		if ((error = copyout((char *)&bsdi_si, SCARG(uap, where),
308 		    left)) != 0)
309 			break;
310 
311 		/* is there any point in continuing? */
312 		if (left > sizeof(bsdi_si))
313 			left -= sizeof(bsdi_si);
314 		else
315 			break;
316 
317 		error = copyout(&bsdi_strings, SCARG(uap, where) +
318 				sizeof(bsdi_si), left);
319 
320 		break;
321 	}
322 
323 	default:
324 		return (EOPNOTSUPP);
325 	}
326 	if (error)
327 		return (error);
328 	*retval = size;
329 	if (SCARG(uap, size))
330 		error = copyout((caddr_t)&size, (caddr_t)SCARG(uap, size),
331 		    sizeof(size));
332 	return (error);
333 }
334 
335 
336 /* ARGSUSED */
337 int
compat_43_sys_sethostid(p,v,retval)338 compat_43_sys_sethostid(p, v, retval)
339 	struct proc *p;
340 	void *v;
341 	register_t *retval;
342 {
343 	struct compat_43_sys_sethostid_args /* {
344 		syscallarg(int32_t) hostid;
345 	} */ *uap = v;
346 	int error;
347 
348 	if ((error = suser(p, 0)) != 0)
349 		return (error);
350 	hostid = SCARG(uap, hostid);
351 	return (0);
352 }
353 #endif
354 
355 #if defined(COMPAT_OPENBSD) || defined(COMPAT_LINUX)
356 /* ARGSUSED */
357 int
compat_43_sys_sethostname(p,v,retval)358 compat_43_sys_sethostname(p, v, retval)
359 	struct proc *p;
360 	void *v;
361 	register_t *retval;
362 {
363 	struct compat_43_sys_sethostname_args *uap = v;
364 	int name;
365 	int error;
366 
367 	if ((error = suser(p, 0)) != 0)
368 		return (error);
369 	name = KERN_HOSTNAME;
370 	return (kern_sysctl(&name, 1, 0, 0, SCARG(uap, hostname),
371 			    SCARG(uap, len), p));
372 }
373 #endif
374