Sync usage with man page.
[netbsd-mini2440.git] / sys / compat / darwin / darwin_socket.c
blobc5bbf4a6b9fbe6e81b74f39def17df8ba58310ef
1 /* $NetBSD: darwin_socket.c,v 1.19.2.2 2008/11/01 21:22:25 christos Exp $ */
3 /*-
4 * Copyright (c) 2004, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Emmanuel Dreyfus
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: darwin_socket.c,v 1.19.2.2 2008/11/01 21:22:25 christos Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/socket.h>
38 #include <sys/signal.h>
39 #include <sys/lwp.h>
40 #include <sys/socketvar.h>
41 #include <sys/un.h>
42 #include <sys/mbuf.h>
43 #include <sys/filedesc.h>
44 #include <sys/protosw.h>
45 #include <sys/syscallargs.h>
47 #include <compat/sys/signal.h>
49 #include <compat/common/compat_util.h>
51 #include <compat/mach/mach_vm.h>
53 #include <compat/darwin/darwin_types.h>
54 #include <compat/darwin/darwin_audit.h>
55 #include <compat/darwin/darwin_socket.h>
56 #include <compat/darwin/darwin_syscallargs.h>
58 unsigned char native_to_darwin_af[] = {
60 DARWIN_AF_LOCAL,
61 DARWIN_AF_INET,
62 DARWIN_AF_IMPLINK,
63 DARWIN_AF_PUP,
64 DARWIN_AF_CHAOS, /* 5 */
65 DARWIN_AF_NS,
66 DARWIN_AF_ISO,
67 DARWIN_AF_ECMA,
68 DARWIN_AF_DATAKIT,
69 DARWIN_AF_CCITT, /* 10 */
70 DARWIN_AF_SNA,
71 DARWIN_AF_DECnet,
72 DARWIN_AF_DLI,
73 DARWIN_AF_LAT,
74 DARWIN_AF_HYLINK, /* 15 */
75 DARWIN_AF_APPLETALK,
76 DARWIN_AF_ROUTE,
77 DARWIN_AF_LINK,
78 DARWIN_AF_XTP,
79 DARWIN_AF_COIP, /* 20 */
80 DARWIN_AF_CNT,
81 DARWIN_AF_RTIP,
82 DARWIN_AF_IPX,
83 DARWIN_AF_INET6,
84 DARWIN_AF_PIP, /* 25 */
85 DARWIN_AF_ISDN,
86 DARWIN_AF_NATM,
88 DARWIN_AF_KEY,
89 DARWIN_AF_HDRCMPLT, /* 30 */
94 0, /* 35 */
98 unsigned char darwin_to_native_af[] = {
100 AF_LOCAL,
101 AF_INET,
102 AF_IMPLINK,
103 AF_PUP,
104 AF_CHAOS, /* 5 */
105 AF_NS,
106 AF_ISO,
107 AF_ECMA,
108 AF_DATAKIT,
109 AF_CCITT, /* 10 */
110 AF_SNA,
111 AF_DECnet,
112 AF_DLI,
113 AF_LAT,
114 AF_HYLINK, /* 15 */
115 AF_APPLETALK,
116 AF_ROUTE,
117 AF_LINK,
119 AF_COIP, /* 20 */
120 AF_CNT,
122 AF_IPX,
124 0, /* 25 */
127 AF_ISDN,
128 pseudo_AF_KEY,
129 AF_INET6, /* 30 */
130 AF_NATM,
134 pseudo_AF_HDRCMPLT, /* 35 */
138 static int
139 native_to_darwin_sockaddr(struct mbuf *nam)
141 struct sockaddr *sa = mtod(nam, void *);
143 /* We only need to translate the address family */
144 if ((unsigned)sa->sa_family >= __arraycount(native_to_darwin_af))
145 return EPROTONOSUPPORT;
147 sa->sa_family = native_to_darwin_af[sa->sa_family];
148 return 0;
151 static int
152 darwin_to_native_sockaddr(struct mbuf *nam)
154 struct sockaddr *sa = mtod(nam, void *);
156 if ((unsigned)sa->sa_family >= __arraycount(darwin_to_native_af)) {
157 m_free(nam);
158 return EPROTONOSUPPORT;
160 sa->sa_family = darwin_to_native_af[sa->sa_family];
163 * sa_len is zero for AF_LOCAL sockets, believe size we copied in!
164 * The code used to strlen the filename, but that way lies madness!
167 if (sa->sa_len > nam->m_len || sa->sa_len == 0)
168 sa->sa_len = nam->m_len;
169 else
170 nam->m_len = sa->sa_len;
172 return 0;
176 darwin_sys_socket(struct lwp *l, const struct darwin_sys_socket_args *uap, register_t *retval)
178 /* {
179 syscallarg(int) domain;
180 syscallarg(int) type;
181 syscallarg(int) protocol;
182 } */
183 struct compat_30_sys_socket_args cup;
185 if ((unsigned)SCARG(uap, domain) >= __arraycount(darwin_to_native_af))
186 return (EPROTONOSUPPORT);
188 SCARG(&cup, domain) = darwin_to_native_af[SCARG(uap, domain)];
189 SCARG(&cup, type) = SCARG(uap, type);
190 SCARG(&cup, protocol) = SCARG(uap, protocol);
192 return compat_30_sys_socket(l, &cup, retval);
196 darwin_sys_recvfrom(struct lwp *l, const struct darwin_sys_recvfrom_args *uap, register_t *retval)
198 /* {
199 syscallarg(int) s;
200 syscallarg(void *) buf;
201 syscallarg(size_t) len;
202 syscallarg(int) flags;
203 syscallarg(struct sockaddr *) from;
204 syscallarg(unsigned int *) fromlenaddr;
205 } */
206 struct msghdr msg;
207 struct iovec aiov;
208 int error;
209 struct mbuf *from;
211 msg.msg_name = NULL;;
212 msg.msg_iov = &aiov;
213 msg.msg_iovlen = 1;
214 aiov.iov_base = SCARG(uap, buf);
215 aiov.iov_len = SCARG(uap, len);
216 msg.msg_control = NULL;
217 msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
219 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval);
220 if (error != 0)
221 return error;
223 error = native_to_darwin_sockaddr(from);
224 if (error == 0)
225 error = copyout_sockname(SCARG(uap, from),
226 SCARG(uap, fromlenaddr), MSG_LENUSRSPACE, from);
227 if (from != NULL)
228 m_free(from);
229 return error;
233 darwin_sys_accept(struct lwp *l, const struct darwin_sys_accept_args *uap, register_t *retval)
235 /* {
236 syscallarg(int) s;
237 syscallarg(struct sockaddr *) name;
238 syscallarg(unsigned int *) anamelen;
239 } */
240 int error, fd;
241 struct mbuf *name;
243 error = do_sys_accept(l, SCARG(uap, s), &name, retval);
244 if (error != 0)
245 return error;
247 error = native_to_darwin_sockaddr(name);
248 if (error == 0)
249 error = copyout_sockname(SCARG(uap, name), SCARG(uap, anamelen),
250 MSG_LENUSRSPACE, name);
251 if (name != NULL)
252 m_free(name);
253 if (error != 0) {
254 fd = (int)*retval;
255 if (fd_getfile(fd) != NULL)
256 fd_close(fd);
258 return error;
262 darwin_sys_getpeername(struct lwp *l, const struct darwin_sys_getpeername_args *uap, register_t *retval)
264 /* {
265 syscallarg(int) fdes;
266 syscallarg(struct sockaddr *) asa;
267 syscallarg(unsigned int *) alen;
268 } */
269 struct mbuf *m;
270 int error;
272 error = do_sys_getsockname(l, SCARG(uap, fdes), PRU_PEERADDR, &m);
273 if (error != 0)
274 return error;
276 error = native_to_darwin_sockaddr(m);
277 if (error != 0)
278 error = copyout_sockname(SCARG(uap, asa), SCARG(uap, alen),
279 MSG_LENUSRSPACE, m);
280 if (m != NULL)
281 m_free(m);
282 return error;
286 darwin_sys_getsockname(struct lwp *l, const struct darwin_sys_getsockname_args *uap, register_t *retval)
288 /* {
289 syscallarg(int) fdes;
290 syscallarg(struct sockaddr *) asa;
291 syscallarg(unsigned int *) alen;
292 } */
293 struct mbuf *m;
294 int error;
296 error = do_sys_getsockname(l, SCARG(uap, fdes), PRU_SOCKADDR, &m);
297 if (error != 0)
298 return error;
300 error = native_to_darwin_sockaddr(m);
301 if (error != 0)
302 error = copyout_sockname(SCARG(uap, asa), SCARG(uap, alen),
303 MSG_LENUSRSPACE, m);
304 if (m != NULL)
305 m_free(m);
306 return error;
310 darwin_sys_connect(struct lwp *l, const struct darwin_sys_connect_args *uap, register_t *retval)
312 /* {
313 syscallarg(int) s;
314 syscallarg(struct sockaddr *) name;
315 syscallarg(unsigned int *) namelen;
316 } */
317 struct mbuf *nam;
318 int error;
320 error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
321 MT_SONAME);
322 if (error == 0)
323 error = darwin_to_native_sockaddr(nam);
324 if (error == 0)
325 error = do_sys_connect(l, SCARG(uap, s), nam);
327 return error;
331 darwin_sys_bind(struct lwp *l, const struct darwin_sys_bind_args *uap, register_t *retval)
333 /* {
334 syscallarg(int) s;
335 syscallarg(struct sockaddr *) name;
336 syscallarg(unsigned int *) namelen;
337 } */
338 struct mbuf *nam;
339 int error;
341 error = sockargs(&nam, SCARG(uap, name), SCARG(uap, namelen),
342 MT_SONAME);
343 if (error == 0)
344 error = darwin_to_native_sockaddr(nam);
345 if (error == 0)
346 error = do_sys_bind(l, SCARG(uap, s), nam);
348 return error;
352 darwin_sys_sendto(struct lwp *l, const struct darwin_sys_sendto_args *uap, register_t *retval)
354 /* {
355 syscallarg(int) s;
356 syscallarg(const void *) buf;
357 syscallarg(size_t) len;
358 syscallarg(int) flags;
359 syscallarg(struct sockaddr *) to;
360 syscallarg(unsigned int) tolen;
361 } */
363 struct msghdr msg;
364 struct iovec aiov;
365 struct mbuf *nam;
366 int error;
368 error = sockargs(&nam, SCARG(uap, to), SCARG(uap, tolen), MT_SONAME);
369 if (error != 0)
370 return error;
371 error = darwin_to_native_sockaddr(nam);
372 if (error != 0)
373 return error;
375 msg.msg_name = nam;
376 msg.msg_namelen = 0;
377 msg.msg_iov = &aiov;
378 msg.msg_iovlen = 1;
379 msg.msg_control = 0;
380 msg.msg_flags = MSG_NAMEMBUF;
381 aiov.iov_base = __UNCONST(SCARG(uap, buf)); /* XXXUNCONST kills const */
382 aiov.iov_len = SCARG(uap, len);
383 return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval);