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 #pragma ident "%Z%%M% %I% %E% SMI"
28
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/stropts.h>
32 #include <sys/stream.h>
33 #include <sys/socketvar.h>
34 #include <sys/sockio.h>
35
36 #include <errno.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39 #include <stropts.h>
40 #include <stdio.h>
41 #include <strings.h>
42 #include <netinet/sctp.h>
43
44 #pragma weak bind = _bind
45 #pragma weak listen = _listen
46 #pragma weak accept = _accept
47 #pragma weak connect = _connect
48 #pragma weak shutdown = _shutdown
49 #pragma weak recv = _recv
50 #pragma weak recvfrom = _recvfrom
51 #pragma weak recvmsg = _recvmsg
52 #pragma weak send = _send
53 #pragma weak sendmsg = _sendmsg
54 #pragma weak sendto = _sendto
55 #pragma weak getpeername = _getpeername
56 #pragma weak getsockname = _getsockname
57 #pragma weak getsockopt = _getsockopt
58 #pragma weak setsockopt = _setsockopt
59
60 extern int _so_bind();
61 extern int _so_listen();
62 extern int _so_accept();
63 extern int _so_connect();
64 extern int _so_shutdown();
65 extern int _so_recv();
66 extern int _so_recvfrom();
67 extern int _so_recvmsg();
68 extern int _so_send();
69 extern int _so_sendmsg();
70 extern int _so_sendto();
71 extern int _so_getpeername();
72 extern int _so_getsockopt();
73 extern int _so_setsockopt();
74 extern int _so_getsockname();
75
76 /*
77 * Note that regular sockets use SOV_SOCKBSD here to not allow a rebind of an
78 * already bound socket.
79 */
80 int
_bind(int sock,struct sockaddr * addr,int addrlen)81 _bind(int sock, struct sockaddr *addr, int addrlen)
82 {
83 return (_so_bind(sock, addr, addrlen, SOV_SOCKBSD));
84 }
85
86 int
_listen(int sock,int backlog)87 _listen(int sock, int backlog)
88 {
89 return (_so_listen(sock, backlog, SOV_DEFAULT));
90 }
91
92 int
_accept(int sock,struct sockaddr * addr,int * addrlen)93 _accept(int sock, struct sockaddr *addr, int *addrlen)
94 {
95 return (_so_accept(sock, addr, addrlen, SOV_DEFAULT));
96 }
97
98 int
_connect(int sock,struct sockaddr * addr,int addrlen)99 _connect(int sock, struct sockaddr *addr, int addrlen)
100 {
101 return (_so_connect(sock, addr, addrlen, SOV_DEFAULT));
102 }
103
104 int
_shutdown(int sock,int how)105 _shutdown(int sock, int how)
106 {
107 return (_so_shutdown(sock, how, SOV_DEFAULT));
108 }
109
110 int
_recv(int sock,char * buf,int len,int flags)111 _recv(int sock, char *buf, int len, int flags)
112 {
113 return (_so_recv(sock, buf, len, flags & ~MSG_XPG4_2));
114 }
115
116 int
_recvfrom(int sock,char * buf,int len,int flags,struct sockaddr * addr,int * addrlen)117 _recvfrom(int sock, char *buf, int len, int flags,
118 struct sockaddr *addr, int *addrlen)
119 {
120 return (_so_recvfrom(sock, buf, len, flags & ~MSG_XPG4_2,
121 addr, addrlen));
122 }
123
124 int
_recvmsg(int sock,struct msghdr * msg,int flags)125 _recvmsg(int sock, struct msghdr *msg, int flags)
126 {
127 return (_so_recvmsg(sock, msg, flags & ~MSG_XPG4_2));
128 }
129
130 int
_send(int sock,char * buf,int len,int flags)131 _send(int sock, char *buf, int len, int flags)
132 {
133 return (_so_send(sock, buf, len, flags & ~MSG_XPG4_2));
134 }
135
136 int
_sendmsg(int sock,struct msghdr * msg,int flags)137 _sendmsg(int sock, struct msghdr *msg, int flags)
138 {
139 return (_so_sendmsg(sock, msg, flags & ~MSG_XPG4_2));
140 }
141
142 int
_sendto(int sock,char * buf,int len,int flags,struct sockaddr * addr,int * addrlen)143 _sendto(int sock, char *buf, int len, int flags,
144 struct sockaddr *addr, int *addrlen)
145 {
146 return (_so_sendto(sock, buf, len, flags & ~MSG_XPG4_2,
147 addr, addrlen));
148 }
149
150 int
_getpeername(int sock,struct sockaddr * name,int * namelen)151 _getpeername(int sock, struct sockaddr *name, int *namelen)
152 {
153 return (_so_getpeername(sock, name, namelen, SOV_DEFAULT));
154 }
155
156 int
_getsockname(int sock,struct sockaddr * name,int * namelen)157 _getsockname(int sock, struct sockaddr *name, int *namelen)
158 {
159 return (_so_getsockname(sock, name, namelen, SOV_DEFAULT));
160 }
161
162 int
_getsockopt(int sock,int level,int optname,char * optval,int * optlen)163 _getsockopt(int sock, int level, int optname, char *optval, int *optlen)
164 {
165 if (level == IPPROTO_SCTP) {
166 sctp_assoc_t id = 0;
167 socklen_t len = *optlen;
168 int err = 0;
169 struct sctpopt sopt;
170
171 switch (optname) {
172 case SCTP_RTOINFO:
173 case SCTP_ASSOCINFO:
174 case SCTP_SET_PEER_PRIMARY_ADDR:
175 case SCTP_PRIMARY_ADDR:
176 case SCTP_PEER_ADDR_PARAMS:
177 case SCTP_STATUS:
178 case SCTP_GET_PEER_ADDR_INFO:
179 /*
180 * Association ID is the first element params struct
181 */
182 bcopy(optval, &id, sizeof (id));
183 break;
184 case SCTP_DEFAULT_SEND_PARAM:
185 bcopy(&((struct sctp_sndrcvinfo *)
186 optval)->sinfo_assoc_id, &id, sizeof (id));
187 break;
188 }
189
190 sopt.sopt_aid = id;
191 sopt.sopt_name = optname;
192 sopt.sopt_val = optval;
193 sopt.sopt_len = len;
194 if (ioctl(sock, SIOCSCTPGOPT, &sopt) == -1) {
195 err = -1;
196 } else {
197 *optlen = sopt.sopt_len;
198 }
199 return (err);
200 } else {
201 return (_so_getsockopt(sock, level, optname, optval, optlen,
202 SOV_DEFAULT));
203 }
204 }
205
206 int
_setsockopt(int sock,int level,int optname,char * optval,int optlen)207 _setsockopt(int sock, int level, int optname, char *optval, int optlen)
208 {
209 return (_so_setsockopt(sock, level, optname, optval, optlen,
210 SOV_DEFAULT));
211 }
212
213 int
__xnet_bind(int sock,const struct sockaddr * addr,socklen_t addrlen)214 __xnet_bind(int sock, const struct sockaddr *addr, socklen_t addrlen)
215 {
216 return (_so_bind(sock, addr, addrlen, SOV_XPG4_2));
217 }
218
219
220 int
__xnet_listen(int sock,int backlog)221 __xnet_listen(int sock, int backlog)
222 {
223 return (_so_listen(sock, backlog, SOV_XPG4_2));
224 }
225
226 int
__xnet_connect(int sock,const struct sockaddr * addr,socklen_t addrlen)227 __xnet_connect(int sock, const struct sockaddr *addr, socklen_t addrlen)
228 {
229 return (_so_connect(sock, addr, addrlen, SOV_XPG4_2));
230 }
231
232 int
__xnet_recvmsg(int sock,struct msghdr * msg,int flags)233 __xnet_recvmsg(int sock, struct msghdr *msg, int flags)
234 {
235 return (_so_recvmsg(sock, msg, flags | MSG_XPG4_2));
236 }
237
238 int
__xnet_sendmsg(int sock,const struct msghdr * msg,int flags)239 __xnet_sendmsg(int sock, const struct msghdr *msg, int flags)
240 {
241 return (_so_sendmsg(sock, msg, flags | MSG_XPG4_2));
242 }
243
244 int
__xnet_sendto(int sock,const void * buf,size_t len,int flags,const struct sockaddr * addr,socklen_t addrlen)245 __xnet_sendto(int sock, const void *buf, size_t len, int flags,
246 const struct sockaddr *addr, socklen_t addrlen)
247 {
248 return (_so_sendto(sock, buf, len, flags | MSG_XPG4_2,
249 addr, addrlen));
250 }
251
252 int
__xnet_getsockopt(int sock,int level,int option_name,void * option_value,socklen_t * option_lenp)253 __xnet_getsockopt(int sock, int level, int option_name,
254 void *option_value, socklen_t *option_lenp)
255 {
256 if (level == IPPROTO_SCTP) {
257 return (_getsockopt(sock, level, option_name, option_value,
258 (int *)option_lenp));
259 } else {
260 return (_so_getsockopt(sock, level, option_name, option_value,
261 option_lenp, SOV_XPG4_2));
262 }
263 }
264