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