netbsd32_socket.c revision 1.37.8.2 1 1.37.8.2 yamt /* $NetBSD: netbsd32_socket.c,v 1.37.8.2 2012/10/30 17:20:47 yamt 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.8.2 yamt __KERNEL_RCSID(0, "$NetBSD: netbsd32_socket.c,v 1.37.8.2 2012/10/30 17:20:47 yamt 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.8.1 yamt * XXX Assumes that struct sockaddr is compatible.
53 1.37 rmind */
54 1.37.8.1 yamt
55 1.37.8.1 yamt #define CMSG32_ALIGN(n) (((n) + ALIGNBYTES32) & ~ALIGNBYTES32)
56 1.37.8.1 yamt #define CMSG32_DATA(cmsg) \
57 1.37.8.1 yamt ((u_char *)(void *)(cmsg) + CMSG32_ALIGN(sizeof(struct cmsghdr)))
58 1.37.8.1 yamt
59 1.37.8.1 yamt #define CMSG32_NXTHDR(mhdr, cmsg) \
60 1.37.8.1 yamt (((char *)(cmsg) + CMSG32_ALIGN((cmsg)->cmsg_len) + \
61 1.37.8.1 yamt CMSG32_ALIGN(sizeof(struct cmsghdr)) > \
62 1.37.8.1 yamt (((char *)(mhdr)->msg_control) + (mhdr)->msg_controllen)) ? \
63 1.37.8.1 yamt (struct cmsghdr *)0 : \
64 1.37.8.1 yamt (struct cmsghdr *)((char *)(cmsg) + \
65 1.37.8.1 yamt CMSG32_ALIGN((cmsg)->cmsg_len)))
66 1.37.8.1 yamt #define CMSG32_FIRSTHDR(mhdr) \
67 1.37.8.1 yamt ((mhdr)->msg_controllen >= sizeof(struct cmsghdr) ? \
68 1.37.8.1 yamt (struct cmsghdr *)(mhdr)->msg_control : \
69 1.37.8.1 yamt (struct cmsghdr *)0)
70 1.37.8.1 yamt
71 1.37.8.1 yamt #define CMSG32_SPACE(l) (CMSG32_ALIGN(sizeof(struct cmsghdr)) + CMSG32_ALIGN(l))
72 1.37.8.1 yamt #define CMSG32_LEN(l) (CMSG32_ALIGN(sizeof(struct cmsghdr)) + (l))
73 1.37.8.1 yamt
74 1.37.8.1 yamt static int
75 1.37.8.1 yamt copyout32_msg_control_mbuf(struct lwp *l, struct msghdr *mp, int *len, struct mbuf *m, char **q, bool *truncated)
76 1.37.8.1 yamt {
77 1.37.8.1 yamt struct cmsghdr *cmsg, cmsg32;
78 1.37.8.1 yamt int i, j, error;
79 1.37.8.1 yamt
80 1.37.8.1 yamt *truncated = false;
81 1.37.8.1 yamt cmsg = mtod(m, struct cmsghdr *);
82 1.37.8.1 yamt do {
83 1.37.8.1 yamt if ((char *)cmsg == mtod(m, char *) + m->m_len)
84 1.37.8.1 yamt break;
85 1.37.8.1 yamt if ((char *)cmsg > mtod(m, char *) + m->m_len - sizeof(*cmsg))
86 1.37.8.1 yamt return EINVAL;
87 1.37.8.1 yamt cmsg32 = *cmsg;
88 1.37.8.1 yamt j = cmsg->cmsg_len - CMSG_LEN(0);
89 1.37.8.1 yamt i = cmsg32.cmsg_len = CMSG32_LEN(j);
90 1.37.8.1 yamt if (i > *len) {
91 1.37.8.1 yamt mp->msg_flags |= MSG_CTRUNC;
92 1.37.8.1 yamt if (cmsg->cmsg_level == SOL_SOCKET
93 1.37.8.1 yamt && cmsg->cmsg_type == SCM_RIGHTS) {
94 1.37.8.1 yamt *truncated = true;
95 1.37.8.1 yamt return 0;
96 1.37.8.1 yamt }
97 1.37.8.1 yamt j -= i - *len;
98 1.37.8.1 yamt i = *len;
99 1.37.8.1 yamt }
100 1.37.8.1 yamt
101 1.37.8.1 yamt ktrkuser("msgcontrol", cmsg, cmsg->cmsg_len);
102 1.37.8.1 yamt error = copyout(&cmsg32, *q, MAX(i, sizeof(cmsg32)));
103 1.37.8.1 yamt if (error)
104 1.37.8.1 yamt return (error);
105 1.37.8.1 yamt if (i > CMSG32_LEN(0)) {
106 1.37.8.1 yamt error = copyout(CMSG_DATA(cmsg), *q + CMSG32_LEN(0), i - CMSG32_LEN(0));
107 1.37.8.1 yamt if (error)
108 1.37.8.1 yamt return (error);
109 1.37.8.1 yamt }
110 1.37.8.1 yamt j = CMSG32_SPACE(cmsg->cmsg_len - CMSG_LEN(0));
111 1.37.8.1 yamt if (*len >= j) {
112 1.37.8.1 yamt *len -= j;
113 1.37.8.1 yamt *q += j;
114 1.37.8.1 yamt } else {
115 1.37.8.1 yamt *q += i;
116 1.37.8.1 yamt *len = 0;
117 1.37.8.1 yamt }
118 1.37.8.1 yamt cmsg = (void *)((char *)cmsg + CMSG_ALIGN(cmsg->cmsg_len));
119 1.37.8.1 yamt } while (*len > 0);
120 1.37.8.1 yamt
121 1.37.8.1 yamt return 0;
122 1.37.8.1 yamt }
123 1.37.8.1 yamt
124 1.37.8.1 yamt static int
125 1.37.8.1 yamt copyout32_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control)
126 1.37.8.1 yamt {
127 1.37.8.1 yamt int len, error = 0;
128 1.37.8.1 yamt struct mbuf *m;
129 1.37.8.1 yamt char *q;
130 1.37.8.1 yamt bool truncated;
131 1.37.8.1 yamt
132 1.37.8.1 yamt len = mp->msg_controllen;
133 1.37.8.1 yamt if (len <= 0 || control == 0) {
134 1.37.8.1 yamt mp->msg_controllen = 0;
135 1.37.8.1 yamt free_control_mbuf(l, control, control);
136 1.37.8.1 yamt return 0;
137 1.37.8.1 yamt }
138 1.37.8.1 yamt
139 1.37.8.1 yamt q = (char *)mp->msg_control;
140 1.37.8.1 yamt
141 1.37.8.2 yamt for (m = control; len > 0 && m != NULL; m = m->m_next) {
142 1.37.8.1 yamt error = copyout32_msg_control_mbuf(l, mp, &len, m, &q, &truncated);
143 1.37.8.1 yamt if (truncated) {
144 1.37.8.1 yamt m = control;
145 1.37.8.1 yamt break;
146 1.37.8.1 yamt }
147 1.37.8.1 yamt if (error)
148 1.37.8.1 yamt break;
149 1.37.8.1 yamt }
150 1.37.8.1 yamt
151 1.37.8.1 yamt free_control_mbuf(l, control, m);
152 1.37.8.1 yamt
153 1.37.8.1 yamt mp->msg_controllen = q - (char *)mp->msg_control;
154 1.37.8.1 yamt return error;
155 1.37.8.1 yamt }
156 1.1 mrg
157 1.1 mrg int
158 1.30 dsl netbsd32_recvmsg(struct lwp *l, const struct netbsd32_recvmsg_args *uap, register_t *retval)
159 1.1 mrg {
160 1.30 dsl /* {
161 1.1 mrg syscallarg(int) s;
162 1.1 mrg syscallarg(netbsd32_msghdrp_t) msg;
163 1.1 mrg syscallarg(int) flags;
164 1.30 dsl } */
165 1.37.8.1 yamt struct netbsd32_msghdr msg32;
166 1.35 njoly struct iovec aiov[UIO_SMALLIOV], *iov;
167 1.37.8.1 yamt struct msghdr msg;
168 1.37.8.1 yamt int error;
169 1.37.8.1 yamt struct mbuf *from, *control;
170 1.37 rmind size_t iovsz;
171 1.1 mrg
172 1.37.8.1 yamt error = copyin(SCARG_P32(uap, msg), &msg32, sizeof(msg32));
173 1.1 mrg if (error)
174 1.1 mrg return (error);
175 1.37.8.1 yamt
176 1.37.8.1 yamt iovsz = msg32.msg_iovlen * sizeof(struct iovec);
177 1.37.8.1 yamt if (msg32.msg_iovlen > UIO_SMALLIOV) {
178 1.37.8.1 yamt if (msg32.msg_iovlen > IOV_MAX)
179 1.1 mrg return (EMSGSIZE);
180 1.37 rmind iov = kmem_alloc(iovsz, KM_SLEEP);
181 1.25 christos } else
182 1.1 mrg iov = aiov;
183 1.37.8.1 yamt error = netbsd32_to_iovecin(NETBSD32PTR64(msg32.msg_iov), iov,
184 1.37.8.1 yamt msg32.msg_iovlen);
185 1.1 mrg if (error)
186 1.1 mrg goto done;
187 1.37.8.1 yamt
188 1.37.8.1 yamt msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
189 1.37.8.1 yamt msg.msg_name = NETBSD32PTR64(msg32.msg_name);
190 1.37.8.1 yamt msg.msg_namelen = msg32.msg_namelen;
191 1.37.8.1 yamt msg.msg_control = NETBSD32PTR64(msg32.msg_control);
192 1.37.8.1 yamt msg.msg_controllen = msg32.msg_controllen;
193 1.37.8.1 yamt msg.msg_iov = iov;
194 1.37.8.1 yamt msg.msg_iovlen = msg32.msg_iovlen;
195 1.37.8.1 yamt
196 1.37.8.1 yamt error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
197 1.37.8.1 yamt msg.msg_control != NULL ? &control : NULL, retval);
198 1.37.8.1 yamt if (error != 0)
199 1.37.8.1 yamt goto done;
200 1.37.8.1 yamt
201 1.37.8.1 yamt if (msg.msg_control != NULL)
202 1.37.8.1 yamt error = copyout32_msg_control(l, &msg, control);
203 1.37.8.1 yamt
204 1.37.8.1 yamt if (error == 0)
205 1.37.8.1 yamt error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0,
206 1.37.8.1 yamt from);
207 1.37.8.1 yamt if (from != NULL)
208 1.37.8.1 yamt m_free(from);
209 1.37.8.1 yamt if (error == 0) {
210 1.37.8.1 yamt ktrkuser("msghdr", &msg, sizeof msg);
211 1.37.8.1 yamt msg32.msg_namelen = msg.msg_namelen;
212 1.37.8.1 yamt msg32.msg_controllen = msg.msg_controllen;
213 1.37.8.1 yamt msg32.msg_flags = msg.msg_flags;
214 1.37.8.1 yamt error = copyout(&msg32, SCARG_P32(uap, msg), sizeof(msg32));
215 1.1 mrg }
216 1.37.8.1 yamt
217 1.37.8.1 yamt done:
218 1.1 mrg if (iov != aiov)
219 1.37 rmind kmem_free(iov, iovsz);
220 1.1 mrg return (error);
221 1.1 mrg }
222 1.1 mrg
223 1.37.8.1 yamt static int
224 1.37.8.1 yamt copyin32_msg_control(struct lwp *l, struct msghdr *mp)
225 1.1 mrg {
226 1.37.8.1 yamt /*
227 1.37.8.1 yamt * Handle cmsg if there is any.
228 1.37.8.1 yamt */
229 1.37.8.1 yamt struct cmsghdr *cmsg, cmsg32, *cc;
230 1.37.8.1 yamt struct mbuf *ctl_mbuf;
231 1.37.8.1 yamt ssize_t resid = mp->msg_controllen;
232 1.37.8.1 yamt size_t clen, cidx = 0, cspace;
233 1.37.8.1 yamt u_int8_t *control;
234 1.37.8.1 yamt int error;
235 1.37.8.1 yamt
236 1.37.8.1 yamt ctl_mbuf = m_get(M_WAIT, MT_CONTROL);
237 1.37.8.1 yamt clen = MLEN;
238 1.37.8.1 yamt control = mtod(ctl_mbuf, void *);
239 1.37.8.1 yamt memset(control, 0, clen);
240 1.37.8.1 yamt
241 1.37.8.1 yamt cc = CMSG32_FIRSTHDR(mp);
242 1.37.8.1 yamt do {
243 1.37.8.1 yamt error = copyin(cc, &cmsg32, sizeof(cmsg32));
244 1.37.8.1 yamt if (error)
245 1.37.8.1 yamt goto failure;
246 1.13 perry
247 1.1 mrg /*
248 1.37.8.1 yamt * Sanity check the control message length.
249 1.1 mrg */
250 1.37.8.1 yamt if (cmsg32.cmsg_len > resid ||
251 1.37.8.1 yamt cmsg32.cmsg_len < sizeof(cmsg32)) {
252 1.1 mrg error = EINVAL;
253 1.37.8.1 yamt goto failure;
254 1.1 mrg }
255 1.1 mrg
256 1.37.8.1 yamt cspace = CMSG_SPACE(cmsg32.cmsg_len - CMSG32_LEN(0));
257 1.27 ad
258 1.37.8.1 yamt /* Check the buffer is big enough */
259 1.37.8.1 yamt if (__predict_false(cidx + cspace > clen)) {
260 1.37.8.1 yamt u_int8_t *nc;
261 1.37.8.1 yamt size_t nclen;
262 1.37.8.1 yamt
263 1.37.8.1 yamt nclen = cidx + cspace;
264 1.37.8.1 yamt if (nclen >= PAGE_SIZE) {
265 1.37.8.1 yamt error = EINVAL;
266 1.37.8.1 yamt goto failure;
267 1.37.8.1 yamt }
268 1.37.8.1 yamt nc = realloc(clen <= MLEN ? NULL : control,
269 1.37.8.1 yamt nclen, M_TEMP, M_WAITOK);
270 1.37.8.1 yamt if (!nc) {
271 1.37.8.1 yamt error = ENOMEM;
272 1.37.8.1 yamt goto failure;
273 1.37.8.1 yamt }
274 1.37.8.1 yamt if (cidx <= MLEN) {
275 1.37.8.1 yamt /* Old buffer was in mbuf... */
276 1.37.8.1 yamt memcpy(nc, control, cidx);
277 1.37.8.1 yamt memset(nc + cidx, 0, nclen - cidx);
278 1.37.8.1 yamt } else {
279 1.37.8.1 yamt memset(nc + nclen, 0, nclen - clen);
280 1.37.8.1 yamt }
281 1.37.8.1 yamt control = nc;
282 1.37.8.1 yamt clen = nclen;
283 1.37.8.1 yamt }
284 1.27 ad
285 1.37.8.1 yamt /* Copy header */
286 1.37.8.1 yamt cmsg = (void *)&control[cidx];
287 1.37.8.1 yamt cmsg->cmsg_len = CMSG_LEN(cmsg32.cmsg_len - CMSG32_LEN(0));
288 1.37.8.1 yamt cmsg->cmsg_level = cmsg32.cmsg_level;
289 1.37.8.1 yamt cmsg->cmsg_type = cmsg32.cmsg_type;
290 1.37.8.1 yamt
291 1.37.8.1 yamt /* Copyin the data */
292 1.37.8.1 yamt error = copyin(CMSG32_DATA(cc), CMSG_DATA(cmsg),
293 1.37.8.1 yamt cmsg32.cmsg_len - CMSG32_LEN(0));
294 1.37.8.1 yamt if (error)
295 1.37.8.1 yamt goto failure;
296 1.27 ad
297 1.37.8.1 yamt resid -= CMSG32_ALIGN(cmsg32.cmsg_len);
298 1.37.8.1 yamt cidx += cmsg->cmsg_len;
299 1.37.8.2 yamt } while (resid > 0 && (cc = CMSG32_NXTHDR(mp, &cmsg32)));
300 1.37.8.1 yamt
301 1.37.8.1 yamt /* If we allocated a buffer, attach to mbuf */
302 1.37.8.1 yamt if (cidx > MLEN) {
303 1.37.8.1 yamt MEXTADD(ctl_mbuf, control, clen, M_MBUF, NULL, NULL);
304 1.37.8.1 yamt ctl_mbuf->m_flags |= M_EXT_RW;
305 1.1 mrg }
306 1.37.8.1 yamt control = NULL;
307 1.37.8.1 yamt mp->msg_controllen = ctl_mbuf->m_len = CMSG_ALIGN(cidx);
308 1.37.8.1 yamt
309 1.37.8.1 yamt mp->msg_control = ctl_mbuf;
310 1.37.8.1 yamt mp->msg_flags |= MSG_CONTROLMBUF;
311 1.37.8.1 yamt
312 1.37.8.1 yamt ktrkuser("msgcontrol", mtod(ctl_mbuf, void *),
313 1.37.8.1 yamt mp->msg_controllen);
314 1.37.8.1 yamt
315 1.37.8.1 yamt return 0;
316 1.37.8.1 yamt
317 1.37.8.1 yamt failure:
318 1.37.8.1 yamt if (control != mtod(ctl_mbuf, void *))
319 1.37.8.1 yamt free(control, M_MBUF);
320 1.37.8.1 yamt m_free(ctl_mbuf);
321 1.37.8.1 yamt return error;
322 1.1 mrg }
323 1.1 mrg
324 1.1 mrg int
325 1.30 dsl netbsd32_sendmsg(struct lwp *l, const struct netbsd32_sendmsg_args *uap, register_t *retval)
326 1.1 mrg {
327 1.30 dsl /* {
328 1.1 mrg syscallarg(int) s;
329 1.1 mrg syscallarg(const netbsd32_msghdrp_t) msg;
330 1.1 mrg syscallarg(int) flags;
331 1.30 dsl } */
332 1.1 mrg struct msghdr msg;
333 1.1 mrg struct netbsd32_msghdr msg32;
334 1.1 mrg struct iovec aiov[UIO_SMALLIOV], *iov;
335 1.35 njoly struct netbsd32_iovec *iov32;
336 1.37 rmind size_t iovsz;
337 1.1 mrg int error;
338 1.1 mrg
339 1.24 dsl error = copyin(SCARG_P32(uap, msg), &msg32, sizeof(msg32));
340 1.1 mrg if (error)
341 1.1 mrg return (error);
342 1.1 mrg netbsd32_to_msghdr(&msg32, &msg);
343 1.37.8.1 yamt msg.msg_flags = 0;
344 1.37.8.1 yamt
345 1.37.8.1 yamt if (CMSG32_FIRSTHDR(&msg)) {
346 1.37.8.1 yamt error = copyin32_msg_control(l, &msg);
347 1.37.8.1 yamt if (error)
348 1.37.8.1 yamt return (error);
349 1.37.8.1 yamt } else {
350 1.37.8.1 yamt msg.msg_control = NULL;
351 1.37.8.1 yamt msg.msg_controllen = 0;
352 1.37.8.1 yamt }
353 1.26 dsl
354 1.37 rmind iovsz = msg.msg_iovlen * sizeof(struct iovec);
355 1.1 mrg if ((u_int)msg.msg_iovlen > UIO_SMALLIOV) {
356 1.1 mrg if ((u_int)msg.msg_iovlen > IOV_MAX)
357 1.1 mrg return (EMSGSIZE);
358 1.37 rmind iov = kmem_alloc(iovsz, KM_SLEEP);
359 1.36 njoly } else
360 1.1 mrg iov = aiov;
361 1.26 dsl
362 1.35 njoly iov32 = NETBSD32PTR64(msg32.msg_iov);
363 1.35 njoly error = netbsd32_to_iovecin(iov32, iov, msg.msg_iovlen);
364 1.1 mrg if (error)
365 1.1 mrg goto done;
366 1.1 mrg msg.msg_iov = iov;
367 1.26 dsl
368 1.26 dsl error = do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
369 1.1 mrg done:
370 1.1 mrg if (iov != aiov)
371 1.37 rmind kmem_free(iov, iovsz);
372 1.1 mrg return (error);
373 1.1 mrg }
374 1.1 mrg
375 1.1 mrg int
376 1.30 dsl netbsd32_recvfrom(struct lwp *l, const struct netbsd32_recvfrom_args *uap, register_t *retval)
377 1.1 mrg {
378 1.30 dsl /* {
379 1.1 mrg syscallarg(int) s;
380 1.1 mrg syscallarg(netbsd32_voidp) buf;
381 1.1 mrg syscallarg(netbsd32_size_t) len;
382 1.1 mrg syscallarg(int) flags;
383 1.1 mrg syscallarg(netbsd32_sockaddrp_t) from;
384 1.1 mrg syscallarg(netbsd32_intp) fromlenaddr;
385 1.30 dsl } */
386 1.37.8.1 yamt struct msghdr msg;
387 1.37.8.1 yamt struct iovec aiov;
388 1.37.8.1 yamt int error;
389 1.37.8.1 yamt struct mbuf *from;
390 1.1 mrg
391 1.37.8.1 yamt msg.msg_name = NULL;
392 1.37.8.1 yamt msg.msg_iov = &aiov;
393 1.1 mrg msg.msg_iovlen = 1;
394 1.24 dsl aiov.iov_base = SCARG_P32(uap, buf);
395 1.37.8.1 yamt aiov.iov_len = SCARG(uap, len);
396 1.37.8.1 yamt msg.msg_control = NULL;
397 1.37.8.1 yamt msg.msg_flags = SCARG(uap, flags) & MSG_USERFLAGS;
398 1.37.8.1 yamt
399 1.37.8.1 yamt error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, NULL, retval);
400 1.37.8.1 yamt if (error != 0)
401 1.37.8.1 yamt return error;
402 1.37.8.1 yamt
403 1.37.8.1 yamt error = copyout_sockname(SCARG_P32(uap, from), SCARG_P32(uap, fromlenaddr),
404 1.37.8.1 yamt MSG_LENUSRSPACE, from);
405 1.37.8.1 yamt if (from != NULL)
406 1.37.8.1 yamt m_free(from);
407 1.37.8.1 yamt return error;
408 1.1 mrg }
409 1.1 mrg
410 1.1 mrg int
411 1.30 dsl netbsd32_sendto(struct lwp *l, const struct netbsd32_sendto_args *uap, register_t *retval)
412 1.1 mrg {
413 1.30 dsl /* {
414 1.1 mrg syscallarg(int) s;
415 1.1 mrg syscallarg(const netbsd32_voidp) buf;
416 1.1 mrg syscallarg(netbsd32_size_t) len;
417 1.1 mrg syscallarg(int) flags;
418 1.1 mrg syscallarg(const netbsd32_sockaddrp_t) to;
419 1.1 mrg syscallarg(int) tolen;
420 1.30 dsl } */
421 1.1 mrg struct msghdr msg;
422 1.1 mrg struct iovec aiov;
423 1.1 mrg
424 1.24 dsl msg.msg_name = SCARG_P32(uap, to); /* XXX kills const */
425 1.1 mrg msg.msg_namelen = SCARG(uap, tolen);
426 1.1 mrg msg.msg_iov = &aiov;
427 1.1 mrg msg.msg_iovlen = 1;
428 1.1 mrg msg.msg_control = 0;
429 1.24 dsl aiov.iov_base = SCARG_P32(uap, buf); /* XXX kills const */
430 1.1 mrg aiov.iov_len = SCARG(uap, len);
431 1.26 dsl msg.msg_flags = 0;
432 1.26 dsl return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags), retval);
433 1.1 mrg }
434