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 * 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 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 * 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 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 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 116 ndmp_door_get_uint32(ndmp_door_ctx_t *ctx) 117 { 118 return ((uint32_t)ndmp_door_get_int32(ctx)); 119 } 120 121 char * 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 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 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 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 195 ndmp_door_free_string(char *buf) 196 { 197 free(buf); 198 } 199 200 int64_t 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 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 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 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 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 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 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 276 ndmp_door_get_ushort(ndmp_door_ctx_t *ctx) 277 { 278 return ((unsigned short)ndmp_door_get_short(ctx)); 279 } 280 281 void 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 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