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