2 * Copyright 2000, International Business Machines Corporation and others.
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
11 * xdr_rx.c. XDR using RX.
14 #include <afsconfig.h>
16 #include "afs/param.h"
18 #include <afs/param.h>
23 #include "afs/sysincludes.h"
28 #include <net/net_globals.h>
29 #endif /* AFS_OSF_ENV */
30 #ifdef AFS_LINUX20_ENV
33 #include "rpc/types.h"
41 #endif /* AFS_OSF_ENV */
42 #ifdef AFS_LINUX22_ENV
44 #define quad_t __quad_t
45 #define u_quad_t __u_quad_t
49 #include "netinet/in.h"
51 #include "rpc/types.h"
57 #include <sys/types.h>
60 #include <netinet/in.h>
67 * This section should really go in the param.*.h files.
71 * kernel version needs to agree with <rpc/xdr.h>
72 * except on Linux which does XDR differently from everyone else
74 # if defined(AFS_LINUX20_ENV) && !defined(UKERNEL)
75 # define AFS_XDRS_T void *
77 # define AFS_XDRS_T XDR *
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 *
88 # define AFS_RPC_INLINE_T long
92 * user version needs to agree with "xdr.h", i.e. <rx/xdr.h>
94 # define AFS_XDRS_T void *
95 # define AFS_RPC_INLINE_T afs_int32
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) */
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,
108 static bool_t xdrrx_putbytes(AFS_XDRS_T axdrs, caddr_t addr,
110 static AFS_RPC_INLINE_T *xdrrx_inline(AFS_XDRS_T axdrs, u_int len);
114 * Ops vector for stdio type XDR
116 static struct xdr_ops xdrrx_ops = {
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 */
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)) */
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 */
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)
147 .x_getint32 = xdrrx_getint32, /* deserialize an afs_int32 */
148 .x_putint32 = xdrrx_putint32, /* serialize an afs_int32 */
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.
158 xdrrx_create(XDR * xdrs, struct rx_call *call,
162 xdrs->x_ops = &xdrrx_ops;
163 xdrs->x_private = (caddr_t) call;
166 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
167 #define STACK_TO_PIN 2*PAGESIZE /* 8K */
168 int rx_pin_failed = 0;
171 #if (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV)
173 xdrrx_getint64(AFS_XDRS_T axdrs, long *lp)
175 XDR * xdrs = (XDR *)axdrs;
176 struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
179 if (rx_Read32(call, &i) == sizeof(i)) {
187 xdrrx_putint64(AFS_XDRS_T axdrs, long *lp)
189 XDR * xdrs = (XDR *)axdrs;
190 afs_int32 code, i = htonl(*lp);
191 struct rx_call *call = ((struct rx_call *)(xdrs)->x_private);
193 code = (rx_Write32(call, &i) == sizeof(i));
196 #endif /* (defined(AFS_SGI61_ENV) && (_MIPS_SZLONG != _MIPS_SZINT)) || defined(AFS_HPUX_64BIT_ENV) */
199 xdrrx_getint32(AFS_XDRS_T axdrs, afs_int32 * lp)
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;
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.
216 if (pin(saddr, STACK_TO_PIN)) {
217 /* XXX There's little we can do by continue XXX */
222 if (rx_Read32(call, &l) == sizeof(l)) {
224 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
226 unpin(saddr, STACK_TO_PIN);
230 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
232 unpin(saddr, STACK_TO_PIN);
238 xdrrx_putint32(AFS_XDRS_T axdrs, afs_int32 * lp)
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;
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.
255 if (pin(saddr, STACK_TO_PIN)) {
260 code = (rx_Write32(call, &l) == sizeof(l));
261 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
263 unpin(saddr, STACK_TO_PIN);
269 xdrrx_getbytes(AFS_XDRS_T axdrs, caddr_t addr, u_int len)
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;
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.
286 if (pin(saddr, STACK_TO_PIN)) {
287 /* XXX There's little we can do by continue XXX */
292 code = (rx_Read(call, addr, len) == len);
293 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
295 unpin(saddr, STACK_TO_PIN);
301 xdrrx_putbytes(AFS_XDRS_T axdrs, caddr_t addr, u_int len)
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;
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.
318 if (pin(saddr, STACK_TO_PIN)) {
319 /* XXX There's little we can do by continue XXX */
324 code = (rx_Write(call, addr, len) == len);
325 #if defined(KERNEL) && defined(AFS_AIX32_ENV)
327 unpin(saddr, STACK_TO_PIN);
332 #ifdef undef /* not used */
334 xdrrx_getpos(XDR * xdrs)
336 /* Not supported. What error code should we return? (It doesn't matter: it will never be called, anyway!) */
341 xdrrx_setpos(XDR * xdrs, u_int pos)
348 static AFS_RPC_INLINE_T *
349 xdrrx_inline(AFS_XDRS_T axdrs, u_int len)
351 /* I don't know what this routine is supposed to do, but the stdio module returns null, so we will, too */