1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
29 * Copyright 2018 Nexenta Systems, Inc.
30 */
31
32 #include "lint.h"
33
34 #include <sys/types.h>
35 #include <sys/socket.h>
36 #include <sys/stropts.h>
37 #include <sys/stream.h>
38 #include <sys/socketvar.h>
39 #include <sys/sockio.h>
40
41 #include <errno.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <stropts.h>
45 #include <stdio.h>
46 #include <strings.h>
47 #include <netinet/sctp.h>
48
49 #pragma weak accept = _accept
50 #pragma weak accept4 = _accept4
51 #pragma weak bind = _bind
52 #pragma weak connect = _connect
53 #pragma weak getpeername = _getpeername
54 #pragma weak getsockname = _getsockname
55 #pragma weak getsockopt = _getsockopt
56 #pragma weak listen = _listen
57 #pragma weak recv = _recv
58 #pragma weak recvfrom = _recvfrom
59 #pragma weak recvmsg = _recvmsg
60 #pragma weak send = _send
61 #pragma weak sendmsg = _sendmsg
62 #pragma weak sendto = _sendto
63 #pragma weak setsockopt = _setsockopt
64 #pragma weak shutdown = _shutdown
65 #pragma weak socket = _socket
66
67 extern int _so_accept(int, struct sockaddr *, socklen_t *, int, int);
68 extern int _so_bind(int, const struct sockaddr *, socklen_t, int);
69 extern int _so_connect(int, const struct sockaddr *, socklen_t, int);
70 extern int _so_getpeername(int, struct sockaddr *, socklen_t *,
71 int);
72 extern int _so_getsockname(int, struct sockaddr *, socklen_t *,
73 int);
74 extern int _so_getsockopt(int, int, int, void *, socklen_t *, int);
75 extern int _so_listen(int, int, int);
76 extern ssize_t _so_recv(int, void *, size_t, int);
77 extern ssize_t _so_recvfrom(int, void *, size_t, int, struct sockaddr *,
78 socklen_t *);
79 extern ssize_t _so_recvmsg(int, struct msghdr *, int);
80 extern ssize_t _so_send(int, const void *, size_t, int);
81 extern ssize_t _so_sendmsg(int, const struct msghdr *, int);
82 extern ssize_t _so_sendto(int, const void *, size_t, int,
83 const struct sockaddr *, socklen_t);
84 extern int _so_setsockopt(int, int, int, const void *, socklen_t, int);
85 extern int _so_shutdown(int, int, int);
86 extern int _so_socket(int, int, int, dev_t, int);
87
88 int
89 _accept(int sock, struct sockaddr *_RESTRICT_KYWD addr, socklen_t *addrlen)
90 {
91 return (_so_accept(sock, addr, addrlen, SOV_DEFAULT, 0));
92 }
93
94 int
95 _accept4(int sock, struct sockaddr *_RESTRICT_KYWD addr, socklen_t *addrlen,
96 int flags)
97 {
98 return (_so_accept(sock, addr, addrlen, SOV_DEFAULT, flags));
99 }
100
101 /*
102 * Note that regular sockets use SOV_SOCKBSD here to not allow a rebind of an
103 * already bound socket.
104 */
105 int
106 _bind(int sock, const struct sockaddr *addr, socklen_t addrlen)
107 {
108 return (_so_bind(sock, addr, addrlen, SOV_SOCKBSD));
109 }
110
111 int
112 _connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
113 {
114 return (_so_connect(sock, addr, addrlen, SOV_DEFAULT));
115 }
116
117 int
118 _getpeername(int sock, struct sockaddr *_RESTRICT_KYWD name, socklen_t *namelen)
119 {
120 return (_so_getpeername(sock, name, namelen, SOV_DEFAULT));
121 }
122
123 int
124 _getsockname(int sock, struct sockaddr *_RESTRICT_KYWD name, socklen_t *namelen)
125 {
126 return (_so_getsockname(sock, name, namelen, SOV_DEFAULT));
127 }
128
129 int
130 _getsockopt(int sock, int level, int optname, void *_RESTRICT_KYWD optval,
131 socklen_t *optlen)
132 {
133 if (level == IPPROTO_SCTP) {
134 sctp_assoc_t id = 0;
135 socklen_t len = *optlen;
136 int err = 0;
137 struct sctpopt sopt;
138
139 switch (optname) {
140 case SCTP_RTOINFO:
141 case SCTP_ASSOCINFO:
142 case SCTP_SET_PEER_PRIMARY_ADDR:
143 case SCTP_PRIMARY_ADDR:
144 case SCTP_PEER_ADDR_PARAMS:
145 case SCTP_STATUS:
146 case SCTP_GET_PEER_ADDR_INFO:
147 /*
148 * Association ID is the first element params struct
149 */
150 bcopy(optval, &id, sizeof (id));
151 break;
152 case SCTP_DEFAULT_SEND_PARAM:
153 bcopy(&((struct sctp_sndrcvinfo *)
154 optval)->sinfo_assoc_id, &id, sizeof (id));
155 break;
156 }
157
158 sopt.sopt_aid = id;
159 sopt.sopt_name = optname;
160 sopt.sopt_val = optval;
161 sopt.sopt_len = len;
162 if (ioctl(sock, SIOCSCTPGOPT, &sopt) == -1) {
163 err = -1;
164 } else {
165 *optlen = sopt.sopt_len;
166 }
167 return (err);
168 } else {
169 return (_so_getsockopt(sock, level, optname, optval, optlen,
170 SOV_DEFAULT));
171 }
172 }
173
174 int
175 _listen(int sock, int backlog)
176 {
177 return (_so_listen(sock, backlog, SOV_DEFAULT));
178 }
179
180 ssize_t
181 _recv(int sock, void *buf, size_t len, int flags)
182 {
183 return (_so_recv(sock, buf, len, flags & ~MSG_XPG4_2));
184 }
185
186 int
187 _recvfrom(int sock, void *_RESTRICT_KYWD buf, size_t len, int flags,
188 struct sockaddr *_RESTRICT_KYWD addr, socklen_t *addrlen)
189 {
190 return (_so_recvfrom(sock, buf, len, flags & ~MSG_XPG4_2,
191 addr, addrlen));
192 }
193
194 ssize_t
195 _recvmsg(int sock, struct msghdr *msg, int flags)
196 {
197 return (_so_recvmsg(sock, msg, flags & ~MSG_XPG4_2));
198 }
199
200 ssize_t
201 _send(int sock, const void *buf, size_t len, int flags)
202 {
203 return (_so_send(sock, buf, len, flags & ~MSG_XPG4_2));
204 }
205
206 ssize_t
207 _sendmsg(int sock, const struct msghdr *msg, int flags)
208 {
209 return (_so_sendmsg(sock, msg, flags & ~MSG_XPG4_2));
210 }
211
212 ssize_t
213 _sendto(int sock, const void *buf, size_t len, int flags,
214 const struct sockaddr *addr, socklen_t addrlen)
215 {
216 return (_so_sendto(sock, buf, len, flags & ~MSG_XPG4_2, addr, addrlen));
217 }
218
219 int
220 _setsockopt(int sock, int level, int optname, const void *optval,
221 socklen_t optlen)
222 {
223 return (_so_setsockopt(sock, level, optname, optval, optlen,
224 SOV_DEFAULT));
225 }
226
227 int
228 _shutdown(int sock, int how)
229 {
230 return (_so_shutdown(sock, how, SOV_DEFAULT));
231 }
232
233 int
234 _socket(int family, int type, int protocol)
235 {
236 return (_so_socket(family, type, protocol, NULL, SOV_DEFAULT));
237 }
238
239 /*
240 * Used by the BCP library.
241 */
242 int
243 _socket_bsd(int family, int type, int protocol)
244 {
245 return (_so_socket(family, type, protocol, NULL, SOV_SOCKBSD));
246 }
247
248
249 int
250 __xnet_bind(int sock, const struct sockaddr *addr, socklen_t addrlen)
251 {
252 return (_so_bind(sock, addr, addrlen, SOV_XPG4_2));
253 }
254
255 int
256 __xnet_connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
257 {
258 return (_so_connect(sock, addr, addrlen, SOV_XPG4_2));
259 }
260
261 int
262 __xnet_getsockopt(int sock, int level, int optname, void *optval,
263 socklen_t *optlen)
264 {
265 if (level == IPPROTO_SCTP) {
266 return (_getsockopt(sock, level, optname, optval, optlen));
267 } else {
268 return (_so_getsockopt(sock, level, optname, optval, optlen,
269 SOV_XPG4_2));
270 }
271 }
272
273 int
274 __xnet_listen(int sock, int backlog)
275 {
276 return (_so_listen(sock, backlog, SOV_XPG4_2));
277 }
278
279 int
280 __xnet_recvmsg(int sock, struct msghdr *msg, int flags)
281 {
282 return (_so_recvmsg(sock, msg, flags | MSG_XPG4_2));
283 }
284
285 int
286 __xnet_sendmsg(int sock, const struct msghdr *msg, int flags)
287 {
288 return (_so_sendmsg(sock, msg, flags | MSG_XPG4_2));
289 }
290
291 int
292 __xnet_sendto(int sock, const void *buf, size_t len, int flags,
293 const struct sockaddr *addr, socklen_t addrlen)
294 {
295 return (_so_sendto(sock, buf, len, flags | MSG_XPG4_2,
296 addr, addrlen));
297 }
298
299 int
300 __xnet_socket(int family, int type, int protocol)
301 {
302 return (_so_socket(family, type, protocol, NULL, SOV_XPG4_2));
303 }