0aa7eed28d4ed371b4821f429d4950c7572df2bd
[openafs.git] / src / rx / xdr_rx.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 /*
11  * xdr_rx.c.  XDR using RX. 
12  */
13
14 #include <afsconfig.h>
15 #ifdef  KERNEL
16 #include "afs/param.h"
17 #else
18 #include <afs/param.h>
19 #endif
20
21
22 #ifdef KERNEL
23 #include "afs/sysincludes.h"
24 #ifndef UKERNEL
25 #include "h/types.h"
26 #include "h/uio.h"
27 #ifdef  AFS_OSF_ENV
28 #include <net/net_globals.h>
29 #endif /* AFS_OSF_ENV */
30 #ifdef AFS_LINUX20_ENV
31 #include "h/socket.h"
32 #else
33 #include "rpc/types.h"
34 #endif
35 #ifdef  AFS_OSF_ENV
36 #undef kmem_alloc
37 #undef kmem_free
38 #undef mem_alloc
39 #undef mem_free
40 #undef register
41 #endif /* AFS_OSF_ENV */
42 #ifdef AFS_LINUX22_ENV
43 #ifndef quad_t
44 #define quad_t __quad_t
45 #define u_quad_t __u_quad_t
46 #endif
47 #endif
48 #include "rx/xdr.h"
49 #include "netinet/in.h"
50 #else /* !UKERNEL */
51 #include "rpc/types.h"
52 #include "rpc/xdr.h"
53 #endif /* !UKERNEL */
54 #include "rx/rx.h"
55
56 #else /* KERNEL */
57 #include <sys/types.h>
58 #include <stdio.h>
59 #ifndef AFS_NT40_ENV
60 #include <netinet/in.h>
61 #endif
62 #include "rx.h"
63 #include "xdr.h"
64 #endif /* KERNEL */
65
66 /*
67  * This section should really go in the param.*.h files.
68  */
69 #if defined(KERNEL)
70 /*
71  * kernel version needs to agree with <rpc/xdr.h>
72  * except on Linux which does XDR differently from everyone else
73  */
74 # if defined(AFS_LINUX20_ENV) && !defined(UKERNEL)
75 #  define AFS_XDRS_T void *
76 # else
77 #  define AFS_XDRS_T XDR *
78 # endif
79 # if defined(AFS_SUN57_ENV)
80 #  define AFS_RPC_INLINE_T rpc_inline_t
81 # elif defined(AFS_DUX40_ENV)
82 #  define AFS_RPC_INLINE_T int
83 # elif defined(AFS_LINUX20_ENV) && !defined(UKERNEL)
84 #  define AFS_RPC_INLINE_T afs_int32
85 # elif defined(AFS_LINUX20_ENV)
86 #  define AFS_RPC_INLINE_T int32_t *
87 # else
88 #  define AFS_RPC_INLINE_T long
89 # endif
90 #else /* KERNEL */
91 /*
92  * user version needs to agree with "xdr.h", i.e. <rx/xdr.h>
93  */
94 #  define AFS_XDRS_T void *
95 #  define AFS_RPC_INLINE_T afs_int32
96 #endif /* KERNEL */
97
98 /* Static prototypes */
99 #if (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV)
100 static bool_t xdrrx_getint64(AFS_XDRS_T axdrs, long *lp);
101 static bool_t xdrrx_putint64(AFS_XDRS_T axdrs, long *lp);
102 #endif /* (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV) */
103
104 static bool_t xdrrx_getint32(AFS_XDRS_T axdrs, afs_int32 * lp);
105 static bool_t xdrrx_putint32(AFS_XDRS_T axdrs, afs_int32 * lp);
106 static bool_t xdrrx_getbytes(AFS_XDRS_T axdrs, caddr_t addr,
107                              u_int len);
108 static bool_t xdrrx_putbytes(AFS_XDRS_T axdrs, caddr_t addr,
109                              u_int len);
110 static AFS_RPC_INLINE_T *xdrrx_inline(AFS_XDRS_T axdrs, u_int len);
111
112
113 /*
114  * Ops vector for stdio type XDR
115  */
116 static struct xdr_ops xdrrx_ops = {
117 #ifdef AFS_NT40_ENV
118     /* Windows does not support labeled assigments */
119     xdrrx_getint32,     /* deserialize an afs_int32 */
120     xdrrx_putint32,     /* serialize an afs_int32 */
121     xdrrx_getbytes,     /* deserialize counted bytes */
122     xdrrx_putbytes,     /* serialize counted bytes */
123     NULL,               /* get offset in the stream: not supported. */
124     NULL,               /* set offset in the stream: not supported. */
125     xdrrx_inline,       /* prime stream for inline macros */
126     NULL                /* destroy stream */
127 #else
128 #if defined(KERNEL) && ((defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV))
129     .x_getint64 = xdrrx_getint64,
130     .x_putint64 = xdrrx_putint64,
131 #endif /* defined(KERNEL) && ((defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV)) */
132 #if defined(UKERNEL)
133     .x_getlong = xdrrx_getint32,
134     .x_putlong = xdrrx_putint32,
135 #elif !(defined(KERNEL) && defined(AFS_SUN57_ENV))
136     .x_getint32 = xdrrx_getint32,       /* deserialize an afs_int32 */
137     .x_putint32 = xdrrx_putint32,       /* serialize an afs_int32 */
138 #endif
139     .x_getbytes = xdrrx_getbytes,       /* deserialize counted bytes */
140     .x_putbytes = xdrrx_putbytes,       /* serialize counted bytes */
141     .x_getpostn = NULL,         /* get offset in the stream: not supported. */
142     .x_setpostn = NULL,         /* set offset in the stream: not supported. */
143     .x_inline = xdrrx_inline,           /* prime stream for inline macros */
144     .x_destroy = NULL,                  /* destroy stream */
145 #if defined(KERNEL) && defined(AFS_SUN57_ENV)
146     .x_control = NULL,
147     .x_getint32 = xdrrx_getint32,       /* deserialize an afs_int32 */
148     .x_putint32 = xdrrx_putint32,       /* serialize an afs_int32 */
149 #endif
150 #endif
151 };
152
153 /*
154  * Initialize an rx xdr handle, for a given rx call.  op must be XDR_ENCODE or XDR_DECODE.
155  * Call must have been returned by rx_MakeCall or rx_GetCall.
156  */
157 void
158 xdrrx_create(XDR * xdrs, struct rx_call *call,
159              enum xdr_op op)
160 {
161     xdrs->x_op = op;
162     xdrs->x_ops = &xdrrx_ops;
163     xdrs->x_private = (caddr_t) call;
164 }
165
166 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
167 #define STACK_TO_PIN    2*PAGESIZE      /* 8K */
168 int rx_pin_failed = 0;
169 #endif
170
171 #if (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV)
172 static bool_t
173 xdrrx_getint64(AFS_XDRS_T axdrs, long *lp)
174 {
175     XDR * xdrs = (XDR *)axdrs;
176     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
177     afs_int32 i;
178
179     if (rx_Read32(call, &i) == sizeof(i)) {
180         *lp = ntohl(i);
181         return TRUE;
182     }
183     return FALSE;
184 }
185
186 static bool_t
187 xdrrx_putint64(AFS_XDRS_T axdrs, long *lp)
188 {
189     XDR * xdrs = (XDR *)axdrs;
190     afs_int32 code, i = htonl(*lp);
191     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
192
193     code = (rx_Write32(call, &i) == sizeof(i));
194     return code;
195 }
196 #endif /* (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV) */
197
198 static bool_t
199 xdrrx_getint32(AFS_XDRS_T axdrs, afs_int32 * lp)
200 {
201     afs_int32 l;
202     XDR * xdrs = (XDR *)axdrs;
203     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
204 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
205     char *saddr = (char *)&l;
206     saddr -= STACK_TO_PIN;
207     /*
208      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under 
209      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
210      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
211      * 2K stack we could try to bring the next few stack pages in here before we call the rx
212      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
213      * out between here and calling splnet. So we now pin (and unpin) them instead to
214      * guarantee that they remain there.
215      */
216     if (pin(saddr, STACK_TO_PIN)) {
217         /* XXX There's little we can do by continue XXX */
218         saddr = NULL;
219         rx_pin_failed++;
220     }
221 #endif
222     if (rx_Read32(call, &l) == sizeof(l)) {
223         *lp = ntohl(l);
224 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
225         if (saddr)
226             unpin(saddr, STACK_TO_PIN);
227 #endif
228         return TRUE;
229     }
230 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
231     if (saddr)
232         unpin(saddr, STACK_TO_PIN);
233 #endif
234     return FALSE;
235 }
236
237 static bool_t
238 xdrrx_putint32(AFS_XDRS_T axdrs, afs_int32 * lp)
239 {
240     afs_int32 code, l = htonl(*lp);
241     XDR * xdrs = (XDR *)axdrs;
242     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
243 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
244     char *saddr = (char *)&code;
245     saddr -= STACK_TO_PIN;
246     /*
247      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under 
248      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
249      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
250      * 2K stack we could try to bring the next few stack pages in here before we call the rx
251      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
252      * out between here and calling splnet. So we now pin (and unpin) them instead to
253      * guarantee that they remain there.
254      */
255     if (pin(saddr, STACK_TO_PIN)) {
256         saddr = NULL;
257         rx_pin_failed++;
258     }
259 #endif
260     code = (rx_Write32(call, &l) == sizeof(l));
261 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
262     if (saddr)
263         unpin(saddr, STACK_TO_PIN);
264 #endif
265     return code;
266 }
267
268 static bool_t
269 xdrrx_getbytes(AFS_XDRS_T axdrs, caddr_t addr, u_int len)
270 {
271     afs_int32 code;
272     XDR * xdrs = (XDR *)axdrs;
273     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
274 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
275     char *saddr = (char *)&code;
276     saddr -= STACK_TO_PIN;
277     /*
278      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under 
279      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
280      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
281      * 2K stack we could try to bring the next few stack pages in here before we call the rx
282      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
283      * out between here and calling splnet. So we now pin (and unpin) them instead to
284      * guarantee that they remain there.
285      */
286     if (pin(saddr, STACK_TO_PIN)) {
287         /* XXX There's little we can do by continue XXX */
288         saddr = NULL;
289         rx_pin_failed++;
290     }
291 #endif
292     code = (rx_Read(call, addr, len) == len);
293 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
294     if (saddr)
295         unpin(saddr, STACK_TO_PIN);
296 #endif
297     return code;
298 }
299
300 static bool_t
301 xdrrx_putbytes(AFS_XDRS_T axdrs, caddr_t addr, u_int len)
302 {
303     afs_int32 code;
304     XDR * xdrs = (XDR *)axdrs;
305     struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
306 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
307     char *saddr = (char *)&code;
308     saddr -= STACK_TO_PIN;
309     /*
310      * Hack of hacks: Aix3.2 only guarantees that the next 2K of stack in pinned. Under 
311      * splnet (disables interrupts), which is set throughout rx, we can't swap in stack
312      * pages if we need so we panic. Since sometimes, under splnet, we'll use more than
313      * 2K stack we could try to bring the next few stack pages in here before we call the rx
314      * layer. Of course this doesn't guarantee that those stack pages won't be swapped
315      * out between here and calling splnet. So we now pin (and unpin) them instead to
316      * guarantee that they remain there.
317      */
318     if (pin(saddr, STACK_TO_PIN)) {
319         /* XXX There's little we can do by continue XXX */
320         saddr = NULL;
321         rx_pin_failed++;
322     }
323 #endif
324     code = (rx_Write(call, addr, len) == len);
325 #if     defined(KERNEL) && defined(AFS_AIX32_ENV)
326     if (saddr)
327         unpin(saddr, STACK_TO_PIN);
328 #endif
329     return code;
330 }
331
332 #ifdef undef                    /* not used */
333 static u_int
334 xdrrx_getpos(XDR * xdrs)
335 {
336     /* Not supported.  What error code should we return? (It doesn't matter:  it will never be called, anyway!) */
337     return -1;
338 }
339
340 static bool_t
341 xdrrx_setpos(XDR * xdrs, u_int pos)
342 {
343     /* Not supported */
344     return FALSE;
345 }
346 #endif
347
348 static AFS_RPC_INLINE_T *
349 xdrrx_inline(AFS_XDRS_T axdrs, u_int len)
350 {
351     /* I don't know what this routine is supposed to do, but the stdio module returns null, so we will, too */
352     return (0);
353 }