netbsd32_socket.c revision 1.37.12.1 1 1.37.12.1 mrg /* $NetBSD: netbsd32_socket.c,v 1.37.12.1 2012/02/18 07:33:58 mrg Exp $ */
2 1.1 mrg
3 1.1 mrg /*
4 1.1 mrg * Copyright (c) 1998, 2001 Matthew R. Green
5 1.1 mrg * All rights reserved.
6 1.1 mrg *
7 1.1 mrg * Redistribution and use in source and binary forms, with or without
8 1.1 mrg * modification, are permitted provided that the following conditions
9 1.1 mrg * are met:
10 1.1 mrg * 1. Redistributions of source code must retain the above copyright
11 1.1 mrg * notice, this list of conditions and the following disclaimer.
12 1.1 mrg * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 mrg * notice, this list of conditions and the following disclaimer in the
14 1.1 mrg * documentation and/or other materials provided with the distribution.
15 1.1 mrg *
16 1.1 mrg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.1 mrg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 1.1 mrg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 1.1 mrg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 1.1 mrg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 1.1 mrg * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 1.1 mrg * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 1.1 mrg * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 1.1 mrg * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 1.1 mrg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 1.1 mrg * SUCH DAMAGE.
27 1.1 mrg */
28 1.6 lukem
29 1.6 lukem #include <sys/cdefs.h>
30 1.37.12.1 mrg __KERNEL_RCSID(0, "$NetBSD: netbsd32_socket.c,v 1.37.12.1 2012/02/18 07:33:58 mrg Exp $");
31 1.1 mrg
32 1.1 mrg #include <sys/param.h>
33 1.1 mrg #include <sys/systm.h>
34 1.1 mrg #define msg __msg /* Don't ask me! */
35 1.1 mrg #include <sys/mount.h>
36 1.1 mrg #include <sys/socket.h>
37 1.1 mrg #include <sys/sockio.h>
38 1.1 mrg #include <sys/socketvar.h>
39 1.1 mrg #include <sys/mbuf.h>
40 1.1 mrg #include <sys/ktrace.h>
41 1.1 mrg #include <sys/file.h>
42 1.1 mrg #include <sys/filedesc.h>
43 1.1 mrg #include <sys/syscallargs.h>
44 1.1 mrg #include <sys/proc.h>
45 1.15 christos #include <sys/dirent.h>
46 1.1 mrg
47 1.1 mrg #include <compat/netbsd32/netbsd32.h>
48 1.1 mrg #include <compat/netbsd32/netbsd32_syscallargs.h>
49 1.1 mrg #include <compat/netbsd32/netbsd32_conv.h>
50 1.1 mrg
51 1.37 rmind /*
52 1.37.12.1 mrg * XXX Assumes that struct sockaddr is compatible.
53 1.37 rmind */
54 1.37.12.1 mrg
55 1.37.12.1 mrg #define CMSG32_ALIGN(n) (((n) + ALIGNBYTES32) & ~ALIGNBYTES32)
56 1.37.12.1 mrg #define CMSG32_DATA(cmsg) \
57 1.37.12.1 mrg ((u_char *)(void *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr)))
58 1.37.12.1 mrg
59 1.37.12.1 mrg #define CMSG32_NXTHDR(mhdr, cmsg) \
60 1.37.12.1 mrg (((char *)(cmsg) + CMSG32_ALIGN((cmsg)->cmsg_len) + \
61 1.37.12.1 mrg CMSG32_ALIGN(sizeof(struct cmsghdr)) > \
62 1.37.12.1 mrg (((char *)(mhdr)->msg_control) + (mhdr)->msg_controllen)) ? \
63 1.37.12.1 mrg (struct cmsghdr *)0 : \
64 1.37.12.1 mrg (struct cmsghdr *)((char *)(cmsg) + \
65 1.37.12.1 mrg CMSG32_ALIGN((cmsg)->cmsg_len)))
66 1.37.12.1 mrg #define CMSG32_FIRSTHDR(mhdr) \
67 1.37.12.1 mrg ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
68 1.37.12.1 mrg (struct cmsghdr *)(mhdr)->msg_control : \
69 1.37.12.1 mrg (struct cmsghdr *)0)
70 1.37.12.1 mrg
71 1.37.12.1 mrg #define CMSG32_SPACE(l) (CMSG32_ALIGN(sizeof(struct cmsghdr)) + CMSG32_ALIGN(l))
72 1.37.12.1 mrg #define CMSG32_LEN(l) (CMSG32_ALIGN(sizeof(struct cmsghdr)) + (l))
73 1.37.12.1 mrg
74 1.37.12.1 mrg static int
75 1.37.12.1 mrg copyout32_msg_control_mbuf(struct lwp *l, struct msghdr *mp, int *len, struct mbuf *m, char **q, bool *truncated)
76 1.37.12.1 mrg {
77 1.37.12.1 mrg struct cmsghdr *cmsg, cmsg32;
78 1.37.12.1 mrg int i, j, error;
79 1.37.12.1 mrg
80 1.37.12.1 mrg *truncated = false;
81 1.37.12.1 mrg cmsg = mtod(m, struct cmsghdr *);
82 1.37.12.1 mrg do {
83 1.37.12.1 mrg if ((char *)cmsg == mtod(m, char *) + m->m_len)
84 1.37.12.1 mrg break;
85 1.37.12.1 mrg if ((char *)cmsg > mtod(m, char *) + m->m_len - sizeof(*cmsg))
86 1.37.12.1 mrg return EINVAL;
87 1.37.12.1 mrg cmsg32 = *cmsg;
88 1.37.12.1 mrg j = cmsg->cmsg_len - CMSG_LEN(0);
89 1.37.12.1 mrg i = cmsg32.cmsg_len = CMSG32_LEN(j);
90 1.37.12.1 mrg if (i > *len) {
91 1.37.12.1 mrg mp->msg_flags |= MSG_CTRUNC;
92 1.37.12.1 mrg if (cmsg->cmsg_level == SOL_SOCKET
93 1.37.12.1 mrg && cmsg->cmsg_type == SCM_RIGHTS) {
94 1.37.12.1 mrg *truncated = true;
95 1.37.12.1 mrg return 0;
96 1.37.12.1 mrg }
97 1.37.12.1 mrg j -= i - *len;
98 1.37.12.1 mrg i = *len;
99 1.37.12.1 mrg }
100 1.37.12.1 mrg
101 1.37.12.1 mrg ktrkuser("msgcontrol", cmsg, cmsg->cmsg_len);
102 1.37.12.1 mrg error = copyout(&cmsg32, *q, MAX(i, sizeof(cmsg32)));
103 1.37.12.1 mrg if (error)
104 1.37.12.1 mrg return (error);
105 1.37.12.1 mrg if (i > CMSG32_LEN(0)) {
106 1.37.12.1 mrg error = copyout(CMSG_DATA(cmsg), *q + CMSG32_LEN(0), i - CMSG32_LEN(0));
107 1.37.12.1 mrg if (error)
108 1.37.12.1 mrg return (error);
109 1.37.12.1 mrg }
110 1.37.12.1 mrg j = CMSG32_SPACE(cmsg->cmsg_len - CMSG_LEN(0));
111 1.37.12.1 mrg if (*len >= j) {
112 1.37.12.1 mrg *len -= j;
113 1.37.12.1 mrg *q += j;
114 1.37.12.1 mrg } else {
115 1.37.12.1 mrg *q += i;
116 1.37.12.1 mrg *len = 0;
117 1.37.12.1 mrg }
118 1.37.12.1 mrg cmsg = (void *)((char *)cmsg + CMSG_ALIGN(cmsg->cmsg_len));
119 1.37.12.1 mrg } while (*len > 0);
120 1.37.12.1 mrg
121 1.37.12.1 mrg return 0;
122 1.37.12.1 mrg }
123 1.37.12.1 mrg
124 1.37.12.1 mrg static int
125 1.37.12.1 mrg copyout32_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control)
126 1.37.12.1 mrg {
127 1.37.12.1 mrg int len, error = 0;
128 1.37.12.1 mrg struct mbuf *m;
129 1.37.12.1 mrg char *q;
130 1.37.12.1 mrg bool truncated;
131 1.37.12.1 mrg
132 1.37.12.1 mrg len = mp->msg_controllen;
133 1.37.12.1 mrg if (len <= 0 || control == 0) {
134 1.37.12.1 mrg mp->msg_controllen = 0;
135 1.37.12.1 mrg free_control_mbuf(l, control, control);
136 1.37.12.1 mrg return 0;
137 1.37.12.1 mrg }
138 1.37.12.1 mrg
139 1.37.12.1 mrg q = (char *)mp->msg_control;
140 1.37.12.1 mrg
141 1.37.12.1 mrg for (m = control; m != NULL; m = m->m_next) {
142 1.37.12.1 mrg error = copyout32_msg_control_mbuf(l, mp, &len, m, &q, &truncated);
143 1.37.12.1 mrg if (truncated) {
144 1.37.12.1 mrg m = control;
145 1.37.12.1 mrg break;
146 1.37.12.1 mrg }
147 1.37.12.1 mrg if (error)
148 1.37.12.1 mrg break;
149 1.37.12.1 mrg if (len <= 0)
150 1.37.12.1 mrg break;
151 1.37.12.1 mrg }
152 1.37.12.1 mrg
153 1.37.12.1 mrg free_control_mbuf(l, control, m);
154 1.37.12.1 mrg
155 1.37.12.1 mrg mp->msg_controllen = q - (char *)mp->msg_control;
156 1.37.12.1 mrg return error;
157 1.37.12.1 mrg }
158 1.1 mrg
159 1.1 mrg int
160 1.30 dsl netbsd32_recvmsg(struct lwp *l, const struct netbsd32_recvmsg_args *uap, register_t *retval)
161 1.1 mrg {
162 1.30 dsl /* {
163 1.1 mrg syscallarg(int) s;
164 1.1 mrg syscallarg(netbsd32_msghdrp_t) msg;
165 1.1 mrg syscallarg(int) flags;
166 1.30 dsl } */
167 1.37.12.1 mrg struct netbsd32_msghdr msg32;
168 1.35 njoly struct iovec aiov[UIO_SMALLIOV], *iov;
169 1.37.12.1 mrg struct msghdr msg;
170 1.37.12.1 mrg int error;
171 1.37.12.1 mrg struct mbuf *from, *control;
172 1.37 rmind size_t iovsz;
173 1.1 mrg
174 1.37.12.1 mrg error = copyin(SCARG_P32(uap, msg), &msg32, sizeof(msg32));
175 1.1 mrg if (error)
176 1.1 mrg return (error);
177 1.37.12.1 mrg
178 1.37.12.1 mrg iovsz = msg32.msg_iovlen * sizeof(struct iovec);
179 1.37.12.1 mrg if (msg32.msg_iovlen > UIO_SMALLIOV) {
180 1.37.12.1 mrg if (msg32.msg_iovlen > IOV_MAX)
181 1.1 mrg return (EMSGSIZE);
182 1.37 rmind iov = kmem_alloc(iovsz, KM_SLEEP);
183 1.25 christos } else
184 1.1 mrg iov = aiov;
185 1.37.12.1 mrg error = netbsd32_to_iovecin(NETBSD32PTR64(msg32.msg_iov), iov,
186 1.37.12.1 mrg msg32.msg_iovlen);
187 1.1 mrg if (error)
188 1.1 mrg goto done;
189 1.37.12.1 mrg
190 1.37.12.1 mrg msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
191 1.37.12.1 mrg msg.msg_name = NETBSD32PTR64(msg32.msg_name);
192 1.37.12.1 mrg msg.msg_namelen = msg32.msg_namelen;
193 1.37.12.1 mrg msg.msg_control = NETBSD32PTR64(msg32.msg_control);
194 1.37.12.1 mrg msg.msg_controllen = msg32.msg_controllen;
195 1.37.12.1 mrg msg.msg_iov = iov;
196 1.37.12.1 mrg msg.msg_iovlen = msg32.msg_iovlen;
197 1.37.12.1 mrg
198 1.37.12.1 mrg error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
199 1.37.12.1 mrg msg.msg_control != NULL ? &control : NULL, retval);
200 1.37.12.1 mrg if (error != 0)
201 1.37.12.1 mrg goto done;
202 1.37.12.1 mrg
203 1.37.12.1 mrg if (msg.msg_control != NULL)
204 1.37.12.1 mrg error = copyout32_msg_control(l, &msg, control);
205 1.37.12.1 mrg
206 1.37.12.1 mrg if (error == 0)
207 1.37.12.1 mrg error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0,
208 1.37.12.1 mrg from);
209 1.37.12.1 mrg if (from != NULL)
210 1.37.12.1 mrg m_free(from);
211 1.37.12.1 mrg if (error == 0) {
212 1.37.12.1 mrg ktrkuser("msghdr", &msg, sizeof msg);
213 1.37.12.1 mrg msg32.msg_namelen = msg.msg_namelen;
214 1.37.12.1 mrg msg32.msg_controllen = msg.msg_controllen;
215 1.37.12.1 mrg msg32.msg_flags = msg.msg_flags;
216 1.37.12.1 mrg error = copyout(&msg32, SCARG_P32(uap, msg), sizeof(msg32));
217 1.1 mrg }
218 1.37.12.1 mrg
219 1.37.12.1 mrg done:
220 1.1 mrg if (iov != aiov)
221 1.37 rmind kmem_free(iov, iovsz);
222 1.1 mrg return (error);
223 1.1 mrg }
224 1.1 mrg
225 1.37.12.1 mrg static int
226 1.37.12.1 mrg copyin32_msg_control(struct lwp *l, struct msghdr *mp)
227 1.1 mrg {
228 1.37.12.1 mrg /*
229 1.37.12.1 mrg * Handle cmsg if there is any.
230 1.37.12.1 mrg */
231 1.37.12.1 mrg struct cmsghdr *cmsg, cmsg32, *cc;
232 1.37.12.1 mrg struct mbuf *ctl_mbuf;
233 1.37.12.1 mrg ssize_t resid = mp->msg_controllen;
234 1.37.12.1 mrg size_t clen, cidx = 0, cspace;
235 1.37.12.1 mrg u_int8_t *control;
236 1.37.12.1 mrg int error;
237 1.37.12.1 mrg
238 1.37.12.1 mrg ctl_mbuf = m_get(M_WAIT, MT_CONTROL);
239 1.37.12.1 mrg clen = MLEN;
240 1.37.12.1 mrg control = mtod(ctl_mbuf, void *);
241 1.37.12.1 mrg memset(control, 0, clen);
242 1.37.12.1 mrg
243 1.37.12.1 mrg cc = CMSG32_FIRSTHDR(mp);
244 1.37.12.1 mrg do {
245 1.37.12.1 mrg error = copyin(cc, &cmsg32, sizeof(cmsg32));
246 1.37.12.1 mrg if (error)
247 1.37.12.1 mrg goto failure;
248 1.13 perry
249 1.1 mrg /*
250 1.37.12.1 mrg * Sanity check the control message length.
251 1.1 mrg */
252 1.37.12.1 mrg if (cmsg32.cmsg_len > resid ||
253 1.37.12.1 mrg cmsg32.cmsg_len < sizeof(cmsg32)) {
254 1.1 mrg error = EINVAL;
255 1.37.12.1 mrg goto failure;
256 1.1 mrg }
257 1.1 mrg
258 1.37.12.1 mrg cspace = CMSG_SPACE(cmsg32.cmsg_len - CMSG32_LEN(0));
259 1.27 ad
260 1.37.12.1 mrg /* Check the buffer is big enough */
261 1.37.12.1 mrg if (__predict_false(cidx + cspace > clen)) {
262 1.37.12.1 mrg u_int8_t *nc;
263 1.37.12.1 mrg size_t nclen;
264 1.37.12.1 mrg
265 1.37.12.1 mrg nclen = cidx + cspace;
266 1.37.12.1 mrg if (nclen >= PAGE_SIZE) {
267 1.37.12.1 mrg error = EINVAL;
268 1.37.12.1 mrg goto failure;
269 1.37.12.1 mrg }
270 1.37.12.1 mrg nc = realloc(clen <= MLEN ? NULL : control,
271 1.37.12.1 mrg nclen, M_TEMP, M_WAITOK);
272 1.37.12.1 mrg if (!nc) {
273 1.37.12.1 mrg error = ENOMEM;
274 1.37.12.1 mrg goto failure;
275 1.37.12.1 mrg }
276 1.37.12.1 mrg if (cidx <= MLEN) {
277 1.37.12.1 mrg /* Old buffer was in mbuf... */
278 1.37.12.1 mrg memcpy(nc, control, cidx);
279 1.37.12.1 mrg memset(nc + cidx, 0, nclen - cidx);
280 1.37.12.1 mrg } else {
281 1.37.12.1 mrg memset(nc + nclen, 0, nclen - clen);
282 1.37.12.1 mrg }
283 1.37.12.1 mrg control = nc;
284 1.37.12.1 mrg clen = nclen;
285 1.37.12.1 mrg }
286 1.27 ad
287 1.37.12.1 mrg /* Copy header */
288 1.37.12.1 mrg cmsg = (void *)&control[cidx];
289 1.37.12.1 mrg cmsg->cmsg_len = CMSG_LEN(cmsg32.cmsg_len - CMSG32_LEN(0));
290 1.37.12.1 mrg cmsg->cmsg_level = cmsg32.cmsg_level;
291 1.37.12.1 mrg cmsg->cmsg_type = cmsg32.cmsg_type;
292 1.37.12.1 mrg
293 1.37.12.1 mrg /* Copyin the data */
294 1.37.12.1 mrg error = copyin(CMSG32_DATA(cc), CMSG_DATA(cmsg),
295 1.37.12.1 mrg cmsg32.cmsg_len - CMSG32_LEN(0));
296 1.37.12.1 mrg if (error)
297 1.37.12.1 mrg goto failure;
298 1.27 ad
299 1.37.12.1 mrg resid -= CMSG32_ALIGN(cmsg32.cmsg_len);
300 1.37.12.1 mrg cidx += cmsg->cmsg_len;
301 1.37.12.1 mrg } while ((cc = CMSG32_NXTHDR(mp, cc)) && resid > 0);
302 1.37.12.1 mrg
303 1.37.12.1 mrg /* If we allocated a buffer, attach to mbuf */
304 1.37.12.1 mrg if (cidx > MLEN) {
305 1.37.12.1 mrg MEXTADD(ctl_mbuf, control, clen, M_MBUF, NULL, NULL);
306 1.37.12.1 mrg ctl_mbuf->m_flags |= M_EXT_RW;
307 1.1 mrg }
308 1.37.12.1 mrg control = NULL;
309 1.37.12.1 mrg mp->msg_controllen = ctl_mbuf->m_len = CMSG_ALIGN(cidx);
310 1.37.12.1 mrg
311 1.37.12.1 mrg mp->msg_control = ctl_mbuf;
312 1.37.12.1 mrg mp->msg_flags |= MSG_CONTROLMBUF;
313 1.37.12.1 mrg
314 1.37.12.1 mrg ktrkuser("msgcontrol", mtod(ctl_mbuf, void *),
315 1.37.12.1 mrg mp->msg_controllen);
316 1.37.12.1 mrg
317 1.37.12.1 mrg return 0;
318 1.37.12.1 mrg
319 1.37.12.1 mrg failure:
320 1.37.12.1 mrg if (control != mtod(ctl_mbuf, void *))
321 1.37.12.1 mrg free(control, M_MBUF);
322 1.37.12.1 mrg m_free(ctl_mbuf);
323 1.37.12.1 mrg return error;
324 1.1 mrg }
325 1.1 mrg
326 1.1 mrg int
327 1.30 dsl netbsd32_sendmsg(struct lwp *l, const struct netbsd32_sendmsg_args *uap, register_t *retval)
328 1.1 mrg {
329 1.30 dsl /* {
330 1.1 mrg syscallarg(int) s;
331 1.1 mrg syscallarg(const netbsd32_msghdrp_t) msg;
332 1.1 mrg syscallarg(int) flags;
333 1.30 dsl } */
334 1.1 mrg struct msghdr msg;
335 1.1 mrg struct netbsd32_msghdr msg32;
336 1.1 mrg struct iovec aiov[UIO_SMALLIOV], *iov;
337 1.35 njoly struct netbsd32_iovec *iov32;
338 1.37 rmind size_t iovsz;
339 1.1 mrg int error;
340 1.1 mrg
341 1.24 dsl error = copyin(SCARG_P32(uap, msg), &msg32, sizeof(msg32));
342 1.1 mrg if (error)
343 1.1 mrg return (error);
344 1.1 mrg netbsd32_to_msghdr(&msg32, &msg);
345 1.37.12.1 mrg msg.msg_flags = 0;
346 1.37.12.1 mrg
347 1.37.12.1 mrg if (CMSG32_FIRSTHDR(&msg)) {
348 1.37.12.1 mrg error = copyin32_msg_control(l, &msg);
349 1.37.12.1 mrg if (error)
350 1.37.12.1 mrg return (error);
351 1.37.12.1 mrg } else {
352 1.37.12.1 mrg msg.msg_control = NULL;
353 1.37.12.1 mrg msg.msg_controllen = 0;
354 1.37.12.1 mrg }
355 1.26 dsl
356 1.37 rmind iovsz = msg.msg_iovlen * sizeof(struct iovec);
357 1.1 mrg if ((u_int)msg.msg_iovlen > UIO_SMALLIOV) {
358 1.1 mrg if ((u_int)msg.msg_iovlen > IOV_MAX)
359 1.1 mrg return (EMSGSIZE);
360 1.37 rmind iov = kmem_alloc(iovsz, KM_SLEEP);
361 1.36 njoly } else
362 1.1 mrg iov = aiov;
363 1.26 dsl
364 1.35 njoly iov32 = NETBSD32PTR64(msg32.msg_iov);
365 1.35 njoly error = netbsd32_to_iovecin(iov32, iov, msg.msg_iovlen);
366 1.1 mrg if (error)
367 1.1 mrg goto done;
368 1.1 mrg msg.msg_iov = iov;
369 1.26 dsl
370 1.26 dsl error = do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
371 1.1 mrg done:
372 1.1 mrg if (iov != aiov)
373 1.37 rmind kmem_free(iov, iovsz);
374 1.1 mrg return (error);
375 1.1 mrg }
376 1.1 mrg
377 1.1 mrg int
378 1.30 dsl netbsd32_recvfrom(struct lwp *l, const struct netbsd32_recvfrom_args *uap, register_t *retval)
379 1.1 mrg {
380 1.30 dsl /* {
381 1.1 mrg syscallarg(int) s;
382 1.1 mrg syscallarg(netbsd32_voidp) buf;
383 1.1 mrg syscallarg(netbsd32_size_t) len;
384 1.1 mrg syscallarg(int) flags;
385 1.1 mrg syscallarg(netbsd32_sockaddrp_t) from;
386 1.1 mrg syscallarg(netbsd32_intp) fromlenaddr;
387 1.30 dsl } */
388 1.37.12.1 mrg struct msghdr msg;
389 1.37.12.1 mrg struct iovec aiov;
390 1.37.12.1 mrg int error;
391 1.37.12.1 mrg struct mbuf *from;
392 1.1 mrg
393 1.37.12.1 mrg msg.msg_name = NULL;
394 1.37.12.1 mrg msg.msg_iov = &aiov;
395 1.1 mrg msg.msg_iovlen = 1;
396 1.24 dsl aiov.iov_base = SCARG_P32(uap, buf);
397 1.37.12.1 mrg aiov.iov_len = SCARG(uap, len);
398 1.37.12.1 mrg msg.msg_control = NULL;
399 1.37.12.1 mrg msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
400 1.37.12.1 mrg
401 1.37.12.1 mrg error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval);
402 1.37.12.1 mrg if (error != 0)
403 1.37.12.1 mrg return error;
404 1.37.12.1 mrg
405 1.37.12.1 mrg error = copyout_sockname(SCARG_P32(uap, from), SCARG_P32(uap, fromlenaddr),
406 1.37.12.1 mrg MSG_LENUSRSPACE, from);
407 1.37.12.1 mrg if (from != NULL)
408 1.37.12.1 mrg m_free(from);
409 1.37.12.1 mrg return error;
410 1.1 mrg }
411 1.1 mrg
412 1.1 mrg int
413 1.30 dsl netbsd32_sendto(struct lwp *l, const struct netbsd32_sendto_args *uap, register_t *retval)
414 1.1 mrg {
415 1.30 dsl /* {
416 1.1 mrg syscallarg(int) s;
417 1.1 mrg syscallarg(const netbsd32_voidp) buf;
418 1.1 mrg syscallarg(netbsd32_size_t) len;
419 1.1 mrg syscallarg(int) flags;
420 1.1 mrg syscallarg(const netbsd32_sockaddrp_t) to;
421 1.1 mrg syscallarg(int) tolen;
422 1.30 dsl } */
423 1.1 mrg struct msghdr msg;
424 1.1 mrg struct iovec aiov;
425 1.1 mrg
426 1.24 dsl msg.msg_name = SCARG_P32(uap, to); /* XXX kills const */
427 1.1 mrg msg.msg_namelen = SCARG(uap, tolen);
428 1.1 mrg msg.msg_iov = &aiov;
429 1.1 mrg msg.msg_iovlen = 1;
430 1.1 mrg msg.msg_control = 0;
431 1.24 dsl aiov.iov_base = SCARG_P32(uap, buf); /* XXX kills const */
432 1.1 mrg aiov.iov_len = SCARG(uap, len);
433 1.26 dsl msg.msg_flags = 0;
434 1.26 dsl return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
435 1.1 mrg }
436