xref: /onnv-gate/usr/src/uts/common/ktli/t_kconnect.c (revision 0:68f95e015346)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 1998 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
28*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
29*0Sstevel@tonic-gate 
30*0Sstevel@tonic-gate /*
31*0Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
32*0Sstevel@tonic-gate  * The Regents of the University of California
33*0Sstevel@tonic-gate  * All Rights Reserved
34*0Sstevel@tonic-gate  *
35*0Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
36*0Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
37*0Sstevel@tonic-gate  * contributors.
38*0Sstevel@tonic-gate  */
39*0Sstevel@tonic-gate 
40*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
41*0Sstevel@tonic-gate 
42*0Sstevel@tonic-gate /*
43*0Sstevel@tonic-gate  * Kernel TLI-like function to allow a trasnport endpoint to initiate a
44*0Sstevel@tonic-gate  * connection to another transport endpoint.  This function will wait for
45*0Sstevel@tonic-gate  * an ack and a T_CONN_CON before returning.
46*0Sstevel@tonic-gate  *
47*0Sstevel@tonic-gate  * Returns:
48*0Sstevel@tonic-gate  * 	0 on success, and if rcvcall is non-NULL it shall be
49*0Sstevel@tonic-gate  * 	filled with the connection confirm data.
50*0Sstevel@tonic-gate  * 	Otherwise a positive error code.
51*0Sstevel@tonic-gate  */
52*0Sstevel@tonic-gate 
53*0Sstevel@tonic-gate #include <sys/param.h>
54*0Sstevel@tonic-gate #include <sys/types.h>
55*0Sstevel@tonic-gate #include <sys/user.h>
56*0Sstevel@tonic-gate #include <sys/file.h>
57*0Sstevel@tonic-gate #include <sys/vnode.h>
58*0Sstevel@tonic-gate #include <sys/errno.h>
59*0Sstevel@tonic-gate #include <sys/stream.h>
60*0Sstevel@tonic-gate #include <sys/ioctl.h>
61*0Sstevel@tonic-gate #include <sys/stropts.h>
62*0Sstevel@tonic-gate #include <sys/tihdr.h>
63*0Sstevel@tonic-gate #include <sys/timod.h>
64*0Sstevel@tonic-gate #include <sys/tiuser.h>
65*0Sstevel@tonic-gate #include <sys/t_kuser.h>
66*0Sstevel@tonic-gate #include <sys/strsubr.h>
67*0Sstevel@tonic-gate #include <sys/sysmacros.h>
68*0Sstevel@tonic-gate 
69*0Sstevel@tonic-gate 
70*0Sstevel@tonic-gate int
71*0Sstevel@tonic-gate t_kconnect(TIUSER *tiptr, struct t_call *sndcall, struct t_call *rcvcall)
72*0Sstevel@tonic-gate {
73*0Sstevel@tonic-gate 	int			len;
74*0Sstevel@tonic-gate 	int			msgsz;
75*0Sstevel@tonic-gate 	size_t			hdrsz;
76*0Sstevel@tonic-gate 	struct T_conn_req	*creq;
77*0Sstevel@tonic-gate 	union T_primitives	*pptr;
78*0Sstevel@tonic-gate 	mblk_t			*nbp;
79*0Sstevel@tonic-gate 	file_t			*fp;
80*0Sstevel@tonic-gate 	mblk_t			*bp;
81*0Sstevel@tonic-gate 	int			error;
82*0Sstevel@tonic-gate 	int			flag;
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate 	error = 0;
85*0Sstevel@tonic-gate 
86*0Sstevel@tonic-gate 	fp = tiptr->fp;
87*0Sstevel@tonic-gate 	msgsz = (int)TCONNREQSZ;
88*0Sstevel@tonic-gate 	while (!(bp = allocb(msgsz + sndcall->addr.len + sndcall->opt.len,
89*0Sstevel@tonic-gate 	    BPRI_LO))) {
90*0Sstevel@tonic-gate 		if (strwaitbuf(msgsz + sndcall->addr.len + sndcall->opt.len,
91*0Sstevel@tonic-gate 		    BPRI_LO))
92*0Sstevel@tonic-gate 			return (ENOSR);
93*0Sstevel@tonic-gate 	}
94*0Sstevel@tonic-gate 
95*0Sstevel@tonic-gate 	/* LINTED pointer alignment */
96*0Sstevel@tonic-gate 	creq = (struct T_conn_req *)bp->b_wptr;
97*0Sstevel@tonic-gate 	creq->PRIM_type = T_CONN_REQ;
98*0Sstevel@tonic-gate 	creq->DEST_length = (t_scalar_t)sndcall->addr.len;
99*0Sstevel@tonic-gate 	creq->OPT_length = (t_scalar_t)sndcall->opt.len;
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 	if (sndcall->addr.len) {
102*0Sstevel@tonic-gate 		bcopy(sndcall->addr.buf, (bp->b_wptr+msgsz), sndcall->addr.len);
103*0Sstevel@tonic-gate 		creq->DEST_offset = (t_scalar_t)msgsz;
104*0Sstevel@tonic-gate 		msgsz += sndcall->addr.len;
105*0Sstevel@tonic-gate 	} else
106*0Sstevel@tonic-gate 		creq->DEST_offset = (t_scalar_t)0;
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate 	if (sndcall->opt.len) {
109*0Sstevel@tonic-gate 		bcopy(sndcall->opt.buf, (bp->b_wptr+msgsz), sndcall->opt.len);
110*0Sstevel@tonic-gate 		creq->OPT_offset = (t_scalar_t)msgsz;
111*0Sstevel@tonic-gate 		msgsz += sndcall->opt.len;
112*0Sstevel@tonic-gate 	} else
113*0Sstevel@tonic-gate 		creq->OPT_offset = (t_scalar_t)0;
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate 	bp->b_datap->db_type = M_PROTO;
116*0Sstevel@tonic-gate 	bp->b_wptr += msgsz;
117*0Sstevel@tonic-gate 
118*0Sstevel@tonic-gate 	/*
119*0Sstevel@tonic-gate 	 * copy the users data, if any.
120*0Sstevel@tonic-gate 	 */
121*0Sstevel@tonic-gate 	if (sndcall->udata.len) {
122*0Sstevel@tonic-gate 		/*
123*0Sstevel@tonic-gate 		 * if CO then we would allocate a data block and
124*0Sstevel@tonic-gate 		 * put the users connect data into it.
125*0Sstevel@tonic-gate 		 */
126*0Sstevel@tonic-gate 		KTLILOG(1,
127*0Sstevel@tonic-gate 		    "Attempt to send connectionless data on T_CONN_REQ\n", 0);
128*0Sstevel@tonic-gate 		freemsg(bp);
129*0Sstevel@tonic-gate 		return (EPROTO);
130*0Sstevel@tonic-gate 	}
131*0Sstevel@tonic-gate 
132*0Sstevel@tonic-gate 	flag = fp->f_flag;
133*0Sstevel@tonic-gate 
134*0Sstevel@tonic-gate 	/*
135*0Sstevel@tonic-gate 	 * send it
136*0Sstevel@tonic-gate 	 */
137*0Sstevel@tonic-gate 	if ((error = tli_send(tiptr, bp, flag)) != 0)
138*0Sstevel@tonic-gate 		return (error);
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	/*
141*0Sstevel@tonic-gate 	 * wait for acknowledgment
142*0Sstevel@tonic-gate 	 */
143*0Sstevel@tonic-gate 	if ((error = get_ok_ack(tiptr, T_CONN_REQ, flag)) != 0)
144*0Sstevel@tonic-gate 		return (error);
145*0Sstevel@tonic-gate 
146*0Sstevel@tonic-gate 	bp = NULL;
147*0Sstevel@tonic-gate 	/*
148*0Sstevel@tonic-gate 	 * wait for CONfirm
149*0Sstevel@tonic-gate 	 */
150*0Sstevel@tonic-gate 	if ((error = tli_recv(tiptr, &bp, flag)) != 0)
151*0Sstevel@tonic-gate 		return (error);
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate 	if (bp->b_datap->db_type != M_PROTO) {
154*0Sstevel@tonic-gate 		freemsg(bp);
155*0Sstevel@tonic-gate 		return (EPROTO);
156*0Sstevel@tonic-gate 	}
157*0Sstevel@tonic-gate 
158*0Sstevel@tonic-gate 	/* LINTED pointer alignment */
159*0Sstevel@tonic-gate 	pptr = (union T_primitives *)bp->b_rptr;
160*0Sstevel@tonic-gate 	switch (pptr->type) {
161*0Sstevel@tonic-gate 	case T_CONN_CON:
162*0Sstevel@tonic-gate 		hdrsz = bp->b_wptr -  bp->b_rptr;
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 		/*
165*0Sstevel@tonic-gate 		 * check everything for consistency
166*0Sstevel@tonic-gate 		 */
167*0Sstevel@tonic-gate 		if (hdrsz < TCONNCONSZ ||
168*0Sstevel@tonic-gate 		    hdrsz < (pptr->conn_con.OPT_length +
169*0Sstevel@tonic-gate 		    pptr->conn_con.OPT_offset) ||
170*0Sstevel@tonic-gate 		    hdrsz < (pptr->conn_con.RES_length +
171*0Sstevel@tonic-gate 		    pptr->conn_con.RES_offset)) {
172*0Sstevel@tonic-gate 			error = EPROTO;
173*0Sstevel@tonic-gate 			freemsg(bp);
174*0Sstevel@tonic-gate 			break;
175*0Sstevel@tonic-gate 		}
176*0Sstevel@tonic-gate 
177*0Sstevel@tonic-gate 		if (rcvcall != NULL) {
178*0Sstevel@tonic-gate 			/*
179*0Sstevel@tonic-gate 			 * okay, so now we copy them
180*0Sstevel@tonic-gate 			 */
181*0Sstevel@tonic-gate 			len = MIN(pptr->conn_con.RES_length,
182*0Sstevel@tonic-gate 			    rcvcall->addr.maxlen);
183*0Sstevel@tonic-gate 			bcopy(bp->b_rptr + pptr->conn_con.RES_offset,
184*0Sstevel@tonic-gate 			    rcvcall->addr.buf, len);
185*0Sstevel@tonic-gate 			rcvcall->addr.len = len;
186*0Sstevel@tonic-gate 
187*0Sstevel@tonic-gate 			len = MIN(pptr->conn_con.OPT_length,
188*0Sstevel@tonic-gate 			    rcvcall->opt.maxlen);
189*0Sstevel@tonic-gate 			bcopy(bp->b_rptr + pptr->conn_con.OPT_offset,
190*0Sstevel@tonic-gate 			    rcvcall->opt.buf, len);
191*0Sstevel@tonic-gate 			rcvcall->opt.len = len;
192*0Sstevel@tonic-gate 
193*0Sstevel@tonic-gate 			if (bp->b_cont) {
194*0Sstevel@tonic-gate 				nbp = bp;
195*0Sstevel@tonic-gate 				bp = bp->b_cont;
196*0Sstevel@tonic-gate 				msgsz = (int)(bp->b_wptr - bp->b_rptr);
197*0Sstevel@tonic-gate 				len = MIN(msgsz, rcvcall->udata.maxlen);
198*0Sstevel@tonic-gate 				bcopy(bp->b_rptr, rcvcall->udata.buf, len);
199*0Sstevel@tonic-gate 				rcvcall->udata.len = len;
200*0Sstevel@tonic-gate 				freemsg(nbp);
201*0Sstevel@tonic-gate 			}
202*0Sstevel@tonic-gate 		} else {
203*0Sstevel@tonic-gate 			freemsg(bp);
204*0Sstevel@tonic-gate 		}
205*0Sstevel@tonic-gate 		break;
206*0Sstevel@tonic-gate 
207*0Sstevel@tonic-gate 	default:
208*0Sstevel@tonic-gate 		error = EPROTO;
209*0Sstevel@tonic-gate 		freemsg(bp);
210*0Sstevel@tonic-gate 		break;
211*0Sstevel@tonic-gate 	}
212*0Sstevel@tonic-gate 	return (error);
213*0Sstevel@tonic-gate }
214