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