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