Print this page
3910 t_look(3NSL) should never return T_ERROR
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/ktli/t_krcvudat.c
+++ new/usr/src/uts/common/ktli/t_krcvudat.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 + * Copyright 2014 Gary Mills
22 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 24 * Use is subject to license terms.
24 25 */
25 26
26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
27 28 /* All Rights Reserved */
28 29
29 30 /*
30 31 * University Copyright- Copyright (c) 1982, 1986, 1988
31 32 * The Regents of the University of California
32 33 * All Rights Reserved
33 34 *
34 35 * University Acknowledgment- Portions of this document are derived from
35 36 * software developed by the University of California, Berkeley, and its
36 37 * contributors.
37 38 */
38 39
39 -#pragma ident "%Z%%M% %I% %E% SMI"
40 -
41 40 /*
42 41 * Kernel TLI-like function to read a datagram off of a
43 42 * transport endpoints stream head.
44 43 *
45 44 * Returns:
46 45 * 0 On success or positive error code.
47 46 * On sucess, type is set to:
48 47 * T_DATA If normal data has been received
49 48 * T_UDERR If an error indication has been received,
50 49 * in which case uderr contains the unitdata
51 50 * error number.
52 - * T_ERROR
53 51 */
54 52
55 53 #include <sys/param.h>
56 54 #include <sys/types.h>
57 55 #include <sys/user.h>
58 56 #include <sys/file.h>
59 57 #include <sys/errno.h>
60 58 #include <sys/stream.h>
61 59 #include <sys/strsubr.h>
62 60 #include <sys/vnode.h>
63 61 #include <sys/ioctl.h>
64 62 #include <sys/stropts.h>
65 63 #include <sys/tihdr.h>
66 64 #include <sys/timod.h>
67 65 #include <sys/tiuser.h>
68 66 #include <sys/t_kuser.h>
69 67 #include <sys/sysmacros.h>
70 68 #include <sys/strsun.h>
71 69
72 70
73 71 int
74 72 t_krcvudata(TIUSER *tiptr, struct t_kunitdata *unitdata, int *type, int *uderr)
75 73 {
76 74 int len;
77 75 size_t hdrsz;
78 76 union T_primitives *pptr;
79 77 struct file *fp;
80 78 mblk_t *bp;
81 79 mblk_t *nbp;
82 80 mblk_t *mp;
83 81 mblk_t *tmp;
84 82 int error;
85 83 int flag;
86 84
87 85 fp = tiptr->fp;
88 86
89 87 if (type == NULL || uderr == NULL)
90 88 return (EINVAL);
91 89
92 90 error = 0;
93 91 unitdata->udata.buf = NULL;
94 92
95 93 if (unitdata->udata.udata_mp) {
96 94 KTLILOG(2, "t_krcvudata: freeing existing message block\n", 0);
97 95 freemsg(unitdata->udata.udata_mp);
98 96 unitdata->udata.udata_mp = NULL;
99 97 }
100 98
101 99 /*
102 100 * XXX Grabbing a mutex to do an atomic operation seems pointless
103 101 */
104 102 mutex_enter(&fp->f_tlock);
105 103 flag = fp->f_flag;
106 104 mutex_exit(&fp->f_tlock);
107 105
108 106 if ((error = tli_recv(tiptr, &bp, flag)) != 0)
109 107 return (error);
110 108
111 109 /*
112 110 * Got something
113 111 */
114 112 switch (bp->b_datap->db_type) {
115 113 case M_PROTO:
116 114 /* LINTED pointer alignment */
117 115 pptr = (union T_primitives *)bp->b_rptr;
118 116 switch (pptr->type) {
119 117 case T_UNITDATA_IND:
120 118 KTLILOG(2, "t_krcvudata: Got T_UNITDATA_IND\n", 0);
121 119 hdrsz = MBLKL(bp);
122 120
123 121 /*
124 122 * check everything for consistency
125 123 */
126 124 if (hdrsz < TUNITDATAINDSZ ||
127 125 hdrsz < (pptr->unitdata_ind.OPT_length +
128 126 pptr->unitdata_ind.OPT_offset) ||
129 127 hdrsz < (pptr->unitdata_ind.SRC_length +
130 128 pptr->unitdata_ind.SRC_offset)) {
131 129 error = EPROTO;
132 130 freemsg(bp);
133 131 break;
134 132 }
135 133
136 134 /*
137 135 * okay, so now we copy them
138 136 */
139 137 len = MIN(pptr->unitdata_ind.SRC_length,
140 138 unitdata->addr.maxlen);
141 139 bcopy(bp->b_rptr + pptr->unitdata_ind.SRC_offset,
142 140 unitdata->addr.buf, len);
143 141 unitdata->addr.len = len;
144 142
145 143 len = MIN(pptr->unitdata_ind.OPT_length,
146 144 unitdata->opt.maxlen);
147 145 bcopy(bp->b_rptr + pptr->unitdata_ind.OPT_offset,
148 146 unitdata->opt.buf, len);
149 147 unitdata->opt.len = len;
150 148
151 149 bp->b_rptr += hdrsz;
152 150
153 151 /*
154 152 * we assume that the client knows how to deal
155 153 * with a set of linked mblks, so all we do is
156 154 * make a pass and remove any that are zero
157 155 * length.
158 156 */
159 157 nbp = NULL;
160 158 mp = bp;
161 159 while (mp) {
162 160 if (bp->b_wptr == bp->b_rptr) {
163 161 KTLILOG(2,
164 162 "t_krcvudata: zero length block\n",
165 163 0);
166 164 tmp = mp->b_cont;
167 165 if (nbp)
168 166 nbp->b_cont = tmp;
169 167 else
170 168 bp = tmp;
171 169
172 170 freeb(mp);
173 171 mp = tmp;
174 172 } else {
175 173 nbp = mp;
176 174 mp = mp->b_cont;
177 175 }
178 176 }
179 177 #ifdef KTLIDEBUG
180 178 {
181 179 mblk_t *tp;
182 180
183 181 tp = bp;
184 182 while (tp) {
185 183 struct datab *dbp = tp->b_datap;
186 184 frtn_t *frp = dbp->db_frtnp;
187 185
188 186 KTLILOG(2, "t_krcvudata: bp %x, ", tp);
189 187 KTLILOG(2, "db_size %x, ", dbp->db_lim - dbp->db_base);
190 188 KTLILOG(2, "db_ref %x", dbp->db_ref);
191 189
192 190 if (frp != NULL)
193 191 KTLILOG(2, ", func: %x", frp->free_func);
194 192 KTLILOG(2, ", arg %x\n", frp->free_arg);
195 193 } else
196 194 KTLILOG(2, "\n", 0);
197 195 tp = tp->b_cont;
198 196 }
199 197 }
200 198 #endif /* KTLIDEBUG */
201 199 /*
202 200 * now just point the users mblk
203 201 * pointer to what we received.
204 202 */
205 203 if (bp == NULL) {
206 204 KTLILOG(2, "t_krcvudata: No data\n", 0);
207 205 error = EPROTO;
208 206 break;
209 207 }
210 208 if (bp->b_wptr != bp->b_rptr) {
211 209 if (!IS_P2ALIGNED(bp->b_rptr, sizeof (uint32_t)))
212 210 if (!pullupmsg(bp, MBLKL(bp))) {
213 211 KTLILOG(1,
214 212 "t_krcvudata: pullupmsg failed\n", 0);
215 213 error = EIO;
216 214 freemsg(bp);
217 215 break;
218 216 }
219 217 unitdata->udata.buf = (char *)bp->b_rptr;
220 218 unitdata->udata.len = (uint_t)MBLKL(bp);
221 219
222 220 KTLILOG(2, "t_krcvudata: got %d bytes\n",
223 221 unitdata->udata.len);
224 222 unitdata->udata.udata_mp = bp;
225 223 } else {
226 224 KTLILOG(2,
227 225 "t_krcvudata: 0 length data message\n", 0);
228 226 freemsg(bp);
229 227 unitdata->udata.len = 0;
230 228 }
231 229 *type = T_DATA;
232 230 break;
233 231
234 232 case T_UDERROR_IND:
235 233 KTLILOG(2, "t_krcvudata: Got T_UDERROR_IND\n", 0);
236 234 hdrsz = MBLKL(bp);
237 235
238 236 /*
239 237 * check everything for consistency
240 238 */
241 239 if (hdrsz < TUDERRORINDSZ ||
242 240 hdrsz < (pptr->uderror_ind.OPT_length +
243 241 pptr->uderror_ind.OPT_offset) ||
244 242 hdrsz < (pptr->uderror_ind.DEST_length +
245 243 pptr->uderror_ind.DEST_offset)) {
246 244 error = EPROTO;
247 245 freemsg(bp);
248 246 break;
249 247 }
250 248
251 249 if (pptr->uderror_ind.DEST_length >
252 250 (int)unitdata->addr.maxlen ||
253 251 pptr->uderror_ind.OPT_length >
254 252 (int)unitdata->opt.maxlen) {
255 253 error = EMSGSIZE;
256 254 freemsg(bp);
257 255 break;
258 256 }
259 257
260 258 /*
261 259 * okay, so now we copy them
262 260 */
263 261 bcopy(bp->b_rptr + pptr->uderror_ind.DEST_offset,
264 262 unitdata->addr.buf,
265 263 (size_t)pptr->uderror_ind.DEST_length);
266 264 unitdata->addr.len = pptr->uderror_ind.DEST_length;
267 265
268 266 bcopy(bp->b_rptr + pptr->uderror_ind.OPT_offset,
269 267 unitdata->opt.buf,
270 268 (size_t)pptr->uderror_ind.OPT_length);
271 269 unitdata->opt.len = pptr->uderror_ind.OPT_length;
272 270
273 271 *uderr = pptr->uderror_ind.ERROR_type;
274 272
275 273 unitdata->udata.buf = NULL;
276 274 unitdata->udata.udata_mp = NULL;
277 275 unitdata->udata.len = 0;
278 276
279 277 freemsg(bp);
280 278
281 279 *type = T_UDERR;
282 280 break;
283 281
284 282 default:
285 283 KTLILOG(1,
286 284 "t_krcvudata: Unknown transport primitive %d\n",
↓ open down ↓ |
224 lines elided |
↑ open up ↑ |
287 285 pptr->type);
288 286 error = EPROTO;
289 287 freemsg(bp);
290 288 break;
291 289 }
292 290 break;
293 291
294 292 case M_FLUSH:
295 293 KTLILOG(1, "t_krcvudata: tli_recv returned M_FLUSH\n", 0);
296 294 freemsg(bp);
297 - *type = T_ERROR;
295 + error = EBADMSG;
298 296 break;
299 297
300 298 default:
301 299 KTLILOG(1, "t_krcvudata: unknown message type %x\n",
302 300 bp->b_datap->db_type);
303 301 freemsg(bp);
304 - *type = T_ERROR;
302 + error = EBADMSG;
305 303 break;
306 304 }
307 305
308 306 return (error);
309 307 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX