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