xref: /freebsd/sys/compat/linux/linux_mib.c (revision 23f282aa31e9b6fceacd449020e936e98d6f2298)
1 /*-
2  * Copyright (c) 1999 Marcel Moolenaar
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer
10  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software withough specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  * $FreeBSD$
29  */
30 
31 #include <sys/param.h>
32 #include <sys/kernel.h>
33 #include <sys/systm.h>
34 #include <sys/sysctl.h>
35 #include <sys/proc.h>
36 #include <sys/malloc.h>
37 #include <sys/jail.h>
38 
39 #include <i386/linux/linux.h>
40 #include <i386/linux/linux_mib.h>
41 
42 struct linux_prison {
43 	char	pr_osname[LINUX_MAX_UTSNAME];
44 	char	pr_osrelease[LINUX_MAX_UTSNAME];
45 	int	pr_oss_version;
46 };
47 
48 SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0,
49 	    "Linux mode");
50 
51 static char	linux_osname[LINUX_MAX_UTSNAME] = "Linux";
52 
53 static int
54 linux_sysctl_osname SYSCTL_HANDLER_ARGS
55 {
56 	char osname[LINUX_MAX_UTSNAME];
57 	int error;
58 
59 	strcpy(osname, linux_get_osname(req->p));
60 	error = sysctl_handle_string(oidp, osname, LINUX_MAX_UTSNAME, req);
61 	if (error || req->newptr == NULL)
62 		return (error);
63 	error = linux_set_osname(req->p, osname);
64 	return (error);
65 }
66 
67 SYSCTL_PROC(_compat_linux, OID_AUTO, osname,
68 	    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON,
69 	    0, 0, linux_sysctl_osname, "A",
70 	    "Linux kernel OS name");
71 
72 static char	linux_osrelease[LINUX_MAX_UTSNAME] = "2.2.12";
73 
74 static int
75 linux_sysctl_osrelease SYSCTL_HANDLER_ARGS
76 {
77 	char osrelease[LINUX_MAX_UTSNAME];
78 	int error;
79 
80 	strcpy(osrelease, linux_get_osrelease(req->p));
81 	error = sysctl_handle_string(oidp, osrelease, LINUX_MAX_UTSNAME, req);
82 	if (error || req->newptr == NULL)
83 		return (error);
84 	error = linux_set_osrelease(req->p, osrelease);
85 	return (error);
86 }
87 
88 SYSCTL_PROC(_compat_linux, OID_AUTO, osrelease,
89 	    CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON,
90 	    0, 0, linux_sysctl_osrelease, "A",
91 	    "Linux kernel OS release");
92 
93 static int	linux_oss_version = 0x030600;
94 
95 static int
96 linux_sysctl_oss_version SYSCTL_HANDLER_ARGS
97 {
98 	int oss_version;
99 	int error;
100 
101 	oss_version = linux_get_oss_version(req->p);
102 	error = sysctl_handle_int(oidp, &oss_version, 0, req);
103 	if (error || req->newptr == NULL)
104 		return (error);
105 	error = linux_set_oss_version(req->p, oss_version);
106 	return (error);
107 }
108 
109 SYSCTL_PROC(_compat_linux, OID_AUTO, oss_version,
110 	    CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_PRISON,
111 	    0, 0, linux_sysctl_oss_version, "I",
112 	    "Linux OSS version");
113 
114 static struct linux_prison *
115 get_prison(struct proc *p)
116 {
117 	register struct prison *pr;
118 	register struct linux_prison *lpr;
119 
120 	pr = p->p_prison;
121 	if (pr == NULL)
122 		return (NULL);
123 
124 	if (pr->pr_linux == NULL) {
125 		MALLOC(lpr, struct linux_prison *, sizeof *lpr,
126 		       M_PRISON, M_WAITOK);
127 		bzero((caddr_t)lpr, sizeof *lpr);
128 		pr->pr_linux = lpr;
129 	}
130 
131 	return (pr->pr_linux);
132 }
133 
134 char *
135 linux_get_osname(p)
136 	struct proc *p;
137 {
138 	register struct prison *pr;
139 	register struct linux_prison *lpr;
140 
141 	pr = p->p_prison;
142 	if (pr != NULL && pr->pr_linux != NULL) {
143 		lpr = pr->pr_linux;
144 		if (lpr->pr_osname[0])
145 			return (lpr->pr_osname);
146 	}
147 
148 	return (linux_osname);
149 }
150 
151 int
152 linux_set_osname(p, osname)
153 	struct proc *p;
154 	char *osname;
155 {
156 	register struct linux_prison *lpr;
157 
158 	lpr = get_prison(p);
159 	if (lpr != NULL)
160 		strcpy(lpr->pr_osname, osname);
161 	else
162 		strcpy(linux_osname, osname);
163 
164 	return (0);
165 }
166 
167 char *
168 linux_get_osrelease(p)
169 	struct proc *p;
170 {
171 	register struct prison *pr;
172 	register struct linux_prison *lpr;
173 
174 	pr = p->p_prison;
175 	if (pr != NULL && pr->pr_linux != NULL) {
176 		lpr = pr->pr_linux;
177 		if (lpr->pr_osrelease[0])
178 			return (lpr->pr_osrelease);
179 	}
180 
181 	return (linux_osrelease);
182 }
183 
184 int
185 linux_set_osrelease(p, osrelease)
186 	struct proc *p;
187 	char *osrelease;
188 {
189 	register struct linux_prison *lpr;
190 
191 	lpr = get_prison(p);
192 	if (lpr != NULL)
193 		strcpy(lpr->pr_osrelease, osrelease);
194 	else
195 		strcpy(linux_osrelease, osrelease);
196 
197 	return (0);
198 }
199 
200 int
201 linux_get_oss_version(p)
202 	struct proc *p;
203 {
204 	register struct prison *pr;
205 	register struct linux_prison *lpr;
206 
207 	pr = p->p_prison;
208 	if (pr != NULL && pr->pr_linux != NULL) {
209 		lpr = pr->pr_linux;
210 		if (lpr->pr_oss_version)
211 			return (lpr->pr_oss_version);
212 	}
213 
214 	return (linux_oss_version);
215 }
216 
217 int
218 linux_set_oss_version(p, oss_version)
219 	struct proc *p;
220 	int oss_version;
221 {
222 	register struct linux_prison *lpr;
223 
224 	lpr = get_prison(p);
225 	if (lpr != NULL)
226 		lpr->pr_oss_version = oss_version;
227 	else
228 		linux_oss_version = oss_version;
229 
230 	return (0);
231 }
232