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