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