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 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #pragma ident "%Z%%M% %I% %E% SMI"
43 * Kernel TLI-like function to bind a transport endpoint
46 * Returns 0 on success or positive error code.
49 #include <sys/param.h>
50 #include <sys/types.h>
54 #include <sys/errno.h>
55 #include <sys/stream.h>
56 #include <sys/strsubr.h>
57 #include <sys/ioctl.h>
58 #include <sys/stropts.h>
59 #include <sys/vnode.h>
60 #include <sys/tihdr.h>
61 #include <sys/timod.h>
62 #include <sys/tiuser.h>
63 #include <sys/t_kuser.h>
65 #include <sys/sysmacros.h>
68 t_kbind(TIUSER
*tiptr
, struct t_bind
*req
, struct t_bind
*ret
)
70 struct T_bind_req
*bind_req
;
71 struct T_bind_ack
*bind_ack
;
76 struct strioctl strioc
;
86 * send the ioctl request and wait
89 bindsz
= (req
== NULL
) ? 0 : req
->addr
.len
;
90 bindsz
= MAX(bindsz
, tiptr
->tp_info
.addr
);
91 bindsz
+= MAX(TBINDREQSZ
, TBINDACKSZ
);
92 buf
= kmem_alloc(bindsz
, KM_SLEEP
);
94 /* LINTED pointer alignment */
95 bind_req
= (struct T_bind_req
*)buf
;
96 bind_req
->PRIM_type
= T_BIND_REQ
;
97 bind_req
->ADDR_length
= (req
== NULL
? 0 : req
->addr
.len
);
98 bind_req
->ADDR_offset
= TBINDREQSZ
;
99 bind_req
->CONIND_number
= (req
== NULL
? 0 : req
->qlen
);
101 if (bind_req
->ADDR_length
)
102 bcopy(req
->addr
.buf
, buf
+ bind_req
->ADDR_offset
,
103 bind_req
->ADDR_length
);
105 strioc
.ic_cmd
= TI_BIND
;
106 strioc
.ic_timout
= 0;
108 strioc
.ic_len
= (int)TBINDREQSZ
+ bind_req
->ADDR_length
;
111 * Usually ioctl()s are performed with the credential of the caller;
112 * in this particular case we specifically use the credential of
113 * the opener as this call is typically done in the context of a user
114 * process but on behalf of the kernel, e.g., a client connection
115 * to a server which is later shared by different users.
116 * At open time, we make sure to set fp->f_cred to kcred if such is
119 error
= strdoioctl(vp
->v_stream
, &strioc
, FNATIVE
, K_TO_K
, fp
->f_cred
,
124 if ((retval
& 0xff) == TSYSERR
)
125 error
= (retval
>> 8) & 0xff;
127 error
= t_tlitosyserr(retval
& 0xff);
131 /* LINTED pointer alignment */
132 bind_ack
= (struct T_bind_ack
*)strioc
.ic_dp
;
133 if (strioc
.ic_len
< TBINDACKSZ
|| bind_ack
->ADDR_length
== 0) {
139 * copy bind data into users buffer
142 if (ret
->addr
.maxlen
> bind_ack
->ADDR_length
)
143 ret
->addr
.len
= bind_ack
->ADDR_length
;
145 ret
->addr
.len
= ret
->addr
.maxlen
;
147 bcopy(buf
+ bind_ack
->ADDR_offset
, ret
->addr
.buf
,
150 ret
->qlen
= bind_ack
->CONIND_number
;
154 kmem_free(buf
, bindsz
);