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