1 /* 2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 3 * unrestricted use provided that this legend is included on all tape 4 * media and as a part of the software program in whole or part. Users 5 * may copy or modify Sun RPC without charge, but are not authorized 6 * to license or distribute it to anyone else except as part of a product or 7 * program developed by the user. 8 * 9 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 10 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 11 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 12 * 13 * Sun RPC is provided with no support and without any obligation on the 14 * part of Sun Microsystems, Inc. to assist in its use, correction, 15 * modification or enhancement. 16 * 17 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 18 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 19 * OR ANY PART THEREOF. 20 * 21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 22 * or profits or other special, indirect and consequential damages, even if 23 * Sun has been advised of the possibility of such damages. 24 * 25 * Sun Microsystems, Inc. 26 * 2550 Garcia Avenue 27 * Mountain View, California 94043 28 * 29 * @(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro 30 * @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC 31 * $FreeBSD: src/lib/libc/rpc/rpc_callmsg.c,v 1.9 1999/08/28 00:00:45 peter Exp $ 32 * $DragonFly: src/lib/libc/rpc/rpc_callmsg.c,v 1.4 2005/11/13 12:27:04 swildner Exp $ 33 */ 34 35 /* 36 * rpc_callmsg.c 37 * 38 * Copyright (C) 1984, Sun Microsystems, Inc. 39 * 40 */ 41 42 #include <sys/param.h> 43 #include <stdlib.h> 44 #include <string.h> 45 #include <rpc/rpc.h> 46 47 /* 48 * XDR a call message 49 */ 50 bool_t 51 xdr_callmsg(XDR *xdrs, struct rpc_msg *cmsg) 52 { 53 int32_t *buf; 54 struct opaque_auth *oa; 55 56 if (xdrs->x_op == XDR_ENCODE) { 57 if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) { 58 return (FALSE); 59 } 60 if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) { 61 return (FALSE); 62 } 63 buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT 64 + RNDUP(cmsg->rm_call.cb_cred.oa_length) 65 + 2 * BYTES_PER_XDR_UNIT 66 + RNDUP(cmsg->rm_call.cb_verf.oa_length)); 67 if (buf != NULL) { 68 IXDR_PUT_LONG(buf, cmsg->rm_xid); 69 IXDR_PUT_ENUM(buf, cmsg->rm_direction); 70 if (cmsg->rm_direction != CALL) { 71 return (FALSE); 72 } 73 IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers); 74 if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { 75 return (FALSE); 76 } 77 IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog); 78 IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers); 79 IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc); 80 oa = &cmsg->rm_call.cb_cred; 81 IXDR_PUT_ENUM(buf, oa->oa_flavor); 82 IXDR_PUT_LONG(buf, oa->oa_length); 83 if (oa->oa_length) { 84 memcpy((caddr_t)buf, oa->oa_base, oa->oa_length); 85 buf += RNDUP(oa->oa_length) / sizeof (int32_t); 86 } 87 oa = &cmsg->rm_call.cb_verf; 88 IXDR_PUT_ENUM(buf, oa->oa_flavor); 89 IXDR_PUT_LONG(buf, oa->oa_length); 90 if (oa->oa_length) { 91 memcpy((caddr_t)buf, oa->oa_base, oa->oa_length); 92 /* no real need.... 93 buf += RNDUP(oa->oa_length) / sizeof (int32_t); 94 */ 95 } 96 return (TRUE); 97 } 98 } 99 if (xdrs->x_op == XDR_DECODE) { 100 buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); 101 if (buf != NULL) { 102 cmsg->rm_xid = IXDR_GET_LONG(buf); 103 cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); 104 if (cmsg->rm_direction != CALL) { 105 return (FALSE); 106 } 107 cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf); 108 if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { 109 return (FALSE); 110 } 111 cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf); 112 cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf); 113 cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf); 114 oa = &cmsg->rm_call.cb_cred; 115 oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); 116 oa->oa_length = IXDR_GET_LONG(buf); 117 if (oa->oa_length) { 118 if (oa->oa_length > MAX_AUTH_BYTES) { 119 return (FALSE); 120 } 121 if (oa->oa_base == NULL) { 122 oa->oa_base = (caddr_t) 123 mem_alloc(oa->oa_length); 124 } 125 buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); 126 if (buf == NULL) { 127 if (xdr_opaque(xdrs, oa->oa_base, 128 oa->oa_length) == FALSE) { 129 return (FALSE); 130 } 131 } else { 132 memcpy(oa->oa_base, (caddr_t)buf, 133 oa->oa_length); 134 /* no real need.... 135 buf += RNDUP(oa->oa_length) / 136 sizeof (int32_t); 137 */ 138 } 139 } 140 oa = &cmsg->rm_call.cb_verf; 141 buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); 142 if (buf == NULL) { 143 if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || 144 xdr_u_int(xdrs, &oa->oa_length) == FALSE) { 145 return (FALSE); 146 } 147 } else { 148 oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); 149 oa->oa_length = IXDR_GET_LONG(buf); 150 } 151 if (oa->oa_length) { 152 if (oa->oa_length > MAX_AUTH_BYTES) { 153 return (FALSE); 154 } 155 if (oa->oa_base == NULL) { 156 oa->oa_base = (caddr_t) 157 mem_alloc(oa->oa_length); 158 } 159 buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); 160 if (buf == NULL) { 161 if (xdr_opaque(xdrs, oa->oa_base, 162 oa->oa_length) == FALSE) { 163 return (FALSE); 164 } 165 } else { 166 memcpy(oa->oa_base, (caddr_t)buf, 167 oa->oa_length); 168 /* no real need... 169 buf += RNDUP(oa->oa_length) / 170 sizeof (int32_t); 171 */ 172 } 173 } 174 return (TRUE); 175 } 176 } 177 if ( 178 xdr_u_int32_t(xdrs, &(cmsg->rm_xid)) && 179 xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && 180 (cmsg->rm_direction == CALL) && 181 xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_rpcvers)) && 182 (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) && 183 xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_prog)) && 184 xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_vers)) && 185 xdr_u_int32_t(xdrs, &(cmsg->rm_call.cb_proc)) && 186 xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) ) 187 return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf))); 188 return (FALSE); 189 } 190 191