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