4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
24 /* All Rights Reserved */
27 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 #pragma ident "%Z%%M% %I% %E% SMI"
39 #include <sys/stream.h>
41 #define _SUN_TPI_VERSION 2
42 #include <sys/tihdr.h>
43 #include <sys/timod.h>
48 static int __tx_tlitpi_getprotaddr_locked(struct _ti_user
*tiptr
,
49 struct t_bind
*boundaddr
, struct t_bind
*peer
);
52 static int __tx_getname_locked(int fd
, struct netbuf
*name
, int type
);
55 _tx_getname(int fd
, struct netbuf
*name
, int type
, int api_semantics
)
57 struct _ti_user
*tiptr
;
60 assert(_T_IS_TLI(api_semantics
)); /* TLI only interface */
61 if (!name
|| ((type
!= LOCALNAME
) && (type
!= REMOTENAME
))) {
66 if ((tiptr
= _t_checkfd(fd
, 0, api_semantics
)) == 0)
68 sig_mutex_lock(&tiptr
->ti_lock
);
70 retval
= __tx_getname_locked(fd
, name
, type
);
74 sig_mutex_unlock(&tiptr
->ti_lock
);
79 sig_mutex_unlock(&tiptr
->ti_lock
);
86 __tx_getname_locked(int fd
, struct netbuf
*name
, int type
)
92 (type
== LOCALNAME
) ? TI_GETMYNAME
: TI_GETPEERNAME
, name
);
93 } while (retval
< 0 && errno
== EINTR
);
107 struct t_bind
*boundaddr
,
108 struct t_bind
*peeraddr
,
111 struct _ti_user
*tiptr
;
112 int retval
, sv_errno
;
113 struct T_addr_req
*addreqp
;
114 struct T_addr_ack
*addrackp
;
116 struct strbuf ctlbuf
;
119 if ((tiptr
= _t_checkfd(fd
, 0, api_semantics
)) == 0)
122 sig_mutex_lock(&tiptr
->ti_lock
);
124 if ((tiptr
->ti_prov_flag
& XPG4_1
) == 0) {
126 * Provider does not support XTI inspired TPI so we
127 * try to do operation assuming TLI inspired TPI
129 retval
= __tx_tlitpi_getprotaddr_locked(tiptr
, boundaddr
,
132 sig_mutex_unlock(&tiptr
->ti_lock
);
138 * Acquire buffer for use in sending/receiving the message.
139 * Note: assumes (correctly) that ti_ctlsize is large enough
140 * to hold sizeof (struct T_addr_req/ack)
142 if (_t_acquire_ctlbuf(tiptr
, &ctlbuf
, &didalloc
) < 0) {
144 sig_mutex_unlock(&tiptr
->ti_lock
);
149 /* LINTED pointer cast */
150 addreqp
= (struct T_addr_req
*)ctlbuf
.buf
;
151 addreqp
->PRIM_type
= T_ADDR_REQ
;
154 retval
= _t_do_ioctl(fd
, ctlbuf
.buf
,
155 (int)sizeof (struct T_addr_req
), TI_GETADDRS
, &retlen
);
156 } while (retval
< 0 && errno
== EINTR
);
158 /* retval can now be either 0 or -1 */
161 sig_mutex_unlock(&tiptr
->ti_lock
);
165 sig_mutex_unlock(&tiptr
->ti_lock
);
167 if (retlen
< (int)sizeof (struct T_addr_ack
)) {
174 /* LINTED pointer cast */
175 addrackp
= (struct T_addr_ack
*)ctlbuf
.buf
;
178 * We assume null parameters are OK and not errors
180 if (boundaddr
!= NULL
&& boundaddr
->addr
.maxlen
> 0) {
181 if (TLEN_GT_NLEN(addrackp
->LOCADDR_length
,
182 boundaddr
->addr
.maxlen
)) {
187 boundaddr
->addr
.len
= addrackp
->LOCADDR_length
;
188 (void) memcpy(boundaddr
->addr
.buf
,
189 ctlbuf
.buf
+ addrackp
->LOCADDR_offset
,
190 (size_t)addrackp
->LOCADDR_length
);
194 * Note: In states where there is no remote end of the connection
195 * the T_ADDR_REQ primitive does not return a remote address. However,
196 * in protcols such as TCP, the transport connection is established
197 * before the TLI/XTI level association is established. Therefore,
198 * in state T_OUTCON, the transport may return a remote address where
199 * TLI/XTI level thinks there is no remote end and therefore
200 * no remote address should be returned. We therefore do not look at
201 * address returned by transport provider in T_OUTCON state.
202 * Tested by XTI test suite.
204 if (tiptr
->ti_state
!= T_OUTCON
&&
205 peeraddr
!= NULL
&& peeraddr
->addr
.maxlen
> 0) {
206 if (TLEN_GT_NLEN(addrackp
->REMADDR_length
,
207 peeraddr
->addr
.maxlen
)) {
212 peeraddr
->addr
.len
= addrackp
->REMADDR_length
;
213 (void) memcpy(peeraddr
->addr
.buf
,
214 ctlbuf
.buf
+ addrackp
->REMADDR_offset
,
215 (size_t)addrackp
->REMADDR_length
);
222 tiptr
->ti_ctlbuf
= ctlbuf
.buf
;
227 __tx_tlitpi_getprotaddr_locked(
228 struct _ti_user
*tiptr
,
229 struct t_bind
*boundaddr
,
230 struct t_bind
*peeraddr
)
233 boundaddr
->addr
.len
= 0;
234 if (tiptr
->ti_state
>= TS_IDLE
) {
236 * assume bound endpoint .
237 * Note: TI_GETMYNAME can return
238 * a finite length all zeroes address for unbound
239 * endpoint so we avoid relying on it for bound
240 * endpoints for XTI t_getprotaddr() semantics.
242 if (__tx_getname_locked(tiptr
->ti_fd
, &boundaddr
->addr
,
250 peeraddr
->addr
.len
= 0;
252 if (tiptr
->ti_state
>= TS_DATA_XFER
) {
254 * assume connected endpoint.
255 * The TI_GETPEERNAME call can fail with error
256 * if endpoint is not connected so we don't call it
257 * for XTI t_getprotaddr() semantics
259 if (__tx_getname_locked(tiptr
->ti_fd
, &peeraddr
->addr
,