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