1 /**	$MirOS: src/sys/compat/common/uipc_syscalls_43.c,v 1.2 2005/03/06 21:27:29 tg Exp $ */
2 /*	$OpenBSD: uipc_syscalls_43.c,v 1.7 2003/06/02 23:27:59 millert Exp $	*/
3 /*	$NetBSD: uipc_syscalls_43.c,v 1.5 1996/03/14 19:31:50 christos Exp $	*/
4 
5 /*
6  * Fix "undefined" MSG_COMPAT errors in /sys/sys/socket.h too!
7  */
8 
9 /*
10  * Copyright (c) 1982, 1986, 1989, 1990, 1993
11  *	The Regents of the University of California.  All rights reserved.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  *
37  *	@(#)uipc_syscalls.c	8.4 (Berkeley) 2/21/94
38  */
39 
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/filedesc.h>
43 #include <sys/kernel.h>
44 #include <sys/proc.h>
45 #include <sys/file.h>
46 #include <sys/socket.h>
47 #include <sys/socketvar.h>
48 #include <sys/stat.h>
49 #include <sys/ioctl.h>
50 #include <sys/fcntl.h>
51 #include <sys/malloc.h>
52 #include <sys/syslog.h>
53 #include <sys/unistd.h>
54 #include <sys/resourcevar.h>
55 
56 #include <sys/mount.h>
57 #include <sys/syscallargs.h>
58 
59 #if defined(COMPAT_OPENBSD) || defined(COMPAT_LINUX)
60 int
compat_43_sys_accept(p,v,retval)61 compat_43_sys_accept(p, v, retval)
62 	struct proc *p;
63 	void *v;
64 	register_t *retval;
65 {
66 	struct sys_accept_args /* {
67 		syscallarg(int) s;
68 		syscallarg(caddr_t) name;
69 		syscallarg(int *) anamelen;
70 	} */ *uap = v;
71 	int error;
72 
73 	if ((error = sys_accept(p, uap, retval)) != 0)
74 		return error;
75 
76 	if (SCARG(uap, name)) {
77 		struct sockaddr sa;
78 
79 		if ((error = copyin(SCARG(uap, name), &sa, sizeof(sa))) != 0)
80 			return error;
81 
82 		((struct osockaddr*) &sa)->sa_family = sa.sa_family;
83 
84 		if ((error = copyout(&sa, SCARG(uap, name), sizeof(sa))) != 0)
85 			return error;
86 	}
87 	return 0;
88 }
89 #endif
90 
91 #if defined(COMPAT_OPENBSD)
92 int
compat_43_sys_getpeername(p,v,retval)93 compat_43_sys_getpeername(p, v, retval)
94 	struct proc *p;
95 	void *v;
96 	register_t *retval;
97 {
98 	struct sys_getpeername_args /* {
99 		syscallarg(int) fdes;
100 		syscallarg(caddr_t) asa;
101 		syscallarg(int *) alen;
102 	} */ *uap = v;
103 	struct sockaddr sa;
104 
105 	int error;
106 
107 	if ((error = sys_getpeername(p, uap, retval)) != 0)
108 		return error;
109 
110 	if ((error = copyin(SCARG(uap, asa), &sa, sizeof(sa))) != 0)
111 		return error;
112 
113 	((struct osockaddr*) &sa)->sa_family = sa.sa_family;
114 
115 	if ((error = copyout(&sa, SCARG(uap, asa), sizeof(sa))) != 0)
116 		return error;
117 
118 	return 0;
119 }
120 
121 
122 int
compat_43_sys_getsockname(p,v,retval)123 compat_43_sys_getsockname(p, v, retval)
124 	struct proc *p;
125 	void *v;
126 	register_t *retval;
127 {
128 	struct sys_getsockname_args /* {
129 		syscallarg(int) fdes;
130 		syscallarg(caddr_t) asa;
131 		syscallarg(int *) alen;
132 	} */ *uap = v;
133 	struct sockaddr sa;
134 	int error;
135 
136 	if ((error = sys_getsockname(p, uap, retval)) != 0)
137 		return error;
138 
139 	if ((error = copyin(SCARG(uap, asa), &sa, sizeof(sa))) != 0)
140 		return error;
141 
142 	((struct osockaddr*) &sa)->sa_family = sa.sa_family;
143 
144 	if ((error = copyout(&sa, SCARG(uap, asa), sizeof(sa))) != 0)
145 		return error;
146 
147 	return 0;
148 }
149 #endif
150 
151 #if defined(COMPAT_OPENBSD) || defined(COMPAT_LINUX)
152 int
compat_43_sys_recv(p,v,retval)153 compat_43_sys_recv(p, v, retval)
154 	struct proc *p;
155 	void *v;
156 	register_t *retval;
157 {
158 	register struct compat_43_sys_recv_args /* {
159 		syscallarg(int) s;
160 		syscallarg(caddr_t) buf;
161 		syscallarg(int) len;
162 		syscallarg(int) flags;
163 	} */ *uap = v;
164 	struct msghdr msg;
165 	struct iovec aiov;
166 
167 	msg.msg_name = 0;
168 	msg.msg_namelen = 0;
169 	msg.msg_iov = &aiov;
170 	msg.msg_iovlen = 1;
171 	aiov.iov_base = SCARG(uap, buf);
172 	aiov.iov_len = SCARG(uap, len);
173 	msg.msg_control = 0;
174 	msg.msg_flags = SCARG(uap, flags);
175 	return (recvit(p, SCARG(uap, s), &msg, (caddr_t)0, retval));
176 }
177 #endif
178 
179 #if defined(COMPAT_OPENBSD)
180 int
compat_43_sys_recvfrom(p,v,retval)181 compat_43_sys_recvfrom(p, v, retval)
182 	struct proc *p;
183 	void *v;
184 	register_t *retval;
185 {
186 	struct sys_recvfrom_args /* {
187 		syscallarg(int) s;
188 		syscallarg(caddr_t) buf;
189 		syscallarg(size_t) len;
190 		syscallarg(int) flags;
191 		syscallarg(caddr_t) from;
192 		syscallarg(int *) fromlenaddr;
193 	} */ *uap = v;
194 
195 	SCARG(uap, flags) |= MSG_COMPAT;
196 	return (sys_recvfrom(p, uap, retval));
197 }
198 
199 
200 /*
201  * Old recvmsg.  This code takes advantage of the fact that the old msghdr
202  * overlays the new one, missing only the flags, and with the (old) access
203  * rights where the control fields are now.
204  */
205 int
compat_43_sys_recvmsg(p,v,retval)206 compat_43_sys_recvmsg(p, v, retval)
207 	struct proc *p;
208 	void *v;
209 	register_t *retval;
210 {
211 	register struct compat_43_sys_recvmsg_args /* {
212 		syscallarg(int) s;
213 		syscallarg(struct omsghdr *) msg;
214 		syscallarg(int) flags;
215 	} */ *uap = v;
216 	struct msghdr msg;
217 	struct iovec aiov[UIO_SMALLIOV], *iov;
218 	int error;
219 
220 	error = copyin((caddr_t)SCARG(uap, msg), (caddr_t)&msg,
221 	    sizeof (struct omsghdr));
222 	if (error)
223 		return (error);
224 	if (msg.msg_iovlen <= 0 || msg.msg_iovlen > IOV_MAX)
225 		return (EMSGSIZE);
226 	if (msg.msg_iovlen > UIO_SMALLIOV)
227 		MALLOC(iov, struct iovec *,
228 		      sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
229 	else
230 		iov = aiov;
231 	msg.msg_flags = SCARG(uap, flags) | MSG_COMPAT;
232 	error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
233 	    (unsigned)(msg.msg_iovlen * sizeof (struct iovec)));
234 	if (error)
235 		goto done;
236 	msg.msg_iov = iov;
237 	error = recvit(p, SCARG(uap, s), &msg,
238 	    (caddr_t)&SCARG(uap, msg)->msg_namelen, retval);
239 
240 	if (msg.msg_controllen && error == 0)
241 		error = copyout((caddr_t)&msg.msg_controllen,
242 		    (caddr_t)&SCARG(uap, msg)->msg_accrightslen, sizeof (int));
243 done:
244 	if (iov != aiov)
245 		FREE(iov, M_IOV);
246 	return (error);
247 }
248 #endif
249 
250 #if defined(COMPAT_OPENBSD) || defined(COMPAT_LINUX)
251 int
compat_43_sys_send(p,v,retval)252 compat_43_sys_send(p, v, retval)
253 	struct proc *p;
254 	void *v;
255 	register_t *retval;
256 {
257 	register struct compat_43_sys_send_args /* {
258 		syscallarg(int) s;
259 		syscallarg(caddr_t) buf;
260 		syscallarg(int) len;
261 		syscallarg(int) flags;
262 	} */ *uap = v;
263 	struct msghdr msg;
264 	struct iovec aiov;
265 
266 	msg.msg_name = 0;
267 	msg.msg_namelen = 0;
268 	msg.msg_iov = &aiov;
269 	msg.msg_iovlen = 1;
270 	aiov.iov_base = SCARG(uap, buf);
271 	aiov.iov_len = SCARG(uap, len);
272 	msg.msg_control = 0;
273 	msg.msg_flags = 0;
274 	return (sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval));
275 }
276 #endif
277 
278 #if defined(COMPAT_OPENBSD)
279 int
compat_43_sys_sendmsg(p,v,retval)280 compat_43_sys_sendmsg(p, v, retval)
281 	struct proc *p;
282 	void *v;
283 	register_t *retval;
284 {
285 	register struct compat_43_sys_sendmsg_args /* {
286 		syscallarg(int) s;
287 		syscallarg(caddr_t) msg;
288 		syscallarg(int) flags;
289 	} */ *uap = v;
290 	struct msghdr msg;
291 	struct iovec aiov[UIO_SMALLIOV], *iov;
292 	int error;
293 
294 	error = copyin(SCARG(uap, msg), (caddr_t)&msg,
295 	    sizeof (struct omsghdr));
296 	if (error)
297 		return (error);
298 	if (msg.msg_iovlen <= 0 || msg.msg_iovlen > IOV_MAX)
299 		return (EMSGSIZE);
300 	if (msg.msg_iovlen > UIO_SMALLIOV)
301 		MALLOC(iov, struct iovec *,
302 		      sizeof(struct iovec) * msg.msg_iovlen, M_IOV, M_WAITOK);
303 	else
304 		iov = aiov;
305 	error = copyin((caddr_t)msg.msg_iov, (caddr_t)iov,
306 	    (unsigned)(msg.msg_iovlen * sizeof (struct iovec)));
307 	if (error)
308 		goto done;
309 	msg.msg_flags = MSG_COMPAT;
310 	msg.msg_iov = iov;
311 	error = sendit(p, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
312 done:
313 	if (iov != aiov)
314 		FREE(iov, M_IOV);
315 	return (error);
316 }
317 #endif
318