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 2009 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 /* All Rights Reserved */
30 * University Copyright- Copyright (c) 1982, 1986, 1988
31 * The Regents of the University of California
34 * University Acknowledgment- Portions of this document are derived from
35 * software developed by the University of California, Berkeley, and its
40 * TLI-like function to send datagrams over a specified
44 * 0 on success or positive error code.
47 #include <sys/param.h>
48 #include <sys/types.h>
51 #include <sys/errno.h>
52 #include <sys/stream.h>
53 #include <sys/strsubr.h>
54 #include <sys/vnode.h>
55 #include <sys/ioctl.h>
56 #include <sys/stropts.h>
57 #include <sys/tihdr.h>
58 #include <sys/timod.h>
59 #include <sys/tiuser.h>
60 #include <sys/t_kuser.h>
61 #include <sys/debug.h>
65 t_ksndudata(TIUSER
*tiptr
, struct t_kunitdata
*unitdata
, frtn_t
*frtn
)
71 struct T_unitdata_req
*udreq
;
77 msgsz
= unitdata
->udata
.len
;
80 * See if Class 0 is required
83 ASSERT(unitdata
->udata
.udata_mp
== NULL
);
84 ASSERT(unitdata
->udata
.buf
!= NULL
);
86 * user has supplied their own buffer, all we have to
87 * do is allocate a class 0 streams buffer and set it
90 if ((dbp
= (mblk_t
*)esballoc((uchar_t
*)unitdata
->udata
.buf
,
91 (size_t)msgsz
, BPRI_LO
, frtn
)) == NULL
)
94 dbp
->b_datap
->db_type
= M_DATA
;
95 KTLILOG(2, "t_ksndudata: bp %x, ", dbp
);
96 KTLILOG(2, "len %d, ", msgsz
);
97 KTLILOG(2, "free func %x\n", frtn
->free_func
);
99 } else if (unitdata
->udata
.buf
) {
100 ASSERT(unitdata
->udata
.udata_mp
== NULL
);
101 while (!(dbp
= allocb(msgsz
, BPRI_LO
)))
102 if (strwaitbuf((size_t)msgsz
, BPRI_LO
))
105 bcopy(unitdata
->udata
.buf
, dbp
->b_wptr
, unitdata
->udata
.len
);
106 dbp
->b_datap
->db_type
= M_DATA
;
108 } else if (unitdata
->udata
.udata_mp
) {
109 ASSERT(unitdata
->udata
.buf
== NULL
);
111 * user has done it all
113 dbp
= unitdata
->udata
.udata_mp
;
118 * zero length message.
124 dbp
->b_wptr
+= msgsz
; /* on behalf of the user */
127 * Okay, put the control part in
130 msgsz
= (int)TUNITDATAREQSZ
;
132 * Usually sendto()s are performed with the credential of the caller;
133 * in this particular case we specifically use the credential of
134 * the opener as this call is typically done in the context of a user
135 * process but on behalf of the kernel, e.g., a client connection
136 * to a server which is later shared by different users.
137 * At open time, we make sure to set fp->f_cred to kcred if such is
140 * Note: if the receiver uses SCM_UCRED/getpeerucred the pid will
143 while (!(bp
= allocb_cred(msgsz
+ unitdata
->addr
.len
+
144 unitdata
->opt
.len
, fp
->f_cred
, NOPID
))) {
145 if (strwaitbuf(msgsz
+ unitdata
->addr
.len
+ unitdata
->opt
.len
,
147 if (dbp
&& (dbp
!= unitdata
->udata
.udata_mp
))
153 /* LINTED pointer alignment */
154 udreq
= (struct T_unitdata_req
*)bp
->b_wptr
;
155 udreq
->PRIM_type
= T_UNITDATA_REQ
;
156 udreq
->DEST_length
= unitdata
->addr
.len
;
157 if (unitdata
->addr
.len
) {
158 bcopy(unitdata
->addr
.buf
, bp
->b_wptr
+ msgsz
,
160 udreq
->DEST_offset
= (t_scalar_t
)msgsz
;
161 msgsz
+= unitdata
->addr
.len
;
163 udreq
->DEST_offset
= 0;
165 udreq
->OPT_length
= unitdata
->opt
.len
;
166 if (unitdata
->opt
.len
) {
167 bcopy(unitdata
->opt
.buf
, bp
->b_wptr
+ msgsz
, unitdata
->opt
.len
);
168 udreq
->OPT_offset
= (t_scalar_t
)msgsz
;
169 msgsz
+= unitdata
->opt
.len
;
171 udreq
->OPT_offset
= 0;
173 bp
->b_datap
->db_type
= M_PROTO
;
182 * Put it to the transport provider.
183 * tli_send() always consumes the message.
186 error
= tli_send(tiptr
, bp
, flag
);
187 unitdata
->udata
.udata_mp
= NULL
;