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.
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.
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]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
26 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
34 #include <sys/stream.h>
35 #define _SUN_TPI_VERSION 2
36 #include <sys/tihdr.h>
37 #include <sys/timod.h>
48 static int _alloc_buf(struct netbuf
*buf
, t_scalar_t n
, int fields
,
49 int api_semantics
, boolean_t option
);
52 _tx_alloc(int fd
, int struct_type
, int fields
, int api_semantics
)
54 struct strioctl strioc
;
55 struct T_info_ack info
;
61 struct t_optmgmt
*opt
;
62 struct t_unitdata
*udata
;
63 struct t_uderr
*uderr
;
67 struct _ti_user
*tiptr
;
71 if ((tiptr
= _t_checkfd(fd
, 0, api_semantics
)) == NULL
)
73 sig_mutex_lock(&tiptr
->ti_lock
);
76 * Get size info for T_ADDR, T_OPT, and T_UDATA fields
78 info
.PRIM_type
= T_INFO_REQ
;
79 strioc
.ic_cmd
= TI_GETINFO
;
80 strioc
.ic_timout
= -1;
81 strioc
.ic_len
= (int)sizeof (struct T_info_req
);
82 strioc
.ic_dp
= (char *)&info
;
84 retval
= ioctl(fd
, I_STR
, &strioc
);
85 } while (retval
< 0 && errno
== EINTR
);
89 sig_mutex_unlock(&tiptr
->ti_lock
);
95 if (strioc
.ic_len
!= (int)sizeof (struct T_info_ack
)) {
97 sig_mutex_unlock(&tiptr
->ti_lock
);
104 * Malloc appropriate structure and the specified
105 * fields within each structure. Initialize the
106 * 'buf' and 'maxlen' fields of each.
108 switch (struct_type
) {
111 if ((p
.bind
= calloc(1, sizeof (struct t_bind
))) == NULL
)
113 if (fields
& T_ADDR
) {
114 if (_alloc_buf(&p
.bind
->addr
,
116 fields
, api_semantics
, B_FALSE
) < 0)
119 sig_mutex_unlock(&tiptr
->ti_lock
);
120 return ((char *)p
.bind
);
123 if ((p
.call
= calloc(1, sizeof (struct t_call
))) == NULL
)
125 if (fields
& T_ADDR
) {
126 if (_alloc_buf(&p
.call
->addr
,
128 fields
, api_semantics
, B_FALSE
) < 0)
131 if (fields
& T_OPT
) {
132 if (info
.OPT_size
>= 0 && _T_IS_XTI(api_semantics
))
133 /* compensate for XTI level options */
134 optsize
= info
.OPT_size
+
135 TX_XTI_LEVEL_MAX_OPTBUF
;
137 optsize
= info
.OPT_size
;
138 if (_alloc_buf(&p
.call
->opt
, optsize
,
139 fields
, api_semantics
, B_TRUE
) < 0)
142 if (fields
& T_UDATA
) {
143 dsize
= _T_MAX((int)info
.CDATA_size
,
144 (int)info
.DDATA_size
);
145 if (_alloc_buf(&p
.call
->udata
, (t_scalar_t
)dsize
,
146 fields
, api_semantics
, B_FALSE
) < 0)
149 sig_mutex_unlock(&tiptr
->ti_lock
);
150 return ((char *)p
.call
);
153 if ((p
.opt
= calloc(1, sizeof (struct t_optmgmt
))) == NULL
)
155 if (fields
& T_OPT
) {
156 if (info
.OPT_size
>= 0 && _T_IS_XTI(api_semantics
))
157 /* compensate for XTI level options */
158 optsize
= info
.OPT_size
+
159 TX_XTI_LEVEL_MAX_OPTBUF
;
161 optsize
= info
.OPT_size
;
162 if (_alloc_buf(&p
.opt
->opt
, optsize
,
163 fields
, api_semantics
, B_TRUE
) < 0)
166 sig_mutex_unlock(&tiptr
->ti_lock
);
167 return ((char *)p
.opt
);
170 if ((p
.dis
= calloc(1, sizeof (struct t_discon
))) == NULL
)
172 if (fields
& T_UDATA
) {
173 if (_alloc_buf(&p
.dis
->udata
, info
.DDATA_size
,
174 fields
, api_semantics
, B_FALSE
) < 0)
177 sig_mutex_unlock(&tiptr
->ti_lock
);
178 return ((char *)p
.dis
);
181 if ((p
.udata
= calloc(1, sizeof (struct t_unitdata
))) == NULL
)
183 if (fields
& T_ADDR
) {
184 if (_alloc_buf(&p
.udata
->addr
, info
.ADDR_size
,
185 fields
, api_semantics
, B_FALSE
) < 0)
188 if (fields
& T_OPT
) {
189 if (info
.OPT_size
>= 0 && _T_IS_XTI(api_semantics
))
190 /* compensate for XTI level options */
191 optsize
= info
.OPT_size
+
192 TX_XTI_LEVEL_MAX_OPTBUF
;
194 optsize
= info
.OPT_size
;
195 if (_alloc_buf(&p
.udata
->opt
, optsize
,
196 fields
, api_semantics
, B_TRUE
) < 0)
199 if (fields
& T_UDATA
) {
200 if (_alloc_buf(&p
.udata
->udata
, info
.TSDU_size
,
201 fields
, api_semantics
, B_FALSE
) < 0)
204 sig_mutex_unlock(&tiptr
->ti_lock
);
205 return ((char *)p
.udata
);
208 if ((p
.uderr
= calloc(1, sizeof (struct t_uderr
))) == NULL
)
210 if (fields
& T_ADDR
) {
211 if (_alloc_buf(&p
.uderr
->addr
, info
.ADDR_size
,
212 fields
, api_semantics
, B_FALSE
) < 0)
215 if (fields
& T_OPT
) {
216 if (info
.OPT_size
>= 0 && _T_IS_XTI(api_semantics
))
217 /* compensate for XTI level options */
218 optsize
= info
.OPT_size
+
219 TX_XTI_LEVEL_MAX_OPTBUF
;
221 optsize
= info
.OPT_size
;
222 if (_alloc_buf(&p
.uderr
->opt
, optsize
,
223 fields
, api_semantics
, B_FALSE
) < 0)
226 sig_mutex_unlock(&tiptr
->ti_lock
);
227 return ((char *)p
.uderr
);
230 if ((p
.info
= calloc(1, sizeof (struct t_info
))) == NULL
)
232 sig_mutex_unlock(&tiptr
->ti_lock
);
233 return ((char *)p
.info
);
236 if (_T_IS_XTI(api_semantics
)) {
237 t_errno
= TNOSTRUCTYPE
;
238 sig_mutex_unlock(&tiptr
->ti_lock
);
239 } else { /* TX_TLI_API */
241 sig_mutex_unlock(&tiptr
->ti_lock
);
248 * Clean up. Set t_errno to TSYSERR.
249 * If it is because memory could not be allocated
250 * then errno already should have been set to
255 (void) t_free(p
.caddr
, struct_type
);
258 sig_mutex_unlock(&tiptr
->ti_lock
);
263 _alloc_buf(struct netbuf
*buf
, t_scalar_t n
, int fields
, int api_semantics
,
267 case T_INFINITE
/* -1 */:
268 if (_T_IS_XTI(api_semantics
)) {
271 if (fields
!= T_ALL
) {
273 * Do not return error
279 } else if (option
) { /* TX_TLI_API */
280 static size_t infalloc
;
283 * retain TLI behavior; ucred_t can vary in size,
284 * we need to make sure that we can receive one.
287 size_t uc
= ucred_size();
291 infalloc
= uc
+ 1024/2;
293 if ((buf
->buf
= calloc(1, infalloc
)) == NULL
) {
297 buf
->maxlen
= infalloc
;
298 } else { /* TX_TLI_API */
300 * retain TLI behavior
302 if ((buf
->buf
= calloc(1, 1024)) == NULL
) {
315 case T_INVALID
/* -2 */:
316 if (_T_IS_XTI(api_semantics
)) {
319 if (fields
!= T_ALL
) {
321 * Do not return error
327 } else { /* TX_TLI_API */
329 * retain TLI behavior
337 if ((buf
->buf
= calloc(1, (size_t)n
)) == NULL
) {