xref: /netbsd-src/sys/compat/common/uipc_syscalls_43.c (revision d91f98a8715141154279122ae81737cb65179572)
1*d91f98a8Spgoyette /*	$NetBSD: uipc_syscalls_43.c,v 1.51 2019/01/27 02:08:39 pgoyette Exp $	*/
2dcb2a50bSchristos 
3dcb2a50bSchristos /*
4dcb2a50bSchristos  * Copyright (c) 1982, 1986, 1989, 1990, 1993
5dcb2a50bSchristos  *	The Regents of the University of California.  All rights reserved.
6dcb2a50bSchristos  *
7dcb2a50bSchristos  * Redistribution and use in source and binary forms, with or without
8dcb2a50bSchristos  * modification, are permitted provided that the following conditions
9dcb2a50bSchristos  * are met:
10dcb2a50bSchristos  * 1. Redistributions of source code must retain the above copyright
11dcb2a50bSchristos  *    notice, this list of conditions and the following disclaimer.
12dcb2a50bSchristos  * 2. Redistributions in binary form must reproduce the above copyright
13dcb2a50bSchristos  *    notice, this list of conditions and the following disclaimer in the
14dcb2a50bSchristos  *    documentation and/or other materials provided with the distribution.
15aad01611Sagc  * 3. Neither the name of the University nor the names of its contributors
16dcb2a50bSchristos  *    may be used to endorse or promote products derived from this software
17dcb2a50bSchristos  *    without specific prior written permission.
18dcb2a50bSchristos  *
19dcb2a50bSchristos  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20dcb2a50bSchristos  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21dcb2a50bSchristos  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22dcb2a50bSchristos  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23dcb2a50bSchristos  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24dcb2a50bSchristos  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25dcb2a50bSchristos  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26dcb2a50bSchristos  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27dcb2a50bSchristos  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28dcb2a50bSchristos  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29dcb2a50bSchristos  * SUCH DAMAGE.
30dcb2a50bSchristos  *
31dcb2a50bSchristos  *	@(#)uipc_syscalls.c	8.4 (Berkeley) 2/21/94
32dcb2a50bSchristos  */
33dcb2a50bSchristos 
34dab6ef8bSlukem #include <sys/cdefs.h>
35*d91f98a8Spgoyette __KERNEL_RCSID(0, "$NetBSD: uipc_syscalls_43.c,v 1.51 2019/01/27 02:08:39 pgoyette Exp $");
36*d91f98a8Spgoyette 
37*d91f98a8Spgoyette #if defined(_KERNEL_OPT)
38*d91f98a8Spgoyette #include "opt_compat_netbsd.h"
39*d91f98a8Spgoyette #endif
40dab6ef8bSlukem 
41dcb2a50bSchristos #include <sys/param.h>
42dcb2a50bSchristos #include <sys/systm.h>
43dcb2a50bSchristos #include <sys/filedesc.h>
44dcb2a50bSchristos #include <sys/kernel.h>
45dcb2a50bSchristos #include <sys/proc.h>
46dcb2a50bSchristos #include <sys/file.h>
47dcb2a50bSchristos #include <sys/socket.h>
48dcb2a50bSchristos #include <sys/socketvar.h>
49dcb2a50bSchristos #include <sys/stat.h>
50dcb2a50bSchristos #include <sys/ioctl.h>
51dcb2a50bSchristos #include <sys/fcntl.h>
52dcb2a50bSchristos #include <sys/syslog.h>
53dcb2a50bSchristos #include <sys/unistd.h>
54dcb2a50bSchristos #include <sys/resourcevar.h>
55588b94c0Sjdolecek #include <sys/mbuf.h>		/* for MLEN */
56ca3a1934Schristos #include <sys/protosw.h>
57dcb2a50bSchristos 
58dcb2a50bSchristos #include <sys/mount.h>
59*d91f98a8Spgoyette #include <sys/syscall.h>
60*d91f98a8Spgoyette #include <sys/syscallvar.h>
61dcb2a50bSchristos #include <sys/syscallargs.h>
62dcb2a50bSchristos 
63ca3a1934Schristos #include <net/if.h>
642adca4d3Smartin #include <net/bpf.h>
652adca4d3Smartin #include <net/route.h>
662adca4d3Smartin #include <netinet/in.h>
672adca4d3Smartin #include <netinet/in_systm.h>
682adca4d3Smartin #include <netinet/ip.h>
692adca4d3Smartin #include <net/if_gre.h>
702adca4d3Smartin #include <net/if_tap.h>
71a5134c79Smartin #include <net80211/ieee80211_ioctl.h>
722adca4d3Smartin #include <netinet6/in6_var.h>
732adca4d3Smartin #include <netinet6/nd6.h>
7420bfd989Schristos #include <compat/sys/socket.h>
7520bfd989Schristos #include <compat/sys/sockio.h>
76ca3a1934Schristos 
77588b94c0Sjdolecek #include <compat/common/compat_util.h>
78*d91f98a8Spgoyette #include <compat/common/compat_mod.h>
79588b94c0Sjdolecek 
80588b94c0Sjdolecek #include <uvm/uvm_extern.h>
81588b94c0Sjdolecek 
82588b94c0Sjdolecek /*
83588b94c0Sjdolecek  * Following 4.3 syscalls were not versioned, even through they should
84588b94c0Sjdolecek  * have been:
85588b94c0Sjdolecek  * connect(2), bind(2), sendto(2)
86588b94c0Sjdolecek  */
87588b94c0Sjdolecek 
88*d91f98a8Spgoyette static struct syscall_package uipc_syscalls_43_syscalls[] = {
89*d91f98a8Spgoyette 	{ SYS_compat_43_oaccept, 0, (sy_call_t *)compat_43_sys_accept },
90*d91f98a8Spgoyette 	{ SYS_compat_43_ogetpeername, 0,
91*d91f98a8Spgoyette 	    (sy_call_t *)compat_43_sys_getpeername },
92*d91f98a8Spgoyette 	{ SYS_compat_43_ogetsockname, 0,
93*d91f98a8Spgoyette 	    (sy_call_t *)compat_43_sys_getsockname },
94*d91f98a8Spgoyette 	{ SYS_compat_43_orecv, 0, (sy_call_t *)compat_43_sys_recv },
95*d91f98a8Spgoyette 	{ SYS_compat_43_orecvfrom, 0, (sy_call_t *)compat_43_sys_recvfrom },
96*d91f98a8Spgoyette 	{ SYS_compat_43_orecvmsg, 0, (sy_call_t *)compat_43_sys_recvmsg },
97*d91f98a8Spgoyette 	{ SYS_compat_43_osend, 0, (sy_call_t *)compat_43_sys_send },
98*d91f98a8Spgoyette 	{ SYS_compat_43_osendmsg, 0, (sy_call_t *)compat_43_sys_sendmsg },
99*d91f98a8Spgoyette 	{ 0, 0, NULL }
100*d91f98a8Spgoyette };
101*d91f98a8Spgoyette 
10253524e44Schristos static int compat_43_sa_put(void *);
103588b94c0Sjdolecek 
104dcb2a50bSchristos int
compat_43_sys_accept(struct lwp * l,const struct compat_43_sys_accept_args * uap,register_t * retval)1057e2790cfSdsl compat_43_sys_accept(struct lwp *l, const struct compat_43_sys_accept_args *uap, register_t *retval)
1067160dfc8Sthorpej {
1077e2790cfSdsl 	/* {
108dcb2a50bSchristos 		syscallarg(int) s;
10953524e44Schristos 		syscallarg(void *) name;
110dcb2a50bSchristos 		syscallarg(int *) anamelen;
1117e2790cfSdsl 	} */
112dcb2a50bSchristos 	int error;
113dcb2a50bSchristos 
11445b1ec74Smatt 	if ((error = sys_accept(l, (const struct sys_accept_args *)uap, retval)) != 0)
115dcb2a50bSchristos 		return error;
116dcb2a50bSchristos 
117588b94c0Sjdolecek 	if (SCARG(uap, name)
118588b94c0Sjdolecek 	    && (error = compat_43_sa_put(SCARG(uap, name))))
119588b94c0Sjdolecek 		return (error);
120dcb2a50bSchristos 
121dcb2a50bSchristos 	return 0;
122dcb2a50bSchristos }
123dcb2a50bSchristos 
124dcb2a50bSchristos int
compat_43_sys_getpeername(struct lwp * l,const struct compat_43_sys_getpeername_args * uap,register_t * retval)1257e2790cfSdsl compat_43_sys_getpeername(struct lwp *l, const struct compat_43_sys_getpeername_args *uap, register_t *retval)
1267160dfc8Sthorpej {
1277e2790cfSdsl 	/* {
128dcb2a50bSchristos 		syscallarg(int) fdes;
12953524e44Schristos 		syscallarg(void *) asa;
130dcb2a50bSchristos 		syscallarg(int *) alen;
1317e2790cfSdsl 	} */
132dcb2a50bSchristos 
133dcb2a50bSchristos 	int error;
134dcb2a50bSchristos 
13545b1ec74Smatt 	if ((error = sys_getpeername(l, (const struct sys_getpeername_args *)uap, retval)) != 0)
136dcb2a50bSchristos 		return error;
137dcb2a50bSchristos 
138588b94c0Sjdolecek 	if ((error = compat_43_sa_put(SCARG(uap, asa))))
139588b94c0Sjdolecek 		return (error);
140dcb2a50bSchristos 
141dcb2a50bSchristos 	return 0;
142dcb2a50bSchristos }
143dcb2a50bSchristos 
144dcb2a50bSchristos int
compat_43_sys_getsockname(struct lwp * l,const struct compat_43_sys_getsockname_args * uap,register_t * retval)1457e2790cfSdsl compat_43_sys_getsockname(struct lwp *l, const struct compat_43_sys_getsockname_args *uap, register_t *retval)
1467160dfc8Sthorpej {
1477e2790cfSdsl 	/* {
148dcb2a50bSchristos 		syscallarg(int) fdes;
14953524e44Schristos 		syscallarg(void *) asa;
150dcb2a50bSchristos 		syscallarg(int *) alen;
1517e2790cfSdsl 	} */
152dcb2a50bSchristos 	int error;
153dcb2a50bSchristos 
15445b1ec74Smatt 	if ((error = sys_getsockname(l, (const struct sys_getsockname_args *)uap, retval)) != 0)
155dcb2a50bSchristos 		return error;
156dcb2a50bSchristos 
157588b94c0Sjdolecek 	if ((error = compat_43_sa_put(SCARG(uap, asa))))
158588b94c0Sjdolecek 		return (error);
159dcb2a50bSchristos 
160dcb2a50bSchristos 	return 0;
161dcb2a50bSchristos }
162dcb2a50bSchristos 
163dcb2a50bSchristos int
compat_43_sys_recv(struct lwp * l,const struct compat_43_sys_recv_args * uap,register_t * retval)1647e2790cfSdsl compat_43_sys_recv(struct lwp *l, const struct compat_43_sys_recv_args *uap, register_t *retval)
1657160dfc8Sthorpej {
1667e2790cfSdsl 	/* {
167dcb2a50bSchristos 		syscallarg(int) s;
16853524e44Schristos 		syscallarg(void *) buf;
169dcb2a50bSchristos 		syscallarg(int) len;
170dcb2a50bSchristos 		syscallarg(int) flags;
1717e2790cfSdsl 	} */
172e24cc0f4Sjdolecek 	struct sys_recvfrom_args bra;
173dcb2a50bSchristos 
174e24cc0f4Sjdolecek 	SCARG(&bra, s) = SCARG(uap, s);
175e24cc0f4Sjdolecek 	SCARG(&bra, buf) = SCARG(uap, buf);
176e24cc0f4Sjdolecek 	SCARG(&bra, len) = (size_t) SCARG(uap, len);
177e24cc0f4Sjdolecek 	SCARG(&bra, flags) = SCARG(uap, flags);
178e24cc0f4Sjdolecek 	SCARG(&bra, from) = NULL;
179e24cc0f4Sjdolecek 	SCARG(&bra, fromlenaddr) = NULL;
180e24cc0f4Sjdolecek 
1816762b37eSthorpej 	return (sys_recvfrom(l, &bra, retval));
182dcb2a50bSchristos }
183dcb2a50bSchristos 
184dcb2a50bSchristos int
compat_43_sys_recvfrom(struct lwp * l,const struct compat_43_sys_recvfrom_args * uap,register_t * retval)1857e2790cfSdsl compat_43_sys_recvfrom(struct lwp *l, const struct compat_43_sys_recvfrom_args *uap, register_t *retval)
1867160dfc8Sthorpej {
1877e2790cfSdsl 	/* {
188dcb2a50bSchristos 		syscallarg(int) s;
18953524e44Schristos 		syscallarg(void *) buf;
190dcb2a50bSchristos 		syscallarg(size_t) len;
191dcb2a50bSchristos 		syscallarg(int) flags;
19253524e44Schristos 		syscallarg(void *) from;
193dcb2a50bSchristos 		syscallarg(int *) fromlenaddr;
1947e2790cfSdsl 	} */
195588b94c0Sjdolecek 	int error;
196dcb2a50bSchristos 
19745b1ec74Smatt 	if ((error = sys_recvfrom(l, (const struct sys_recvfrom_args *)uap, retval)))
198588b94c0Sjdolecek 		return (error);
199588b94c0Sjdolecek 
200588b94c0Sjdolecek 	if (SCARG(uap, from) && (error = compat_43_sa_put(SCARG(uap, from))))
201588b94c0Sjdolecek 		return (error);
202588b94c0Sjdolecek 
203588b94c0Sjdolecek 	return (0);
204dcb2a50bSchristos }
205dcb2a50bSchristos 
206dcb2a50bSchristos /*
207588b94c0Sjdolecek  * Old recvmsg. Arrange necessary structures, calls generic code and
208588b94c0Sjdolecek  * adjusts results accordingly.
209dcb2a50bSchristos  */
210dcb2a50bSchristos int
compat_43_sys_recvmsg(struct lwp * l,const struct compat_43_sys_recvmsg_args * uap,register_t * retval)2117e2790cfSdsl compat_43_sys_recvmsg(struct lwp *l, const struct compat_43_sys_recvmsg_args *uap, register_t *retval)
2127160dfc8Sthorpej {
2137e2790cfSdsl 	/* {
214dcb2a50bSchristos 		syscallarg(int) s;
215dcb2a50bSchristos 		syscallarg(struct omsghdr *) msg;
216dcb2a50bSchristos 		syscallarg(int) flags;
2177e2790cfSdsl 	} */
218588b94c0Sjdolecek 	struct omsghdr omsg;
219dcb2a50bSchristos 	struct msghdr msg;
2200bb69285Sdsl 	struct mbuf *from, *control;
221dcb2a50bSchristos 	int error;
222dcb2a50bSchristos 
2230bb69285Sdsl 	error = copyin(SCARG(uap, msg), &omsg, sizeof (struct omsghdr));
2246cbf515eSchristos 	if (error)
225dcb2a50bSchristos 		return (error);
226588b94c0Sjdolecek 
2270bb69285Sdsl 	if (omsg.msg_accrights == NULL)
2280bb69285Sdsl 		omsg.msg_accrightslen = 0;
2290bb69285Sdsl 	/* it was this way in 4.4BSD */
2300bb69285Sdsl 	if (omsg.msg_accrightslen > MLEN)
2310bb69285Sdsl 		return EINVAL;
232588b94c0Sjdolecek 
233588b94c0Sjdolecek 	msg.msg_name	= omsg.msg_name;
234588b94c0Sjdolecek 	msg.msg_namelen = omsg.msg_namelen;
235588b94c0Sjdolecek 	msg.msg_iovlen	= omsg.msg_iovlen;
2360bb69285Sdsl 	msg.msg_iov	= omsg.msg_iov;
2370bb69285Sdsl 	msg.msg_flags	= (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
238588b94c0Sjdolecek 
239331cb3c9Schristos 	error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
2400bb69285Sdsl 	    omsg.msg_accrights != NULL ? &control : NULL, retval);
2410bb69285Sdsl 	if (error != 0)
2420bb69285Sdsl 		return error;
243dcb2a50bSchristos 
244588b94c0Sjdolecek 	/*
245588b94c0Sjdolecek 	 * If there is any control information and it's SCM_RIGHTS,
246588b94c0Sjdolecek 	 * pass it back to the program.
2470bb69285Sdsl 	 * XXX: maybe there can be more than one chunk of control data?
248588b94c0Sjdolecek 	 */
2490bb69285Sdsl 	if (omsg.msg_accrights && control != NULL) {
25045b1ec74Smatt 		struct cmsghdr *cmsg = mtod(control, struct cmsghdr *);
251588b94c0Sjdolecek 
2520bb69285Sdsl 		if (cmsg->cmsg_level == SOL_SOCKET
2530bb69285Sdsl 		    && cmsg->cmsg_type == SCM_RIGHTS
2540bb69285Sdsl 		    && cmsg->cmsg_len < omsg.msg_accrightslen
2550bb69285Sdsl 		    && copyout(CMSG_DATA(cmsg), omsg.msg_accrights,
2560bb69285Sdsl 			    cmsg->cmsg_len) == 0) {
2570bb69285Sdsl 			omsg.msg_accrightslen = cmsg->cmsg_len;
2580bb69285Sdsl 			free_control_mbuf(l, control, control->m_next);
2590bb69285Sdsl 		} else {
260588b94c0Sjdolecek 			omsg.msg_accrightslen = 0;
2610bb69285Sdsl 			free_control_mbuf(l, control, control);
262588b94c0Sjdolecek 		}
2630bb69285Sdsl 	} else
2640bb69285Sdsl 		omsg.msg_accrightslen = 0;
265588b94c0Sjdolecek 
2660bb69285Sdsl 	if (from != NULL)
2670bb69285Sdsl 		/* convert from sockaddr sa_family to osockaddr one here */
2680bb69285Sdsl 		mtod(from, struct osockaddr *)->sa_family =
2690bb69285Sdsl 				    mtod(from, struct sockaddr *)->sa_family;
270588b94c0Sjdolecek 
27145b1ec74Smatt 	error = copyout_sockname((struct sockaddr *)omsg.msg_name, &omsg.msg_namelen, 0, from);
2720bb69285Sdsl 	if (from != NULL)
2730bb69285Sdsl 		m_free(from);
274588b94c0Sjdolecek 
2750bb69285Sdsl 	if (error != 0)
2760bb69285Sdsl 		 error = copyout(&omsg, SCARG(uap, msg), sizeof(omsg));
277588b94c0Sjdolecek 
2780bb69285Sdsl 	return error;
279dcb2a50bSchristos }
280dcb2a50bSchristos 
281dcb2a50bSchristos int
compat_43_sys_send(struct lwp * l,const struct compat_43_sys_send_args * uap,register_t * retval)2827e2790cfSdsl compat_43_sys_send(struct lwp *l, const struct compat_43_sys_send_args *uap, register_t *retval)
2837160dfc8Sthorpej {
2847e2790cfSdsl 	/* {
285dcb2a50bSchristos 		syscallarg(int) s;
28653524e44Schristos 		syscallarg(void *) buf;
287dcb2a50bSchristos 		syscallarg(int) len;
288dcb2a50bSchristos 		syscallarg(int) flags;
2897e2790cfSdsl 	} */
290e24cc0f4Sjdolecek 	struct sys_sendto_args bsa;
291dcb2a50bSchristos 
292e24cc0f4Sjdolecek 	SCARG(&bsa, s)		= SCARG(uap, s);
293e24cc0f4Sjdolecek 	SCARG(&bsa, buf)	= SCARG(uap, buf);
294e24cc0f4Sjdolecek 	SCARG(&bsa, len)	= SCARG(uap, len);
295e24cc0f4Sjdolecek 	SCARG(&bsa, flags)	= SCARG(uap, flags);
296e24cc0f4Sjdolecek 	SCARG(&bsa, to)		= NULL;
297e24cc0f4Sjdolecek 	SCARG(&bsa, tolen)	= 0;
298e24cc0f4Sjdolecek 
2996762b37eSthorpej 	return (sys_sendto(l, &bsa, retval));
300dcb2a50bSchristos }
301dcb2a50bSchristos 
30253e0243fSdsl int
compat43_set_accrights(struct msghdr * msg,void * accrights,int accrightslen)30353e0243fSdsl compat43_set_accrights(struct msghdr *msg, void *accrights, int accrightslen)
30453e0243fSdsl {
30553e0243fSdsl 	struct cmsghdr *cmsg;
30653e0243fSdsl 	int error;
30753e0243fSdsl 	struct mbuf *ctl;
30853e0243fSdsl 	u_int clen;
30953e0243fSdsl 
31053e0243fSdsl 	if (accrights == NULL || accrightslen == 0) {
31153e0243fSdsl 		msg->msg_control = NULL;
31253e0243fSdsl 		msg->msg_controllen = 0;
31353e0243fSdsl 		return 0;
31453e0243fSdsl 	}
31553e0243fSdsl 
31653e0243fSdsl 	clen = CMSG_SPACE(accrightslen);
31753e0243fSdsl 	/* it was (almost) this way in 4.4BSD */
31853e0243fSdsl 	if (accrightslen < 0 || clen > MLEN)
31953e0243fSdsl 		return EINVAL;
32053e0243fSdsl 
32153e0243fSdsl 	ctl = m_get(M_WAIT, MT_CONTROL);
32253e0243fSdsl 	ctl->m_len = clen;
32345b1ec74Smatt 	cmsg = mtod(ctl, struct cmsghdr *);
32453e0243fSdsl 	cmsg->cmsg_len		= CMSG_SPACE(accrightslen);
32553e0243fSdsl 	cmsg->cmsg_level	= SOL_SOCKET;
32653e0243fSdsl 	cmsg->cmsg_type 	= SCM_RIGHTS;
32753e0243fSdsl 
32853e0243fSdsl 	error = copyin(accrights, CMSG_DATA(cmsg), accrightslen);
32953e0243fSdsl 	if (error) {
33053e0243fSdsl 		m_free(ctl);
33153e0243fSdsl 		return error;
33253e0243fSdsl 	}
33353e0243fSdsl 
33453e0243fSdsl 	msg->msg_control = ctl;
33553e0243fSdsl 	msg->msg_controllen = clen;
33653e0243fSdsl 	msg->msg_flags |= MSG_CONTROLMBUF;
33753e0243fSdsl 	return 0;
33853e0243fSdsl }
33953e0243fSdsl 
340588b94c0Sjdolecek /*
341588b94c0Sjdolecek  * Old sendmsg. Arrange necessary structures, call generic code and
342588b94c0Sjdolecek  * adjust the results accordingly for old code.
343588b94c0Sjdolecek  */
344dcb2a50bSchristos int
compat_43_sys_sendmsg(struct lwp * l,const struct compat_43_sys_sendmsg_args * uap,register_t * retval)3457e2790cfSdsl compat_43_sys_sendmsg(struct lwp *l, const struct compat_43_sys_sendmsg_args *uap, register_t *retval)
3467160dfc8Sthorpej {
3477e2790cfSdsl 	/* {
348dcb2a50bSchristos 		syscallarg(int) s;
34953524e44Schristos 		syscallarg(void *) msg;
350dcb2a50bSchristos 		syscallarg(int) flags;
3517e2790cfSdsl 	} */
352588b94c0Sjdolecek 	struct omsghdr omsg;
353dcb2a50bSchristos 	struct msghdr msg;
354dcb2a50bSchristos 	int error;
355d7f93c5cSdsl 	struct mbuf *nam;
356588b94c0Sjdolecek 	struct osockaddr *osa;
357d7f93c5cSdsl 	struct sockaddr *sa;
358588b94c0Sjdolecek 
359d7f93c5cSdsl 	error = copyin(SCARG(uap, msg), &omsg, sizeof (struct omsghdr));
360d7f93c5cSdsl 	if (error != 0)
361588b94c0Sjdolecek 		return (error);
362588b94c0Sjdolecek 
363d7f93c5cSdsl 	msg.msg_iovlen = omsg.msg_iovlen;
364d7f93c5cSdsl 	msg.msg_iov = omsg.msg_iov;
365d7f93c5cSdsl 
3668cb1b001Schristos 	error = sockargs(&nam, omsg.msg_name, omsg.msg_namelen,
3678cb1b001Schristos 	    UIO_USERSPACE, MT_SONAME);
368d7f93c5cSdsl 	if (error != 0)
369d7f93c5cSdsl 		return (error);
370d7f93c5cSdsl 
37145b1ec74Smatt 	sa = mtod(nam, struct sockaddr *);
37245b1ec74Smatt 	osa = mtod(nam, struct osockaddr *);
373588b94c0Sjdolecek 	sa->sa_family = osa->sa_family;
374588b94c0Sjdolecek 	sa->sa_len = omsg.msg_namelen;
375588b94c0Sjdolecek 
376d7f93c5cSdsl 	msg.msg_flags = MSG_IOVUSRSPACE | MSG_NAMEMBUF;
377588b94c0Sjdolecek 
378d7f93c5cSdsl 	msg.msg_name = nam;
379588b94c0Sjdolecek 	msg.msg_namelen = omsg.msg_namelen;
38053e0243fSdsl 	error = compat43_set_accrights(&msg, omsg.msg_accrights,
381588b94c0Sjdolecek 	    omsg.msg_accrightslen);
38253e0243fSdsl 	if (error != 0)
383d7f93c5cSdsl 		goto bad;
384588b94c0Sjdolecek 
3851766e4eeSmartin 	return do_sys_sendmsg(l, SCARG(uap, s), &msg, SCARG(uap, flags),
386331cb3c9Schristos 	    retval);
387d7f93c5cSdsl 
388d7f93c5cSdsl     bad:
389d7f93c5cSdsl 	if (nam != NULL)
390d7f93c5cSdsl 		m_free(nam);
391d7f93c5cSdsl 
392dcb2a50bSchristos 	return (error);
393dcb2a50bSchristos }
394588b94c0Sjdolecek 
395588b94c0Sjdolecek static int
compat_43_sa_put(void * from)39628bae79bSdsl compat_43_sa_put(void *from)
397588b94c0Sjdolecek {
398588b94c0Sjdolecek 	struct osockaddr *osa = (struct osockaddr *) from;
399588b94c0Sjdolecek 	struct sockaddr sa;
400588b94c0Sjdolecek 	struct osockaddr *kosa;
401588b94c0Sjdolecek 	int error, len;
402588b94c0Sjdolecek 
403588b94c0Sjdolecek 	/*
404588b94c0Sjdolecek 	 * Only read/write the sockaddr family and length, the rest is
405588b94c0Sjdolecek 	 * not changed.
406588b94c0Sjdolecek 	 */
407588b94c0Sjdolecek 	len = sizeof(sa.sa_len) + sizeof(sa.sa_family);
408588b94c0Sjdolecek 
40953524e44Schristos 	error = copyin((void *) osa, (void *) &sa, len);
410588b94c0Sjdolecek 	if (error)
411588b94c0Sjdolecek 		return (error);
412588b94c0Sjdolecek 
413588b94c0Sjdolecek 	/* Note: we convert from sockaddr sa_family to osockaddr one here */
414588b94c0Sjdolecek 	kosa = (struct osockaddr *) &sa;
415588b94c0Sjdolecek 	kosa->sa_family = sa.sa_family;
416588b94c0Sjdolecek 	error = copyout(kosa, osa, len);
417588b94c0Sjdolecek 	if (error)
418588b94c0Sjdolecek 		return (error);
419588b94c0Sjdolecek 
420588b94c0Sjdolecek 	return (0);
421588b94c0Sjdolecek }
422*d91f98a8Spgoyette 
423*d91f98a8Spgoyette int
uipc_syscalls_43_init(void)424*d91f98a8Spgoyette uipc_syscalls_43_init(void)
425*d91f98a8Spgoyette {
426*d91f98a8Spgoyette 
427*d91f98a8Spgoyette 	return syscall_establish(NULL, uipc_syscalls_43_syscalls);
428*d91f98a8Spgoyette }
429*d91f98a8Spgoyette 
430*d91f98a8Spgoyette int
uipc_syscalls_43_fini(void)431*d91f98a8Spgoyette uipc_syscalls_43_fini(void)
432*d91f98a8Spgoyette {
433*d91f98a8Spgoyette 
434*d91f98a8Spgoyette 	return syscall_disestablish(NULL, uipc_syscalls_43_syscalls);
435*d91f98a8Spgoyette }
436