Bring in a transport-independent RPC (TI-RPC).
[dragonfly.git] / sys / netproto / atm / spans / spans_kxdr.c
... / ...
CommitLineData
1/*
2 *
3 * ===================================
4 * HARP | Host ATM Research Platform
5 * ===================================
6 *
7 *
8 * This Host ATM Research Platform ("HARP") file (the "Software") is
9 * made available by Network Computing Services, Inc. ("NetworkCS")
10 * "AS IS". NetworkCS does not provide maintenance, improvements or
11 * support of any kind.
12 *
13 * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14 * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15 * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16 * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17 * In no event shall NetworkCS be responsible for any damages, including
18 * but not limited to consequential damages, arising from or relating to
19 * any use of the Software or related support.
20 *
21 * Copyright 1994-1998 Network Computing Services, Inc.
22 *
23 * Copies of this Software may be made, however, the above copyright
24 * notice must be reproduced on all copies.
25 *
26 * @(#) $FreeBSD: src/sys/netatm/spans/spans_kxdr.c,v 1.3 1999/08/28 00:48:50 peter Exp $
27 * @(#) $DragonFly: src/sys/netproto/atm/spans/spans_kxdr.c,v 1.9 2008/10/28 17:23:46 swildner Exp $
28 */
29
30/*
31 * SPANS Signalling Manager
32 * ---------------------------
33 *
34 * Kernel XDR (External Data Representation) routines
35 *
36 */
37
38#include <netproto/atm/kern_include.h>
39
40/*
41 * This file contains code that has been copied and/or modified from
42 * the following FreeBSD files:
43 *
44 * /usr/src/lib/libc/xdr/xdr.c
45 * /usr/src/lib/libc/xdr/xdr_mem.c
46 *
47 * which are covered by the copyright notice below.
48 */
49
50/*
51 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
52 * unrestricted use provided that this legend is included on all tape
53 * media and as a part of the software program in whole or part. Users
54 * may copy or modify Sun RPC without charge, but are not authorized
55 * to license or distribute it to anyone else except as part of a product or
56 * program developed by the user.
57 *
58 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
59 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
60 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
61 *
62 * Sun RPC is provided with no support and without any obligation on the
63 * part of Sun Microsystems, Inc. to assist in its use, correction,
64 * modification or enhancement.
65 *
66 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
67 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
68 * OR ANY PART THEREOF.
69 *
70 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
71 * or profits or other special, indirect and consequential damages, even if
72 * Sun has been advised of the possibility of such damages.
73 *
74 * Sun Microsystems, Inc.
75 * 2550 Garcia Avenue
76 * Mountain View, California 94043
77 */
78
79/*
80 * xdr.c, Generic XDR routines implementation.
81 *
82 * Copyright (C) 1986, Sun Microsystems, Inc.
83 *
84 * These are the "generic" xdr routines used to serialize and de-serialize
85 * most common data items. See xdr.h for more info on the interface to
86 * xdr.
87 */
88
89#include <netproto/atm/spans/spans_kxdr.h>
90
91/*
92 * constants specific to the xdr "protocol"
93 */
94#define XDR_FALSE ((long) 0)
95#define XDR_TRUE ((long) 1)
96#define LASTUNSIGNED ((u_int) 0-1)
97
98/*
99 * for unit alignment
100 */
101static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
102
103/*
104 * XDR integers
105 */
106bool_t
107xdr_int(XDR *xdrs, int *ip)
108{
109
110#ifdef lint
111 (xdr_short(xdrs, (short *)ip));
112 return (xdr_long(xdrs, (long *)ip));
113#else
114 if (sizeof (int) == sizeof (long)) {
115 return (xdr_long(xdrs, (long *)ip));
116 } else {
117 return (xdr_short(xdrs, (short *)ip));
118 }
119#endif
120}
121
122/*
123 * XDR unsigned integers
124 */
125bool_t
126xdr_u_int(XDR *xdrs, u_int *up)
127{
128
129#ifdef lint
130 (xdr_short(xdrs, (short *)up));
131 return (xdr_u_long(xdrs, (u_long *)up));
132#else
133 if (sizeof (u_int) == sizeof (u_long)) {
134 return (xdr_u_long(xdrs, (u_long *)up));
135 } else {
136 return (xdr_short(xdrs, (short *)up));
137 }
138#endif
139}
140
141/*
142 * XDR long integers
143 * same as xdr_u_long - open coded to save a proc call!
144 */
145bool_t
146xdr_long(XDR *xdrs, long *lp)
147{
148
149 if (xdrs->x_op == XDR_ENCODE)
150 return (XDR_PUTLONG(xdrs, lp));
151
152 if (xdrs->x_op == XDR_DECODE)
153 return (XDR_GETLONG(xdrs, lp));
154
155 if (xdrs->x_op == XDR_FREE)
156 return (TRUE);
157
158 return (FALSE);
159}
160
161/*
162 * XDR unsigned long integers
163 * same as xdr_long - open coded to save a proc call!
164 */
165bool_t
166xdr_u_long(XDR *xdrs, u_long *ulp)
167{
168
169 if (xdrs->x_op == XDR_DECODE)
170 return (XDR_GETLONG(xdrs, (long *)ulp));
171 if (xdrs->x_op == XDR_ENCODE)
172 return (XDR_PUTLONG(xdrs, (long *)ulp));
173 if (xdrs->x_op == XDR_FREE)
174 return (TRUE);
175 return (FALSE);
176}
177
178/*
179 * XDR short integers
180 */
181bool_t
182xdr_short(XDR *xdrs, short *sp)
183{
184 long l;
185
186 switch (xdrs->x_op) {
187
188 case XDR_ENCODE:
189 l = (long) *sp;
190 return (XDR_PUTLONG(xdrs, &l));
191
192 case XDR_DECODE:
193 if (!XDR_GETLONG(xdrs, &l)) {
194 return (FALSE);
195 }
196 *sp = (short) l;
197 return (TRUE);
198
199 case XDR_FREE:
200 return (TRUE);
201 }
202 return (FALSE);
203}
204
205/*
206 * XDR unsigned short integers
207 */
208bool_t
209xdr_u_short(XDR *xdrs, u_short *usp)
210{
211 u_long l;
212
213 switch (xdrs->x_op) {
214
215 case XDR_ENCODE:
216 l = (u_long) *usp;
217 return (XDR_PUTLONG(xdrs, &l));
218
219 case XDR_DECODE:
220 if (!XDR_GETLONG(xdrs, &l)) {
221 return (FALSE);
222 }
223 *usp = (u_short) l;
224 return (TRUE);
225
226 case XDR_FREE:
227 return (TRUE);
228 }
229 return (FALSE);
230}
231
232
233/*
234 * XDR a char
235 */
236bool_t
237xdr_char(XDR *xdrs, char *cp)
238{
239 int i;
240
241 i = (*cp);
242 if (!xdr_int(xdrs, &i)) {
243 return (FALSE);
244 }
245 *cp = i;
246 return (TRUE);
247}
248
249/*
250 * XDR an unsigned char
251 */
252bool_t
253xdr_u_char(XDR *xdrs, u_char *cp)
254{
255 u_int u;
256
257 u = (*cp);
258 if (!xdr_u_int(xdrs, &u)) {
259 return (FALSE);
260 }
261 *cp = u;
262 return (TRUE);
263}
264
265/*
266 * XDR booleans
267 */
268bool_t
269xdr_bool(XDR *xdrs, bool_t *bp)
270{
271 long lb;
272
273 switch (xdrs->x_op) {
274
275 case XDR_ENCODE:
276 lb = *bp ? XDR_TRUE : XDR_FALSE;
277 return (XDR_PUTLONG(xdrs, &lb));
278
279 case XDR_DECODE:
280 if (!XDR_GETLONG(xdrs, &lb)) {
281 return (FALSE);
282 }
283 *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
284 return (TRUE);
285
286 case XDR_FREE:
287 return (TRUE);
288 }
289 return (FALSE);
290}
291
292/*
293 * XDR enumerations
294 */
295bool_t
296xdr_enum(XDR *xdrs, enum_t *ep)
297{
298#ifndef lint
299 enum sizecheck { SIZEVAL }; /* used to find the size of an enum */
300
301 /*
302 * enums are treated as ints
303 */
304 if (sizeof (enum sizecheck) == sizeof (long)) {
305 return (xdr_long(xdrs, (long *)ep));
306 } else if (sizeof (enum sizecheck) == sizeof (short)) {
307 return (xdr_short(xdrs, (short *)ep));
308 } else {
309 return (FALSE);
310 }
311#else
312 (xdr_short(xdrs, (short *)ep));
313 return (xdr_long(xdrs, (long *)ep));
314#endif
315}
316
317/*
318 * XDR opaque data
319 * Allows the specification of a fixed size sequence of opaque bytes.
320 * cp points to the opaque object and cnt gives the byte length.
321 */
322bool_t
323xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt)
324{
325 u_int rndup;
326 static char crud[BYTES_PER_XDR_UNIT];
327
328 /*
329 * if no data we are done
330 */
331 if (cnt == 0)
332 return (TRUE);
333
334 /*
335 * round byte count to full xdr units
336 */
337 rndup = cnt % BYTES_PER_XDR_UNIT;
338 if (rndup > 0)
339 rndup = BYTES_PER_XDR_UNIT - rndup;
340
341 if (xdrs->x_op == XDR_DECODE) {
342 if (!XDR_GETBYTES(xdrs, cp, cnt)) {
343 return (FALSE);
344 }
345 if (rndup == 0)
346 return (TRUE);
347 return (XDR_GETBYTES(xdrs, crud, rndup));
348 }
349
350 if (xdrs->x_op == XDR_ENCODE) {
351 if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
352 return (FALSE);
353 }
354 if (rndup == 0)
355 return (TRUE);
356 return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
357 }
358
359 if (xdrs->x_op == XDR_FREE) {
360 return (TRUE);
361 }
362
363 return (FALSE);
364}
365
366
367/*
368 * XDR implementation using kernel buffers
369 */
370
371/*
372 * xdr_mem.h, XDR implementation using memory buffers.
373 *
374 * Copyright (C) 1984, Sun Microsystems, Inc.
375 *
376 * If you have some data to be interpreted as external data representation
377 * or to be converted to external data representation in a memory buffer,
378 * then this is the package for you.
379 *
380 */
381
382
383void xdrmbuf_init (XDR *, KBuffer *, enum xdr_op);
384static bool_t xdrmbuf_getlong (XDR *, long *);
385static bool_t xdrmbuf_putlong (XDR *, long *);
386static bool_t xdrmbuf_getbytes (XDR *, caddr_t, u_int);
387static bool_t xdrmbuf_putbytes (XDR *, caddr_t, u_int);
388static u_int xdrmbuf_getpos (XDR *);
389
390static struct xdr_ops xdrmbuf_ops = {
391 xdrmbuf_getlong,
392 xdrmbuf_putlong,
393 xdrmbuf_getbytes,
394 xdrmbuf_putbytes,
395 xdrmbuf_getpos,
396 NULL,
397 NULL,
398 NULL
399};
400
401/*
402 * The procedure xdrmbuf_init initializes a stream descriptor for a
403 * kernel buffer.
404 */
405void
406xdrmbuf_init(XDR *xdrs, KBuffer *m, enum xdr_op op)
407{
408
409 xdrs->x_op = op;
410 xdrs->x_ops = &xdrmbuf_ops;
411 xdrs->x_base = (caddr_t)m;
412 KB_DATASTART(m, xdrs->x_private, caddr_t);
413 xdrs->x_handy = KB_LEN(m);
414}
415
416static bool_t
417xdrmbuf_getlong(XDR *xdrs, long *lp)
418{
419
420 /*
421 * See if long is contained in this buffer
422 */
423 if ((xdrs->x_handy -= sizeof(long)) < 0) {
424 KBuffer *m;
425
426 /*
427 * We (currently) don't allow a long to span a buffer
428 */
429 if (xdrs->x_handy != -sizeof(long)) {
430 kprintf("xdrmbuf_getlong: data spans buffers\n");
431 return (FALSE);
432 }
433
434 /*
435 * Try to move to a chained buffer
436 */
437 if ((m = (KBuffer *)(xdrs->x_base)) != NULL) {
438 m = KB_NEXT(m);
439 xdrs->x_base = (caddr_t)m;
440 }
441 if (m) {
442 /*
443 * Setup new buffer's info
444 */
445 KB_DATASTART(m, xdrs->x_private, caddr_t);
446 if ((xdrs->x_handy = KB_LEN(m) - sizeof(long)) < 0) {
447 kprintf("xdrmbuf_getlong: short buffer\n");
448 return (FALSE);
449 }
450 } else {
451 /*
452 * No more buffers
453 */
454 return (FALSE);
455 }
456 }
457
458 /*
459 * Return the long value
460 */
461 *lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private))));
462
463 /*
464 * Advance the data stream
465 */
466 xdrs->x_private += sizeof(long);
467 return (TRUE);
468}
469
470static bool_t
471xdrmbuf_putlong(XDR *xdrs, long *lp)
472{
473
474 /*
475 * See if long will fit in this buffer
476 */
477 if ((xdrs->x_handy -= sizeof(long)) < 0) {
478 KBuffer *m;
479
480 /*
481 * We (currently) don't allow a long to span a buffer
482 */
483 if (xdrs->x_handy != -sizeof(long)) {
484 kprintf("xdrmbuf_putlong: data spans buffers\n");
485 return (FALSE);
486 }
487
488 /*
489 * Try to move to a chained buffer
490 */
491 if ((m = (KBuffer *)(xdrs->x_base)) != NULL) {
492 m = KB_NEXT(m);
493 xdrs->x_base = (caddr_t)m;
494 }
495 if (m) {
496 /*
497 * Setup new buffer's info
498 */
499 KB_DATASTART(m, xdrs->x_private, caddr_t);
500 if ((xdrs->x_handy = KB_LEN(m) - sizeof(long)) < 0) {
501 kprintf("xdrmbuf_putlong: short buffer\n");
502 return (FALSE);
503 }
504 } else {
505 /*
506 * No more buffers
507 */
508 return (FALSE);
509 }
510 }
511
512 /*
513 * Store the long value into our buffer
514 */
515 *(long *)xdrs->x_private = (long)htonl((u_long)(*lp));
516
517 /*
518 * Advance the data stream
519 */
520 xdrs->x_private += sizeof(long);
521 return (TRUE);
522}
523
524static bool_t
525xdrmbuf_getbytes(XDR *xdrs, caddr_t addr, u_int len)
526{
527
528 while (len > 0) {
529 u_int copy;
530
531 if (xdrs->x_handy <= 0) {
532 KBuffer *m;
533
534 /*
535 * No data in current buffer, move to a chained buffer
536 */
537 if ((m = (KBuffer *)(xdrs->x_base)) != NULL) {
538 m = KB_NEXT(m);
539 xdrs->x_base = (caddr_t)m;
540 }
541 if (m) {
542 /*
543 * Setup new buffer's info
544 */
545 KB_DATASTART(m, xdrs->x_private, caddr_t);
546 xdrs->x_handy = KB_LEN(m);
547 } else {
548 /*
549 * No more buffers
550 */
551 return (FALSE);
552 }
553 }
554
555 /*
556 * Copy from buffer to user's space
557 */
558 copy = MIN(len, xdrs->x_handy);
559 KM_COPY(xdrs->x_private, addr, copy);
560
561 /*
562 * Update data stream controls
563 */
564 xdrs->x_private += copy;
565 xdrs->x_handy -= copy;
566 addr += copy;
567 len -= copy;
568 }
569 return (TRUE);
570}
571
572static bool_t
573xdrmbuf_putbytes(XDR *xdrs, caddr_t addr, u_int len)
574{
575
576 while (len > 0) {
577 u_int copy;
578
579 if (xdrs->x_handy <= 0) {
580 KBuffer *m;
581
582 /*
583 * No data in current buffer, move to a chained buffer
584 */
585 if ((m = (KBuffer *)(xdrs->x_base)) != NULL) {
586 m = KB_NEXT(m);
587 xdrs->x_base = (caddr_t)m;
588 }
589 if (m) {
590 /*
591 * Setup new buffer's info
592 */
593 KB_DATASTART(m, xdrs->x_private, caddr_t);
594 xdrs->x_handy = KB_LEN(m);
595 } else {
596 /*
597 * No more buffers
598 */
599 return (FALSE);
600 }
601 }
602
603 /*
604 * Copy from user's space into buffer
605 */
606 copy = MIN(len, xdrs->x_handy);
607 KM_COPY(addr, xdrs->x_private, copy);
608
609 /*
610 * Update data stream controls
611 */
612 xdrs->x_private += copy;
613 xdrs->x_handy -= copy;
614 addr += copy;
615 len -= copy;
616 }
617 return (TRUE);
618}
619
620static u_int
621xdrmbuf_getpos(XDR *xdrs)
622{
623
624 return ((u_int)xdrs->x_private - (u_int)xdrs->x_base);
625}