Tue Nov 3 22:08:44 2020 UTC ()
PR/55780: Bernd Sieker: setsockopt in Linux emulation misses some options


(christos)
diff -r1.151 -r1.152 src/sys/compat/linux/common/linux_socket.c

cvs diff -r1.151 -r1.152 src/sys/compat/linux/common/linux_socket.c (switch to unified diff)

--- src/sys/compat/linux/common/linux_socket.c 2020/10/24 09:01:56 1.151
+++ src/sys/compat/linux/common/linux_socket.c 2020/11/03 22:08:44 1.152
@@ -1,1895 +1,1926 @@ @@ -1,1895 +1,1926 @@
1/* $NetBSD: linux_socket.c,v 1.151 2020/10/24 09:01:56 mgorny Exp $ */ 1/* $NetBSD: linux_socket.c,v 1.152 2020/11/03 22:08:44 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1995, 1998, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Frank van der Linden and Eric Haszlakiewicz. 8 * by Frank van der Linden and Eric Haszlakiewicz.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 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 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 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 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 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 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 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Functions in multiarch: 33 * Functions in multiarch:
34 * linux_sys_socketcall : linux_socketcall.c 34 * linux_sys_socketcall : linux_socketcall.c
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.151 2020/10/24 09:01:56 mgorny Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: linux_socket.c,v 1.152 2020/11/03 22:08:44 christos Exp $");
39 39
40#if defined(_KERNEL_OPT) 40#if defined(_KERNEL_OPT)
41#include "opt_inet.h" 41#include "opt_inet.h"
42#endif /* defined(_KERNEL_OPT) */ 42#endif /* defined(_KERNEL_OPT) */
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/systm.h> 46#include <sys/systm.h>
47#include <sys/buf.h> 47#include <sys/buf.h>
48#include <sys/ioctl.h> 48#include <sys/ioctl.h>
49#include <sys/tty.h> 49#include <sys/tty.h>
50#include <sys/file.h> 50#include <sys/file.h>
51#include <sys/filedesc.h> 51#include <sys/filedesc.h>
52#include <sys/select.h> 52#include <sys/select.h>
53#include <sys/socket.h> 53#include <sys/socket.h>
54#include <sys/socketvar.h> 54#include <sys/socketvar.h>
55#include <sys/domain.h> 55#include <sys/domain.h>
56#include <net/if.h> 56#include <net/if.h>
57#include <net/if_dl.h> 57#include <net/if_dl.h>
58#include <net/if_types.h> 58#include <net/if_types.h>
59#include <netinet/in.h> 59#include <netinet/in.h>
60#include <netinet/tcp.h> 60#include <netinet/tcp.h>
61#include <sys/mount.h> 61#include <sys/mount.h>
62#include <sys/proc.h> 62#include <sys/proc.h>
63#include <sys/vnode.h> 63#include <sys/vnode.h>
64#include <sys/device.h> 64#include <sys/device.h>
65#include <sys/protosw.h> 65#include <sys/protosw.h>
66#include <sys/mbuf.h> 66#include <sys/mbuf.h>
67#include <sys/syslog.h> 67#include <sys/syslog.h>
68#include <sys/exec.h> 68#include <sys/exec.h>
69#include <sys/kauth.h> 69#include <sys/kauth.h>
70#include <sys/syscallargs.h> 70#include <sys/syscallargs.h>
71#include <sys/ktrace.h> 71#include <sys/ktrace.h>
72 72
73#include <lib/libkern/libkern.h> 73#include <lib/libkern/libkern.h>
74 74
75#include <netinet/ip6.h> 75#include <netinet/ip6.h>
76#include <netinet6/ip6_var.h> 76#include <netinet6/ip6_var.h>
77 77
78#include <compat/sys/socket.h> 78#include <compat/sys/socket.h>
79#include <compat/sys/sockio.h> 79#include <compat/sys/sockio.h>
80 80
81#include <compat/linux/common/linux_types.h> 81#include <compat/linux/common/linux_types.h>
82#include <compat/linux/common/linux_util.h> 82#include <compat/linux/common/linux_util.h>
83#include <compat/linux/common/linux_signal.h> 83#include <compat/linux/common/linux_signal.h>
84#include <compat/linux/common/linux_ioctl.h> 84#include <compat/linux/common/linux_ioctl.h>
85#include <compat/linux/common/linux_sched.h> 85#include <compat/linux/common/linux_sched.h>
86#include <compat/linux/common/linux_socket.h> 86#include <compat/linux/common/linux_socket.h>
87#include <compat/linux/common/linux_fcntl.h> 87#include <compat/linux/common/linux_fcntl.h>
88#if !defined(__alpha__) && !defined(__amd64__) 88#if !defined(__alpha__) && !defined(__amd64__)
89#include <compat/linux/common/linux_socketcall.h> 89#include <compat/linux/common/linux_socketcall.h>
90#endif 90#endif
91#include <compat/linux/common/linux_sockio.h> 91#include <compat/linux/common/linux_sockio.h>
92#include <compat/linux/common/linux_ipc.h> 92#include <compat/linux/common/linux_ipc.h>
93#include <compat/linux/common/linux_sem.h> 93#include <compat/linux/common/linux_sem.h>
94 94
95#include <compat/linux/linux_syscallargs.h> 95#include <compat/linux/linux_syscallargs.h>
96 96
97#ifdef DEBUG_LINUX 97#ifdef DEBUG_LINUX
98#define DPRINTF(a) uprintf a 98#define DPRINTF(a) uprintf a
99#else 99#else
100#define DPRINTF(a) 100#define DPRINTF(a)
101#endif 101#endif
102 102
103/* 103/*
104 * The calls in this file are entered either via the linux_socketcall() 104 * The calls in this file are entered either via the linux_socketcall()
105 * interface or, on the Alpha, as individual syscalls. The 105 * interface or, on the Alpha, as individual syscalls. The
106 * linux_socketcall function does any massaging of arguments so that all 106 * linux_socketcall function does any massaging of arguments so that all
107 * the calls in here need not think that they are anything other 107 * the calls in here need not think that they are anything other
108 * than a normal syscall. 108 * than a normal syscall.
109 */ 109 */
110 110
111static int linux_to_bsd_domain(int); 111static int linux_to_bsd_domain(int);
112static int bsd_to_linux_domain(int); 112static int bsd_to_linux_domain(int);
113static int linux_to_bsd_type(int); 113static int linux_to_bsd_type(int);
114int linux_to_bsd_sopt_level(int); 114int linux_to_bsd_sopt_level(int);
115int linux_to_bsd_so_sockopt(int); 115int linux_to_bsd_so_sockopt(int);
116int linux_to_bsd_ip_sockopt(int); 116int linux_to_bsd_ip_sockopt(int);
117int linux_to_bsd_ipv6_sockopt(int); 117int linux_to_bsd_ipv6_sockopt(int);
118int linux_to_bsd_tcp_sockopt(int); 118int linux_to_bsd_tcp_sockopt(int);
119int linux_to_bsd_udp_sockopt(int); 119int linux_to_bsd_udp_sockopt(int);
120int linux_getifname(struct lwp *, register_t *, void *); 120int linux_getifname(struct lwp *, register_t *, void *);
121int linux_getifconf(struct lwp *, register_t *, void *); 121int linux_getifconf(struct lwp *, register_t *, void *);
122int linux_getifhwaddr(struct lwp *, register_t *, u_int, void *); 122int linux_getifhwaddr(struct lwp *, register_t *, u_int, void *);
123static int linux_get_sa(struct lwp *, int, struct sockaddr_big *, 123static int linux_get_sa(struct lwp *, int, struct sockaddr_big *,
124 const struct osockaddr *, socklen_t); 124 const struct osockaddr *, socklen_t);
125static int linux_sa_put(struct osockaddr *osa); 125static int linux_sa_put(struct osockaddr *osa);
126static int linux_to_bsd_msg_flags(int); 126static int linux_to_bsd_msg_flags(int);
127static int bsd_to_linux_msg_flags(int); 127static int bsd_to_linux_msg_flags(int);
128static void linux_to_bsd_msghdr(const struct linux_msghdr *, struct msghdr *); 128static void linux_to_bsd_msghdr(const struct linux_msghdr *, struct msghdr *);
129static void bsd_to_linux_msghdr(const struct msghdr *, struct linux_msghdr *); 129static void bsd_to_linux_msghdr(const struct msghdr *, struct linux_msghdr *);
130 130
131static const int linux_to_bsd_domain_[LINUX_AF_MAX] = { 131static const int linux_to_bsd_domain_[LINUX_AF_MAX] = {
132 AF_UNSPEC, 132 AF_UNSPEC,
133 AF_UNIX, 133 AF_UNIX,
134 AF_INET, 134 AF_INET,
135 AF_CCITT, /* LINUX_AF_AX25 */ 135 AF_CCITT, /* LINUX_AF_AX25 */
136 AF_IPX, 136 AF_IPX,
137 AF_APPLETALK, 137 AF_APPLETALK,
138 -1, /* LINUX_AF_NETROM */ 138 -1, /* LINUX_AF_NETROM */
139 -1, /* LINUX_AF_BRIDGE */ 139 -1, /* LINUX_AF_BRIDGE */
140 -1, /* LINUX_AF_ATMPVC */ 140 -1, /* LINUX_AF_ATMPVC */
141 AF_CCITT, /* LINUX_AF_X25 */ 141 AF_CCITT, /* LINUX_AF_X25 */
142 AF_INET6, 142 AF_INET6,
143 -1, /* LINUX_AF_ROSE */ 143 -1, /* LINUX_AF_ROSE */
144 AF_DECnet, 144 AF_DECnet,
145 -1, /* LINUX_AF_NETBEUI */ 145 -1, /* LINUX_AF_NETBEUI */
146 -1, /* LINUX_AF_SECURITY */ 146 -1, /* LINUX_AF_SECURITY */
147 pseudo_AF_KEY, 147 pseudo_AF_KEY,
148 AF_ROUTE, /* LINUX_AF_NETLINK */ 148 AF_ROUTE, /* LINUX_AF_NETLINK */
149 -1, /* LINUX_AF_PACKET */ 149 -1, /* LINUX_AF_PACKET */
150 -1, /* LINUX_AF_ASH */ 150 -1, /* LINUX_AF_ASH */
151 -1, /* LINUX_AF_ECONET */ 151 -1, /* LINUX_AF_ECONET */
152 -1, /* LINUX_AF_ATMSVC */ 152 -1, /* LINUX_AF_ATMSVC */
153 AF_SNA, 153 AF_SNA,
154 /* rest up to LINUX_AF_MAX-1 is not allocated */ 154 /* rest up to LINUX_AF_MAX-1 is not allocated */
155 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 155 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
156}; 156};
157 157
158static const int bsd_to_linux_domain_[AF_MAX] = { 158static const int bsd_to_linux_domain_[AF_MAX] = {
159 LINUX_AF_UNSPEC, 159 LINUX_AF_UNSPEC,
160 LINUX_AF_UNIX, 160 LINUX_AF_UNIX,
161 LINUX_AF_INET, 161 LINUX_AF_INET,
162 -1, /* AF_IMPLINK */ 162 -1, /* AF_IMPLINK */
163 -1, /* AF_PUP */ 163 -1, /* AF_PUP */
164 -1, /* AF_CHAOS */ 164 -1, /* AF_CHAOS */
165 -1, /* AF_NS */ 165 -1, /* AF_NS */
166 -1, /* AF_ISO */ 166 -1, /* AF_ISO */
167 -1, /* AF_ECMA */ 167 -1, /* AF_ECMA */
168 -1, /* AF_DATAKIT */ 168 -1, /* AF_DATAKIT */
169 LINUX_AF_AX25, /* AF_CCITT */ 169 LINUX_AF_AX25, /* AF_CCITT */
170 LINUX_AF_SNA, 170 LINUX_AF_SNA,
171 LINUX_AF_DECnet, 171 LINUX_AF_DECnet,
172 -1, /* AF_DLI */ 172 -1, /* AF_DLI */
173 -1, /* AF_LAT */ 173 -1, /* AF_LAT */
174 -1, /* AF_HYLINK */ 174 -1, /* AF_HYLINK */
175 LINUX_AF_APPLETALK, 175 LINUX_AF_APPLETALK,
176 LINUX_AF_NETLINK, 176 LINUX_AF_NETLINK,
177 -1, /* AF_LINK */ 177 -1, /* AF_LINK */
178 -1, /* AF_XTP */ 178 -1, /* AF_XTP */
179 -1, /* AF_COIP */ 179 -1, /* AF_COIP */
180 -1, /* AF_CNT */ 180 -1, /* AF_CNT */
181 -1, /* pseudo_AF_RTIP */ 181 -1, /* pseudo_AF_RTIP */
182 LINUX_AF_IPX, 182 LINUX_AF_IPX,
183 LINUX_AF_INET6, 183 LINUX_AF_INET6,
184 -1, /* pseudo_AF_PIP */ 184 -1, /* pseudo_AF_PIP */
185 -1, /* AF_ISDN */ 185 -1, /* AF_ISDN */
186 -1, /* AF_NATM */ 186 -1, /* AF_NATM */
187 -1, /* AF_ARP */ 187 -1, /* AF_ARP */
188 LINUX_pseudo_AF_KEY, 188 LINUX_pseudo_AF_KEY,
189 -1, /* pseudo_AF_HDRCMPLT */ 189 -1, /* pseudo_AF_HDRCMPLT */
190}; 190};
191 191
192static const struct { 192static const struct {
193 int bfl; 193 int bfl;
194 int lfl; 194 int lfl;
195} bsd_to_linux_msg_flags_[] = { 195} bsd_to_linux_msg_flags_[] = {
196 {MSG_OOB, LINUX_MSG_OOB}, 196 {MSG_OOB, LINUX_MSG_OOB},
197 {MSG_PEEK, LINUX_MSG_PEEK}, 197 {MSG_PEEK, LINUX_MSG_PEEK},
198 {MSG_DONTROUTE, LINUX_MSG_DONTROUTE}, 198 {MSG_DONTROUTE, LINUX_MSG_DONTROUTE},
199 {MSG_EOR, LINUX_MSG_EOR}, 199 {MSG_EOR, LINUX_MSG_EOR},
200 {MSG_TRUNC, LINUX_MSG_TRUNC}, 200 {MSG_TRUNC, LINUX_MSG_TRUNC},
201 {MSG_CTRUNC, LINUX_MSG_CTRUNC}, 201 {MSG_CTRUNC, LINUX_MSG_CTRUNC},
202 {MSG_WAITALL, LINUX_MSG_WAITALL}, 202 {MSG_WAITALL, LINUX_MSG_WAITALL},
203 {MSG_DONTWAIT, LINUX_MSG_DONTWAIT}, 203 {MSG_DONTWAIT, LINUX_MSG_DONTWAIT},
204 {MSG_BCAST, 0}, /* not supported, clear */ 204 {MSG_BCAST, 0}, /* not supported, clear */
205 {MSG_MCAST, 0}, /* not supported, clear */ 205 {MSG_MCAST, 0}, /* not supported, clear */
206 {MSG_NOSIGNAL, LINUX_MSG_NOSIGNAL}, 206 {MSG_NOSIGNAL, LINUX_MSG_NOSIGNAL},
207 {-1, /* not supp */ LINUX_MSG_PROBE}, 207 {-1, /* not supp */ LINUX_MSG_PROBE},
208 {-1, /* not supp */ LINUX_MSG_FIN}, 208 {-1, /* not supp */ LINUX_MSG_FIN},
209 {-1, /* not supp */ LINUX_MSG_SYN}, 209 {-1, /* not supp */ LINUX_MSG_SYN},
210 {-1, /* not supp */ LINUX_MSG_CONFIRM}, 210 {-1, /* not supp */ LINUX_MSG_CONFIRM},
211 {-1, /* not supp */ LINUX_MSG_RST}, 211 {-1, /* not supp */ LINUX_MSG_RST},
212 {-1, /* not supp */ LINUX_MSG_ERRQUEUE}, 212 {-1, /* not supp */ LINUX_MSG_ERRQUEUE},
213 {-1, /* not supp */ LINUX_MSG_MORE}, 213 {-1, /* not supp */ LINUX_MSG_MORE},
214}; 214};
215 215
216/* 216/*
217 * Convert between Linux and BSD socket domain values 217 * Convert between Linux and BSD socket domain values
218 */ 218 */
219static int 219static int
220linux_to_bsd_domain(int ldom) 220linux_to_bsd_domain(int ldom)
221{ 221{
222 if (ldom < 0 || ldom >= LINUX_AF_MAX) 222 if (ldom < 0 || ldom >= LINUX_AF_MAX)
223 return (-1); 223 return (-1);
224 224
225 return linux_to_bsd_domain_[ldom]; 225 return linux_to_bsd_domain_[ldom];
226} 226}
227 227
228/* 228/*
229 * Convert between BSD and Linux socket domain values 229 * Convert between BSD and Linux socket domain values
230 */ 230 */
231static int 231static int
232bsd_to_linux_domain(int bdom) 232bsd_to_linux_domain(int bdom)
233{ 233{
234 if (bdom < 0 || bdom >= AF_MAX) 234 if (bdom < 0 || bdom >= AF_MAX)
235 return (-1); 235 return (-1);
236 236
237 return bsd_to_linux_domain_[bdom]; 237 return bsd_to_linux_domain_[bdom];
238} 238}
239 239
240static int 240static int
241linux_to_bsd_type(int ltype) 241linux_to_bsd_type(int ltype)
242{ 242{
243 int type, flags; 243 int type, flags;
244 244
245 /* Real types are identical between Linux and NetBSD */ 245 /* Real types are identical between Linux and NetBSD */
246 type = ltype & LINUX_SOCK_TYPE_MASK; 246 type = ltype & LINUX_SOCK_TYPE_MASK;
247 247
248 /* But flags are not .. */ 248 /* But flags are not .. */
249 flags = ltype & ~LINUX_SOCK_TYPE_MASK; 249 flags = ltype & ~LINUX_SOCK_TYPE_MASK;
250 if (flags & ~(LINUX_SOCK_CLOEXEC|LINUX_SOCK_NONBLOCK)) 250 if (flags & ~(LINUX_SOCK_CLOEXEC|LINUX_SOCK_NONBLOCK))
251 return -1; 251 return -1;
252 252
253 if (flags & LINUX_SOCK_CLOEXEC) 253 if (flags & LINUX_SOCK_CLOEXEC)
254 type |= SOCK_CLOEXEC; 254 type |= SOCK_CLOEXEC;
255 if (flags & LINUX_SOCK_NONBLOCK) 255 if (flags & LINUX_SOCK_NONBLOCK)
256 type |= SOCK_NONBLOCK; 256 type |= SOCK_NONBLOCK;
257 257
258 return type; 258 return type;
259} 259}
260 260
261static int 261static int
262linux_to_bsd_msg_flags(int lflag) 262linux_to_bsd_msg_flags(int lflag)
263{ 263{
264 int i, lfl, bfl; 264 int i, lfl, bfl;
265 int bflag = 0; 265 int bflag = 0;
266 266
267 if (lflag == 0) 267 if (lflag == 0)
268 return (0); 268 return (0);
269 269
270 for(i = 0; i < __arraycount(bsd_to_linux_msg_flags_); i++) { 270 for(i = 0; i < __arraycount(bsd_to_linux_msg_flags_); i++) {
271 bfl = bsd_to_linux_msg_flags_[i].bfl; 271 bfl = bsd_to_linux_msg_flags_[i].bfl;
272 lfl = bsd_to_linux_msg_flags_[i].lfl; 272 lfl = bsd_to_linux_msg_flags_[i].lfl;
273 273
274 if (lfl == 0) 274 if (lfl == 0)
275 continue; 275 continue;
276 276
277 if (lflag & lfl) { 277 if (lflag & lfl) {
278 if (bfl < 0) 278 if (bfl < 0)
279 return (-1); 279 return (-1);
280 280
281 bflag |= bfl; 281 bflag |= bfl;
282 } 282 }
283 } 283 }
284 284
285 return (bflag); 285 return (bflag);
286} 286}
287 287
288static int 288static int
289bsd_to_linux_msg_flags(int bflag) 289bsd_to_linux_msg_flags(int bflag)
290{ 290{
291 int i, lfl, bfl; 291 int i, lfl, bfl;
292 int lflag = 0; 292 int lflag = 0;
293 293
294 if (bflag == 0) 294 if (bflag == 0)
295 return (0); 295 return (0);
296 296
297 for(i = 0; i < __arraycount(bsd_to_linux_msg_flags_); i++) { 297 for(i = 0; i < __arraycount(bsd_to_linux_msg_flags_); i++) {
298 bfl = bsd_to_linux_msg_flags_[i].bfl; 298 bfl = bsd_to_linux_msg_flags_[i].bfl;
299 lfl = bsd_to_linux_msg_flags_[i].lfl; 299 lfl = bsd_to_linux_msg_flags_[i].lfl;
300 300
301 if (bfl <= 0) 301 if (bfl <= 0)
302 continue; 302 continue;
303 303
304 if (bflag & bfl) { 304 if (bflag & bfl) {
305 if (lfl < 0) 305 if (lfl < 0)
306 return (-1); 306 return (-1);
307 307
308 lflag |= lfl; 308 lflag |= lfl;
309 } 309 }
310 } 310 }
311 311
312 return (lflag); 312 return (lflag);
313} 313}
314 314
315int 315int
316linux_sys_socket(struct lwp *l, const struct linux_sys_socket_args *uap, register_t *retval) 316linux_sys_socket(struct lwp *l, const struct linux_sys_socket_args *uap, register_t *retval)
317{ 317{
318 /* { 318 /* {
319 syscallarg(int) domain; 319 syscallarg(int) domain;
320 syscallarg(int) type; 320 syscallarg(int) type;
321 syscallarg(int) protocol; 321 syscallarg(int) protocol;
322 } */ 322 } */
323 struct sys___socket30_args bsa; 323 struct sys___socket30_args bsa;
324 int error; 324 int error;
325 325
326 326
327 SCARG(&bsa, protocol) = SCARG(uap, protocol); 327 SCARG(&bsa, protocol) = SCARG(uap, protocol);
328 SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain)); 328 SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain));
329 if (SCARG(&bsa, domain) == -1) 329 if (SCARG(&bsa, domain) == -1)
330 return EINVAL; 330 return EINVAL;
331 SCARG(&bsa, type) = linux_to_bsd_type(SCARG(uap, type)); 331 SCARG(&bsa, type) = linux_to_bsd_type(SCARG(uap, type));
332 if (SCARG(&bsa, type) == -1) 332 if (SCARG(&bsa, type) == -1)
333 return EINVAL; 333 return EINVAL;
334 /* 334 /*
335 * Apparently linux uses this to talk to ISDN sockets. If we fail 335 * Apparently linux uses this to talk to ISDN sockets. If we fail
336 * now programs seems to handle it, but if we don't we are going 336 * now programs seems to handle it, but if we don't we are going
337 * to fail when we bind and programs don't handle this well. 337 * to fail when we bind and programs don't handle this well.
338 */ 338 */
339 if (SCARG(&bsa, domain) == AF_ROUTE && SCARG(&bsa, type) == SOCK_RAW) 339 if (SCARG(&bsa, domain) == AF_ROUTE && SCARG(&bsa, type) == SOCK_RAW)
340 return ENOTSUP; 340 return ENOTSUP;
341 error = sys___socket30(l, &bsa, retval); 341 error = sys___socket30(l, &bsa, retval);
342 342
343#ifdef INET6 343#ifdef INET6
344 /* 344 /*
345 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by 345 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by
346 * default and some apps depend on this. So, set V6ONLY to 0 346 * default and some apps depend on this. So, set V6ONLY to 0
347 * for Linux apps if the sysctl value is set to 1. 347 * for Linux apps if the sysctl value is set to 1.
348 */ 348 */
349 if (!error && ip6_v6only && SCARG(&bsa, domain) == PF_INET6) { 349 if (!error && ip6_v6only && SCARG(&bsa, domain) == PF_INET6) {
350 struct socket *so; 350 struct socket *so;
351 351
352 if (fd_getsock(*retval, &so) == 0) { 352 if (fd_getsock(*retval, &so) == 0) {
353 int val = 0; 353 int val = 0;
354 354
355 /* ignore error */ 355 /* ignore error */
356 (void)so_setsockopt(l, so, IPPROTO_IPV6, IPV6_V6ONLY, 356 (void)so_setsockopt(l, so, IPPROTO_IPV6, IPV6_V6ONLY,
357 &val, sizeof(val)); 357 &val, sizeof(val));
358 358
359 fd_putfile(*retval); 359 fd_putfile(*retval);
360 } 360 }
361 } 361 }
362#endif 362#endif
363 363
364 return (error); 364 return (error);
365} 365}
366 366
367int 367int
368linux_sys_socketpair(struct lwp *l, const struct linux_sys_socketpair_args *uap, register_t *retval) 368linux_sys_socketpair(struct lwp *l, const struct linux_sys_socketpair_args *uap, register_t *retval)
369{ 369{
370 /* { 370 /* {
371 syscallarg(int) domain; 371 syscallarg(int) domain;
372 syscallarg(int) type; 372 syscallarg(int) type;
373 syscallarg(int) protocol; 373 syscallarg(int) protocol;
374 syscallarg(int *) rsv; 374 syscallarg(int *) rsv;
375 } */ 375 } */
376 struct sys_socketpair_args bsa; 376 struct sys_socketpair_args bsa;
377 377
378 SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain)); 378 SCARG(&bsa, domain) = linux_to_bsd_domain(SCARG(uap, domain));
379 if (SCARG(&bsa, domain) == -1) 379 if (SCARG(&bsa, domain) == -1)
380 return EINVAL; 380 return EINVAL;
381 SCARG(&bsa, type) = linux_to_bsd_type(SCARG(uap, type)); 381 SCARG(&bsa, type) = linux_to_bsd_type(SCARG(uap, type));
382 if (SCARG(&bsa, type) == -1) 382 if (SCARG(&bsa, type) == -1)
383 return EINVAL; 383 return EINVAL;
384 SCARG(&bsa, protocol) = SCARG(uap, protocol); 384 SCARG(&bsa, protocol) = SCARG(uap, protocol);
385 SCARG(&bsa, rsv) = SCARG(uap, rsv); 385 SCARG(&bsa, rsv) = SCARG(uap, rsv);
386 386
387 return sys_socketpair(l, &bsa, retval); 387 return sys_socketpair(l, &bsa, retval);
388} 388}
389 389
390int 390int
391linux_sys_sendto(struct lwp *l, const struct linux_sys_sendto_args *uap, register_t *retval) 391linux_sys_sendto(struct lwp *l, const struct linux_sys_sendto_args *uap, register_t *retval)
392{ 392{
393 /* { 393 /* {
394 syscallarg(int) s; 394 syscallarg(int) s;
395 syscallarg(void *) msg; 395 syscallarg(void *) msg;
396 syscallarg(int) len; 396 syscallarg(int) len;
397 syscallarg(int) flags; 397 syscallarg(int) flags;
398 syscallarg(struct osockaddr *) to; 398 syscallarg(struct osockaddr *) to;
399 syscallarg(int) tolen; 399 syscallarg(int) tolen;
400 } */ 400 } */
401 struct msghdr msg; 401 struct msghdr msg;
402 struct iovec aiov; 402 struct iovec aiov;
403 struct sockaddr_big nam; 403 struct sockaddr_big nam;
404 struct mbuf *m; 404 struct mbuf *m;
405 int bflags; 405 int bflags;
406 int error; 406 int error;
407 407
408 /* Translate message flags. */ 408 /* Translate message flags. */
409 bflags = linux_to_bsd_msg_flags(SCARG(uap, flags)); 409 bflags = linux_to_bsd_msg_flags(SCARG(uap, flags));
410 if (bflags < 0) 410 if (bflags < 0)
411 /* Some supported flag */ 411 /* Some supported flag */
412 return EINVAL; 412 return EINVAL;
413 413
414 msg.msg_flags = 0; 414 msg.msg_flags = 0;
415 msg.msg_name = NULL; 415 msg.msg_name = NULL;
416 msg.msg_control = NULL; 416 msg.msg_control = NULL;
417 417
418 if (SCARG(uap, tolen)) { 418 if (SCARG(uap, tolen)) {
419 /* Read in and convert the sockaddr */ 419 /* Read in and convert the sockaddr */
420 error = linux_get_sa(l, SCARG(uap, s), &nam, SCARG(uap, to), 420 error = linux_get_sa(l, SCARG(uap, s), &nam, SCARG(uap, to),
421 SCARG(uap, tolen)); 421 SCARG(uap, tolen));
422 if (error) 422 if (error)
423 return error; 423 return error;
424 error = sockargs(&m, &nam, nam.sb_len, UIO_SYSSPACE, MT_SONAME); 424 error = sockargs(&m, &nam, nam.sb_len, UIO_SYSSPACE, MT_SONAME);
425 if (error) 425 if (error)
426 return error; 426 return error;
427 msg.msg_flags |= MSG_NAMEMBUF; 427 msg.msg_flags |= MSG_NAMEMBUF;
428 msg.msg_name = m; 428 msg.msg_name = m;
429 msg.msg_namelen = nam.sb_len; 429 msg.msg_namelen = nam.sb_len;
430 } 430 }
431 431
432 msg.msg_iov = &aiov; 432 msg.msg_iov = &aiov;
433 msg.msg_iovlen = 1; 433 msg.msg_iovlen = 1;
434 aiov.iov_base = __UNCONST(SCARG(uap, msg)); 434 aiov.iov_base = __UNCONST(SCARG(uap, msg));
435 aiov.iov_len = SCARG(uap, len); 435 aiov.iov_len = SCARG(uap, len);
436 436
437 return do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval); 437 return do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval);
438} 438}
439 439
440static void 440static void
441linux_to_bsd_msghdr(const struct linux_msghdr *lmsg, struct msghdr *bmsg) 441linux_to_bsd_msghdr(const struct linux_msghdr *lmsg, struct msghdr *bmsg)
442{ 442{
443 bmsg->msg_name = lmsg->msg_name; 443 bmsg->msg_name = lmsg->msg_name;
444 bmsg->msg_namelen = lmsg->msg_namelen; 444 bmsg->msg_namelen = lmsg->msg_namelen;
445 bmsg->msg_iov = lmsg->msg_iov; 445 bmsg->msg_iov = lmsg->msg_iov;
446 bmsg->msg_iovlen = lmsg->msg_iovlen; 446 bmsg->msg_iovlen = lmsg->msg_iovlen;
447 bmsg->msg_control = lmsg->msg_control; 447 bmsg->msg_control = lmsg->msg_control;
448 bmsg->msg_controllen = lmsg->msg_controllen; 448 bmsg->msg_controllen = lmsg->msg_controllen;
449 bmsg->msg_flags = lmsg->msg_flags; 449 bmsg->msg_flags = lmsg->msg_flags;
450} 450}
451 451
452static void 452static void
453bsd_to_linux_msghdr(const struct msghdr *bmsg, struct linux_msghdr *lmsg) 453bsd_to_linux_msghdr(const struct msghdr *bmsg, struct linux_msghdr *lmsg)
454{ 454{
455 lmsg->msg_name = bmsg->msg_name; 455 lmsg->msg_name = bmsg->msg_name;
456 lmsg->msg_namelen = bmsg->msg_namelen; 456 lmsg->msg_namelen = bmsg->msg_namelen;
457 lmsg->msg_iov = bmsg->msg_iov; 457 lmsg->msg_iov = bmsg->msg_iov;
458 lmsg->msg_iovlen = bmsg->msg_iovlen; 458 lmsg->msg_iovlen = bmsg->msg_iovlen;
459 lmsg->msg_control = bmsg->msg_control; 459 lmsg->msg_control = bmsg->msg_control;
460 lmsg->msg_controllen = bmsg->msg_controllen; 460 lmsg->msg_controllen = bmsg->msg_controllen;
461 lmsg->msg_flags = bmsg->msg_flags; 461 lmsg->msg_flags = bmsg->msg_flags;
462} 462}
463 463
464int 464int
465linux_sys_sendmsg(struct lwp *l, const struct linux_sys_sendmsg_args *uap, register_t *retval) 465linux_sys_sendmsg(struct lwp *l, const struct linux_sys_sendmsg_args *uap, register_t *retval)
466{ 466{
467 /* { 467 /* {
468 syscallarg(int) s; 468 syscallarg(int) s;
469 syscallarg(struct linux_msghdr *) msg; 469 syscallarg(struct linux_msghdr *) msg;
470 syscallarg(u_int) flags; 470 syscallarg(u_int) flags;
471 } */ 471 } */
472 struct msghdr msg; 472 struct msghdr msg;
473 struct linux_msghdr lmsg; 473 struct linux_msghdr lmsg;
474 int error; 474 int error;
475 int bflags; 475 int bflags;
476 struct sockaddr_big nam; 476 struct sockaddr_big nam;
477 u_int8_t *control; 477 u_int8_t *control;
478 struct mbuf *ctl_mbuf = NULL; 478 struct mbuf *ctl_mbuf = NULL;
479 479
480 error = copyin(SCARG(uap, msg), &lmsg, sizeof(lmsg)); 480 error = copyin(SCARG(uap, msg), &lmsg, sizeof(lmsg));
481 if (error) 481 if (error)
482 return error; 482 return error;
483 linux_to_bsd_msghdr(&lmsg, &msg); 483 linux_to_bsd_msghdr(&lmsg, &msg);
484 484
485 msg.msg_flags = MSG_IOVUSRSPACE; 485 msg.msg_flags = MSG_IOVUSRSPACE;
486 486
487 /* 487 /*
488 * Translate message flags. 488 * Translate message flags.
489 */ 489 */
490 bflags = linux_to_bsd_msg_flags(SCARG(uap, flags)); 490 bflags = linux_to_bsd_msg_flags(SCARG(uap, flags));
491 if (bflags < 0) 491 if (bflags < 0)
492 /* Some supported flag */ 492 /* Some supported flag */
493 return EINVAL; 493 return EINVAL;
494 494
495 if (lmsg.msg_name) { 495 if (lmsg.msg_name) {
496 /* Read in and convert the sockaddr */ 496 /* Read in and convert the sockaddr */
497 error = linux_get_sa(l, SCARG(uap, s), &nam, msg.msg_name, 497 error = linux_get_sa(l, SCARG(uap, s), &nam, msg.msg_name,
498 msg.msg_namelen); 498 msg.msg_namelen);
499 if (error) 499 if (error)
500 return (error); 500 return (error);
501 msg.msg_name = &nam; 501 msg.msg_name = &nam;
502 } 502 }
503 503
504 /* 504 /*
505 * Handle cmsg if there is any. 505 * Handle cmsg if there is any.
506 */ 506 */
507 if (LINUX_CMSG_FIRSTHDR(&lmsg)) { 507 if (LINUX_CMSG_FIRSTHDR(&lmsg)) {
508 struct linux_cmsghdr l_cmsg, *l_cc; 508 struct linux_cmsghdr l_cmsg, *l_cc;
509 struct cmsghdr *cmsg; 509 struct cmsghdr *cmsg;
510 ssize_t resid = msg.msg_controllen; 510 ssize_t resid = msg.msg_controllen;
511 size_t clen, cidx = 0, cspace; 511 size_t clen, cidx = 0, cspace;
512 512
513 ctl_mbuf = m_get(M_WAIT, MT_CONTROL); 513 ctl_mbuf = m_get(M_WAIT, MT_CONTROL);
514 clen = MLEN; 514 clen = MLEN;
515 control = mtod(ctl_mbuf, void *); 515 control = mtod(ctl_mbuf, void *);
516 516
517 l_cc = LINUX_CMSG_FIRSTHDR(&lmsg); 517 l_cc = LINUX_CMSG_FIRSTHDR(&lmsg);
518 do { 518 do {
519 error = copyin(l_cc, &l_cmsg, sizeof(l_cmsg)); 519 error = copyin(l_cc, &l_cmsg, sizeof(l_cmsg));
520 if (error) 520 if (error)
521 goto done; 521 goto done;
522 522
523 /* 523 /*
524 * Sanity check the control message length. 524 * Sanity check the control message length.
525 */ 525 */
526 if (l_cmsg.cmsg_len > resid 526 if (l_cmsg.cmsg_len > resid
527 || l_cmsg.cmsg_len < sizeof l_cmsg) { 527 || l_cmsg.cmsg_len < sizeof l_cmsg) {
528 error = EINVAL; 528 error = EINVAL;
529 goto done; 529 goto done;
530 } 530 }
531 531
532 /* 532 /*
533 * Refuse unsupported control messages, and 533 * Refuse unsupported control messages, and
534 * translate fields as appropriate. 534 * translate fields as appropriate.
535 */ 535 */
536 switch (l_cmsg.cmsg_level) { 536 switch (l_cmsg.cmsg_level) {
537 case LINUX_SOL_SOCKET: 537 case LINUX_SOL_SOCKET:
538 /* It only differs on some archs */ 538 /* It only differs on some archs */
539 if (LINUX_SOL_SOCKET != SOL_SOCKET) 539 if (LINUX_SOL_SOCKET != SOL_SOCKET)
540 l_cmsg.cmsg_level = SOL_SOCKET; 540 l_cmsg.cmsg_level = SOL_SOCKET;
541 541
542 switch(l_cmsg.cmsg_type) { 542 switch(l_cmsg.cmsg_type) {
543 case LINUX_SCM_RIGHTS: 543 case LINUX_SCM_RIGHTS:
544 /* Linux SCM_RIGHTS is same as NetBSD */ 544 /* Linux SCM_RIGHTS is same as NetBSD */
545 break; 545 break;
546 546
547 case LINUX_SCM_CREDENTIALS: 547 case LINUX_SCM_CREDENTIALS:
548 /* no native equivalent, just drop it */ 548 /* no native equivalent, just drop it */
549 if (control != mtod(ctl_mbuf, void *)) 549 if (control != mtod(ctl_mbuf, void *))
550 free(control, M_MBUF); 550 free(control, M_MBUF);
551 m_free(ctl_mbuf); 551 m_free(ctl_mbuf);
552 ctl_mbuf = NULL; 552 ctl_mbuf = NULL;
553 msg.msg_control = NULL; 553 msg.msg_control = NULL;
554 msg.msg_controllen = 0; 554 msg.msg_controllen = 0;
555 goto skipcmsg; 555 goto skipcmsg;
556 556
557 default: 557 default:
558 /* other types not supported */ 558 /* other types not supported */
559 error = EINVAL; 559 error = EINVAL;
560 goto done; 560 goto done;
561 } 561 }
562 break; 562 break;
563 default: 563 default:
564 /* pray and leave intact */ 564 /* pray and leave intact */
565 break; 565 break;
566 } 566 }
567 567
568 cspace = CMSG_SPACE(l_cmsg.cmsg_len - sizeof(l_cmsg)); 568 cspace = CMSG_SPACE(l_cmsg.cmsg_len - sizeof(l_cmsg));
569 569
570 /* Check the buffer is big enough */ 570 /* Check the buffer is big enough */
571 if (__predict_false(cidx + cspace > clen)) { 571 if (__predict_false(cidx + cspace > clen)) {
572 u_int8_t *nc; 572 u_int8_t *nc;
573 size_t nclen; 573 size_t nclen;
574 574
575 nclen = cidx + cspace; 575 nclen = cidx + cspace;
576 if (nclen >= PAGE_SIZE) { 576 if (nclen >= PAGE_SIZE) {
577 error = EINVAL; 577 error = EINVAL;
578 goto done; 578 goto done;
579 } 579 }
580 nc = realloc(clen <= MLEN ? NULL : control, 580 nc = realloc(clen <= MLEN ? NULL : control,
581 nclen, M_TEMP, M_WAITOK); 581 nclen, M_TEMP, M_WAITOK);
582 if (!nc) { 582 if (!nc) {
583 error = ENOMEM; 583 error = ENOMEM;
584 goto done; 584 goto done;
585 } 585 }
586 if (cidx <= MLEN) 586 if (cidx <= MLEN)
587 /* Old buffer was in mbuf... */ 587 /* Old buffer was in mbuf... */
588 memcpy(nc, control, cidx); 588 memcpy(nc, control, cidx);
589 control = nc; 589 control = nc;
590 clen = nclen; 590 clen = nclen;
591 } 591 }
592 592
593 /* Copy header */ 593 /* Copy header */
594 cmsg = (void *)&control[cidx]; 594 cmsg = (void *)&control[cidx];
595 cmsg->cmsg_len = l_cmsg.cmsg_len + LINUX_CMSG_ALIGN_DELTA; 595 cmsg->cmsg_len = l_cmsg.cmsg_len + LINUX_CMSG_ALIGN_DELTA;
596 cmsg->cmsg_level = l_cmsg.cmsg_level; 596 cmsg->cmsg_level = l_cmsg.cmsg_level;
597 cmsg->cmsg_type = l_cmsg.cmsg_type; 597 cmsg->cmsg_type = l_cmsg.cmsg_type;
598 598
599 /* Zero area between header and data */ 599 /* Zero area between header and data */
600 memset(cmsg + 1, 0,  600 memset(cmsg + 1, 0,
601 CMSG_ALIGN(sizeof(*cmsg)) - sizeof(*cmsg)); 601 CMSG_ALIGN(sizeof(*cmsg)) - sizeof(*cmsg));
602 602
603 /* Copyin the data */ 603 /* Copyin the data */
604 error = copyin(LINUX_CMSG_DATA(l_cc), 604 error = copyin(LINUX_CMSG_DATA(l_cc),
605 CMSG_DATA(cmsg), 605 CMSG_DATA(cmsg),
606 l_cmsg.cmsg_len - sizeof(l_cmsg)); 606 l_cmsg.cmsg_len - sizeof(l_cmsg));
607 if (error) 607 if (error)
608 goto done; 608 goto done;
609 609
610 resid -= LINUX_CMSG_ALIGN(l_cmsg.cmsg_len); 610 resid -= LINUX_CMSG_ALIGN(l_cmsg.cmsg_len);
611 cidx += cspace; 611 cidx += cspace;
612 } while ((l_cc = LINUX_CMSG_NXTHDR(&msg, l_cc, &l_cmsg)) && resid > 0); 612 } while ((l_cc = LINUX_CMSG_NXTHDR(&msg, l_cc, &l_cmsg)) && resid > 0);
613 613
614 /* If we allocated a buffer, attach to mbuf */ 614 /* If we allocated a buffer, attach to mbuf */
615 if (cidx > MLEN) { 615 if (cidx > MLEN) {
616 MEXTADD(ctl_mbuf, control, clen, M_MBUF, NULL, NULL); 616 MEXTADD(ctl_mbuf, control, clen, M_MBUF, NULL, NULL);
617 ctl_mbuf->m_flags |= M_EXT_RW; 617 ctl_mbuf->m_flags |= M_EXT_RW;
618 } 618 }
619 control = NULL; 619 control = NULL;
620 ctl_mbuf->m_len = cidx; 620 ctl_mbuf->m_len = cidx;
621 621
622 msg.msg_control = ctl_mbuf; 622 msg.msg_control = ctl_mbuf;
623 msg.msg_flags |= MSG_CONTROLMBUF; 623 msg.msg_flags |= MSG_CONTROLMBUF;
624 624
625 ktrkuser("mbcontrol", mtod(ctl_mbuf, void *), 625 ktrkuser("mbcontrol", mtod(ctl_mbuf, void *),
626 msg.msg_controllen); 626 msg.msg_controllen);
627 } 627 }
628 628
629skipcmsg: 629skipcmsg:
630 error = do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval); 630 error = do_sys_sendmsg(l, SCARG(uap, s), &msg, bflags, retval);
631 /* Freed internally */ 631 /* Freed internally */
632 ctl_mbuf = NULL; 632 ctl_mbuf = NULL;
633 633
634done: 634done:
635 if (ctl_mbuf != NULL) { 635 if (ctl_mbuf != NULL) {
636 if (control != NULL && control != mtod(ctl_mbuf, void *)) 636 if (control != NULL && control != mtod(ctl_mbuf, void *))
637 free(control, M_MBUF); 637 free(control, M_MBUF);
638 m_free(ctl_mbuf); 638 m_free(ctl_mbuf);
639 } 639 }
640 return (error); 640 return (error);
641} 641}
642 642
643int 643int
644linux_sys_recvfrom(struct lwp *l, const struct linux_sys_recvfrom_args *uap, register_t *retval) 644linux_sys_recvfrom(struct lwp *l, const struct linux_sys_recvfrom_args *uap, register_t *retval)
645{ 645{
646 /* { 646 /* {
647 syscallarg(int) s; 647 syscallarg(int) s;
648 syscallarg(void *) buf; 648 syscallarg(void *) buf;
649 syscallarg(int) len; 649 syscallarg(int) len;
650 syscallarg(int) flags; 650 syscallarg(int) flags;
651 syscallarg(struct osockaddr *) from; 651 syscallarg(struct osockaddr *) from;
652 syscallarg(int *) fromlenaddr; 652 syscallarg(int *) fromlenaddr;
653 } */ 653 } */
654 int error; 654 int error;
655 struct sys_recvfrom_args bra; 655 struct sys_recvfrom_args bra;
656 656
657 SCARG(&bra, s) = SCARG(uap, s); 657 SCARG(&bra, s) = SCARG(uap, s);
658 SCARG(&bra, buf) = SCARG(uap, buf); 658 SCARG(&bra, buf) = SCARG(uap, buf);
659 SCARG(&bra, len) = SCARG(uap, len); 659 SCARG(&bra, len) = SCARG(uap, len);
660 SCARG(&bra, flags) = SCARG(uap, flags); 660 SCARG(&bra, flags) = SCARG(uap, flags);
661 SCARG(&bra, from) = (struct sockaddr *) SCARG(uap, from); 661 SCARG(&bra, from) = (struct sockaddr *) SCARG(uap, from);
662 SCARG(&bra, fromlenaddr) = (socklen_t *)SCARG(uap, fromlenaddr); 662 SCARG(&bra, fromlenaddr) = (socklen_t *)SCARG(uap, fromlenaddr);
663 663
664 if ((error = sys_recvfrom(l, &bra, retval))) 664 if ((error = sys_recvfrom(l, &bra, retval)))
665 return (error); 665 return (error);
666 666
667 if (SCARG(uap, from) && (error = linux_sa_put(SCARG(uap, from)))) 667 if (SCARG(uap, from) && (error = linux_sa_put(SCARG(uap, from))))
668 return (error); 668 return (error);
669 669
670 return (0); 670 return (0);
671} 671}
672 672
673static int 673static int
674linux_copyout_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control) 674linux_copyout_msg_control(struct lwp *l, struct msghdr *mp, struct mbuf *control)
675{ 675{
676 int dlen, error = 0; 676 int dlen, error = 0;
677 struct cmsghdr *cmsg; 677 struct cmsghdr *cmsg;
678 struct linux_cmsghdr linux_cmsg; 678 struct linux_cmsghdr linux_cmsg;
679 struct mbuf *m; 679 struct mbuf *m;
680 char *q, *q_end; 680 char *q, *q_end;
681 681
682 if (mp->msg_controllen <= 0 || control == 0) { 682 if (mp->msg_controllen <= 0 || control == 0) {
683 mp->msg_controllen = 0; 683 mp->msg_controllen = 0;
684 free_control_mbuf(l, control, control); 684 free_control_mbuf(l, control, control);
685 return 0; 685 return 0;
686 } 686 }
687 687
688 ktrkuser("msgcontrol", mtod(control, void *), mp->msg_controllen); 688 ktrkuser("msgcontrol", mtod(control, void *), mp->msg_controllen);
689 689
690 q = (char *)mp->msg_control; 690 q = (char *)mp->msg_control;
691 q_end = q + mp->msg_controllen; 691 q_end = q + mp->msg_controllen;
692 692
693 for (m = control; m != NULL; ) { 693 for (m = control; m != NULL; ) {
694 cmsg = mtod(m, struct cmsghdr *); 694 cmsg = mtod(m, struct cmsghdr *);
695 695
696 /* 696 /*
697 * Fixup cmsg. We handle two things: 697 * Fixup cmsg. We handle two things:
698 * 0. different sizeof cmsg_len. 698 * 0. different sizeof cmsg_len.
699 * 1. different values for level/type on some archs 699 * 1. different values for level/type on some archs
700 * 2. different alignment of CMSG_DATA on some archs 700 * 2. different alignment of CMSG_DATA on some archs
701 */ 701 */
702 linux_cmsg.cmsg_len = cmsg->cmsg_len - LINUX_CMSG_ALIGN_DELTA; 702 linux_cmsg.cmsg_len = cmsg->cmsg_len - LINUX_CMSG_ALIGN_DELTA;
703 linux_cmsg.cmsg_level = cmsg->cmsg_level; 703 linux_cmsg.cmsg_level = cmsg->cmsg_level;
704 linux_cmsg.cmsg_type = cmsg->cmsg_type; 704 linux_cmsg.cmsg_type = cmsg->cmsg_type;
705 705
706 dlen = q_end - q; 706 dlen = q_end - q;
707 if (linux_cmsg.cmsg_len > dlen) { 707 if (linux_cmsg.cmsg_len > dlen) {
708 /* Not enough room for the parameter */ 708 /* Not enough room for the parameter */
709 dlen -= sizeof linux_cmsg; 709 dlen -= sizeof linux_cmsg;
710 if (dlen <= 0) 710 if (dlen <= 0)
711 /* Discard if header wont fit */ 711 /* Discard if header wont fit */
712 break; 712 break;
713 mp->msg_flags |= MSG_CTRUNC; 713 mp->msg_flags |= MSG_CTRUNC;
714 if (linux_cmsg.cmsg_level == SOL_SOCKET 714 if (linux_cmsg.cmsg_level == SOL_SOCKET
715 && linux_cmsg.cmsg_type == SCM_RIGHTS) 715 && linux_cmsg.cmsg_type == SCM_RIGHTS)
716 /* Do not truncate me ... */ 716 /* Do not truncate me ... */
717 break; 717 break;
718 } else 718 } else
719 dlen = linux_cmsg.cmsg_len - sizeof linux_cmsg; 719 dlen = linux_cmsg.cmsg_len - sizeof linux_cmsg;
720 720
721 switch (linux_cmsg.cmsg_level) { 721 switch (linux_cmsg.cmsg_level) {
722 case SOL_SOCKET: 722 case SOL_SOCKET:
723 linux_cmsg.cmsg_level = LINUX_SOL_SOCKET; 723 linux_cmsg.cmsg_level = LINUX_SOL_SOCKET;
724 switch (linux_cmsg.cmsg_type) { 724 switch (linux_cmsg.cmsg_type) {
725 case SCM_RIGHTS: 725 case SCM_RIGHTS:
726 /* Linux SCM_RIGHTS is same as NetBSD */ 726 /* Linux SCM_RIGHTS is same as NetBSD */
727 break; 727 break;
728 728
729 default: 729 default:
730 /* other types not supported */ 730 /* other types not supported */
731 error = EINVAL; 731 error = EINVAL;
732 goto done; 732 goto done;
733 } 733 }
734 /* machine dependent ! */ 734 /* machine dependent ! */
735 break; 735 break;
736 default: 736 default:
737 /* pray and leave intact */ 737 /* pray and leave intact */
738 break; 738 break;
739 } 739 }
740 740
741 /* There can be padding between the header and data... */ 741 /* There can be padding between the header and data... */
742 error = copyout(&linux_cmsg, q, sizeof linux_cmsg); 742 error = copyout(&linux_cmsg, q, sizeof linux_cmsg);
743 if (error != 0) { 743 if (error != 0) {
744 error = copyout(CCMSG_DATA(cmsg), q + sizeof linux_cmsg, 744 error = copyout(CCMSG_DATA(cmsg), q + sizeof linux_cmsg,
745 dlen); 745 dlen);
746 } 746 }
747 if (error != 0) { 747 if (error != 0) {
748 /* We must free all the SCM_RIGHTS */ 748 /* We must free all the SCM_RIGHTS */
749 m = control; 749 m = control;
750 break; 750 break;
751 } 751 }
752 m = m->m_next; 752 m = m->m_next;
753 if (m == NULL || q + LINUX_CMSG_SPACE(dlen) > q_end) { 753 if (m == NULL || q + LINUX_CMSG_SPACE(dlen) > q_end) {
754 q += LINUX_CMSG_LEN(dlen); 754 q += LINUX_CMSG_LEN(dlen);
755 break; 755 break;
756 } 756 }
757 q += LINUX_CMSG_SPACE(dlen); 757 q += LINUX_CMSG_SPACE(dlen);
758 } 758 }
759 759
760 done: 760 done:
761 free_control_mbuf(l, control, m); 761 free_control_mbuf(l, control, m);
762 762
763 mp->msg_controllen = q - (char *)mp->msg_control; 763 mp->msg_controllen = q - (char *)mp->msg_control;
764 return error; 764 return error;
765} 765}
766 766
767int 767int
768linux_sys_recvmsg(struct lwp *l, const struct linux_sys_recvmsg_args *uap, register_t *retval) 768linux_sys_recvmsg(struct lwp *l, const struct linux_sys_recvmsg_args *uap, register_t *retval)
769{ 769{
770 /* { 770 /* {
771 syscallarg(int) s; 771 syscallarg(int) s;
772 syscallarg(struct linux_msghdr *) msg; 772 syscallarg(struct linux_msghdr *) msg;
773 syscallarg(u_int) flags; 773 syscallarg(u_int) flags;
774 } */ 774 } */
775 struct msghdr msg; 775 struct msghdr msg;
776 struct linux_msghdr lmsg; 776 struct linux_msghdr lmsg;
777 int error; 777 int error;
778 struct mbuf *from, *control; 778 struct mbuf *from, *control;
779 779
780 error = copyin(SCARG(uap, msg), &lmsg, sizeof(lmsg)); 780 error = copyin(SCARG(uap, msg), &lmsg, sizeof(lmsg));
781 if (error) 781 if (error)
782 return (error); 782 return (error);
783 linux_to_bsd_msghdr(&lmsg, &msg); 783 linux_to_bsd_msghdr(&lmsg, &msg);
784 784
785 msg.msg_flags = linux_to_bsd_msg_flags(SCARG(uap, flags)); 785 msg.msg_flags = linux_to_bsd_msg_flags(SCARG(uap, flags));
786 if (msg.msg_flags < 0) { 786 if (msg.msg_flags < 0) {
787 /* Some unsupported flag */ 787 /* Some unsupported flag */
788 return (EINVAL); 788 return (EINVAL);
789 } 789 }
790 msg.msg_flags |= MSG_IOVUSRSPACE; 790 msg.msg_flags |= MSG_IOVUSRSPACE;
791 791
792 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from, 792 error = do_sys_recvmsg(l, SCARG(uap, s), &msg, &from,
793 msg.msg_control != NULL ? &control : NULL, retval); 793 msg.msg_control != NULL ? &control : NULL, retval);
794 if (error != 0) 794 if (error != 0)
795 return error; 795 return error;
796 796
797 if (msg.msg_control != NULL) 797 if (msg.msg_control != NULL)
798 error = linux_copyout_msg_control(l, &msg, control); 798 error = linux_copyout_msg_control(l, &msg, control);
799 799
800 if (error == 0 && from != 0) { 800 if (error == 0 && from != 0) {
801 mtod(from, struct osockaddr *)->sa_family = 801 mtod(from, struct osockaddr *)->sa_family =
802 bsd_to_linux_domain(mtod(from, struct sockaddr *)->sa_family); 802 bsd_to_linux_domain(mtod(from, struct sockaddr *)->sa_family);
803 error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0, 803 error = copyout_sockname(msg.msg_name, &msg.msg_namelen, 0,
804 from); 804 from);
805 } else 805 } else
806 msg.msg_namelen = 0; 806 msg.msg_namelen = 0;
807 807
808 if (from != NULL) 808 if (from != NULL)
809 m_free(from); 809 m_free(from);
810 810
811 if (error == 0) { 811 if (error == 0) {
812 msg.msg_flags = bsd_to_linux_msg_flags(msg.msg_flags); 812 msg.msg_flags = bsd_to_linux_msg_flags(msg.msg_flags);
813 if (msg.msg_flags < 0) 813 if (msg.msg_flags < 0)
814 /* Some flag unsupported by Linux */ 814 /* Some flag unsupported by Linux */
815 error = EINVAL; 815 error = EINVAL;
816 else { 816 else {
817 ktrkuser("msghdr", &msg, sizeof(msg)); 817 ktrkuser("msghdr", &msg, sizeof(msg));
818 bsd_to_linux_msghdr(&msg, &lmsg); 818 bsd_to_linux_msghdr(&msg, &lmsg);
819 error = copyout(&lmsg, SCARG(uap, msg), sizeof(lmsg)); 819 error = copyout(&lmsg, SCARG(uap, msg), sizeof(lmsg));
820 } 820 }
821 } 821 }
822 822
823 return (error); 823 return (error);
824} 824}
825 825
826/* 826/*
827 * Convert socket option level from Linux to NetBSD value. Only SOL_SOCKET 827 * Convert socket option level from Linux to NetBSD value. Only SOL_SOCKET
828 * is different, the rest matches IPPROTO_* on both systems. 828 * is different, the rest matches IPPROTO_* on both systems.
829 */ 829 */
830int 830int
831linux_to_bsd_sopt_level(int llevel) 831linux_to_bsd_sopt_level(int llevel)
832{ 832{
833 833
834 switch (llevel) { 834 switch (llevel) {
835 case LINUX_SOL_SOCKET: 835 case LINUX_SOL_SOCKET:
836 return SOL_SOCKET; 836 return SOL_SOCKET;
837 case LINUX_SOL_IP: 837 case LINUX_SOL_IP:
838 return IPPROTO_IP; 838 return IPPROTO_IP;
839#ifdef INET6 839#ifdef INET6
840 case LINUX_SOL_IPV6: 840 case LINUX_SOL_IPV6:
841 return IPPROTO_IPV6; 841 return IPPROTO_IPV6;
842#endif 842#endif
843 case LINUX_SOL_TCP: 843 case LINUX_SOL_TCP:
844 return IPPROTO_TCP; 844 return IPPROTO_TCP;
845 case LINUX_SOL_UDP: 845 case LINUX_SOL_UDP:
846 return IPPROTO_UDP; 846 return IPPROTO_UDP;
847 default: 847 default:
848 return -1; 848 return -1;
849 } 849 }
850} 850}
851 851
852/* 852/*
853 * Convert Linux socket level socket option numbers to NetBSD values. 853 * Convert Linux socket level socket option numbers to NetBSD values.
854 */ 854 */
855int 855int
856linux_to_bsd_so_sockopt(int lopt) 856linux_to_bsd_so_sockopt(int lopt)
857{ 857{
858 858
859 switch (lopt) { 859 switch (lopt) {
860 case LINUX_SO_DEBUG: 860 case LINUX_SO_DEBUG:
861 return SO_DEBUG; 861 return SO_DEBUG;
862 case LINUX_SO_REUSEADDR: 862 case LINUX_SO_REUSEADDR:
863 /* 863 /*
864 * Linux does not implement SO_REUSEPORT, but allows reuse of a 864 * Linux does not implement SO_REUSEPORT, but allows reuse of
865 * host:port pair through SO_REUSEADDR even if the address is not a 865 * a host:port pair through SO_REUSEADDR even if the address
866 * multicast-address. Effectively, this means that we should use 866 * is not a multicast-address. Effectively, this means that we
867 * SO_REUSEPORT to allow Linux applications to not exit with 867 * should use SO_REUSEPORT to allow Linux applications to not
868 * EADDRINUSE 868 * exit with EADDRINUSE
869 */ 869 */
870 return SO_REUSEPORT; 870 return SO_REUSEPORT;
871 case LINUX_SO_TYPE: 871 case LINUX_SO_TYPE:
872 return SO_TYPE; 872 return SO_TYPE;
873 case LINUX_SO_ERROR: 873 case LINUX_SO_ERROR:
874 return SO_ERROR; 874 return SO_ERROR;
875 case LINUX_SO_DONTROUTE: 875 case LINUX_SO_DONTROUTE:
876 return SO_DONTROUTE; 876 return SO_DONTROUTE;
877 case LINUX_SO_BROADCAST: 877 case LINUX_SO_BROADCAST:
878 return SO_BROADCAST; 878 return SO_BROADCAST;
879 case LINUX_SO_SNDBUF: 879 case LINUX_SO_SNDBUF:
880 return SO_SNDBUF; 880 return SO_SNDBUF;
881 case LINUX_SO_RCVBUF: 881 case LINUX_SO_RCVBUF:
882 return SO_RCVBUF; 882 return SO_RCVBUF;
883 case LINUX_SO_SNDLOWAT: 
884 return SO_SNDLOWAT; 
885 case LINUX_SO_RCVLOWAT: 
886 return SO_RCVLOWAT; 
887 case LINUX_SO_KEEPALIVE: 883 case LINUX_SO_KEEPALIVE:
888 return SO_KEEPALIVE; 884 return SO_KEEPALIVE;
889 case LINUX_SO_OOBINLINE: 885 case LINUX_SO_OOBINLINE:
890 return SO_OOBINLINE; 886 return SO_OOBINLINE;
 887 case LINUX_SO_NO_CHECK:
 888 case LINUX_SO_PRIORITY:
 889 return -1;
891 case LINUX_SO_LINGER: 890 case LINUX_SO_LINGER:
892 return SO_LINGER; 891 return SO_LINGER;
 892 case LINUX_SO_BSDCOMPAT:
 893 case LINUX_SO_PASSCRED:
 894 case LINUX_SO_PEERCRED:
 895 return -1;
 896 case LINUX_SO_RCVLOWAT:
 897 return SO_RCVLOWAT;
 898 case LINUX_SO_SNDLOWAT:
 899 return SO_SNDLOWAT;
 900 case LINUX_SO_RCVTIMEO:
 901 return SO_RCVTIMEO;
 902 case LINUX_SO_SNDTIMEO:
 903 return SO_SNDTIMEO;
 904 case LINUX_SO_SECURITY_AUTHENTICATION:
 905 case LINUX_SO_SECURITY_ENCRYPTION_TRANSPORT:
 906 case LINUX_SO_SECURITY_ENCRYPTION_NETWORK:
 907 case LINUX_SO_BINDTODEVICE:
 908 case LINUX_SO_ATTACH_FILTER:
 909 case LINUX_SO_DETACH_FILTER:
 910 case LINUX_SO_PEERNAME:
 911 return -1;
 912 case LINUX_SO_TIMESTAMP:
 913 return SO_TIMESTAMP;
893 case LINUX_SO_ACCEPTCONN: 914 case LINUX_SO_ACCEPTCONN:
894 return SO_ACCEPTCONN; 915 case LINUX_SO_PEERSEC:
895 case LINUX_SO_PRIORITY: 916 case LINUX_SO_SNDBUFFORCE:
896 case LINUX_SO_NO_CHECK: 917 case LINUX_SO_RCVBUFFORCE:
 918 case LINUX_SO_PASSSEC:
 919 case LINUX_SO_TIMESTAMPNS:
 920 case LINUX_SO_MARK:
 921 case LINUX_SO_TIMESTAMPING:
 922 case LINUX_SO_PROTOCOL:
 923 case LINUX_SO_DOMAIN:
 924 case LINUX_SO_RXQ_OVFL:
 925 case LINUX_SO_WIFI_STATUS:
 926 case LINUX_SO_PEEK_OFF:
 927 case LINUX_SO_NOFCS:
897 default: 928 default:
898 return -1; 929 return -1;
899 } 930 }
900} 931}
901 932
902/* 933/*
903 * Convert Linux IP level socket option number to NetBSD values. 934 * Convert Linux IP level socket option number to NetBSD values.
904 */ 935 */
905int 936int
906linux_to_bsd_ip_sockopt(int lopt) 937linux_to_bsd_ip_sockopt(int lopt)
907{ 938{
908 939
909 switch (lopt) { 940 switch (lopt) {
910 case LINUX_IP_TOS: 941 case LINUX_IP_TOS:
911 return IP_TOS; 942 return IP_TOS;
912 case LINUX_IP_TTL: 943 case LINUX_IP_TTL:
913 return IP_TTL; 944 return IP_TTL;
914 case LINUX_IP_HDRINCL: 945 case LINUX_IP_HDRINCL:
915 return IP_HDRINCL; 946 return IP_HDRINCL;
916 case LINUX_IP_MULTICAST_TTL: 947 case LINUX_IP_MULTICAST_TTL:
917 return IP_MULTICAST_TTL; 948 return IP_MULTICAST_TTL;
918 case LINUX_IP_MULTICAST_LOOP: 949 case LINUX_IP_MULTICAST_LOOP:
919 return IP_MULTICAST_LOOP; 950 return IP_MULTICAST_LOOP;
920 case LINUX_IP_MULTICAST_IF: 951 case LINUX_IP_MULTICAST_IF:
921 return IP_MULTICAST_IF; 952 return IP_MULTICAST_IF;
922 case LINUX_IP_ADD_MEMBERSHIP: 953 case LINUX_IP_ADD_MEMBERSHIP:
923 return IP_ADD_MEMBERSHIP; 954 return IP_ADD_MEMBERSHIP;
924 case LINUX_IP_DROP_MEMBERSHIP: 955 case LINUX_IP_DROP_MEMBERSHIP:
925 return IP_DROP_MEMBERSHIP; 956 return IP_DROP_MEMBERSHIP;
926 default: 957 default:
927 return -1; 958 return -1;
928 } 959 }
929} 960}
930 961
931/* 962/*
932 * Convert Linux IPV6 level socket option number to NetBSD values. 963 * Convert Linux IPV6 level socket option number to NetBSD values.
933 */ 964 */
934#ifdef INET6 965#ifdef INET6
935int 966int
936linux_to_bsd_ipv6_sockopt(int lopt) 967linux_to_bsd_ipv6_sockopt(int lopt)
937{ 968{
938 969
939 switch (lopt) { 970 switch (lopt) {
940 case LINUX_IPV6_V6ONLY: 971 case LINUX_IPV6_V6ONLY:
941 return IPV6_V6ONLY; 972 return IPV6_V6ONLY;
942 default: 973 default:
943 return -1; 974 return -1;
944 } 975 }
945} 976}
946#endif 977#endif
947 978
948/* 979/*
949 * Convert Linux TCP level socket option number to NetBSD values. 980 * Convert Linux TCP level socket option number to NetBSD values.
950 */ 981 */
951int 982int
952linux_to_bsd_tcp_sockopt(int lopt) 983linux_to_bsd_tcp_sockopt(int lopt)
953{ 984{
954 985
955 switch (lopt) { 986 switch (lopt) {
956 case LINUX_TCP_NODELAY: 987 case LINUX_TCP_NODELAY:
957 return TCP_NODELAY; 988 return TCP_NODELAY;
958 case LINUX_TCP_MAXSEG: 989 case LINUX_TCP_MAXSEG:
959 return TCP_MAXSEG; 990 return TCP_MAXSEG;
960 default: 991 default:
961 return -1; 992 return -1;
962 } 993 }
963} 994}
964 995
965/* 996/*
966 * Convert Linux UDP level socket option number to NetBSD values. 997 * Convert Linux UDP level socket option number to NetBSD values.
967 */ 998 */
968int 999int
969linux_to_bsd_udp_sockopt(int lopt) 1000linux_to_bsd_udp_sockopt(int lopt)
970{ 1001{
971 1002
972 switch (lopt) { 1003 switch (lopt) {
973 default: 1004 default:
974 return -1; 1005 return -1;
975 } 1006 }
976} 1007}
977 1008
978/* 1009/*
979 * Another reasonably straightforward function: setsockopt(2). 1010 * Another reasonably straightforward function: setsockopt(2).
980 * The level and option numbers are converted; the values passed 1011 * The level and option numbers are converted; the values passed
981 * are not (yet) converted, the ones currently implemented don't 1012 * are not (yet) converted, the ones currently implemented don't
982 * need conversion, as they are the same on both systems. 1013 * need conversion, as they are the same on both systems.
983 */ 1014 */
984int 1015int
985linux_sys_setsockopt(struct lwp *l, const struct linux_sys_setsockopt_args *uap, register_t *retval) 1016linux_sys_setsockopt(struct lwp *l, const struct linux_sys_setsockopt_args *uap, register_t *retval)
986{ 1017{
987 /* { 1018 /* {
988 syscallarg(int) s; 1019 syscallarg(int) s;
989 syscallarg(int) level; 1020 syscallarg(int) level;
990 syscallarg(int) optname; 1021 syscallarg(int) optname;
991 syscallarg(void *) optval; 1022 syscallarg(void *) optval;
992 syscallarg(int) optlen; 1023 syscallarg(int) optlen;
993 } */ 1024 } */
994 struct sys_setsockopt_args bsa; 1025 struct sys_setsockopt_args bsa;
995 int name; 1026 int name;
996 1027
997 SCARG(&bsa, s) = SCARG(uap, s); 1028 SCARG(&bsa, s) = SCARG(uap, s);
998 SCARG(&bsa, level) = linux_to_bsd_sopt_level(SCARG(uap, level)); 1029 SCARG(&bsa, level) = linux_to_bsd_sopt_level(SCARG(uap, level));
999 SCARG(&bsa, val) = SCARG(uap, optval); 1030 SCARG(&bsa, val) = SCARG(uap, optval);
1000 SCARG(&bsa, valsize) = SCARG(uap, optlen); 1031 SCARG(&bsa, valsize) = SCARG(uap, optlen);
1001 1032
1002 /* 1033 /*
1003 * Linux supports only SOL_SOCKET for AF_LOCAL domain sockets 1034 * Linux supports only SOL_SOCKET for AF_LOCAL domain sockets
1004 * and returns EOPNOTSUPP for other levels 1035 * and returns EOPNOTSUPP for other levels
1005 */ 1036 */
1006 if (SCARG(&bsa, level) != SOL_SOCKET) { 1037 if (SCARG(&bsa, level) != SOL_SOCKET) {
1007 struct socket *so; 1038 struct socket *so;
1008 int error, family; 1039 int error, family;
1009 1040
1010 /* fd_getsock() will use the descriptor for us */ 1041 /* fd_getsock() will use the descriptor for us */
1011 if ((error = fd_getsock(SCARG(&bsa, s), &so)) != 0) 1042 if ((error = fd_getsock(SCARG(&bsa, s), &so)) != 0)
1012 return error; 1043 return error;
1013 family = so->so_proto->pr_domain->dom_family; 1044 family = so->so_proto->pr_domain->dom_family;
1014 fd_putfile(SCARG(&bsa, s)); 1045 fd_putfile(SCARG(&bsa, s));
1015 1046
1016 if (family == AF_LOCAL) 1047 if (family == AF_LOCAL)
1017 return EOPNOTSUPP; 1048 return EOPNOTSUPP;
1018 } 1049 }
1019 1050
1020 switch (SCARG(&bsa, level)) { 1051 switch (SCARG(&bsa, level)) {
1021 case SOL_SOCKET: 1052 case SOL_SOCKET:
1022 name = linux_to_bsd_so_sockopt(SCARG(uap, optname)); 1053 name = linux_to_bsd_so_sockopt(SCARG(uap, optname));
1023 break; 1054 break;
1024 case IPPROTO_IP: 1055 case IPPROTO_IP:
1025 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname)); 1056 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname));
1026 break; 1057 break;
1027#ifdef INET6 1058#ifdef INET6
1028 case IPPROTO_IPV6: 1059 case IPPROTO_IPV6:
1029 name = linux_to_bsd_ipv6_sockopt(SCARG(uap, optname)); 1060 name = linux_to_bsd_ipv6_sockopt(SCARG(uap, optname));
1030 break; 1061 break;
1031#endif 1062#endif
1032 case IPPROTO_TCP: 1063 case IPPROTO_TCP:
1033 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname)); 1064 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname));
1034 break; 1065 break;
1035 case IPPROTO_UDP: 1066 case IPPROTO_UDP:
1036 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname)); 1067 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname));
1037 break; 1068 break;
1038 default: 1069 default:
1039 return EINVAL; 1070 return EINVAL;
1040 } 1071 }
1041 1072
1042 if (name == -1) 1073 if (name == -1)
1043 return EINVAL; 1074 return EINVAL;
1044 SCARG(&bsa, name) = name; 1075 SCARG(&bsa, name) = name;
1045 1076
1046 return sys_setsockopt(l, &bsa, retval); 1077 return sys_setsockopt(l, &bsa, retval);
1047} 1078}
1048 1079
1049/* 1080/*
1050 * getsockopt(2) is very much the same as setsockopt(2) (see above) 1081 * getsockopt(2) is very much the same as setsockopt(2) (see above)
1051 */ 1082 */
1052int 1083int
1053linux_sys_getsockopt(struct lwp *l, const struct linux_sys_getsockopt_args *uap, register_t *retval) 1084linux_sys_getsockopt(struct lwp *l, const struct linux_sys_getsockopt_args *uap, register_t *retval)
1054{ 1085{
1055 /* { 1086 /* {
1056 syscallarg(int) s; 1087 syscallarg(int) s;
1057 syscallarg(int) level; 1088 syscallarg(int) level;
1058 syscallarg(int) optname; 1089 syscallarg(int) optname;
1059 syscallarg(void *) optval; 1090 syscallarg(void *) optval;
1060 syscallarg(int *) optlen; 1091 syscallarg(int *) optlen;
1061 } */ 1092 } */
1062 struct sys_getsockopt_args bga; 1093 struct sys_getsockopt_args bga;
1063 int name; 1094 int name;
1064 1095
1065 SCARG(&bga, s) = SCARG(uap, s); 1096 SCARG(&bga, s) = SCARG(uap, s);
1066 SCARG(&bga, level) = linux_to_bsd_sopt_level(SCARG(uap, level)); 1097 SCARG(&bga, level) = linux_to_bsd_sopt_level(SCARG(uap, level));
1067 SCARG(&bga, val) = SCARG(uap, optval); 1098 SCARG(&bga, val) = SCARG(uap, optval);
1068 SCARG(&bga, avalsize) = (socklen_t *)SCARG(uap, optlen); 1099 SCARG(&bga, avalsize) = (socklen_t *)SCARG(uap, optlen);
1069 1100
1070 switch (SCARG(&bga, level)) { 1101 switch (SCARG(&bga, level)) {
1071 case SOL_SOCKET: 1102 case SOL_SOCKET:
1072 name = linux_to_bsd_so_sockopt(SCARG(uap, optname)); 1103 name = linux_to_bsd_so_sockopt(SCARG(uap, optname));
1073 break; 1104 break;
1074 case IPPROTO_IP: 1105 case IPPROTO_IP:
1075 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname)); 1106 name = linux_to_bsd_ip_sockopt(SCARG(uap, optname));
1076 break; 1107 break;
1077#ifdef INET6 1108#ifdef INET6
1078 case IPPROTO_IPV6: 1109 case IPPROTO_IPV6:
1079 name = linux_to_bsd_ipv6_sockopt(SCARG(uap, optname)); 1110 name = linux_to_bsd_ipv6_sockopt(SCARG(uap, optname));
1080 break; 1111 break;
1081#endif 1112#endif
1082 case IPPROTO_TCP: 1113 case IPPROTO_TCP:
1083 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname)); 1114 name = linux_to_bsd_tcp_sockopt(SCARG(uap, optname));
1084 break; 1115 break;
1085 case IPPROTO_UDP: 1116 case IPPROTO_UDP:
1086 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname)); 1117 name = linux_to_bsd_udp_sockopt(SCARG(uap, optname));
1087 break; 1118 break;
1088 default: 1119 default:
1089 return EINVAL; 1120 return EINVAL;
1090 } 1121 }
1091 1122
1092 if (name == -1) 1123 if (name == -1)
1093 return EINVAL; 1124 return EINVAL;
1094 SCARG(&bga, name) = name; 1125 SCARG(&bga, name) = name;
1095 1126
1096 return sys_getsockopt(l, &bga, retval); 1127 return sys_getsockopt(l, &bga, retval);
1097} 1128}
1098 1129
1099int 1130int
1100linux_getifname(struct lwp *l, register_t *retval, void *data) 1131linux_getifname(struct lwp *l, register_t *retval, void *data)
1101{ 1132{
1102 struct ifnet *ifp; 1133 struct ifnet *ifp;
1103 struct linux_ifreq ifr; 1134 struct linux_ifreq ifr;
1104 int error; 1135 int error;
1105 int s; 1136 int s;
1106 1137
1107 error = copyin(data, &ifr, sizeof(ifr)); 1138 error = copyin(data, &ifr, sizeof(ifr));
1108 if (error) 1139 if (error)
1109 return error; 1140 return error;
1110 1141
1111 s = pserialize_read_enter(); 1142 s = pserialize_read_enter();
1112 ifp = if_byindex(ifr.ifr_ifru.ifru_ifindex); 1143 ifp = if_byindex(ifr.ifr_ifru.ifru_ifindex);
1113 if (ifp == NULL) { 1144 if (ifp == NULL) {
1114 pserialize_read_exit(s); 1145 pserialize_read_exit(s);
1115 return ENODEV; 1146 return ENODEV;
1116 } 1147 }
1117 1148
1118 strncpy(ifr.ifr_name, ifp->if_xname, sizeof(ifr.ifr_name)); 1149 strncpy(ifr.ifr_name, ifp->if_xname, sizeof(ifr.ifr_name));
1119 pserialize_read_exit(s); 1150 pserialize_read_exit(s);
1120 1151
1121 return copyout(&ifr, data, sizeof(ifr)); 1152 return copyout(&ifr, data, sizeof(ifr));
1122} 1153}
1123 1154
1124int 1155int
1125linux_getifconf(struct lwp *l, register_t *retval, void *data) 1156linux_getifconf(struct lwp *l, register_t *retval, void *data)
1126{ 1157{
1127 struct linux_ifreq ifr, *ifrp = NULL; 1158 struct linux_ifreq ifr, *ifrp = NULL;
1128 struct linux_ifconf ifc; 1159 struct linux_ifconf ifc;
1129 struct ifnet *ifp; 1160 struct ifnet *ifp;
1130 struct sockaddr *sa; 1161 struct sockaddr *sa;
1131 struct osockaddr *osa; 1162 struct osockaddr *osa;
1132 int space = 0, error; 1163 int space = 0, error;
1133 const int sz = (int)sizeof(ifr); 1164 const int sz = (int)sizeof(ifr);
1134 bool docopy; 1165 bool docopy;
1135 int s; 1166 int s;
1136 int bound; 1167 int bound;
1137 struct psref psref; 1168 struct psref psref;
1138 1169
1139 error = copyin(data, &ifc, sizeof(ifc)); 1170 error = copyin(data, &ifc, sizeof(ifc));
1140 if (error) 1171 if (error)
1141 return error; 1172 return error;
1142 1173
1143 docopy = ifc.ifc_req != NULL; 1174 docopy = ifc.ifc_req != NULL;
1144 if (docopy) { 1175 if (docopy) {
1145 if (ifc.ifc_len < 0) 1176 if (ifc.ifc_len < 0)
1146 return EINVAL; 1177 return EINVAL;
1147 1178
1148 space = ifc.ifc_len; 1179 space = ifc.ifc_len;
1149 ifrp = ifc.ifc_req; 1180 ifrp = ifc.ifc_req;
1150 } 1181 }
1151 memset(&ifr, 0, sizeof(ifr)); 1182 memset(&ifr, 0, sizeof(ifr));
1152 1183
1153 bound = curlwp_bind(); 1184 bound = curlwp_bind();
1154 s = pserialize_read_enter(); 1185 s = pserialize_read_enter();
1155 IFNET_READER_FOREACH(ifp) { 1186 IFNET_READER_FOREACH(ifp) {
1156 struct ifaddr *ifa; 1187 struct ifaddr *ifa;
1157 if_acquire(ifp, &psref); 1188 if_acquire(ifp, &psref);
1158 pserialize_read_exit(s); 1189 pserialize_read_exit(s);
1159 1190
1160 (void)strncpy(ifr.ifr_name, ifp->if_xname, 1191 (void)strncpy(ifr.ifr_name, ifp->if_xname,
1161 sizeof(ifr.ifr_name)); 1192 sizeof(ifr.ifr_name));
1162 if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0') { 1193 if (ifr.ifr_name[sizeof(ifr.ifr_name) - 1] != '\0') {
1163 error = ENAMETOOLONG; 1194 error = ENAMETOOLONG;
1164 goto release_exit; 1195 goto release_exit;
1165 } 1196 }
1166 1197
1167 s = pserialize_read_enter(); 1198 s = pserialize_read_enter();
1168 IFADDR_READER_FOREACH(ifa, ifp) { 1199 IFADDR_READER_FOREACH(ifa, ifp) {
1169 struct psref psref_ifa; 1200 struct psref psref_ifa;
1170 ifa_acquire(ifa, &psref_ifa); 1201 ifa_acquire(ifa, &psref_ifa);
1171 pserialize_read_exit(s); 1202 pserialize_read_exit(s);
1172 1203
1173 sa = ifa->ifa_addr; 1204 sa = ifa->ifa_addr;
1174 if (sa->sa_family != AF_INET || 1205 if (sa->sa_family != AF_INET ||
1175 sa->sa_len > sizeof(*osa)) 1206 sa->sa_len > sizeof(*osa))
1176 goto next; 1207 goto next;
1177 memcpy(&ifr.ifr_addr, sa, sa->sa_len); 1208 memcpy(&ifr.ifr_addr, sa, sa->sa_len);
1178 osa = (struct osockaddr *)&ifr.ifr_addr; 1209 osa = (struct osockaddr *)&ifr.ifr_addr;
1179 osa->sa_family = sa->sa_family; 1210 osa->sa_family = sa->sa_family;
1180 if (space >= sz) { 1211 if (space >= sz) {
1181 error = copyout(&ifr, ifrp, sz); 1212 error = copyout(&ifr, ifrp, sz);
1182 if (error != 0) { 1213 if (error != 0) {
1183 ifa_release(ifa, &psref_ifa); 1214 ifa_release(ifa, &psref_ifa);
1184 goto release_exit; 1215 goto release_exit;
1185 } 1216 }
1186 ifrp++; 1217 ifrp++;
1187 } 1218 }
1188 space -= sz; 1219 space -= sz;
1189 next: 1220 next:
1190 s = pserialize_read_enter(); 1221 s = pserialize_read_enter();
1191 ifa_release(ifa, &psref_ifa); 1222 ifa_release(ifa, &psref_ifa);
1192 } 1223 }
1193 1224
1194 KASSERT(pserialize_in_read_section()); 1225 KASSERT(pserialize_in_read_section());
1195 if_release(ifp, &psref); 1226 if_release(ifp, &psref);
1196 } 1227 }
1197 pserialize_read_exit(s); 1228 pserialize_read_exit(s);
1198 curlwp_bindx(bound); 1229 curlwp_bindx(bound);
1199 1230
1200 if (docopy) 1231 if (docopy)
1201 ifc.ifc_len -= space; 1232 ifc.ifc_len -= space;
1202 else 1233 else
1203 ifc.ifc_len = -space; 1234 ifc.ifc_len = -space;
1204 1235
1205 return copyout(&ifc, data, sizeof(ifc)); 1236 return copyout(&ifc, data, sizeof(ifc));
1206 1237
1207release_exit: 1238release_exit:
1208 if_release(ifp, &psref); 1239 if_release(ifp, &psref);
1209 curlwp_bindx(bound); 1240 curlwp_bindx(bound);
1210 return error; 1241 return error;
1211} 1242}
1212 1243
1213int 1244int
1214linux_getifhwaddr(struct lwp *l, register_t *retval, u_int fd, 1245linux_getifhwaddr(struct lwp *l, register_t *retval, u_int fd,
1215 void *data) 1246 void *data)
1216{ 1247{
1217 /* Not the full structure, just enough to map what we do here */ 1248 /* Not the full structure, just enough to map what we do here */
1218 struct linux_ifreq lreq; 1249 struct linux_ifreq lreq;
1219 file_t *fp; 1250 file_t *fp;
1220 struct ifaddr *ifa; 1251 struct ifaddr *ifa;
1221 struct ifnet *ifp; 1252 struct ifnet *ifp;
1222 struct sockaddr_dl *sadl; 1253 struct sockaddr_dl *sadl;
1223 int error, found; 1254 int error, found;
1224 int index, ifnum; 1255 int index, ifnum;
1225 int s; 1256 int s;
1226 1257
1227 /* 1258 /*
1228 * We can't emulate this ioctl by calling sys_ioctl() to run 1259 * We can't emulate this ioctl by calling sys_ioctl() to run
1229 * SIOCGIFCONF, because the user buffer is not of the right 1260 * SIOCGIFCONF, because the user buffer is not of the right
1230 * type to take those results. We can't use kernel buffers to 1261 * type to take those results. We can't use kernel buffers to
1231 * receive the results, as the implementation of sys_ioctl() 1262 * receive the results, as the implementation of sys_ioctl()
1232 * and ifconf() [which implements SIOCGIFCONF] use 1263 * and ifconf() [which implements SIOCGIFCONF] use
1233 * copyin()/copyout() which will fail on kernel addresses. 1264 * copyin()/copyout() which will fail on kernel addresses.
1234 * 1265 *
1235 * So, we must duplicate code from sys_ioctl() and ifconf(). Ugh. 1266 * So, we must duplicate code from sys_ioctl() and ifconf(). Ugh.
1236 */ 1267 */
1237 1268
1238 if ((fp = fd_getfile(fd)) == NULL) 1269 if ((fp = fd_getfile(fd)) == NULL)
1239 return (EBADF); 1270 return (EBADF);
1240 1271
1241 KERNEL_LOCK(1, NULL); 1272 KERNEL_LOCK(1, NULL);
1242 1273
1243 if ((fp->f_flag & (FREAD | FWRITE)) == 0) { 1274 if ((fp->f_flag & (FREAD | FWRITE)) == 0) {
1244 error = EBADF; 1275 error = EBADF;
1245 goto out; 1276 goto out;
1246 } 1277 }
1247 1278
1248 error = copyin(data, &lreq, sizeof(lreq)); 1279 error = copyin(data, &lreq, sizeof(lreq));
1249 if (error) 1280 if (error)
1250 goto out; 1281 goto out;
1251 lreq.ifr_name[LINUX_IFNAMSIZ-1] = '\0'; /* just in case */ 1282 lreq.ifr_name[LINUX_IFNAMSIZ-1] = '\0'; /* just in case */
1252 1283
1253 /* 1284 /*
1254 * Try real interface name first, then fake "ethX" 1285 * Try real interface name first, then fake "ethX"
1255 */ 1286 */
1256 found = 0; 1287 found = 0;
1257 s = pserialize_read_enter(); 1288 s = pserialize_read_enter();
1258 IFNET_READER_FOREACH(ifp) { 1289 IFNET_READER_FOREACH(ifp) {
1259 if (found) 1290 if (found)
1260 break; 1291 break;
1261 if (strcmp(lreq.ifr_name, ifp->if_xname)) 1292 if (strcmp(lreq.ifr_name, ifp->if_xname))
1262 /* not this interface */ 1293 /* not this interface */
1263 continue; 1294 continue;
1264 1295
1265 found=1; 1296 found=1;
1266 if (IFADDR_READER_EMPTY(ifp)) { 1297 if (IFADDR_READER_EMPTY(ifp)) {
1267 pserialize_read_exit(s); 1298 pserialize_read_exit(s);
1268 error = ENODEV; 1299 error = ENODEV;
1269 goto out; 1300 goto out;
1270 } 1301 }
1271 IFADDR_READER_FOREACH(ifa, ifp) { 1302 IFADDR_READER_FOREACH(ifa, ifp) {
1272 sadl = satosdl(ifa->ifa_addr); 1303 sadl = satosdl(ifa->ifa_addr);
1273 /* only return ethernet addresses */ 1304 /* only return ethernet addresses */
1274 /* XXX what about FDDI, etc. ? */ 1305 /* XXX what about FDDI, etc. ? */
1275 if (sadl->sdl_family != AF_LINK || 1306 if (sadl->sdl_family != AF_LINK ||
1276 sadl->sdl_type != IFT_ETHER) 1307 sadl->sdl_type != IFT_ETHER)
1277 continue; 1308 continue;
1278 memcpy(&lreq.ifr_hwaddr.sa_data, CLLADDR(sadl), 1309 memcpy(&lreq.ifr_hwaddr.sa_data, CLLADDR(sadl),
1279 MIN(sadl->sdl_alen, 1310 MIN(sadl->sdl_alen,
1280 sizeof(lreq.ifr_hwaddr.sa_data))); 1311 sizeof(lreq.ifr_hwaddr.sa_data)));
1281 lreq.ifr_hwaddr.sa_family = 1312 lreq.ifr_hwaddr.sa_family =
1282 sadl->sdl_family; 1313 sadl->sdl_family;
1283 pserialize_read_exit(s); 1314 pserialize_read_exit(s);
1284 1315
1285 error = copyout(&lreq, data, sizeof(lreq)); 1316 error = copyout(&lreq, data, sizeof(lreq));
1286 goto out; 1317 goto out;
1287 } 1318 }
1288 } 1319 }
1289 pserialize_read_exit(s); 1320 pserialize_read_exit(s);
1290 1321
1291 if (strncmp(lreq.ifr_name, "eth", 3) != 0) { 1322 if (strncmp(lreq.ifr_name, "eth", 3) != 0) {
1292 /* unknown interface, not even an "eth*" name */ 1323 /* unknown interface, not even an "eth*" name */
1293 error = ENODEV; 1324 error = ENODEV;
1294 goto out; 1325 goto out;
1295 } 1326 }
1296 1327
1297 for (ifnum = 0, index = 3; 1328 for (ifnum = 0, index = 3;
1298 index < LINUX_IFNAMSIZ && lreq.ifr_name[index] != '\0'; 1329 index < LINUX_IFNAMSIZ && lreq.ifr_name[index] != '\0';
1299 index++) { 1330 index++) {
1300 ifnum *= 10; 1331 ifnum *= 10;
1301 ifnum += lreq.ifr_name[index] - '0'; 1332 ifnum += lreq.ifr_name[index] - '0';
1302 } 1333 }
1303 1334
1304 error = EINVAL; /* in case we don't find one */ 1335 error = EINVAL; /* in case we don't find one */
1305 s = pserialize_read_enter(); 1336 s = pserialize_read_enter();
1306 IFNET_READER_FOREACH(ifp) { 1337 IFNET_READER_FOREACH(ifp) {
1307 memcpy(lreq.ifr_name, ifp->if_xname, 1338 memcpy(lreq.ifr_name, ifp->if_xname,
1308 MIN(LINUX_IFNAMSIZ, IFNAMSIZ)); 1339 MIN(LINUX_IFNAMSIZ, IFNAMSIZ));
1309 IFADDR_READER_FOREACH(ifa, ifp) { 1340 IFADDR_READER_FOREACH(ifa, ifp) {
1310 sadl = satosdl(ifa->ifa_addr); 1341 sadl = satosdl(ifa->ifa_addr);
1311 /* only return ethernet addresses */ 1342 /* only return ethernet addresses */
1312 /* XXX what about FDDI, etc. ? */ 1343 /* XXX what about FDDI, etc. ? */
1313 if (sadl->sdl_family != AF_LINK || 1344 if (sadl->sdl_family != AF_LINK ||
1314 sadl->sdl_type != IFT_ETHER) 1345 sadl->sdl_type != IFT_ETHER)
1315 continue; 1346 continue;
1316 if (ifnum--) 1347 if (ifnum--)
1317 /* not the reqested iface */ 1348 /* not the reqested iface */
1318 continue; 1349 continue;
1319 memcpy(&lreq.ifr_hwaddr.sa_data, 1350 memcpy(&lreq.ifr_hwaddr.sa_data,
1320 CLLADDR(sadl), 1351 CLLADDR(sadl),
1321 MIN(sadl->sdl_alen, 1352 MIN(sadl->sdl_alen,
1322 sizeof(lreq.ifr_hwaddr.sa_data))); 1353 sizeof(lreq.ifr_hwaddr.sa_data)));
1323 lreq.ifr_hwaddr.sa_family = 1354 lreq.ifr_hwaddr.sa_family =
1324 sadl->sdl_family; 1355 sadl->sdl_family;
1325 pserialize_read_exit(s); 1356 pserialize_read_exit(s);
1326 1357
1327 error = copyout(&lreq, data, sizeof(lreq)); 1358 error = copyout(&lreq, data, sizeof(lreq));
1328 goto out; 1359 goto out;
1329 } 1360 }
1330 } 1361 }
1331 pserialize_read_exit(s); 1362 pserialize_read_exit(s);
1332 1363
1333out: 1364out:
1334 KERNEL_UNLOCK_ONE(NULL); 1365 KERNEL_UNLOCK_ONE(NULL);
1335 fd_putfile(fd); 1366 fd_putfile(fd);
1336 return error; 1367 return error;
1337} 1368}
1338 1369
1339int 1370int
1340linux_ioctl_socket(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval) 1371linux_ioctl_socket(struct lwp *l, const struct linux_sys_ioctl_args *uap, register_t *retval)
1341{ 1372{
1342 /* { 1373 /* {
1343 syscallarg(int) fd; 1374 syscallarg(int) fd;
1344 syscallarg(u_long) com; 1375 syscallarg(u_long) com;
1345 syscallarg(void *) data; 1376 syscallarg(void *) data;
1346 } */ 1377 } */
1347 u_long com; 1378 u_long com;
1348 int error = 0, isdev = 0, dosys = 1; 1379 int error = 0, isdev = 0, dosys = 1;
1349 struct sys_ioctl_args ia; 1380 struct sys_ioctl_args ia;
1350 file_t *fp; 1381 file_t *fp;
1351 struct vnode *vp; 1382 struct vnode *vp;
1352 int (*ioctlf)(file_t *, u_long, void *); 1383 int (*ioctlf)(file_t *, u_long, void *);
1353 struct ioctl_pt pt; 1384 struct ioctl_pt pt;
1354 1385
1355 if ((fp = fd_getfile(SCARG(uap, fd))) == NULL) 1386 if ((fp = fd_getfile(SCARG(uap, fd))) == NULL)
1356 return (EBADF); 1387 return (EBADF);
1357 1388
1358 if (fp->f_type == DTYPE_VNODE) { 1389 if (fp->f_type == DTYPE_VNODE) {
1359 vp = (struct vnode *)fp->f_data; 1390 vp = (struct vnode *)fp->f_data;
1360 isdev = vp->v_type == VCHR; 1391 isdev = vp->v_type == VCHR;
1361 } 1392 }
1362 1393
1363 /* 1394 /*
1364 * Don't try to interpret socket ioctl calls that are done 1395 * Don't try to interpret socket ioctl calls that are done
1365 * on a device filedescriptor, just pass them through, to 1396 * on a device filedescriptor, just pass them through, to
1366 * emulate Linux behaviour. Use PTIOCLINUX so that the 1397 * emulate Linux behaviour. Use PTIOCLINUX so that the
1367 * device will only handle these if it's prepared to do 1398 * device will only handle these if it's prepared to do
1368 * so, to avoid unexpected things from happening. 1399 * so, to avoid unexpected things from happening.
1369 */ 1400 */
1370 if (isdev) { 1401 if (isdev) {
1371 dosys = 0; 1402 dosys = 0;
1372 ioctlf = fp->f_ops->fo_ioctl; 1403 ioctlf = fp->f_ops->fo_ioctl;
1373 pt.com = SCARG(uap, com); 1404 pt.com = SCARG(uap, com);
1374 pt.data = SCARG(uap, data); 1405 pt.data = SCARG(uap, data);
1375 error = ioctlf(fp, PTIOCLINUX, &pt); 1406 error = ioctlf(fp, PTIOCLINUX, &pt);
1376 /* 1407 /*
1377 * XXX hack: if the function returns EJUSTRETURN, 1408 * XXX hack: if the function returns EJUSTRETURN,
1378 * it has stuffed a sysctl return value in pt.data. 1409 * it has stuffed a sysctl return value in pt.data.
1379 */ 1410 */
1380 if (error == EJUSTRETURN) { 1411 if (error == EJUSTRETURN) {
1381 retval[0] = (register_t)pt.data; 1412 retval[0] = (register_t)pt.data;
1382 error = 0; 1413 error = 0;
1383 } 1414 }
1384 goto out; 1415 goto out;
1385 } 1416 }
1386 1417
1387 com = SCARG(uap, com); 1418 com = SCARG(uap, com);
1388 retval[0] = 0; 1419 retval[0] = 0;
1389 1420
1390 switch (com) { 1421 switch (com) {
1391 case LINUX_SIOCGIFNAME: 1422 case LINUX_SIOCGIFNAME:
1392 error = linux_getifname(l, retval, SCARG(uap, data)); 1423 error = linux_getifname(l, retval, SCARG(uap, data));
1393 dosys = 0; 1424 dosys = 0;
1394 break; 1425 break;
1395 case LINUX_SIOCGIFCONF: 1426 case LINUX_SIOCGIFCONF:
1396 error = linux_getifconf(l, retval, SCARG(uap, data)); 1427 error = linux_getifconf(l, retval, SCARG(uap, data));
1397 dosys = 0; 1428 dosys = 0;
1398 break; 1429 break;
1399 case LINUX_SIOCGIFFLAGS: 1430 case LINUX_SIOCGIFFLAGS:
1400 SCARG(&ia, com) = OSIOCGIFFLAGS; 1431 SCARG(&ia, com) = OSIOCGIFFLAGS;
1401 break; 1432 break;
1402 case LINUX_SIOCSIFFLAGS: 1433 case LINUX_SIOCSIFFLAGS:
1403 SCARG(&ia, com) = OSIOCSIFFLAGS; 1434 SCARG(&ia, com) = OSIOCSIFFLAGS;
1404 break; 1435 break;
1405 case LINUX_SIOCGIFADDR: 1436 case LINUX_SIOCGIFADDR:
1406 SCARG(&ia, com) = OOSIOCGIFADDR; 1437 SCARG(&ia, com) = OOSIOCGIFADDR;
1407 break; 1438 break;
1408 case LINUX_SIOCGIFDSTADDR: 1439 case LINUX_SIOCGIFDSTADDR:
1409 SCARG(&ia, com) = OOSIOCGIFDSTADDR; 1440 SCARG(&ia, com) = OOSIOCGIFDSTADDR;
1410 break; 1441 break;
1411 case LINUX_SIOCGIFBRDADDR: 1442 case LINUX_SIOCGIFBRDADDR:
1412 SCARG(&ia, com) = OOSIOCGIFBRDADDR; 1443 SCARG(&ia, com) = OOSIOCGIFBRDADDR;
1413 break; 1444 break;
1414 case LINUX_SIOCGIFNETMASK: 1445 case LINUX_SIOCGIFNETMASK:
1415 SCARG(&ia, com) = OOSIOCGIFNETMASK; 1446 SCARG(&ia, com) = OOSIOCGIFNETMASK;
1416 break; 1447 break;
1417 case LINUX_SIOCGIFMTU: 1448 case LINUX_SIOCGIFMTU:
1418 SCARG(&ia, com) = OSIOCGIFMTU; 1449 SCARG(&ia, com) = OSIOCGIFMTU;
1419 break; 1450 break;
1420 case LINUX_SIOCADDMULTI: 1451 case LINUX_SIOCADDMULTI:
1421 SCARG(&ia, com) = OSIOCADDMULTI; 1452 SCARG(&ia, com) = OSIOCADDMULTI;
1422 break; 1453 break;
1423 case LINUX_SIOCDELMULTI: 1454 case LINUX_SIOCDELMULTI:
1424 SCARG(&ia, com) = OSIOCDELMULTI; 1455 SCARG(&ia, com) = OSIOCDELMULTI;
1425 break; 1456 break;
1426 case LINUX_SIOCGIFHWADDR: 1457 case LINUX_SIOCGIFHWADDR:
1427 error = linux_getifhwaddr(l, retval, SCARG(uap, fd), 1458 error = linux_getifhwaddr(l, retval, SCARG(uap, fd),
1428 SCARG(uap, data)); 1459 SCARG(uap, data));
1429 dosys = 0; 1460 dosys = 0;
1430 break; 1461 break;
1431 default: 1462 default:
1432 error = EINVAL; 1463 error = EINVAL;
1433 } 1464 }
1434 1465
1435 out: 1466 out:
1436 fd_putfile(SCARG(uap, fd)); 1467 fd_putfile(SCARG(uap, fd));
1437 1468
1438 if (error ==0 && dosys) { 1469 if (error ==0 && dosys) {
1439 SCARG(&ia, fd) = SCARG(uap, fd); 1470 SCARG(&ia, fd) = SCARG(uap, fd);
1440 SCARG(&ia, data) = SCARG(uap, data); 1471 SCARG(&ia, data) = SCARG(uap, data);
1441 error = sys_ioctl(curlwp, &ia, retval); 1472 error = sys_ioctl(curlwp, &ia, retval);
1442 } 1473 }
1443 1474
1444 return error; 1475 return error;
1445} 1476}
1446 1477
1447int 1478int
1448linux_sys_connect(struct lwp *l, const struct linux_sys_connect_args *uap, register_t *retval) 1479linux_sys_connect(struct lwp *l, const struct linux_sys_connect_args *uap, register_t *retval)
1449{ 1480{
1450 /* { 1481 /* {
1451 syscallarg(int) s; 1482 syscallarg(int) s;
1452 syscallarg(const struct sockaddr *) name; 1483 syscallarg(const struct sockaddr *) name;
1453 syscallarg(int) namelen; 1484 syscallarg(int) namelen;
1454 } */ 1485 } */
1455 int error; 1486 int error;
1456 struct sockaddr_big sb; 1487 struct sockaddr_big sb;
1457 1488
1458 error = linux_get_sa(l, SCARG(uap, s), &sb, SCARG(uap, name), 1489 error = linux_get_sa(l, SCARG(uap, s), &sb, SCARG(uap, name),
1459 SCARG(uap, namelen)); 1490 SCARG(uap, namelen));
1460 if (error) 1491 if (error)
1461 return (error); 1492 return (error);
1462 1493
1463 error = do_sys_connect(l, SCARG(uap, s), (struct sockaddr *)&sb); 1494 error = do_sys_connect(l, SCARG(uap, s), (struct sockaddr *)&sb);
1464 1495
1465 if (error == EISCONN) { 1496 if (error == EISCONN) {
1466 struct socket *so; 1497 struct socket *so;
1467 int state, prflags; 1498 int state, prflags;
1468 1499
1469 /* fd_getsock() will use the descriptor for us */ 1500 /* fd_getsock() will use the descriptor for us */
1470 if (fd_getsock(SCARG(uap, s), &so) != 0) 1501 if (fd_getsock(SCARG(uap, s), &so) != 0)
1471 return EISCONN; 1502 return EISCONN;
1472 1503
1473 solock(so); 1504 solock(so);
1474 state = so->so_state; 1505 state = so->so_state;
1475 prflags = so->so_proto->pr_flags; 1506 prflags = so->so_proto->pr_flags;
1476 sounlock(so); 1507 sounlock(so);
1477 fd_putfile(SCARG(uap, s)); 1508 fd_putfile(SCARG(uap, s));
1478 /* 1509 /*
1479 * We should only let this call succeed once per 1510 * We should only let this call succeed once per
1480 * non-blocking connect; however we don't have 1511 * non-blocking connect; however we don't have
1481 * a convenient place to keep that state.. 1512 * a convenient place to keep that state..
1482 */ 1513 */
1483 if ((state & (SS_ISCONNECTED|SS_NBIO)) == 1514 if ((state & (SS_ISCONNECTED|SS_NBIO)) ==
1484 (SS_ISCONNECTED|SS_NBIO) && 1515 (SS_ISCONNECTED|SS_NBIO) &&
1485 (prflags & PR_CONNREQUIRED)) 1516 (prflags & PR_CONNREQUIRED))
1486 return 0; 1517 return 0;
1487 } 1518 }
1488 1519
1489 return (error); 1520 return (error);
1490} 1521}
1491 1522
1492int 1523int
1493linux_sys_bind(struct lwp *l, const struct linux_sys_bind_args *uap, register_t *retval) 1524linux_sys_bind(struct lwp *l, const struct linux_sys_bind_args *uap, register_t *retval)
1494{ 1525{
1495 /* { 1526 /* {
1496 syscallarg(int) s; 1527 syscallarg(int) s;
1497 syscallarg(const struct osockaddr *) name; 1528 syscallarg(const struct osockaddr *) name;
1498 syscallarg(int) namelen; 1529 syscallarg(int) namelen;
1499 } */ 1530 } */
1500 int error; 1531 int error;
1501 struct sockaddr_big sb; 1532 struct sockaddr_big sb;
1502 1533
1503 error = linux_get_sa(l, SCARG(uap, s), &sb, SCARG(uap, name), 1534 error = linux_get_sa(l, SCARG(uap, s), &sb, SCARG(uap, name),
1504 SCARG(uap, namelen)); 1535 SCARG(uap, namelen));
1505 if (error) 1536 if (error)
1506 return (error); 1537 return (error);
1507 1538
1508 return do_sys_bind(l, SCARG(uap, s), (struct sockaddr *)&sb); 1539 return do_sys_bind(l, SCARG(uap, s), (struct sockaddr *)&sb);
1509} 1540}
1510 1541
1511int 1542int
1512linux_sys_getsockname(struct lwp *l, const struct linux_sys_getsockname_args *uap, register_t *retval) 1543linux_sys_getsockname(struct lwp *l, const struct linux_sys_getsockname_args *uap, register_t *retval)
1513{ 1544{
1514 /* { 1545 /* {
1515 syscallarg(int) fdes; 1546 syscallarg(int) fdes;
1516 syscallarg(void *) asa; 1547 syscallarg(void *) asa;
1517 syscallarg(int *) alen; 1548 syscallarg(int *) alen;
1518 } */ 1549 } */
1519 int error; 1550 int error;
1520 1551
1521 if ((error = sys_getsockname(l, (const void *)uap, retval)) != 0) 1552 if ((error = sys_getsockname(l, (const void *)uap, retval)) != 0)
1522 return (error); 1553 return (error);
1523 1554
1524 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa)))) 1555 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa))))
1525 return (error); 1556 return (error);
1526 1557
1527 return (0); 1558 return (0);
1528} 1559}
1529 1560
1530int 1561int
1531linux_sys_getpeername(struct lwp *l, const struct linux_sys_getpeername_args *uap, register_t *retval) 1562linux_sys_getpeername(struct lwp *l, const struct linux_sys_getpeername_args *uap, register_t *retval)
1532{ 1563{
1533 /* { 1564 /* {
1534 syscallarg(int) fdes; 1565 syscallarg(int) fdes;
1535 syscallarg(void *) asa; 1566 syscallarg(void *) asa;
1536 syscallarg(int *) alen; 1567 syscallarg(int *) alen;
1537 } */ 1568 } */
1538 int error; 1569 int error;
1539 1570
1540 if ((error = sys_getpeername(l, (const void *)uap, retval)) != 0) 1571 if ((error = sys_getpeername(l, (const void *)uap, retval)) != 0)
1541 return (error); 1572 return (error);
1542 1573
1543 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa)))) 1574 if ((error = linux_sa_put((struct osockaddr *)SCARG(uap, asa))))
1544 return (error); 1575 return (error);
1545 1576
1546 return (0); 1577 return (0);
1547} 1578}
1548 1579
1549/* 1580/*
1550 * Copy the osockaddr structure pointed to by name to sb, adjust 1581 * Copy the osockaddr structure pointed to by name to sb, adjust
1551 * family and convert to sockaddr. 1582 * family and convert to sockaddr.
1552 */ 1583 */
1553static int 1584static int
1554linux_get_sa(struct lwp *l, int s, struct sockaddr_big *sb, 1585linux_get_sa(struct lwp *l, int s, struct sockaddr_big *sb,
1555 const struct osockaddr *name, socklen_t namelen) 1586 const struct osockaddr *name, socklen_t namelen)
1556{ 1587{
1557 int error, bdom; 1588 int error, bdom;
1558 1589
1559 if (namelen > UCHAR_MAX || 1590 if (namelen > UCHAR_MAX ||
1560 namelen <= offsetof(struct sockaddr_big, sb_data)) 1591 namelen <= offsetof(struct sockaddr_big, sb_data))
1561 return EINVAL; 1592 return EINVAL;
1562 1593
1563 error = copyin(name, sb, namelen); 1594 error = copyin(name, sb, namelen);
1564 if (error) 1595 if (error)
1565 return error; 1596 return error;
1566 1597
1567 bdom = linux_to_bsd_domain(sb->sb_family); 1598 bdom = linux_to_bsd_domain(sb->sb_family);
1568 if (bdom == -1) 1599 if (bdom == -1)
1569 return EINVAL; 1600 return EINVAL;
1570 1601
1571 /* 1602 /*
1572 * If the family is unspecified, use address family of the socket. 1603 * If the family is unspecified, use address family of the socket.
1573 * This avoid triggering strict family checks in netinet/in_pcb.c et.al. 1604 * This avoid triggering strict family checks in netinet/in_pcb.c et.al.
1574 */ 1605 */
1575 if (bdom == AF_UNSPEC) { 1606 if (bdom == AF_UNSPEC) {
1576 struct socket *so; 1607 struct socket *so;
1577 1608
1578 /* fd_getsock() will use the descriptor for us */ 1609 /* fd_getsock() will use the descriptor for us */
1579 if ((error = fd_getsock(s, &so)) != 0) 1610 if ((error = fd_getsock(s, &so)) != 0)
1580 return error; 1611 return error;
1581 1612
1582 bdom = so->so_proto->pr_domain->dom_family; 1613 bdom = so->so_proto->pr_domain->dom_family;
1583 fd_putfile(s); 1614 fd_putfile(s);
1584 } 1615 }
1585 1616
1586 /* 1617 /*
1587 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6, 1618 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6,
1588 * which lacks the scope id compared with RFC2553 one. If we detect 1619 * which lacks the scope id compared with RFC2553 one. If we detect
1589 * the situation, reject the address and write a message to system log. 1620 * the situation, reject the address and write a message to system log.
1590 * 1621 *
1591 * Still accept addresses for which the scope id is not used. 1622 * Still accept addresses for which the scope id is not used.
1592 */ 1623 */
1593 if (bdom == AF_INET6 && 1624 if (bdom == AF_INET6 &&
1594 namelen == sizeof(struct sockaddr_in6) - sizeof(uint32_t)) { 1625 namelen == sizeof(struct sockaddr_in6) - sizeof(uint32_t)) {
1595 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sb; 1626 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sb;
1596 if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) && 1627 if (!IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) &&
1597 (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || 1628 (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
1598 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) || 1629 IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) ||
1599 IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) || 1630 IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) ||
1600 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) || 1631 IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
1601 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) { 1632 IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) {
1602 struct proc *p = l->l_proc; 1633 struct proc *p = l->l_proc;
1603 int uid = l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1; 1634 int uid = l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1;
1604 1635
1605 log(LOG_DEBUG, 1636 log(LOG_DEBUG,
1606 "pid %d (%s), uid %d: obsolete pre-RFC2553 " 1637 "pid %d (%s), uid %d: obsolete pre-RFC2553 "
1607 "sockaddr_in6 rejected", 1638 "sockaddr_in6 rejected",
1608 p->p_pid, p->p_comm, uid); 1639 p->p_pid, p->p_comm, uid);
1609 return EINVAL; 1640 return EINVAL;
1610 } 1641 }
1611 namelen = sizeof(struct sockaddr_in6); 1642 namelen = sizeof(struct sockaddr_in6);
1612 sin6->sin6_scope_id = 0; 1643 sin6->sin6_scope_id = 0;
1613 } 1644 }
1614 1645
1615 /* 1646 /*
1616 * Linux is less strict than NetBSD and permits namelen to be larger 1647 * Linux is less strict than NetBSD and permits namelen to be larger
1617 * than valid struct sockaddr_in*. If this is the case, truncate 1648 * than valid struct sockaddr_in*. If this is the case, truncate
1618 * the value to the correct size, so that NetBSD networking does not 1649 * the value to the correct size, so that NetBSD networking does not
1619 * return an error. 1650 * return an error.
1620 */ 1651 */
1621 switch (bdom) { 1652 switch (bdom) {
1622 case AF_INET: 1653 case AF_INET:
1623 namelen = MIN(namelen, sizeof(struct sockaddr_in)); 1654 namelen = MIN(namelen, sizeof(struct sockaddr_in));
1624 break; 1655 break;
1625 case AF_INET6: 1656 case AF_INET6:
1626 namelen = MIN(namelen, sizeof(struct sockaddr_in6)); 1657 namelen = MIN(namelen, sizeof(struct sockaddr_in6));
1627 break; 1658 break;
1628 } 1659 }
1629 1660
1630 sb->sb_family = bdom; 1661 sb->sb_family = bdom;
1631 sb->sb_len = namelen; 1662 sb->sb_len = namelen;
1632 ktrkuser("mbsoname", sb, namelen); 1663 ktrkuser("mbsoname", sb, namelen);
1633 return 0; 1664 return 0;
1634} 1665}
1635 1666
1636static int 1667static int
1637linux_sa_put(struct osockaddr *osa) 1668linux_sa_put(struct osockaddr *osa)
1638{ 1669{
1639 struct sockaddr sa; 1670 struct sockaddr sa;
1640 struct osockaddr *kosa; 1671 struct osockaddr *kosa;
1641 int error, bdom, len; 1672 int error, bdom, len;
1642 1673
1643 /* 1674 /*
1644 * Only read/write the sockaddr family and length part, the rest is 1675 * Only read/write the sockaddr family and length part, the rest is
1645 * not changed. 1676 * not changed.
1646 */ 1677 */
1647 len = sizeof(sa.sa_len) + sizeof(sa.sa_family); 1678 len = sizeof(sa.sa_len) + sizeof(sa.sa_family);
1648 1679
1649 error = copyin(osa, &sa, len); 1680 error = copyin(osa, &sa, len);
1650 if (error) 1681 if (error)
1651 return (error); 1682 return (error);
1652 1683
1653 bdom = bsd_to_linux_domain(sa.sa_family); 1684 bdom = bsd_to_linux_domain(sa.sa_family);
1654 if (bdom == -1) 1685 if (bdom == -1)
1655 return (EINVAL); 1686 return (EINVAL);
1656 1687
1657 /* Note: we convert from sockaddr to osockaddr here, too */ 1688 /* Note: we convert from sockaddr to osockaddr here, too */
1658 kosa = (struct osockaddr *) &sa; 1689 kosa = (struct osockaddr *) &sa;
1659 kosa->sa_family = bdom; 1690 kosa->sa_family = bdom;
1660 error = copyout(kosa, osa, len); 1691 error = copyout(kosa, osa, len);
1661 if (error) 1692 if (error)
1662 return (error); 1693 return (error);
1663 1694
1664 return (0); 1695 return (0);
1665} 1696}
1666 1697
1667#ifndef __amd64__ 1698#ifndef __amd64__
1668int 1699int
1669linux_sys_recv(struct lwp *l, const struct linux_sys_recv_args *uap, register_t *retval) 1700linux_sys_recv(struct lwp *l, const struct linux_sys_recv_args *uap, register_t *retval)
1670{ 1701{
1671 /* { 1702 /* {
1672 syscallarg(int) s; 1703 syscallarg(int) s;
1673 syscallarg(void *) buf; 1704 syscallarg(void *) buf;
1674 syscallarg(int) len; 1705 syscallarg(int) len;
1675 syscallarg(int) flags; 1706 syscallarg(int) flags;
1676 } */ 1707 } */
1677 struct sys_recvfrom_args bra; 1708 struct sys_recvfrom_args bra;
1678 1709
1679 1710
1680 SCARG(&bra, s) = SCARG(uap, s); 1711 SCARG(&bra, s) = SCARG(uap, s);
1681 SCARG(&bra, buf) = SCARG(uap, buf); 1712 SCARG(&bra, buf) = SCARG(uap, buf);
1682 SCARG(&bra, len) = (size_t) SCARG(uap, len); 1713 SCARG(&bra, len) = (size_t) SCARG(uap, len);
1683 SCARG(&bra, flags) = SCARG(uap, flags); 1714 SCARG(&bra, flags) = SCARG(uap, flags);
1684 SCARG(&bra, from) = NULL; 1715 SCARG(&bra, from) = NULL;
1685 SCARG(&bra, fromlenaddr) = NULL; 1716 SCARG(&bra, fromlenaddr) = NULL;
1686 1717
1687 return (sys_recvfrom(l, &bra, retval)); 1718 return (sys_recvfrom(l, &bra, retval));
1688} 1719}
1689 1720
1690int 1721int
1691linux_sys_send(struct lwp *l, const struct linux_sys_send_args *uap, register_t *retval) 1722linux_sys_send(struct lwp *l, const struct linux_sys_send_args *uap, register_t *retval)
1692{ 1723{
1693 /* { 1724 /* {
1694 syscallarg(int) s; 1725 syscallarg(int) s;
1695 syscallarg(void *) buf; 1726 syscallarg(void *) buf;
1696 syscallarg(int) len; 1727 syscallarg(int) len;
1697 syscallarg(int) flags; 1728 syscallarg(int) flags;
1698 } */ 1729 } */
1699 struct sys_sendto_args bsa; 1730 struct sys_sendto_args bsa;
1700 1731
1701 SCARG(&bsa, s) = SCARG(uap, s); 1732 SCARG(&bsa, s) = SCARG(uap, s);
1702 SCARG(&bsa, buf) = SCARG(uap, buf); 1733 SCARG(&bsa, buf) = SCARG(uap, buf);
1703 SCARG(&bsa, len) = SCARG(uap, len); 1734 SCARG(&bsa, len) = SCARG(uap, len);
1704 SCARG(&bsa, flags) = SCARG(uap, flags); 1735 SCARG(&bsa, flags) = SCARG(uap, flags);
1705 SCARG(&bsa, to) = NULL; 1736 SCARG(&bsa, to) = NULL;
1706 SCARG(&bsa, tolen) = 0; 1737 SCARG(&bsa, tolen) = 0;
1707 1738
1708 return (sys_sendto(l, &bsa, retval)); 1739 return (sys_sendto(l, &bsa, retval));
1709} 1740}
1710#endif 1741#endif
1711 1742
1712int 1743int
1713linux_sys_accept(struct lwp *l, const struct linux_sys_accept_args *uap, register_t *retval) 1744linux_sys_accept(struct lwp *l, const struct linux_sys_accept_args *uap, register_t *retval)
1714{ 1745{
1715 /* { 1746 /* {
1716 syscallarg(int) s; 1747 syscallarg(int) s;
1717 syscallarg(struct osockaddr *) name; 1748 syscallarg(struct osockaddr *) name;
1718 syscallarg(int *) anamelen; 1749 syscallarg(int *) anamelen;
1719 } */ 1750 } */
1720 int error; 1751 int error;
1721 struct sys_accept_args baa; 1752 struct sys_accept_args baa;
1722 1753
1723 SCARG(&baa, s) = SCARG(uap, s); 1754 SCARG(&baa, s) = SCARG(uap, s);
1724 SCARG(&baa, name) = (struct sockaddr *) SCARG(uap, name); 1755 SCARG(&baa, name) = (struct sockaddr *) SCARG(uap, name);
1725 SCARG(&baa, anamelen) = (unsigned int *) SCARG(uap, anamelen); 1756 SCARG(&baa, anamelen) = (unsigned int *) SCARG(uap, anamelen);
1726 1757
1727 if ((error = sys_accept(l, &baa, retval))) 1758 if ((error = sys_accept(l, &baa, retval)))
1728 return (error); 1759 return (error);
1729 1760
1730 if (SCARG(uap, name) && (error = linux_sa_put(SCARG(uap, name)))) 1761 if (SCARG(uap, name) && (error = linux_sa_put(SCARG(uap, name))))
1731 return (error); 1762 return (error);
1732 1763
1733 return (0); 1764 return (0);
1734} 1765}
1735 1766
1736int 1767int
1737linux_sys_accept4(struct lwp *l, const struct linux_sys_accept4_args *uap, register_t *retval) 1768linux_sys_accept4(struct lwp *l, const struct linux_sys_accept4_args *uap, register_t *retval)
1738{ 1769{
1739 /* { 1770 /* {
1740 syscallarg(int) s; 1771 syscallarg(int) s;
1741 syscallarg(struct osockaddr *) name; 1772 syscallarg(struct osockaddr *) name;
1742 syscallarg(int *) anamelen; 1773 syscallarg(int *) anamelen;
1743 syscallarg(int) flags; 1774 syscallarg(int) flags;
1744 } */ 1775 } */
1745 int error, flags; 1776 int error, flags;
1746 struct sockaddr_big name; 1777 struct sockaddr_big name;
1747 1778
1748 if ((flags = linux_to_bsd_type(SCARG(uap, flags))) == -1) 1779 if ((flags = linux_to_bsd_type(SCARG(uap, flags))) == -1)
1749 return EINVAL; 1780 return EINVAL;
1750 1781
1751 name.sb_len = UCHAR_MAX; 1782 name.sb_len = UCHAR_MAX;
1752 error = do_sys_accept(l, SCARG(uap, s), (struct sockaddr *)&name, 1783 error = do_sys_accept(l, SCARG(uap, s), (struct sockaddr *)&name,
1753 retval, NULL, flags, 0); 1784 retval, NULL, flags, 0);
1754 if (error != 0) 1785 if (error != 0)
1755 return error; 1786 return error;
1756 1787
1757 error = copyout_sockname_sb((struct sockaddr *)SCARG(uap, name), 1788 error = copyout_sockname_sb((struct sockaddr *)SCARG(uap, name),
1758 SCARG(uap, anamelen), MSG_LENUSRSPACE, &name); 1789 SCARG(uap, anamelen), MSG_LENUSRSPACE, &name);
1759 if (error != 0) { 1790 if (error != 0) {
1760 int fd = (int)*retval; 1791 int fd = (int)*retval;
1761 if (fd_getfile(fd) != NULL) 1792 if (fd_getfile(fd) != NULL)
1762 (void)fd_close(fd); 1793 (void)fd_close(fd);
1763 return error; 1794 return error;
1764 } 1795 }
1765 if (SCARG(uap, name) && (error = linux_sa_put(SCARG(uap, name)))) 1796 if (SCARG(uap, name) && (error = linux_sa_put(SCARG(uap, name))))
1766 return error; 1797 return error;
1767 1798
1768 return 0; 1799 return 0;
1769} 1800}
1770 1801
1771int 1802int
1772linux_sys_sendmmsg(struct lwp *l, const struct linux_sys_sendmmsg_args *uap, 1803linux_sys_sendmmsg(struct lwp *l, const struct linux_sys_sendmmsg_args *uap,
1773 register_t *retval) 1804 register_t *retval)
1774{ 1805{
1775 /* { 1806 /* {
1776 syscallarg(int) s; 1807 syscallarg(int) s;
1777 syscallarg(struct linux_mmsghdr *) msgvec; 1808 syscallarg(struct linux_mmsghdr *) msgvec;
1778 syscallarg(unsigned int) vlen; 1809 syscallarg(unsigned int) vlen;
1779 syscallarg(unsigned int) flags; 1810 syscallarg(unsigned int) flags;
1780 } */ 1811 } */
1781 struct linux_mmsghdr lmsg; 1812 struct linux_mmsghdr lmsg;
1782 struct mmsghdr bmsg; 1813 struct mmsghdr bmsg;
1783 struct socket *so; 1814 struct socket *so;
1784 file_t *fp; 1815 file_t *fp;
1785 struct msghdr *msg = &bmsg.msg_hdr; 1816 struct msghdr *msg = &bmsg.msg_hdr;
1786 int error, s; 1817 int error, s;
1787 unsigned int vlen, flags, dg; 1818 unsigned int vlen, flags, dg;
1788 1819
1789 if ((flags = linux_to_bsd_msg_flags(SCARG(uap, flags))) == -1) 1820 if ((flags = linux_to_bsd_msg_flags(SCARG(uap, flags))) == -1)
1790 return EINVAL; 1821 return EINVAL;
1791 1822
1792 flags = (flags & MSG_USERFLAGS) | MSG_IOVUSRSPACE; 1823 flags = (flags & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
1793 1824
1794 s = SCARG(uap, s); 1825 s = SCARG(uap, s);
1795 if ((error = fd_getsock1(s, &so, &fp)) != 0) 1826 if ((error = fd_getsock1(s, &so, &fp)) != 0)
1796 return error; 1827 return error;
1797 1828
1798 vlen = SCARG(uap, vlen); 1829 vlen = SCARG(uap, vlen);
1799 if (vlen > 1024) 1830 if (vlen > 1024)
1800 vlen = 1024; 1831 vlen = 1024;
1801 1832
1802 for (dg = 0; dg < vlen;) { 1833 for (dg = 0; dg < vlen;) {
1803 error = copyin(SCARG(uap, msgvec) + dg, &lmsg, sizeof(lmsg)); 1834 error = copyin(SCARG(uap, msgvec) + dg, &lmsg, sizeof(lmsg));
1804 if (error) 1835 if (error)
1805 break; 1836 break;
1806 linux_to_bsd_msghdr(&lmsg.msg_hdr, &bmsg.msg_hdr); 1837 linux_to_bsd_msghdr(&lmsg.msg_hdr, &bmsg.msg_hdr);
1807 1838
1808 msg->msg_flags = flags; 1839 msg->msg_flags = flags;
1809 1840
1810 error = do_sys_sendmsg_so(l, s, so, fp, msg, flags, retval); 1841 error = do_sys_sendmsg_so(l, s, so, fp, msg, flags, retval);
1811 if (error) 1842 if (error)
1812 break; 1843 break;
1813 1844
1814 ktrkuser("msghdr", msg, sizeof *msg); 1845 ktrkuser("msghdr", msg, sizeof *msg);
1815 lmsg.msg_len = *retval; 1846 lmsg.msg_len = *retval;
1816 error = copyout(&lmsg, SCARG(uap, msgvec) + dg, sizeof(lmsg)); 1847 error = copyout(&lmsg, SCARG(uap, msgvec) + dg, sizeof(lmsg));
1817 if (error) 1848 if (error)
1818 break; 1849 break;
1819 dg++; 1850 dg++;
1820 1851
1821 } 1852 }
1822 1853
1823 *retval = dg; 1854 *retval = dg;
1824 1855
1825 fd_putfile(s); 1856 fd_putfile(s);
1826 1857
1827 /* 1858 /*
1828 * If we succeeded at least once, return 0. 1859 * If we succeeded at least once, return 0.
1829 */ 1860 */
1830 if (dg) 1861 if (dg)
1831 return 0; 1862 return 0;
1832 return error; 1863 return error;
1833} 1864}
1834 1865
1835int 1866int
1836linux_sys_recvmmsg(struct lwp *l, const struct linux_sys_recvmmsg_args *uap, 1867linux_sys_recvmmsg(struct lwp *l, const struct linux_sys_recvmmsg_args *uap,
1837 register_t *retval) 1868 register_t *retval)
1838{ 1869{
1839 /* { 1870 /* {
1840 syscallarg(int) s; 1871 syscallarg(int) s;
1841 syscallarg(struct linux_mmsghdr *) msgvec; 1872 syscallarg(struct linux_mmsghdr *) msgvec;
1842 syscallarg(unsigned int) vlen; 1873 syscallarg(unsigned int) vlen;
1843 syscallarg(unsigned int) flags; 1874 syscallarg(unsigned int) flags;
1844 syscallarg(struct linux_timespec *) timeout; 1875 syscallarg(struct linux_timespec *) timeout;
1845 } */ 1876 } */
1846 struct linux_mmsghdr lmsg; 1877 struct linux_mmsghdr lmsg;
1847 struct mmsghdr bmsg; 1878 struct mmsghdr bmsg;
1848 struct socket *so; 1879 struct socket *so;
1849 struct msghdr *msg = &bmsg.msg_hdr; 1880 struct msghdr *msg = &bmsg.msg_hdr;
1850 int error, s; 1881 int error, s;
1851 struct mbuf *from, *control; 1882 struct mbuf *from, *control;
1852 struct timespec ts = {0}, now; 1883 struct timespec ts = {0}, now;
1853 struct linux_timespec lts; 1884 struct linux_timespec lts;
1854 unsigned int vlen, flags, dg; 1885 unsigned int vlen, flags, dg;
1855 1886
1856 if (SCARG(uap, timeout)) { 1887 if (SCARG(uap, timeout)) {
1857 error = copyin(SCARG(uap, timeout), &lts, sizeof(lts)); 1888 error = copyin(SCARG(uap, timeout), &lts, sizeof(lts));
1858 return error; 1889 return error;
1859 ts.tv_sec = lts.tv_sec; 1890 ts.tv_sec = lts.tv_sec;
1860 ts.tv_nsec = lts.tv_nsec; 1891 ts.tv_nsec = lts.tv_nsec;
1861 getnanotime(&now); 1892 getnanotime(&now);
1862 timespecadd(&now, &ts, &ts); 1893 timespecadd(&now, &ts, &ts);
1863 } 1894 }
1864 1895
1865 s = SCARG(uap, s); 1896 s = SCARG(uap, s);
1866 if ((error = fd_getsock(s, &so)) != 0) 1897 if ((error = fd_getsock(s, &so)) != 0)
1867 return error; 1898 return error;
1868 1899
1869 /* 1900 /*
1870 * If so->so_rerror holds a deferred error return it now. 1901 * If so->so_rerror holds a deferred error return it now.
1871 */ 1902 */
1872 if (so->so_rerror) { 1903 if (so->so_rerror) {
1873 error = so->so_rerror; 1904 error = so->so_rerror;
1874 so->so_rerror = 0; 1905 so->so_rerror = 0;
1875 fd_putfile(s); 1906 fd_putfile(s);
1876 return error; 1907 return error;
1877 } 1908 }
1878 1909
1879 vlen = SCARG(uap, vlen); 1910 vlen = SCARG(uap, vlen);
1880 if (vlen > 1024) 1911 if (vlen > 1024)
1881 vlen = 1024; 1912 vlen = 1024;
1882 1913
1883 from = NULL; 1914 from = NULL;
1884 flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE; 1915 flags = (SCARG(uap, flags) & MSG_USERFLAGS) | MSG_IOVUSRSPACE;
1885 1916
1886 for (dg = 0; dg < vlen;) { 1917 for (dg = 0; dg < vlen;) {
1887 error = copyin(SCARG(uap, msgvec) + dg, &lmsg, sizeof(lmsg)); 1918 error = copyin(SCARG(uap, msgvec) + dg, &lmsg, sizeof(lmsg));
1888 if (error) 1919 if (error)
1889 break; 1920 break;
1890 linux_to_bsd_msghdr(&lmsg.msg_hdr, &bmsg.msg_hdr); 1921 linux_to_bsd_msghdr(&lmsg.msg_hdr, &bmsg.msg_hdr);
1891 msg->msg_flags = flags & ~MSG_WAITFORONE; 1922 msg->msg_flags = flags & ~MSG_WAITFORONE;
1892 1923
1893 if (from != NULL) { 1924 if (from != NULL) {
1894 m_free(from); 1925 m_free(from);
1895 from = NULL; 1926 from = NULL;