1 1.4 msaitoh /* $NetBSD: xdr.c,v 1.4 2024/05/12 23:52:57 msaitoh Exp $ */ 2 1.1 hannken 3 1.1 hannken /* 4 1.1 hannken * Copyright (c) 2010, Oracle America, Inc. 5 1.1 hannken * 6 1.1 hannken * Redistribution and use in source and binary forms, with or without 7 1.1 hannken * modification, are permitted provided that the following conditions are 8 1.1 hannken * met: 9 1.1 hannken * 10 1.1 hannken * * Redistributions of source code must retain the above copyright 11 1.1 hannken * notice, this list of conditions and the following disclaimer. 12 1.1 hannken * * Redistributions in binary form must reproduce the above 13 1.1 hannken * copyright notice, this list of conditions and the following 14 1.1 hannken * disclaimer in the documentation and/or other materials 15 1.1 hannken * provided with the distribution. 16 1.1 hannken * * Neither the name of the "Oracle America, Inc." nor the names of its 17 1.1 hannken * contributors may be used to endorse or promote products derived 18 1.1 hannken * from this software without specific prior written permission. 19 1.1 hannken * 20 1.1 hannken * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 1.1 hannken * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 1.1 hannken * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 23 1.1 hannken * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 24 1.1 hannken * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 25 1.1 hannken * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 1.1 hannken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 27 1.1 hannken * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 1.1 hannken * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 29 1.1 hannken * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 1.1 hannken * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 1.1 hannken * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 hannken */ 33 1.1 hannken 34 1.1 hannken #include <sys/cdefs.h> 35 1.1 hannken #if defined(LIBC_SCCS) && !defined(lint) 36 1.1 hannken #if 0 37 1.1 hannken static char *sccsid = "@(#)xdr.c 1.35 87/08/12"; 38 1.1 hannken static char *sccsid = "@(#)xdr.c 2.1 88/07/29 4.0 RPCSRC"; 39 1.1 hannken #else 40 1.4 msaitoh __RCSID("$NetBSD: xdr.c,v 1.4 2024/05/12 23:52:57 msaitoh Exp $"); 41 1.1 hannken #endif 42 1.1 hannken #endif 43 1.1 hannken 44 1.1 hannken /* 45 1.1 hannken * xdr.c, Generic XDR routines implementation. 46 1.1 hannken * 47 1.1 hannken * Copyright (C) 1986, Sun Microsystems, Inc. 48 1.1 hannken * 49 1.1 hannken * These are the "generic" xdr routines used to serialize and de-serialize 50 1.1 hannken * most common data items. See xdr.h for more info on the interface to 51 1.1 hannken * xdr. 52 1.1 hannken */ 53 1.1 hannken 54 1.2 hannken #if defined(_KERNEL) || defined(_STANDALONE) 55 1.2 hannken 56 1.2 hannken #include <lib/libkern/libkern.h> 57 1.2 hannken #include <rpc/types.h> 58 1.2 hannken #include <rpc/xdr.h> 59 1.2 hannken 60 1.2 hannken #else /* _KERNEL || _STANDALONE */ 61 1.2 hannken 62 1.1 hannken #include "namespace.h" 63 1.1 hannken 64 1.1 hannken #include <assert.h> 65 1.1 hannken #include <err.h> 66 1.1 hannken #include <stdio.h> 67 1.1 hannken #include <stdlib.h> 68 1.1 hannken #include <string.h> 69 1.1 hannken 70 1.1 hannken #include <rpc/rpc.h> 71 1.1 hannken #include <rpc/types.h> 72 1.1 hannken #include <rpc/xdr.h> 73 1.1 hannken #include <rpc/rpc_com.h> 74 1.1 hannken 75 1.1 hannken #ifdef __weak_alias 76 1.1 hannken __weak_alias(xdr_bool,_xdr_bool) 77 1.1 hannken __weak_alias(xdr_bytes,_xdr_bytes) 78 1.1 hannken __weak_alias(xdr_char,_xdr_char) 79 1.1 hannken __weak_alias(xdr_enum,_xdr_enum) 80 1.1 hannken __weak_alias(xdr_free,_xdr_free) 81 1.1 hannken __weak_alias(xdr_hyper,_xdr_hyper) 82 1.1 hannken __weak_alias(xdr_int,_xdr_int) 83 1.1 hannken __weak_alias(xdr_int16_t,_xdr_int16_t) 84 1.1 hannken __weak_alias(xdr_int32_t,_xdr_int32_t) 85 1.1 hannken __weak_alias(xdr_int64_t,_xdr_int64_t) 86 1.1 hannken __weak_alias(xdr_long,_xdr_long) 87 1.1 hannken __weak_alias(xdr_longlong_t,_xdr_longlong_t) 88 1.1 hannken __weak_alias(xdr_netobj,_xdr_netobj) 89 1.1 hannken __weak_alias(xdr_opaque,_xdr_opaque) 90 1.1 hannken __weak_alias(xdr_short,_xdr_short) 91 1.1 hannken __weak_alias(xdr_string,_xdr_string) 92 1.1 hannken __weak_alias(xdr_u_char,_xdr_u_char) 93 1.1 hannken __weak_alias(xdr_u_hyper,_xdr_u_hyper) 94 1.1 hannken __weak_alias(xdr_u_int,_xdr_u_int) 95 1.1 hannken __weak_alias(xdr_u_int16_t,_xdr_u_int16_t) 96 1.1 hannken __weak_alias(xdr_u_int32_t,_xdr_u_int32_t) 97 1.1 hannken __weak_alias(xdr_u_int64_t,_xdr_u_int64_t) 98 1.1 hannken __weak_alias(xdr_u_long,_xdr_u_long) 99 1.1 hannken __weak_alias(xdr_u_longlong_t,_xdr_u_longlong_t) 100 1.1 hannken __weak_alias(xdr_u_short,_xdr_u_short) 101 1.1 hannken __weak_alias(xdr_union,_xdr_union) 102 1.1 hannken __weak_alias(xdr_void,_xdr_void) 103 1.1 hannken __weak_alias(xdr_wrapstring,_xdr_wrapstring) 104 1.1 hannken #endif 105 1.1 hannken 106 1.2 hannken #endif /* _KERNEL || _STANDALONE */ 107 1.2 hannken 108 1.1 hannken /* 109 1.1 hannken * constants specific to the xdr "protocol" 110 1.1 hannken */ 111 1.1 hannken #define XDR_FALSE ((long) 0) 112 1.1 hannken #define XDR_TRUE ((long) 1) 113 1.1 hannken 114 1.1 hannken /* 115 1.1 hannken * for unit alignment 116 1.1 hannken */ 117 1.1 hannken static const char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; 118 1.1 hannken 119 1.1 hannken /* 120 1.1 hannken * Free a data structure using XDR 121 1.1 hannken * Not a filter, but a convenient utility nonetheless 122 1.1 hannken */ 123 1.1 hannken void 124 1.1 hannken xdr_free(xdrproc_t proc, char *objp) 125 1.1 hannken { 126 1.1 hannken XDR x; 127 1.1 hannken 128 1.1 hannken x.x_op = XDR_FREE; 129 1.1 hannken (*proc)(&x, objp); 130 1.1 hannken } 131 1.1 hannken 132 1.1 hannken /* 133 1.1 hannken * XDR nothing 134 1.1 hannken */ 135 1.1 hannken bool_t 136 1.1 hannken xdr_void(void) { 137 1.1 hannken 138 1.1 hannken return (TRUE); 139 1.1 hannken } 140 1.1 hannken 141 1.1 hannken 142 1.1 hannken /* 143 1.1 hannken * XDR integers 144 1.1 hannken */ 145 1.1 hannken bool_t 146 1.1 hannken xdr_int(XDR *xdrs, int *ip) 147 1.1 hannken { 148 1.1 hannken long l; 149 1.1 hannken 150 1.1 hannken _DIAGASSERT(xdrs != NULL); 151 1.1 hannken _DIAGASSERT(ip != NULL); 152 1.1 hannken 153 1.1 hannken switch (xdrs->x_op) { 154 1.1 hannken 155 1.1 hannken case XDR_ENCODE: 156 1.1 hannken l = (long) *ip; 157 1.1 hannken return (XDR_PUTLONG(xdrs, &l)); 158 1.1 hannken 159 1.1 hannken case XDR_DECODE: 160 1.1 hannken if (!XDR_GETLONG(xdrs, &l)) { 161 1.1 hannken return (FALSE); 162 1.1 hannken } 163 1.1 hannken *ip = (int) l; 164 1.1 hannken return (TRUE); 165 1.1 hannken 166 1.1 hannken case XDR_FREE: 167 1.1 hannken return (TRUE); 168 1.1 hannken } 169 1.1 hannken /* NOTREACHED */ 170 1.1 hannken return (FALSE); 171 1.1 hannken } 172 1.1 hannken 173 1.1 hannken /* 174 1.1 hannken * XDR unsigned integers 175 1.1 hannken */ 176 1.1 hannken bool_t 177 1.1 hannken xdr_u_int(XDR *xdrs, u_int *up) 178 1.1 hannken { 179 1.1 hannken u_long l; 180 1.1 hannken 181 1.1 hannken _DIAGASSERT(xdrs != NULL); 182 1.1 hannken _DIAGASSERT(up != NULL); 183 1.1 hannken 184 1.1 hannken switch (xdrs->x_op) { 185 1.1 hannken 186 1.1 hannken case XDR_ENCODE: 187 1.1 hannken l = (u_long) *up; 188 1.1 hannken return (XDR_PUTLONG(xdrs, (long *)&l)); 189 1.1 hannken 190 1.1 hannken case XDR_DECODE: 191 1.1 hannken if (!XDR_GETLONG(xdrs, (long *)&l)) { 192 1.1 hannken return (FALSE); 193 1.1 hannken } 194 1.1 hannken *up = (u_int) l; 195 1.1 hannken return (TRUE); 196 1.1 hannken 197 1.1 hannken case XDR_FREE: 198 1.1 hannken return (TRUE); 199 1.1 hannken } 200 1.1 hannken /* NOTREACHED */ 201 1.1 hannken return (FALSE); 202 1.1 hannken } 203 1.1 hannken 204 1.1 hannken 205 1.1 hannken /* 206 1.1 hannken * XDR long integers 207 1.1 hannken * same as xdr_u_long - open coded to save a proc call! 208 1.1 hannken */ 209 1.1 hannken bool_t 210 1.1 hannken xdr_long(XDR *xdrs, long *lp) 211 1.1 hannken { 212 1.1 hannken 213 1.1 hannken _DIAGASSERT(xdrs != NULL); 214 1.1 hannken _DIAGASSERT(lp != NULL); 215 1.1 hannken 216 1.1 hannken switch (xdrs->x_op) { 217 1.1 hannken case XDR_ENCODE: 218 1.1 hannken return (XDR_PUTLONG(xdrs, lp)); 219 1.1 hannken case XDR_DECODE: 220 1.1 hannken return (XDR_GETLONG(xdrs, lp)); 221 1.1 hannken case XDR_FREE: 222 1.1 hannken return (TRUE); 223 1.1 hannken } 224 1.1 hannken /* NOTREACHED */ 225 1.1 hannken return (FALSE); 226 1.1 hannken } 227 1.1 hannken 228 1.1 hannken /* 229 1.1 hannken * XDR unsigned long integers 230 1.1 hannken * same as xdr_long - open coded to save a proc call! 231 1.1 hannken */ 232 1.1 hannken bool_t 233 1.1 hannken xdr_u_long(XDR *xdrs, u_long *ulp) 234 1.1 hannken { 235 1.1 hannken 236 1.1 hannken _DIAGASSERT(xdrs != NULL); 237 1.1 hannken _DIAGASSERT(ulp != NULL); 238 1.1 hannken 239 1.1 hannken switch (xdrs->x_op) { 240 1.1 hannken case XDR_ENCODE: 241 1.1 hannken return (XDR_PUTLONG(xdrs, (long *)ulp)); 242 1.1 hannken case XDR_DECODE: 243 1.1 hannken return (XDR_GETLONG(xdrs, (long *)ulp)); 244 1.1 hannken case XDR_FREE: 245 1.1 hannken return (TRUE); 246 1.1 hannken } 247 1.1 hannken /* NOTREACHED */ 248 1.1 hannken return (FALSE); 249 1.1 hannken } 250 1.1 hannken 251 1.1 hannken 252 1.1 hannken /* 253 1.1 hannken * XDR 32-bit integers 254 1.1 hannken * same as xdr_u_int32_t - open coded to save a proc call! 255 1.1 hannken */ 256 1.1 hannken bool_t 257 1.1 hannken xdr_int32_t(XDR *xdrs, int32_t *int32_p) 258 1.1 hannken { 259 1.1 hannken long l; 260 1.1 hannken 261 1.1 hannken _DIAGASSERT(xdrs != NULL); 262 1.1 hannken _DIAGASSERT(int32_p != NULL); 263 1.1 hannken 264 1.1 hannken switch (xdrs->x_op) { 265 1.1 hannken 266 1.1 hannken case XDR_ENCODE: 267 1.1 hannken l = (long) *int32_p; 268 1.1 hannken return (XDR_PUTLONG(xdrs, &l)); 269 1.1 hannken 270 1.1 hannken case XDR_DECODE: 271 1.1 hannken if (!XDR_GETLONG(xdrs, &l)) { 272 1.1 hannken return (FALSE); 273 1.1 hannken } 274 1.1 hannken *int32_p = (int32_t) l; 275 1.1 hannken return (TRUE); 276 1.1 hannken 277 1.1 hannken case XDR_FREE: 278 1.1 hannken return (TRUE); 279 1.1 hannken } 280 1.1 hannken /* NOTREACHED */ 281 1.1 hannken return (FALSE); 282 1.1 hannken } 283 1.1 hannken 284 1.1 hannken /* 285 1.1 hannken * XDR unsigned 32-bit integers 286 1.1 hannken * same as xdr_int32_t - open coded to save a proc call! 287 1.1 hannken */ 288 1.1 hannken bool_t 289 1.1 hannken xdr_u_int32_t(XDR *xdrs, u_int32_t *u_int32_p) 290 1.1 hannken { 291 1.1 hannken u_long l; 292 1.1 hannken 293 1.1 hannken _DIAGASSERT(xdrs != NULL); 294 1.1 hannken _DIAGASSERT(u_int32_p != NULL); 295 1.1 hannken 296 1.1 hannken switch (xdrs->x_op) { 297 1.1 hannken 298 1.1 hannken case XDR_ENCODE: 299 1.1 hannken l = (u_long) *u_int32_p; 300 1.1 hannken return (XDR_PUTLONG(xdrs, (long *)&l)); 301 1.1 hannken 302 1.1 hannken case XDR_DECODE: 303 1.1 hannken if (!XDR_GETLONG(xdrs, (long *)&l)) { 304 1.1 hannken return (FALSE); 305 1.1 hannken } 306 1.1 hannken *u_int32_p = (u_int32_t) l; 307 1.1 hannken return (TRUE); 308 1.1 hannken 309 1.1 hannken case XDR_FREE: 310 1.1 hannken return (TRUE); 311 1.1 hannken } 312 1.1 hannken /* NOTREACHED */ 313 1.1 hannken return (FALSE); 314 1.1 hannken } 315 1.1 hannken 316 1.1 hannken 317 1.1 hannken /* 318 1.1 hannken * XDR short integers 319 1.1 hannken */ 320 1.1 hannken bool_t 321 1.1 hannken xdr_short(XDR *xdrs, short *sp) 322 1.1 hannken { 323 1.1 hannken long l; 324 1.1 hannken 325 1.1 hannken _DIAGASSERT(xdrs != NULL); 326 1.1 hannken _DIAGASSERT(sp != NULL); 327 1.1 hannken 328 1.1 hannken switch (xdrs->x_op) { 329 1.1 hannken 330 1.1 hannken case XDR_ENCODE: 331 1.1 hannken l = (long) *sp; 332 1.1 hannken return (XDR_PUTLONG(xdrs, &l)); 333 1.1 hannken 334 1.1 hannken case XDR_DECODE: 335 1.1 hannken if (!XDR_GETLONG(xdrs, &l)) { 336 1.1 hannken return (FALSE); 337 1.1 hannken } 338 1.1 hannken *sp = (short) l; 339 1.1 hannken return (TRUE); 340 1.1 hannken 341 1.1 hannken case XDR_FREE: 342 1.1 hannken return (TRUE); 343 1.1 hannken } 344 1.1 hannken /* NOTREACHED */ 345 1.1 hannken return (FALSE); 346 1.1 hannken } 347 1.1 hannken 348 1.1 hannken /* 349 1.1 hannken * XDR unsigned short integers 350 1.1 hannken */ 351 1.1 hannken bool_t 352 1.1 hannken xdr_u_short(XDR *xdrs, u_short *usp) 353 1.1 hannken { 354 1.1 hannken u_long l; 355 1.1 hannken 356 1.1 hannken _DIAGASSERT(xdrs != NULL); 357 1.1 hannken _DIAGASSERT(usp != NULL); 358 1.1 hannken 359 1.1 hannken switch (xdrs->x_op) { 360 1.1 hannken 361 1.1 hannken case XDR_ENCODE: 362 1.1 hannken l = (u_long) *usp; 363 1.1 hannken return (XDR_PUTLONG(xdrs, (long *)&l)); 364 1.1 hannken 365 1.1 hannken case XDR_DECODE: 366 1.1 hannken if (!XDR_GETLONG(xdrs, (long *)&l)) { 367 1.1 hannken return (FALSE); 368 1.1 hannken } 369 1.1 hannken *usp = (u_short) l; 370 1.1 hannken return (TRUE); 371 1.1 hannken 372 1.1 hannken case XDR_FREE: 373 1.1 hannken return (TRUE); 374 1.1 hannken } 375 1.1 hannken /* NOTREACHED */ 376 1.1 hannken return (FALSE); 377 1.1 hannken } 378 1.1 hannken 379 1.1 hannken 380 1.1 hannken /* 381 1.1 hannken * XDR 16-bit integers 382 1.1 hannken */ 383 1.1 hannken bool_t 384 1.1 hannken xdr_int16_t(XDR *xdrs, int16_t *int16_p) 385 1.1 hannken { 386 1.1 hannken long l; 387 1.1 hannken 388 1.1 hannken _DIAGASSERT(xdrs != NULL); 389 1.1 hannken _DIAGASSERT(int16_p != NULL); 390 1.1 hannken 391 1.1 hannken switch (xdrs->x_op) { 392 1.1 hannken 393 1.1 hannken case XDR_ENCODE: 394 1.1 hannken l = (long) *int16_p; 395 1.1 hannken return (XDR_PUTLONG(xdrs, &l)); 396 1.1 hannken 397 1.1 hannken case XDR_DECODE: 398 1.1 hannken if (!XDR_GETLONG(xdrs, &l)) { 399 1.1 hannken return (FALSE); 400 1.1 hannken } 401 1.1 hannken *int16_p = (int16_t) l; 402 1.1 hannken return (TRUE); 403 1.1 hannken 404 1.1 hannken case XDR_FREE: 405 1.1 hannken return (TRUE); 406 1.1 hannken } 407 1.1 hannken /* NOTREACHED */ 408 1.1 hannken return (FALSE); 409 1.1 hannken } 410 1.1 hannken 411 1.1 hannken /* 412 1.1 hannken * XDR unsigned 16-bit integers 413 1.1 hannken */ 414 1.1 hannken bool_t 415 1.1 hannken xdr_u_int16_t(XDR *xdrs, u_int16_t *u_int16_p) 416 1.1 hannken { 417 1.1 hannken u_long l; 418 1.1 hannken 419 1.1 hannken _DIAGASSERT(xdrs != NULL); 420 1.1 hannken _DIAGASSERT(u_int16_p != NULL); 421 1.1 hannken 422 1.1 hannken switch (xdrs->x_op) { 423 1.1 hannken 424 1.1 hannken case XDR_ENCODE: 425 1.1 hannken l = (u_long) *u_int16_p; 426 1.1 hannken return (XDR_PUTLONG(xdrs, (long *)&l)); 427 1.1 hannken 428 1.1 hannken case XDR_DECODE: 429 1.1 hannken if (!XDR_GETLONG(xdrs, (long *)&l)) { 430 1.1 hannken return (FALSE); 431 1.1 hannken } 432 1.1 hannken *u_int16_p = (u_int16_t) l; 433 1.1 hannken return (TRUE); 434 1.1 hannken 435 1.1 hannken case XDR_FREE: 436 1.1 hannken return (TRUE); 437 1.1 hannken } 438 1.1 hannken /* NOTREACHED */ 439 1.1 hannken return (FALSE); 440 1.1 hannken } 441 1.1 hannken 442 1.1 hannken 443 1.1 hannken /* 444 1.1 hannken * XDR a char 445 1.1 hannken */ 446 1.1 hannken bool_t 447 1.1 hannken xdr_char(XDR *xdrs, char *cp) 448 1.1 hannken { 449 1.1 hannken int i; 450 1.1 hannken 451 1.1 hannken _DIAGASSERT(xdrs != NULL); 452 1.1 hannken _DIAGASSERT(cp != NULL); 453 1.1 hannken 454 1.1 hannken i = (*cp); 455 1.1 hannken if (!xdr_int(xdrs, &i)) { 456 1.1 hannken return (FALSE); 457 1.1 hannken } 458 1.1 hannken *cp = i; 459 1.1 hannken return (TRUE); 460 1.1 hannken } 461 1.1 hannken 462 1.1 hannken /* 463 1.1 hannken * XDR an unsigned char 464 1.1 hannken */ 465 1.1 hannken bool_t 466 1.1 hannken xdr_u_char(XDR *xdrs, u_char *cp) 467 1.1 hannken { 468 1.1 hannken u_int u; 469 1.1 hannken 470 1.1 hannken _DIAGASSERT(xdrs != NULL); 471 1.1 hannken _DIAGASSERT(cp != NULL); 472 1.1 hannken 473 1.1 hannken u = (*cp); 474 1.1 hannken if (!xdr_u_int(xdrs, &u)) { 475 1.1 hannken return (FALSE); 476 1.1 hannken } 477 1.1 hannken *cp = u; 478 1.1 hannken return (TRUE); 479 1.1 hannken } 480 1.1 hannken 481 1.1 hannken /* 482 1.1 hannken * XDR booleans 483 1.1 hannken */ 484 1.1 hannken bool_t 485 1.1 hannken xdr_bool(XDR *xdrs, bool_t *bp) 486 1.1 hannken { 487 1.1 hannken long lb; 488 1.1 hannken 489 1.1 hannken _DIAGASSERT(xdrs != NULL); 490 1.1 hannken _DIAGASSERT(bp != NULL); 491 1.1 hannken 492 1.1 hannken switch (xdrs->x_op) { 493 1.1 hannken 494 1.1 hannken case XDR_ENCODE: 495 1.1 hannken lb = *bp ? XDR_TRUE : XDR_FALSE; 496 1.1 hannken return (XDR_PUTLONG(xdrs, &lb)); 497 1.1 hannken 498 1.1 hannken case XDR_DECODE: 499 1.1 hannken if (!XDR_GETLONG(xdrs, &lb)) { 500 1.1 hannken return (FALSE); 501 1.1 hannken } 502 1.1 hannken *bp = (lb == XDR_FALSE) ? FALSE : TRUE; 503 1.1 hannken return (TRUE); 504 1.1 hannken 505 1.1 hannken case XDR_FREE: 506 1.1 hannken return (TRUE); 507 1.1 hannken } 508 1.1 hannken /* NOTREACHED */ 509 1.1 hannken return (FALSE); 510 1.1 hannken } 511 1.1 hannken 512 1.1 hannken /* 513 1.1 hannken * XDR enumerations 514 1.1 hannken */ 515 1.1 hannken bool_t 516 1.1 hannken xdr_enum(XDR *xdrs, enum_t *ep) 517 1.1 hannken { 518 1.1 hannken long l; 519 1.1 hannken 520 1.1 hannken _DIAGASSERT(xdrs != NULL); 521 1.1 hannken _DIAGASSERT(ep != NULL); 522 1.1 hannken 523 1.1 hannken switch (xdrs->x_op) { 524 1.1 hannken 525 1.1 hannken case XDR_ENCODE: 526 1.1 hannken l = (long) *ep; 527 1.1 hannken return (XDR_PUTLONG(xdrs, &l)); 528 1.1 hannken 529 1.1 hannken case XDR_DECODE: 530 1.1 hannken if (!XDR_GETLONG(xdrs, &l)) { 531 1.1 hannken return (FALSE); 532 1.1 hannken } 533 1.1 hannken *ep = (enum_t) l; 534 1.1 hannken return (TRUE); 535 1.1 hannken 536 1.1 hannken case XDR_FREE: 537 1.1 hannken return (TRUE); 538 1.1 hannken } 539 1.1 hannken /* NOTREACHED */ 540 1.1 hannken return (FALSE); 541 1.1 hannken } 542 1.1 hannken 543 1.1 hannken /* 544 1.1 hannken * XDR opaque data 545 1.1 hannken * Allows the specification of a fixed size sequence of opaque bytes. 546 1.1 hannken * cp points to the opaque object and cnt gives the byte length. 547 1.1 hannken */ 548 1.1 hannken bool_t 549 1.3 christos xdr_opaque(XDR *xdrs, char *cp, u_int cnt) 550 1.1 hannken { 551 1.1 hannken u_int rndup; 552 1.1 hannken static int crud[BYTES_PER_XDR_UNIT]; 553 1.1 hannken 554 1.1 hannken _DIAGASSERT(xdrs != NULL); 555 1.1 hannken /* 556 1.1 hannken * if no data we are done 557 1.1 hannken */ 558 1.1 hannken if (cnt == 0) 559 1.1 hannken return (TRUE); 560 1.1 hannken _DIAGASSERT(cp != NULL); 561 1.1 hannken 562 1.1 hannken /* 563 1.1 hannken * round byte count to full xdr units 564 1.1 hannken */ 565 1.1 hannken rndup = cnt % BYTES_PER_XDR_UNIT; 566 1.1 hannken if (rndup > 0) 567 1.1 hannken rndup = BYTES_PER_XDR_UNIT - rndup; 568 1.1 hannken 569 1.1 hannken if (xdrs->x_op == XDR_DECODE) { 570 1.1 hannken if (!XDR_GETBYTES(xdrs, cp, cnt)) { 571 1.1 hannken return (FALSE); 572 1.1 hannken } 573 1.1 hannken if (rndup == 0) 574 1.1 hannken return (TRUE); 575 1.3 christos return (XDR_GETBYTES(xdrs, (void *)crud, rndup)); 576 1.1 hannken } 577 1.1 hannken 578 1.1 hannken if (xdrs->x_op == XDR_ENCODE) { 579 1.1 hannken if (!XDR_PUTBYTES(xdrs, cp, cnt)) { 580 1.1 hannken return (FALSE); 581 1.1 hannken } 582 1.1 hannken if (rndup == 0) 583 1.1 hannken return (TRUE); 584 1.1 hannken return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); 585 1.1 hannken } 586 1.1 hannken 587 1.1 hannken if (xdrs->x_op == XDR_FREE) { 588 1.1 hannken return (TRUE); 589 1.1 hannken } 590 1.1 hannken 591 1.1 hannken return (FALSE); 592 1.1 hannken } 593 1.1 hannken 594 1.1 hannken /* 595 1.1 hannken * XDR counted bytes 596 1.1 hannken * *cpp is a pointer to the bytes, *sizep is the count. 597 1.1 hannken * If *cpp is NULL maxsize bytes are allocated 598 1.1 hannken */ 599 1.1 hannken bool_t 600 1.1 hannken xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize) 601 1.1 hannken { 602 1.1 hannken char *sp; /* sp is the actual string pointer */ 603 1.1 hannken u_int nodesize; 604 1.1 hannken bool_t ret, allocated = FALSE; 605 1.1 hannken 606 1.1 hannken _DIAGASSERT(xdrs != NULL); 607 1.1 hannken _DIAGASSERT(cpp != NULL); 608 1.1 hannken _DIAGASSERT(sizep != NULL); 609 1.1 hannken 610 1.1 hannken sp = *cpp; 611 1.1 hannken 612 1.1 hannken /* 613 1.1 hannken * first deal with the length since xdr bytes are counted 614 1.1 hannken */ 615 1.1 hannken if (! xdr_u_int(xdrs, sizep)) { 616 1.1 hannken return (FALSE); 617 1.1 hannken } 618 1.1 hannken nodesize = *sizep; 619 1.1 hannken if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { 620 1.1 hannken return (FALSE); 621 1.1 hannken } 622 1.1 hannken 623 1.1 hannken /* 624 1.1 hannken * now deal with the actual bytes 625 1.1 hannken */ 626 1.1 hannken switch (xdrs->x_op) { 627 1.1 hannken 628 1.1 hannken case XDR_DECODE: 629 1.1 hannken if (nodesize == 0) { 630 1.1 hannken return (TRUE); 631 1.1 hannken } 632 1.1 hannken if (sp == NULL) { 633 1.1 hannken *cpp = sp = mem_alloc(nodesize); 634 1.1 hannken allocated = TRUE; 635 1.1 hannken } 636 1.1 hannken if (sp == NULL) { 637 1.1 hannken warn("%s: out of memory", __func__); 638 1.1 hannken return (FALSE); 639 1.1 hannken } 640 1.1 hannken /* FALLTHROUGH */ 641 1.1 hannken 642 1.1 hannken case XDR_ENCODE: 643 1.1 hannken ret = xdr_opaque(xdrs, sp, nodesize); 644 1.1 hannken if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) { 645 1.1 hannken if (allocated == TRUE) { 646 1.2 hannken mem_free(sp, nodesize); 647 1.1 hannken *cpp = NULL; 648 1.1 hannken } 649 1.1 hannken } 650 1.1 hannken return (ret); 651 1.1 hannken 652 1.1 hannken case XDR_FREE: 653 1.1 hannken if (sp != NULL) { 654 1.1 hannken mem_free(sp, nodesize); 655 1.1 hannken *cpp = NULL; 656 1.1 hannken } 657 1.1 hannken return (TRUE); 658 1.1 hannken } 659 1.1 hannken /* NOTREACHED */ 660 1.1 hannken return (FALSE); 661 1.1 hannken } 662 1.1 hannken 663 1.1 hannken /* 664 1.1 hannken * Implemented here due to commonality of the object. 665 1.1 hannken */ 666 1.1 hannken bool_t 667 1.1 hannken xdr_netobj(XDR *xdrs, struct netobj *np) 668 1.1 hannken { 669 1.1 hannken 670 1.1 hannken _DIAGASSERT(xdrs != NULL); 671 1.1 hannken _DIAGASSERT(np != NULL); 672 1.1 hannken 673 1.1 hannken return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); 674 1.1 hannken } 675 1.1 hannken 676 1.1 hannken /* 677 1.4 msaitoh * XDR a discriminated union 678 1.1 hannken * Support routine for discriminated unions. 679 1.1 hannken * You create an array of xdrdiscrim structures, terminated with 680 1.1 hannken * an entry with a null procedure pointer. The routine gets 681 1.1 hannken * the discriminant value and then searches the array of xdrdiscrims 682 1.1 hannken * looking for that value. It calls the procedure given in the xdrdiscrim 683 1.1 hannken * to handle the discriminant. If there is no specific routine a default 684 1.1 hannken * routine may be called. 685 1.1 hannken * If there is no specific or default routine an error is returned. 686 1.1 hannken */ 687 1.1 hannken bool_t 688 1.1 hannken xdr_union( 689 1.1 hannken XDR *xdrs, 690 1.1 hannken enum_t *dscmp, /* enum to decide which arm to work on */ 691 1.1 hannken char *unp, /* the union itself */ 692 1.1 hannken const struct xdr_discrim *choices, /* [value, xdr proc] for each arm */ 693 1.1 hannken xdrproc_t dfault /* default xdr routine */ 694 1.1 hannken ) 695 1.1 hannken { 696 1.1 hannken enum_t dscm; 697 1.1 hannken 698 1.1 hannken _DIAGASSERT(xdrs != NULL); 699 1.1 hannken _DIAGASSERT(dscmp != NULL); 700 1.1 hannken _DIAGASSERT(unp != NULL); 701 1.1 hannken _DIAGASSERT(choices != NULL); 702 1.1 hannken /* dfault may be NULL */ 703 1.1 hannken 704 1.1 hannken /* 705 1.1 hannken * we deal with the discriminator; it's an enum 706 1.1 hannken */ 707 1.1 hannken if (! xdr_enum(xdrs, dscmp)) { 708 1.1 hannken return (FALSE); 709 1.1 hannken } 710 1.1 hannken dscm = *dscmp; 711 1.1 hannken 712 1.1 hannken /* 713 1.1 hannken * search choices for a value that matches the discriminator. 714 1.1 hannken * if we find one, execute the xdr routine for that value. 715 1.1 hannken */ 716 1.1 hannken for (; choices->proc != NULL_xdrproc_t; choices++) { 717 1.1 hannken if (choices->value == dscm) 718 1.1 hannken return ((*(choices->proc))(xdrs, unp)); 719 1.1 hannken } 720 1.1 hannken 721 1.1 hannken /* 722 1.1 hannken * no match - execute the default xdr routine if there is one 723 1.1 hannken */ 724 1.1 hannken return ((dfault == NULL_xdrproc_t) ? FALSE : 725 1.1 hannken (*dfault)(xdrs, unp)); 726 1.1 hannken } 727 1.1 hannken 728 1.1 hannken 729 1.1 hannken /* 730 1.1 hannken * Non-portable xdr primitives. 731 1.1 hannken * Care should be taken when moving these routines to new architectures. 732 1.1 hannken */ 733 1.1 hannken 734 1.1 hannken 735 1.1 hannken /* 736 1.1 hannken * XDR null terminated ASCII strings 737 1.1 hannken * xdr_string deals with "C strings" - arrays of bytes that are 738 1.1 hannken * terminated by a NULL character. The parameter cpp references a 739 1.1 hannken * pointer to storage; If the pointer is null, then the necessary 740 1.1 hannken * storage is allocated. The last parameter is the max allowed length 741 1.1 hannken * of the string as specified by a protocol. 742 1.1 hannken */ 743 1.1 hannken bool_t 744 1.1 hannken xdr_string(XDR *xdrs, char **cpp, u_int maxsize) 745 1.1 hannken { 746 1.1 hannken char *sp; /* sp is the actual string pointer */ 747 1.1 hannken u_int size = 0; /* XXX: GCC */ 748 1.1 hannken u_int nodesize; 749 1.1 hannken size_t len; 750 1.1 hannken bool_t ret, allocated = FALSE; 751 1.1 hannken 752 1.1 hannken _DIAGASSERT(xdrs != NULL); 753 1.1 hannken _DIAGASSERT(cpp != NULL); 754 1.1 hannken 755 1.1 hannken sp = *cpp; 756 1.1 hannken 757 1.1 hannken /* 758 1.1 hannken * first deal with the length since xdr strings are counted-strings 759 1.1 hannken */ 760 1.1 hannken switch (xdrs->x_op) { 761 1.1 hannken case XDR_FREE: 762 1.1 hannken if (sp == NULL) { 763 1.1 hannken return(TRUE); /* already free */ 764 1.1 hannken } 765 1.1 hannken /* FALLTHROUGH */ 766 1.1 hannken case XDR_ENCODE: 767 1.1 hannken len = strlen(sp); 768 1.1 hannken _DIAGASSERT(__type_fit(u_int, len)); 769 1.1 hannken size = (u_int)len; 770 1.1 hannken break; 771 1.1 hannken case XDR_DECODE: 772 1.1 hannken break; 773 1.1 hannken } 774 1.1 hannken if (! xdr_u_int(xdrs, &size)) { 775 1.1 hannken return (FALSE); 776 1.1 hannken } 777 1.1 hannken if (size > maxsize) { 778 1.1 hannken return (FALSE); 779 1.1 hannken } 780 1.1 hannken nodesize = size + 1; 781 1.1 hannken 782 1.1 hannken /* 783 1.1 hannken * now deal with the actual bytes 784 1.1 hannken */ 785 1.1 hannken switch (xdrs->x_op) { 786 1.1 hannken 787 1.1 hannken case XDR_DECODE: 788 1.1 hannken if (nodesize == 0) { 789 1.1 hannken return (TRUE); 790 1.1 hannken } 791 1.1 hannken if (sp == NULL) { 792 1.1 hannken *cpp = sp = mem_alloc(nodesize); 793 1.1 hannken allocated = TRUE; 794 1.1 hannken } 795 1.1 hannken if (sp == NULL) { 796 1.1 hannken warn("%s: out of memory", __func__); 797 1.1 hannken return (FALSE); 798 1.1 hannken } 799 1.1 hannken sp[size] = 0; 800 1.1 hannken /* FALLTHROUGH */ 801 1.1 hannken 802 1.1 hannken case XDR_ENCODE: 803 1.1 hannken ret = xdr_opaque(xdrs, sp, size); 804 1.1 hannken if ((xdrs->x_op == XDR_DECODE) && (ret == FALSE)) { 805 1.1 hannken if (allocated == TRUE) { 806 1.2 hannken mem_free(sp, nodesize); 807 1.1 hannken *cpp = NULL; 808 1.1 hannken } 809 1.1 hannken } 810 1.1 hannken return (ret); 811 1.1 hannken 812 1.1 hannken case XDR_FREE: 813 1.1 hannken mem_free(sp, nodesize); 814 1.1 hannken *cpp = NULL; 815 1.1 hannken return (TRUE); 816 1.1 hannken } 817 1.1 hannken /* NOTREACHED */ 818 1.1 hannken return (FALSE); 819 1.1 hannken } 820 1.1 hannken 821 1.2 hannken #if !defined(_KERNEL) && !defined(_STANDALONE) 822 1.2 hannken 823 1.1 hannken /* 824 1.1 hannken * Wrapper for xdr_string that can be called directly from 825 1.1 hannken * routines like clnt_call 826 1.1 hannken */ 827 1.1 hannken bool_t 828 1.1 hannken xdr_wrapstring(XDR *xdrs, char **cpp) 829 1.1 hannken { 830 1.1 hannken 831 1.1 hannken _DIAGASSERT(xdrs != NULL); 832 1.1 hannken _DIAGASSERT(cpp != NULL); 833 1.1 hannken 834 1.1 hannken return xdr_string(xdrs, cpp, RPC_MAXDATASIZE); 835 1.1 hannken } 836 1.1 hannken 837 1.2 hannken #endif /* !_KERNEL && !_STANDALONE */ 838 1.2 hannken 839 1.1 hannken /* 840 1.1 hannken * NOTE: xdr_hyper(), xdr_u_hyper(), xdr_longlong_t(), and xdr_u_longlong_t() 841 1.1 hannken * are in the "non-portable" section because they require that a `long long' 842 1.1 hannken * be a 64-bit type. 843 1.1 hannken * 844 1.1 hannken * --thorpej (at) NetBSD.org, November 30, 1999 845 1.1 hannken */ 846 1.1 hannken 847 1.1 hannken /* 848 1.1 hannken * XDR 64-bit integers 849 1.1 hannken */ 850 1.1 hannken bool_t 851 1.1 hannken xdr_int64_t(XDR *xdrs, int64_t *llp) 852 1.1 hannken { 853 1.1 hannken u_long ul[2]; 854 1.1 hannken 855 1.1 hannken _DIAGASSERT(xdrs != NULL); 856 1.1 hannken _DIAGASSERT(llp != NULL); 857 1.1 hannken 858 1.1 hannken switch (xdrs->x_op) { 859 1.1 hannken case XDR_ENCODE: 860 1.1 hannken ul[0] = (u_long)(((uint64_t)*llp >> 32) & 861 1.1 hannken (uint64_t)0xffffffffULL); 862 1.1 hannken ul[1] = (u_long)(((uint64_t)*llp) & 863 1.1 hannken (uint64_t)0xffffffffULL); 864 1.1 hannken if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 865 1.1 hannken return (FALSE); 866 1.1 hannken return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 867 1.1 hannken case XDR_DECODE: 868 1.1 hannken if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 869 1.1 hannken return (FALSE); 870 1.1 hannken if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 871 1.1 hannken return (FALSE); 872 1.1 hannken *llp = (int64_t) 873 1.1 hannken (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 874 1.1 hannken return (TRUE); 875 1.1 hannken case XDR_FREE: 876 1.1 hannken return (TRUE); 877 1.1 hannken } 878 1.1 hannken /* NOTREACHED */ 879 1.1 hannken return (FALSE); 880 1.1 hannken } 881 1.1 hannken 882 1.1 hannken 883 1.1 hannken /* 884 1.1 hannken * XDR unsigned 64-bit integers 885 1.1 hannken */ 886 1.1 hannken bool_t 887 1.1 hannken xdr_u_int64_t(XDR *xdrs, u_int64_t *ullp) 888 1.1 hannken { 889 1.1 hannken u_long ul[2]; 890 1.1 hannken 891 1.1 hannken _DIAGASSERT(xdrs != NULL); 892 1.1 hannken _DIAGASSERT(ullp != NULL); 893 1.1 hannken 894 1.1 hannken switch (xdrs->x_op) { 895 1.1 hannken case XDR_ENCODE: 896 1.1 hannken ul[0] = (u_long)(*ullp >> 32) & 0xffffffffUL; 897 1.1 hannken ul[1] = (u_long)(*ullp) & 0xffffffffUL; 898 1.1 hannken if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE) 899 1.1 hannken return (FALSE); 900 1.1 hannken return (XDR_PUTLONG(xdrs, (long *)&ul[1])); 901 1.1 hannken case XDR_DECODE: 902 1.1 hannken if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE) 903 1.1 hannken return (FALSE); 904 1.1 hannken if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE) 905 1.1 hannken return (FALSE); 906 1.1 hannken *ullp = (u_int64_t) 907 1.1 hannken (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1])); 908 1.1 hannken return (TRUE); 909 1.1 hannken case XDR_FREE: 910 1.1 hannken return (TRUE); 911 1.1 hannken } 912 1.1 hannken /* NOTREACHED */ 913 1.1 hannken return (FALSE); 914 1.1 hannken } 915 1.1 hannken 916 1.1 hannken 917 1.1 hannken /* 918 1.1 hannken * XDR hypers 919 1.1 hannken */ 920 1.1 hannken bool_t 921 1.1 hannken xdr_hyper(XDR *xdrs, longlong_t *llp) 922 1.1 hannken { 923 1.1 hannken 924 1.1 hannken _DIAGASSERT(xdrs != NULL); 925 1.1 hannken _DIAGASSERT(llp != NULL); 926 1.1 hannken 927 1.1 hannken /* 928 1.1 hannken * Don't bother open-coding this; it's a fair amount of code. Just 929 1.1 hannken * call xdr_int64_t(). 930 1.1 hannken */ 931 1.1 hannken return (xdr_int64_t(xdrs, (int64_t *)llp)); 932 1.1 hannken } 933 1.1 hannken 934 1.1 hannken 935 1.1 hannken /* 936 1.1 hannken * XDR unsigned hypers 937 1.1 hannken */ 938 1.1 hannken bool_t 939 1.1 hannken xdr_u_hyper(XDR *xdrs, u_longlong_t *ullp) 940 1.1 hannken { 941 1.1 hannken 942 1.1 hannken _DIAGASSERT(xdrs != NULL); 943 1.1 hannken _DIAGASSERT(ullp != NULL); 944 1.1 hannken 945 1.1 hannken /* 946 1.1 hannken * Don't bother open-coding this; it's a fair amount of code. Just 947 1.1 hannken * call xdr_u_int64_t(). 948 1.1 hannken */ 949 1.1 hannken return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp)); 950 1.1 hannken } 951 1.1 hannken 952 1.1 hannken 953 1.1 hannken /* 954 1.1 hannken * XDR longlong_t's 955 1.1 hannken */ 956 1.1 hannken bool_t 957 1.1 hannken xdr_longlong_t(XDR *xdrs, longlong_t *llp) 958 1.1 hannken { 959 1.1 hannken 960 1.1 hannken _DIAGASSERT(xdrs != NULL); 961 1.1 hannken _DIAGASSERT(llp != NULL); 962 1.1 hannken 963 1.1 hannken /* 964 1.1 hannken * Don't bother open-coding this; it's a fair amount of code. Just 965 1.1 hannken * call xdr_int64_t(). 966 1.1 hannken */ 967 1.1 hannken return (xdr_int64_t(xdrs, (int64_t *)llp)); 968 1.1 hannken } 969 1.1 hannken 970 1.1 hannken 971 1.1 hannken /* 972 1.1 hannken * XDR u_longlong_t's 973 1.1 hannken */ 974 1.1 hannken bool_t 975 1.1 hannken xdr_u_longlong_t(XDR *xdrs, u_longlong_t *ullp) 976 1.1 hannken { 977 1.1 hannken 978 1.1 hannken _DIAGASSERT(xdrs != NULL); 979 1.1 hannken _DIAGASSERT(ullp != NULL); 980 1.1 hannken 981 1.1 hannken /* 982 1.1 hannken * Don't bother open-coding this; it's a fair amount of code. Just 983 1.1 hannken * call xdr_u_int64_t(). 984 1.1 hannken */ 985 1.1 hannken return (xdr_u_int64_t(xdrs, (u_int64_t *)ullp)); 986 1.1 hannken } 987