1*2654012fSReza Sabdar /*
2*2654012fSReza Sabdar  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3*2654012fSReza Sabdar  * Use is subject to license terms.
4*2654012fSReza Sabdar  */
5*2654012fSReza Sabdar 
6*2654012fSReza Sabdar /*
7*2654012fSReza Sabdar  * BSD 3 Clause License
8*2654012fSReza Sabdar  *
9*2654012fSReza Sabdar  * Copyright (c) 2007, The Storage Networking Industry Association.
10*2654012fSReza Sabdar  *
11*2654012fSReza Sabdar  * Redistribution and use in source and binary forms, with or without
12*2654012fSReza Sabdar  * modification, are permitted provided that the following conditions
13*2654012fSReza Sabdar  * are met:
14*2654012fSReza Sabdar  * 	- Redistributions of source code must retain the above copyright
15*2654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer.
16*2654012fSReza Sabdar  *
17*2654012fSReza Sabdar  * 	- Redistributions in binary form must reproduce the above copyright
18*2654012fSReza Sabdar  *	  notice, this list of conditions and the following disclaimer in
19*2654012fSReza Sabdar  *	  the documentation and/or other materials provided with the
20*2654012fSReza Sabdar  *	  distribution.
21*2654012fSReza Sabdar  *
22*2654012fSReza Sabdar  *	- Neither the name of The Storage Networking Industry Association (SNIA)
23*2654012fSReza Sabdar  *	  nor the names of its contributors may be used to endorse or promote
24*2654012fSReza Sabdar  *	  products derived from this software without specific prior written
25*2654012fSReza Sabdar  *	  permission.
26*2654012fSReza Sabdar  *
27*2654012fSReza Sabdar  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28*2654012fSReza Sabdar  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29*2654012fSReza Sabdar  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30*2654012fSReza Sabdar  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31*2654012fSReza Sabdar  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32*2654012fSReza Sabdar  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33*2654012fSReza Sabdar  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34*2654012fSReza Sabdar  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35*2654012fSReza Sabdar  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36*2654012fSReza Sabdar  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37*2654012fSReza Sabdar  * POSSIBILITY OF SUCH DAMAGE.
38*2654012fSReza Sabdar  */
39*2654012fSReza Sabdar 
40*2654012fSReza Sabdar /*
41*2654012fSReza Sabdar  * Provides encode/decode routines for all door servers/clients.
42*2654012fSReza Sabdar  */
43*2654012fSReza Sabdar 
44*2654012fSReza Sabdar #include <string.h>
45*2654012fSReza Sabdar #include <errno.h>
46*2654012fSReza Sabdar #include <stdlib.h>
47*2654012fSReza Sabdar #include <libndmp.h>
48*2654012fSReza Sabdar 
49*2654012fSReza Sabdar ndmp_door_ctx_t *
ndmp_door_decode_start(char * ptr,int size)50*2654012fSReza Sabdar ndmp_door_decode_start(char *ptr, int size)
51*2654012fSReza Sabdar {
52*2654012fSReza Sabdar 	ndmp_door_ctx_t *ctx = malloc(sizeof (ndmp_door_ctx_t));
53*2654012fSReza Sabdar 	if (ctx) {
54*2654012fSReza Sabdar 		ctx->start_ptr = ctx->ptr = ptr;
55*2654012fSReza Sabdar 		ctx->end_ptr = ptr + size;
56*2654012fSReza Sabdar 		ctx->status = 0;
57*2654012fSReza Sabdar 	}
58*2654012fSReza Sabdar 	return (ctx);
59*2654012fSReza Sabdar }
60*2654012fSReza Sabdar 
61*2654012fSReza Sabdar int
ndmp_door_decode_finish(ndmp_door_ctx_t * ctx)62*2654012fSReza Sabdar ndmp_door_decode_finish(ndmp_door_ctx_t *ctx)
63*2654012fSReza Sabdar {
64*2654012fSReza Sabdar 	int status = ctx->status;
65*2654012fSReza Sabdar 	if ((status == 0) && (ctx->ptr != ctx->end_ptr)) {
66*2654012fSReza Sabdar 		status = ENOTEMPTY;
67*2654012fSReza Sabdar 	}
68*2654012fSReza Sabdar 	free(ctx);
69*2654012fSReza Sabdar 	return (status);
70*2654012fSReza Sabdar }
71*2654012fSReza Sabdar 
72*2654012fSReza Sabdar ndmp_door_ctx_t *
ndmp_door_encode_start(char * ptr,int size)73*2654012fSReza Sabdar ndmp_door_encode_start(char *ptr, int size)
74*2654012fSReza Sabdar {
75*2654012fSReza Sabdar 	ndmp_door_ctx_t *ctx = malloc(sizeof (ndmp_door_ctx_t));
76*2654012fSReza Sabdar 	if (ctx) {
77*2654012fSReza Sabdar 		ctx->start_ptr = ctx->ptr = ptr;
78*2654012fSReza Sabdar 		ctx->end_ptr = ptr + size;
79*2654012fSReza Sabdar 		ctx->status = 0;
80*2654012fSReza Sabdar 	}
81*2654012fSReza Sabdar 	return (ctx);
82*2654012fSReza Sabdar }
83*2654012fSReza Sabdar 
84*2654012fSReza Sabdar int
ndmp_door_encode_finish(ndmp_door_ctx_t * ctx,unsigned int * used)85*2654012fSReza Sabdar ndmp_door_encode_finish(ndmp_door_ctx_t *ctx, unsigned int *used)
86*2654012fSReza Sabdar {
87*2654012fSReza Sabdar 	int status = ctx->status;
88*2654012fSReza Sabdar 	if (status == 0) {
89*2654012fSReza Sabdar 		if (ctx->ptr < ctx->end_ptr) {
90*2654012fSReza Sabdar 			/*LINTED E_PTRDIFF_OVERFLOW*/
91*2654012fSReza Sabdar 			*used = ctx->ptr - ctx->start_ptr;
92*2654012fSReza Sabdar 		} else {
93*2654012fSReza Sabdar 			status = ENOSPC;
94*2654012fSReza Sabdar 		}
95*2654012fSReza Sabdar 	}
96*2654012fSReza Sabdar 	free(ctx);
97*2654012fSReza Sabdar 	return (status);
98*2654012fSReza Sabdar }
99*2654012fSReza Sabdar 
100*2654012fSReza Sabdar int32_t
ndmp_door_get_int32(ndmp_door_ctx_t * ctx)101*2654012fSReza Sabdar ndmp_door_get_int32(ndmp_door_ctx_t *ctx)
102*2654012fSReza Sabdar {
103*2654012fSReza Sabdar 	int32_t num = 0;
104*2654012fSReza Sabdar 	if (ctx->status == 0) {
105*2654012fSReza Sabdar 		if (ctx->ptr + sizeof (int32_t) <= ctx->end_ptr) {
106*2654012fSReza Sabdar 			(void) memcpy(&num, ctx->ptr, sizeof (int32_t));
107*2654012fSReza Sabdar 			ctx->ptr += sizeof (int32_t);
108*2654012fSReza Sabdar 		} else {
109*2654012fSReza Sabdar 			ctx->status = ENOSPC;
110*2654012fSReza Sabdar 		}
111*2654012fSReza Sabdar 	}
112*2654012fSReza Sabdar 	return (num);
113*2654012fSReza Sabdar }
114*2654012fSReza Sabdar 
115*2654012fSReza Sabdar uint32_t
ndmp_door_get_uint32(ndmp_door_ctx_t * ctx)116*2654012fSReza Sabdar ndmp_door_get_uint32(ndmp_door_ctx_t *ctx)
117*2654012fSReza Sabdar {
118*2654012fSReza Sabdar 	return ((uint32_t)ndmp_door_get_int32(ctx));
119*2654012fSReza Sabdar }
120*2654012fSReza Sabdar 
121*2654012fSReza Sabdar char *
ndmp_door_get_string(ndmp_door_ctx_t * ctx)122*2654012fSReza Sabdar ndmp_door_get_string(ndmp_door_ctx_t *ctx)
123*2654012fSReza Sabdar {
124*2654012fSReza Sabdar 	char *buf = NULL;
125*2654012fSReza Sabdar 	int len = ndmp_door_get_int32(ctx);
126*2654012fSReza Sabdar 
127*2654012fSReza Sabdar 	if (ctx->status == 0) {
128*2654012fSReza Sabdar 		if (len == -1)
129*2654012fSReza Sabdar 			return (buf);
130*2654012fSReza Sabdar 
131*2654012fSReza Sabdar 		if (ctx->ptr + len <= ctx->end_ptr) {
132*2654012fSReza Sabdar 			buf = malloc(len +1);
133*2654012fSReza Sabdar 			if (buf) {
134*2654012fSReza Sabdar 				if (len == 0) {
135*2654012fSReza Sabdar 					(void) strcpy(buf, "");
136*2654012fSReza Sabdar 				} else {
137*2654012fSReza Sabdar 					(void) memcpy(buf, ctx->ptr, len);
138*2654012fSReza Sabdar 					ctx->ptr += len;
139*2654012fSReza Sabdar 					*(buf + len) = '\0';
140*2654012fSReza Sabdar 				}
141*2654012fSReza Sabdar 			} else {
142*2654012fSReza Sabdar 				ctx->status = errno;
143*2654012fSReza Sabdar 			}
144*2654012fSReza Sabdar 		} else {
145*2654012fSReza Sabdar 			ctx->status = ENOSPC;
146*2654012fSReza Sabdar 		}
147*2654012fSReza Sabdar 	}
148*2654012fSReza Sabdar 	return (buf);
149*2654012fSReza Sabdar }
150*2654012fSReza Sabdar 
151*2654012fSReza Sabdar void
ndmp_door_put_int32(ndmp_door_ctx_t * ctx,int32_t num)152*2654012fSReza Sabdar ndmp_door_put_int32(ndmp_door_ctx_t *ctx, int32_t num)
153*2654012fSReza Sabdar {
154*2654012fSReza Sabdar 	if (ctx->status == 0) {
155*2654012fSReza Sabdar 		if (ctx->ptr + sizeof (int32_t) <= ctx->end_ptr) {
156*2654012fSReza Sabdar 			(void) memcpy(ctx->ptr, &num, sizeof (int32_t));
157*2654012fSReza Sabdar 			ctx->ptr += sizeof (int32_t);
158*2654012fSReza Sabdar 		} else {
159*2654012fSReza Sabdar 			ctx->status = ENOSPC;
160*2654012fSReza Sabdar 		}
161*2654012fSReza Sabdar 	}
162*2654012fSReza Sabdar }
163*2654012fSReza Sabdar 
164*2654012fSReza Sabdar void
ndmp_door_put_uint32(ndmp_door_ctx_t * ctx,uint32_t num)165*2654012fSReza Sabdar ndmp_door_put_uint32(ndmp_door_ctx_t *ctx, uint32_t num)
166*2654012fSReza Sabdar {
167*2654012fSReza Sabdar 	ndmp_door_put_int32(ctx, (int32_t)num);
168*2654012fSReza Sabdar }
169*2654012fSReza Sabdar 
170*2654012fSReza Sabdar void
ndmp_door_put_string(ndmp_door_ctx_t * ctx,char * buf)171*2654012fSReza Sabdar ndmp_door_put_string(ndmp_door_ctx_t *ctx, char *buf)
172*2654012fSReza Sabdar {
173*2654012fSReza Sabdar 	int len;
174*2654012fSReza Sabdar 
175*2654012fSReza Sabdar 	if (!buf)
176*2654012fSReza Sabdar 		len = -1;
177*2654012fSReza Sabdar 	else
178*2654012fSReza Sabdar 		len = strlen(buf);
179*2654012fSReza Sabdar 
180*2654012fSReza Sabdar 	if (ctx->status == 0) {
181*2654012fSReza Sabdar 		ndmp_door_put_int32(ctx, len);
182*2654012fSReza Sabdar 		if (len <= 0)
183*2654012fSReza Sabdar 			return;
184*2654012fSReza Sabdar 
185*2654012fSReza Sabdar 		if (ctx->ptr + len <= ctx->end_ptr) {
186*2654012fSReza Sabdar 			(void) memcpy(ctx->ptr, buf, len);
187*2654012fSReza Sabdar 			ctx->ptr += len;
188*2654012fSReza Sabdar 		} else {
189*2654012fSReza Sabdar 			ctx->status = ENOSPC;
190*2654012fSReza Sabdar 		}
191*2654012fSReza Sabdar 	}
192*2654012fSReza Sabdar }
193*2654012fSReza Sabdar 
194*2654012fSReza Sabdar void
ndmp_door_free_string(char * buf)195*2654012fSReza Sabdar ndmp_door_free_string(char *buf)
196*2654012fSReza Sabdar {
197*2654012fSReza Sabdar 	free(buf);
198*2654012fSReza Sabdar }
199*2654012fSReza Sabdar 
200*2654012fSReza Sabdar int64_t
ndmp_door_get_int64(ndmp_door_ctx_t * ctx)201*2654012fSReza Sabdar ndmp_door_get_int64(ndmp_door_ctx_t *ctx)
202*2654012fSReza Sabdar {
203*2654012fSReza Sabdar 	int64_t num = 0;
204*2654012fSReza Sabdar 	if (ctx->status == 0) {
205*2654012fSReza Sabdar 		if (ctx->ptr + sizeof (int64_t) <= ctx->end_ptr) {
206*2654012fSReza Sabdar 			(void) memcpy(&num, ctx->ptr, sizeof (int64_t));
207*2654012fSReza Sabdar 			ctx->ptr += sizeof (int64_t);
208*2654012fSReza Sabdar 		} else {
209*2654012fSReza Sabdar 			ctx->status = ENOSPC;
210*2654012fSReza Sabdar 		}
211*2654012fSReza Sabdar 	}
212*2654012fSReza Sabdar 	return (num);
213*2654012fSReza Sabdar }
214*2654012fSReza Sabdar 
215*2654012fSReza Sabdar uint64_t
ndmp_door_get_uint64(ndmp_door_ctx_t * ctx)216*2654012fSReza Sabdar ndmp_door_get_uint64(ndmp_door_ctx_t *ctx)
217*2654012fSReza Sabdar {
218*2654012fSReza Sabdar 	return ((uint64_t)ndmp_door_get_int64(ctx));
219*2654012fSReza Sabdar }
220*2654012fSReza Sabdar 
221*2654012fSReza Sabdar 
222*2654012fSReza Sabdar void
ndmp_door_put_int64(ndmp_door_ctx_t * ctx,int64_t num)223*2654012fSReza Sabdar ndmp_door_put_int64(ndmp_door_ctx_t *ctx, int64_t num)
224*2654012fSReza Sabdar {
225*2654012fSReza Sabdar 	if (ctx->status == 0) {
226*2654012fSReza Sabdar 		if (ctx->ptr + sizeof (int64_t) <= ctx->end_ptr) {
227*2654012fSReza Sabdar 			(void) memcpy(ctx->ptr, &num, sizeof (int64_t));
228*2654012fSReza Sabdar 			ctx->ptr += sizeof (int64_t);
229*2654012fSReza Sabdar 		} else {
230*2654012fSReza Sabdar 			ctx->status = ENOSPC;
231*2654012fSReza Sabdar 		}
232*2654012fSReza Sabdar 	}
233*2654012fSReza Sabdar }
234*2654012fSReza Sabdar 
235*2654012fSReza Sabdar void
ndmp_door_put_uint64(ndmp_door_ctx_t * ctx,uint64_t num)236*2654012fSReza Sabdar ndmp_door_put_uint64(ndmp_door_ctx_t *ctx, uint64_t num)
237*2654012fSReza Sabdar {
238*2654012fSReza Sabdar 	ndmp_door_put_int64(ctx, (int64_t)num);
239*2654012fSReza Sabdar }
240*2654012fSReza Sabdar 
241*2654012fSReza Sabdar void
ndmp_door_put_short(ndmp_door_ctx_t * ctx,short num)242*2654012fSReza Sabdar ndmp_door_put_short(ndmp_door_ctx_t *ctx, short num)
243*2654012fSReza Sabdar {
244*2654012fSReza Sabdar 	if (ctx->status == 0) {
245*2654012fSReza Sabdar 		if (ctx->ptr + sizeof (short) <= ctx->end_ptr) {
246*2654012fSReza Sabdar 			(void) memcpy(ctx->ptr, &num, sizeof (short));
247*2654012fSReza Sabdar 			ctx->ptr += sizeof (short);
248*2654012fSReza Sabdar 		} else {
249*2654012fSReza Sabdar 			ctx->status = ENOSPC;
250*2654012fSReza Sabdar 		}
251*2654012fSReza Sabdar 	}
252*2654012fSReza Sabdar }
253*2654012fSReza Sabdar 
254*2654012fSReza Sabdar short
ndmp_door_get_short(ndmp_door_ctx_t * ctx)255*2654012fSReza Sabdar ndmp_door_get_short(ndmp_door_ctx_t *ctx)
256*2654012fSReza Sabdar {
257*2654012fSReza Sabdar 	short num = 0;
258*2654012fSReza Sabdar 	if (ctx->status == 0) {
259*2654012fSReza Sabdar 		if (ctx->ptr + sizeof (short) <= ctx->end_ptr) {
260*2654012fSReza Sabdar 			(void) memcpy(&num, ctx->ptr, sizeof (short));
261*2654012fSReza Sabdar 			ctx->ptr += sizeof (short);
262*2654012fSReza Sabdar 		} else {
263*2654012fSReza Sabdar 			ctx->status = ENOSPC;
264*2654012fSReza Sabdar 		}
265*2654012fSReza Sabdar 	}
266*2654012fSReza Sabdar 	return (num);
267*2654012fSReza Sabdar }
268*2654012fSReza Sabdar 
269*2654012fSReza Sabdar void
ndmp_door_put_ushort(ndmp_door_ctx_t * ctx,unsigned short num)270*2654012fSReza Sabdar ndmp_door_put_ushort(ndmp_door_ctx_t *ctx, unsigned short num)
271*2654012fSReza Sabdar {
272*2654012fSReza Sabdar 	ndmp_door_put_short(ctx, (short)num);
273*2654012fSReza Sabdar }
274*2654012fSReza Sabdar 
275*2654012fSReza Sabdar unsigned short
ndmp_door_get_ushort(ndmp_door_ctx_t * ctx)276*2654012fSReza Sabdar ndmp_door_get_ushort(ndmp_door_ctx_t *ctx)
277*2654012fSReza Sabdar {
278*2654012fSReza Sabdar 	return ((unsigned short)ndmp_door_get_short(ctx));
279*2654012fSReza Sabdar }
280*2654012fSReza Sabdar 
281*2654012fSReza Sabdar void
ndmp_door_put_buf(ndmp_door_ctx_t * ctx,unsigned char * start,int len)282*2654012fSReza Sabdar ndmp_door_put_buf(ndmp_door_ctx_t *ctx, unsigned char *start, int len)
283*2654012fSReza Sabdar {
284*2654012fSReza Sabdar 	ndmp_door_put_int32(ctx, len);
285*2654012fSReza Sabdar 	if (ctx->status == 0) {
286*2654012fSReza Sabdar 		if (ctx->ptr + len <= ctx->end_ptr) {
287*2654012fSReza Sabdar 			(void) memcpy(ctx->ptr, start, len);
288*2654012fSReza Sabdar 			ctx->ptr += len;
289*2654012fSReza Sabdar 		} else {
290*2654012fSReza Sabdar 			ctx->status = ENOSPC;
291*2654012fSReza Sabdar 		}
292*2654012fSReza Sabdar 	}
293*2654012fSReza Sabdar }
294*2654012fSReza Sabdar 
295*2654012fSReza Sabdar int
ndmp_door_get_buf(ndmp_door_ctx_t * ctx,unsigned char * buf,int bufsize)296*2654012fSReza Sabdar ndmp_door_get_buf(ndmp_door_ctx_t *ctx, unsigned char *buf, int bufsize)
297*2654012fSReza Sabdar {
298*2654012fSReza Sabdar 	int len = -1;
299*2654012fSReza Sabdar 
300*2654012fSReza Sabdar 	if (!buf)
301*2654012fSReza Sabdar 		return (-1);
302*2654012fSReza Sabdar 
303*2654012fSReza Sabdar 	len = ndmp_door_get_int32(ctx);
304*2654012fSReza Sabdar 	if (ctx->status == 0) {
305*2654012fSReza Sabdar 		if (bufsize < len) {
306*2654012fSReza Sabdar 			ctx->status = ENOSPC;
307*2654012fSReza Sabdar 			return (-2);
308*2654012fSReza Sabdar 		}
309*2654012fSReza Sabdar 
310*2654012fSReza Sabdar 		if (ctx->ptr + len <= ctx->end_ptr) {
311*2654012fSReza Sabdar 			(void) memcpy(buf, ctx->ptr, len);
312*2654012fSReza Sabdar 			ctx->ptr += len;
313*2654012fSReza Sabdar 		} else {
314*2654012fSReza Sabdar 			ctx->status = ENOSPC;
315*2654012fSReza Sabdar 			return (-3);
316*2654012fSReza Sabdar 		}
317*2654012fSReza Sabdar 	}
318*2654012fSReza Sabdar 
319*2654012fSReza Sabdar 	return (len);
320*2654012fSReza Sabdar }
321