xref: /freebsd/sys/compat/linux/linux_mib.c (revision 924836d50eac8e2f8a56ded8c3c62ebc420e00f3)
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 without 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 <machine/../linux/linux.h>
40 #include <compat/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|M_ZERO);
127 		pr->pr_linux = lpr;
128 	}
129 
130 	return (pr->pr_linux);
131 }
132 
133 char *
134 linux_get_osname(p)
135 	struct proc *p;
136 {
137 	register struct prison *pr;
138 	register struct linux_prison *lpr;
139 
140 	pr = p->p_prison;
141 	if (pr != NULL && pr->pr_linux != NULL) {
142 		lpr = pr->pr_linux;
143 		if (lpr->pr_osname[0])
144 			return (lpr->pr_osname);
145 	}
146 
147 	return (linux_osname);
148 }
149 
150 int
151 linux_set_osname(p, osname)
152 	struct proc *p;
153 	char *osname;
154 {
155 	register struct linux_prison *lpr;
156 
157 	lpr = get_prison(p);
158 	if (lpr != NULL)
159 		strcpy(lpr->pr_osname, osname);
160 	else
161 		strcpy(linux_osname, osname);
162 
163 	return (0);
164 }
165 
166 char *
167 linux_get_osrelease(p)
168 	struct proc *p;
169 {
170 	register struct prison *pr;
171 	register struct linux_prison *lpr;
172 
173 	pr = p->p_prison;
174 	if (pr != NULL && pr->pr_linux != NULL) {
175 		lpr = pr->pr_linux;
176 		if (lpr->pr_osrelease[0])
177 			return (lpr->pr_osrelease);
178 	}
179 
180 	return (linux_osrelease);
181 }
182 
183 int
184 linux_set_osrelease(p, osrelease)
185 	struct proc *p;
186 	char *osrelease;
187 {
188 	register struct linux_prison *lpr;
189 
190 	lpr = get_prison(p);
191 	if (lpr != NULL)
192 		strcpy(lpr->pr_osrelease, osrelease);
193 	else
194 		strcpy(linux_osrelease, osrelease);
195 
196 	return (0);
197 }
198 
199 int
200 linux_get_oss_version(p)
201 	struct proc *p;
202 {
203 	register struct prison *pr;
204 	register struct linux_prison *lpr;
205 
206 	pr = p->p_prison;
207 	if (pr != NULL && pr->pr_linux != NULL) {
208 		lpr = pr->pr_linux;
209 		if (lpr->pr_oss_version)
210 			return (lpr->pr_oss_version);
211 	}
212 
213 	return (linux_oss_version);
214 }
215 
216 int
217 linux_set_oss_version(p, oss_version)
218 	struct proc *p;
219 	int oss_version;
220 {
221 	register struct linux_prison *lpr;
222 
223 	lpr = get_prison(p);
224 	if (lpr != NULL)
225 		lpr->pr_oss_version = oss_version;
226 	else
227 		linux_oss_version = oss_version;
228 
229 	return (0);
230 }
231