1 /* $NetBSD: rpcb_prot.c,v 1.3 2000/07/14 08:40:42 fvdl Exp $ */ 2 3 /*- 4 * SPDX-License-Identifier: BSD-3-Clause 5 * 6 * Copyright (c) 2009, Sun Microsystems, Inc. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions are met: 11 * - Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the following disclaimer. 13 * - Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * - Neither the name of Sun Microsystems, Inc. nor the names of its 17 * contributors may be used to endorse or promote products derived 18 * from this software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 /* 33 * Copyright (c) 1986-1991 by Sun Microsystems Inc. 34 */ 35 36 /* #ident "@(#)rpcb_prot.c 1.13 94/04/24 SMI" */ 37 38 #if defined(LIBC_SCCS) && !defined(lint) 39 static char sccsid[] = "@(#)rpcb_prot.c 1.9 89/04/21 Copyr 1984 Sun Micro"; 40 #endif 41 #include <sys/cdefs.h> 42 __FBSDID("$FreeBSD$"); 43 44 /* 45 * rpcb_prot.c 46 * XDR routines for the rpcbinder version 3. 47 * 48 * Copyright (C) 1984, 1988, Sun Microsystems, Inc. 49 */ 50 51 #include <sys/param.h> 52 #include <sys/systm.h> 53 #include <sys/kernel.h> 54 #include <sys/malloc.h> 55 56 #include <rpc/rpc.h> 57 #include <rpc/rpc_com.h> 58 #include <rpc/rpcb_prot.h> 59 60 bool_t 61 xdr_portmap(XDR *xdrs, struct portmap *regs) 62 { 63 64 if (xdr_u_long(xdrs, ®s->pm_prog) && 65 xdr_u_long(xdrs, ®s->pm_vers) && 66 xdr_u_long(xdrs, ®s->pm_prot)) 67 return (xdr_u_long(xdrs, ®s->pm_port)); 68 return (FALSE); 69 } 70 71 bool_t 72 xdr_rpcb(XDR *xdrs, RPCB *objp) 73 { 74 if (!xdr_uint32_t(xdrs, &objp->r_prog)) { 75 return (FALSE); 76 } 77 if (!xdr_uint32_t(xdrs, &objp->r_vers)) { 78 return (FALSE); 79 } 80 if (!xdr_string(xdrs, &objp->r_netid, RPC_MAXDATASIZE)) { 81 return (FALSE); 82 } 83 if (!xdr_string(xdrs, &objp->r_addr, RPC_MAXDATASIZE)) { 84 return (FALSE); 85 } 86 if (!xdr_string(xdrs, &objp->r_owner, RPC_MAXDATASIZE)) { 87 return (FALSE); 88 } 89 return (TRUE); 90 } 91 92 /* 93 * rpcblist_ptr implements a linked list. The RPCL definition from 94 * rpcb_prot.x is: 95 * 96 * struct rpcblist { 97 * rpcb rpcb_map; 98 * struct rpcblist *rpcb_next; 99 * }; 100 * typedef rpcblist *rpcblist_ptr; 101 * 102 * Recall that "pointers" in XDR are encoded as a boolean, indicating whether 103 * there's any data behind the pointer, followed by the data (if any exists). 104 * The boolean can be interpreted as ``more data follows me''; if FALSE then 105 * nothing follows the boolean; if TRUE then the boolean is followed by an 106 * actual struct rpcb, and another rpcblist_ptr (declared in RPCL as "struct 107 * rpcblist *"). 108 * 109 * This could be implemented via the xdr_pointer type, though this would 110 * result in one recursive call per element in the list. Rather than do that 111 * we can ``unwind'' the recursion into a while loop and use xdr_reference to 112 * serialize the rpcb elements. 113 */ 114 115 bool_t 116 xdr_rpcblist_ptr(XDR *xdrs, rpcblist_ptr *rp) 117 { 118 /* 119 * more_elements is pre-computed in case the direction is 120 * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 121 * xdr_bool when the direction is XDR_DECODE. 122 */ 123 bool_t more_elements; 124 int freeing = (xdrs->x_op == XDR_FREE); 125 rpcblist_ptr next; 126 rpcblist_ptr next_copy; 127 128 next = NULL; 129 for (;;) { 130 more_elements = (bool_t)(*rp != NULL); 131 if (! xdr_bool(xdrs, &more_elements)) { 132 return (FALSE); 133 } 134 if (! more_elements) { 135 return (TRUE); /* we are done */ 136 } 137 /* 138 * the unfortunate side effect of non-recursion is that in 139 * the case of freeing we must remember the next object 140 * before we free the current object ... 141 */ 142 if (freeing && *rp) 143 next = (*rp)->rpcb_next; 144 if (! xdr_reference(xdrs, (caddr_t *)rp, 145 (u_int)sizeof (RPCBLIST), (xdrproc_t)xdr_rpcb)) { 146 return (FALSE); 147 } 148 if (freeing) { 149 next_copy = next; 150 rp = &next_copy; 151 /* 152 * Note that in the subsequent iteration, next_copy 153 * gets nulled out by the xdr_reference 154 * but next itself survives. 155 */ 156 } else if (*rp) { 157 rp = &((*rp)->rpcb_next); 158 } 159 } 160 /*NOTREACHED*/ 161 } 162 163 #if 0 164 /* 165 * xdr_rpcblist() is specified to take a RPCBLIST **, but is identical in 166 * functionality to xdr_rpcblist_ptr(). 167 */ 168 bool_t 169 xdr_rpcblist(XDR *xdrs, RPCBLIST **rp) 170 { 171 bool_t dummy; 172 173 dummy = xdr_rpcblist_ptr(xdrs, (rpcblist_ptr *)rp); 174 return (dummy); 175 } 176 #endif 177 178 bool_t 179 xdr_rpcb_entry(XDR *xdrs, rpcb_entry *objp) 180 { 181 if (!xdr_string(xdrs, &objp->r_maddr, RPC_MAXDATASIZE)) { 182 return (FALSE); 183 } 184 if (!xdr_string(xdrs, &objp->r_nc_netid, RPC_MAXDATASIZE)) { 185 return (FALSE); 186 } 187 if (!xdr_uint32_t(xdrs, &objp->r_nc_semantics)) { 188 return (FALSE); 189 } 190 if (!xdr_string(xdrs, &objp->r_nc_protofmly, RPC_MAXDATASIZE)) { 191 return (FALSE); 192 } 193 if (!xdr_string(xdrs, &objp->r_nc_proto, RPC_MAXDATASIZE)) { 194 return (FALSE); 195 } 196 return (TRUE); 197 } 198 199 bool_t 200 xdr_rpcb_entry_list_ptr(XDR *xdrs, rpcb_entry_list_ptr *rp) 201 { 202 /* 203 * more_elements is pre-computed in case the direction is 204 * XDR_ENCODE or XDR_FREE. more_elements is overwritten by 205 * xdr_bool when the direction is XDR_DECODE. 206 */ 207 bool_t more_elements; 208 int freeing = (xdrs->x_op == XDR_FREE); 209 rpcb_entry_list_ptr next; 210 rpcb_entry_list_ptr next_copy; 211 212 next = NULL; 213 for (;;) { 214 more_elements = (bool_t)(*rp != NULL); 215 if (! xdr_bool(xdrs, &more_elements)) { 216 return (FALSE); 217 } 218 if (! more_elements) { 219 return (TRUE); /* we are done */ 220 } 221 /* 222 * the unfortunate side effect of non-recursion is that in 223 * the case of freeing we must remember the next object 224 * before we free the current object ... 225 */ 226 if (freeing) 227 next = (*rp)->rpcb_entry_next; 228 if (! xdr_reference(xdrs, (caddr_t *)rp, 229 (u_int)sizeof (rpcb_entry_list), 230 (xdrproc_t)xdr_rpcb_entry)) { 231 return (FALSE); 232 } 233 if (freeing && *rp) { 234 next_copy = next; 235 rp = &next_copy; 236 /* 237 * Note that in the subsequent iteration, next_copy 238 * gets nulled out by the xdr_reference 239 * but next itself survives. 240 */ 241 } else if (*rp) { 242 rp = &((*rp)->rpcb_entry_next); 243 } 244 } 245 /*NOTREACHED*/ 246 } 247