1 /*
2 * 43BSD_HOSTINFO.C - 4.3BSD compatibility host info syscalls
3 *
4 * Copyright (c) 1982, 1986, 1989, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. 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 * $DragonFly: src/sys/emulation/43bsd/43bsd_hostinfo.c,v 1.4 2006/09/05 00:55:44 dillon Exp $
36 * from: DragonFly kern/kern_xxx.c,v 1.7
37 * from: DragonFly kern/kern_sysctl.c,v 1.12
38 *
39 * These syscalls used to live in kern/kern_xxx.c and kern/kern_sysctl.c.
40 */
41
42 #include "opt_compat.h"
43
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/sysproto.h>
47 #include <sys/kernel.h>
48 #include <sys/proc.h>
49 #include <sys/priv.h>
50 #include <sys/socket.h>
51 #include <sys/sysctl.h>
52
53 #include <vm/vm_param.h>
54
55 int
56 sys_ogethostname(struct gethostname_args *uap)
57 {
58 size_t len;
59 char *hostname;
60 int error, name[2];
61
62 name[0] = CTL_KERN;
63 name[1] = KERN_HOSTNAME;
64 len = MIN(uap->len, MAXHOSTNAMELEN);
65 hostname = kmalloc(MAXHOSTNAMELEN, M_TEMP, M_WAITOK);
66
67 error = kernel_sysctl(name, 2, hostname, &len, NULL, 0, NULL);
68
69 if (error == 0)
70 error = copyout(hostname, uap->hostname, len);
71
72 kfree(hostname, M_TEMP);
73 return (error);
74 }
75
76 int
77 sys_osethostname(struct sethostname_args *uap)
78 {
79 struct thread *td = curthread;
80 size_t len;
81 char *hostname;
82 int name[2];
83 int error;
84
85 name[0] = CTL_KERN;
86 name[1] = KERN_HOSTNAME;
87 error = priv_check_cred(td->td_ucred, PRIV_SETHOSTNAME, 0);
88 if (error)
89 return (error);
90 len = MIN(uap->len, MAXHOSTNAMELEN);
91 hostname = kmalloc(MAXHOSTNAMELEN, M_TEMP, M_WAITOK);
92
93 error = copyin(uap->hostname, hostname, len);
94 if (error) {
95 kfree(hostname, M_TEMP);
96 return (error);
97 }
98
99 error = kernel_sysctl(name, 2, NULL, 0, hostname, len, NULL);
100
101 kfree(hostname, M_TEMP);
102 return (error);
103 }
104
105 /*
106 * MPSAFE
107 */
108 int
109 sys_ogethostid(struct ogethostid_args *uap)
110 {
111 uap->sysmsg_lresult = hostid;
112 return (0);
113 }
114
115 /*
116 * MPSAFE
117 */
118 int
119 sys_osethostid(struct osethostid_args *uap)
120 {
121 struct thread *td = curthread;
122 int error;
123
124 error = priv_check(td, PRIV_ROOT);
125 if (error)
126 return (error);
127 hostid = uap->hostid;
128 return (0);
129 }
130
131 /*
132 * MPSAFE
133 */
134 int
135 sys_oquota(struct oquota_args *uap)
136 {
137 return (ENOSYS);
138 }
139
140 #define KINFO_PROC (0<<8)
141 #define KINFO_RT (1<<8)
142 #define KINFO_VNODE (2<<8)
143 #define KINFO_FILE (3<<8)
144 #define KINFO_METER (4<<8)
145 #define KINFO_LOADAVG (5<<8)
146 #define KINFO_CLOCKRATE (6<<8)
147
148 /* Non-standard BSDI extension - only present on their 4.3 net-2 releases */
149 #define KINFO_BSDI_SYSINFO (101<<8)
150
151 /*
152 * XXX this is bloat, but I hope it's better here than on the potentially
153 * limited kernel stack... -Peter
154 */
155
156 static struct {
157 int bsdi_machine; /* "i386" on BSD/386 */
158 /* ^^^ this is an offset to the string, relative to the struct start */
159 char *pad0;
160 long pad1;
161 long pad2;
162 long pad3;
163 u_long pad4;
164 u_long pad5;
165 u_long pad6;
166
167 int bsdi_ostype; /* "BSD/386" on BSD/386 */
168 int bsdi_osrelease; /* "1.1" on BSD/386 */
169 long pad7;
170 long pad8;
171 char *pad9;
172
173 long pad10;
174 long pad11;
175 int pad12;
176 long pad13;
177 quad_t pad14;
178 long pad15;
179
180 struct timeval pad16;
181 /* we dont set this, because BSDI's uname used gethostname() instead */
182 int bsdi_hostname; /* hostname on BSD/386 */
183
184 /* the actual string data is appended here */
185
186 } bsdi_si;
187 /*
188 * this data is appended to the end of the bsdi_si structure during copyout.
189 * The "char *" offsets are relative to the base of the bsdi_si struct.
190 * This contains "FreeBSD\02.0-BUILT-nnnnnn\0i386\0", and these strings
191 * should not exceed the length of the buffer here... (or else!! :-)
192 */
193 static char bsdi_strings[80]; /* It had better be less than this! */
194
195 /*
196 * MPALMOSTSAFE
197 */
198 int
199 sys_ogetkerninfo(struct getkerninfo_args *uap)
200 {
201 int error, name[6];
202 size_t size;
203 u_int needed = 0;
204
205 switch (uap->op & 0xff00) {
206 case KINFO_RT:
207 name[0] = CTL_NET;
208 name[1] = PF_ROUTE;
209 name[2] = 0;
210 name[3] = (uap->op & 0xff0000) >> 16;
211 name[4] = uap->op & 0xff;
212 name[5] = uap->arg;
213 error = userland_sysctl(name, 6, uap->where, uap->size,
214 0, 0, 0, &size);
215 break;
216
217 case KINFO_VNODE:
218 name[0] = CTL_KERN;
219 name[1] = KERN_VNODE;
220 error = userland_sysctl(name, 2, uap->where, uap->size,
221 0, 0, 0, &size);
222 break;
223
224 case KINFO_PROC:
225 name[0] = CTL_KERN;
226 name[1] = KERN_PROC;
227 name[2] = uap->op & 0xff;
228 name[3] = uap->arg;
229 error = userland_sysctl(name, 4, uap->where, uap->size,
230 0, 0, 0, &size);
231 break;
232
233 case KINFO_FILE:
234 name[0] = CTL_KERN;
235 name[1] = KERN_FILE;
236 error = userland_sysctl(name, 2, uap->where, uap->size,
237 0, 0, 0, &size);
238 break;
239
240 case KINFO_METER:
241 name[0] = CTL_VM;
242 name[1] = VM_METER;
243 error = userland_sysctl(name, 2, uap->where, uap->size,
244 0, 0, 0, &size);
245 break;
246
247 case KINFO_LOADAVG:
248 name[0] = CTL_VM;
249 name[1] = VM_LOADAVG;
250 error = userland_sysctl(name, 2, uap->where, uap->size,
251 0, 0, 0, &size);
252 break;
253
254 case KINFO_CLOCKRATE:
255 name[0] = CTL_KERN;
256 name[1] = KERN_CLOCKRATE;
257 error = userland_sysctl(name, 2, uap->where, uap->size,
258 0, 0, 0, &size);
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 * *size gives the size of the buffer before the call, and
266 * the amount of data copied after a successful call.
267 * If successful, the return value is the amount of data
268 * available, which can be larger than *size.
269 *
270 * BSDI's 2.x product apparently fails with ENOMEM if
271 * *size is too small.
272 */
273
274 u_int left;
275 char *s;
276
277 bzero((char *)&bsdi_si, sizeof(bsdi_si));
278 bzero(bsdi_strings, sizeof(bsdi_strings));
279
280 s = bsdi_strings;
281
282 bsdi_si.bsdi_ostype = (s - bsdi_strings) + sizeof(bsdi_si);
283 strcpy(s, ostype);
284 s += strlen(s) + 1;
285
286 bsdi_si.bsdi_osrelease = (s - bsdi_strings) + sizeof(bsdi_si);
287 strcpy(s, osrelease);
288 s += strlen(s) + 1;
289
290 bsdi_si.bsdi_machine = (s - bsdi_strings) + sizeof(bsdi_si);
291 strcpy(s, machine);
292 s += strlen(s) + 1;
293
294 needed = sizeof(bsdi_si) + (s - bsdi_strings);
295
296 if (uap->where == NULL || (uap->size == NULL)) {
297 /* process is asking how much buffer to supply.. */
298 size = needed;
299 error = 0;
300 break;
301 }
302
303 if ((error = copyin(uap->size, &size, sizeof(size))) != 0)
304 break;
305
306 /* if too much buffer supplied, trim it down */
307 if (size > needed)
308 size = needed;
309
310 /* how much of the buffer is remaining */
311 left = size;
312
313 if ((error = copyout((char *)&bsdi_si, uap->where, left)) != 0)
314 break;
315
316 /* is there any point in continuing? */
317 if (left > sizeof(bsdi_si)) {
318 left -= sizeof(bsdi_si);
319 error = copyout(&bsdi_strings,
320 uap->where + sizeof(bsdi_si), left);
321 }
322 break;
323 }
324 default:
325 error = EOPNOTSUPP;
326 break;
327 }
328
329 if (error)
330 return (error);
331 uap->sysmsg_iresult = (int)size;
332 if (uap->size)
333 error = copyout(&size, uap->size, sizeof(size));
334 return (error);
335 }
Cache object: 3064dfbe2e10890c93e537dd6ae9fd1c
|