xref: /titanic_53/usr/src/boot/lib/libstand/bootparam.c (revision 4a5d661a82b942b6538acd26209d959ce98b593a)
1*4a5d661aSToomas Soome /*	$NetBSD: bootparam.c,v 1.11 1997/06/26 19:11:32 drochner Exp $	*/
2*4a5d661aSToomas Soome 
3*4a5d661aSToomas Soome /*
4*4a5d661aSToomas Soome  * Copyright (c) 1995 Gordon W. Ross
5*4a5d661aSToomas Soome  * All rights reserved.
6*4a5d661aSToomas Soome  *
7*4a5d661aSToomas Soome  * Redistribution and use in source and binary forms, with or without
8*4a5d661aSToomas Soome  * modification, are permitted provided that the following conditions
9*4a5d661aSToomas Soome  * are met:
10*4a5d661aSToomas Soome  * 1. Redistributions of source code must retain the above copyright
11*4a5d661aSToomas Soome  *    notice, this list of conditions and the following disclaimer.
12*4a5d661aSToomas Soome  * 2. Redistributions in binary form must reproduce the above copyright
13*4a5d661aSToomas Soome  *    notice, this list of conditions and the following disclaimer in the
14*4a5d661aSToomas Soome  *    documentation and/or other materials provided with the distribution.
15*4a5d661aSToomas Soome  * 3. The name of the author may not be used to endorse or promote products
16*4a5d661aSToomas Soome  *    derived from this software without specific prior written permission.
17*4a5d661aSToomas Soome  * 4. All advertising materials mentioning features or use of this software
18*4a5d661aSToomas Soome  *    must display the following acknowledgement:
19*4a5d661aSToomas Soome  *      This product includes software developed by Gordon W. Ross
20*4a5d661aSToomas Soome  *
21*4a5d661aSToomas Soome  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22*4a5d661aSToomas Soome  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23*4a5d661aSToomas Soome  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24*4a5d661aSToomas Soome  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25*4a5d661aSToomas Soome  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26*4a5d661aSToomas Soome  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27*4a5d661aSToomas Soome  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28*4a5d661aSToomas Soome  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29*4a5d661aSToomas Soome  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30*4a5d661aSToomas Soome  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*4a5d661aSToomas Soome  */
32*4a5d661aSToomas Soome 
33*4a5d661aSToomas Soome #include <sys/cdefs.h>
34*4a5d661aSToomas Soome __FBSDID("$FreeBSD$");
35*4a5d661aSToomas Soome 
36*4a5d661aSToomas Soome /*
37*4a5d661aSToomas Soome  * RPC/bootparams
38*4a5d661aSToomas Soome  */
39*4a5d661aSToomas Soome 
40*4a5d661aSToomas Soome #include <sys/param.h>
41*4a5d661aSToomas Soome #include <sys/socket.h>
42*4a5d661aSToomas Soome 
43*4a5d661aSToomas Soome #include <net/if.h>
44*4a5d661aSToomas Soome 
45*4a5d661aSToomas Soome #include <netinet/in.h>
46*4a5d661aSToomas Soome #include <netinet/in_systm.h>
47*4a5d661aSToomas Soome 
48*4a5d661aSToomas Soome #include <string.h>
49*4a5d661aSToomas Soome 
50*4a5d661aSToomas Soome #include "rpcv2.h"
51*4a5d661aSToomas Soome 
52*4a5d661aSToomas Soome #include "stand.h"
53*4a5d661aSToomas Soome #include "net.h"
54*4a5d661aSToomas Soome #include "netif.h"
55*4a5d661aSToomas Soome #include "rpc.h"
56*4a5d661aSToomas Soome #include "bootparam.h"
57*4a5d661aSToomas Soome 
58*4a5d661aSToomas Soome #ifdef DEBUG_RPC
59*4a5d661aSToomas Soome #define RPC_PRINTF(a)	printf a
60*4a5d661aSToomas Soome #else
61*4a5d661aSToomas Soome #define RPC_PRINTF(a)
62*4a5d661aSToomas Soome #endif
63*4a5d661aSToomas Soome 
64*4a5d661aSToomas Soome struct in_addr	bp_server_addr;	/* net order */
65*4a5d661aSToomas Soome n_short		bp_server_port;	/* net order */
66*4a5d661aSToomas Soome 
67*4a5d661aSToomas Soome /*
68*4a5d661aSToomas Soome  * RPC definitions for bootparamd
69*4a5d661aSToomas Soome  */
70*4a5d661aSToomas Soome #define	BOOTPARAM_PROG		100026
71*4a5d661aSToomas Soome #define	BOOTPARAM_VERS		1
72*4a5d661aSToomas Soome #define BOOTPARAM_WHOAMI	1
73*4a5d661aSToomas Soome #define BOOTPARAM_GETFILE	2
74*4a5d661aSToomas Soome 
75*4a5d661aSToomas Soome /*
76*4a5d661aSToomas Soome  * Inet address in RPC messages
77*4a5d661aSToomas Soome  * (Note, really four ints, NOT chars.  Blech.)
78*4a5d661aSToomas Soome  */
79*4a5d661aSToomas Soome struct xdr_inaddr {
80*4a5d661aSToomas Soome 	u_int32_t  atype;
81*4a5d661aSToomas Soome 	int32_t	addr[4];
82*4a5d661aSToomas Soome };
83*4a5d661aSToomas Soome 
84*4a5d661aSToomas Soome int xdr_inaddr_encode(char **p, struct in_addr ia);
85*4a5d661aSToomas Soome int xdr_inaddr_decode(char **p, struct in_addr *ia);
86*4a5d661aSToomas Soome 
87*4a5d661aSToomas Soome int xdr_string_encode(char **p, char *str, int len);
88*4a5d661aSToomas Soome int xdr_string_decode(char **p, char *str, int *len_p);
89*4a5d661aSToomas Soome 
90*4a5d661aSToomas Soome 
91*4a5d661aSToomas Soome /*
92*4a5d661aSToomas Soome  * RPC: bootparam/whoami
93*4a5d661aSToomas Soome  * Given client IP address, get:
94*4a5d661aSToomas Soome  *	client name	(hostname)
95*4a5d661aSToomas Soome  *	domain name (domainname)
96*4a5d661aSToomas Soome  *	gateway address
97*4a5d661aSToomas Soome  *
98*4a5d661aSToomas Soome  * The hostname and domainname are set here for convenience.
99*4a5d661aSToomas Soome  *
100*4a5d661aSToomas Soome  * Note - bpsin is initialized to the broadcast address,
101*4a5d661aSToomas Soome  * and will be replaced with the bootparam server address
102*4a5d661aSToomas Soome  * after this call is complete.  Have to use PMAP_PROC_CALL
103*4a5d661aSToomas Soome  * to make sure we get responses only from a servers that
104*4a5d661aSToomas Soome  * know about us (don't want to broadcast a getport call).
105*4a5d661aSToomas Soome  */
106*4a5d661aSToomas Soome int
107*4a5d661aSToomas Soome bp_whoami(sockfd)
108*4a5d661aSToomas Soome 	int sockfd;
109*4a5d661aSToomas Soome {
110*4a5d661aSToomas Soome 	/* RPC structures for PMAPPROC_CALLIT */
111*4a5d661aSToomas Soome 	struct args {
112*4a5d661aSToomas Soome 		u_int32_t prog;
113*4a5d661aSToomas Soome 		u_int32_t vers;
114*4a5d661aSToomas Soome 		u_int32_t proc;
115*4a5d661aSToomas Soome 		u_int32_t arglen;
116*4a5d661aSToomas Soome 		struct xdr_inaddr xina;
117*4a5d661aSToomas Soome 	} *args;
118*4a5d661aSToomas Soome 	struct repl {
119*4a5d661aSToomas Soome 		u_int16_t _pad;
120*4a5d661aSToomas Soome 		u_int16_t port;
121*4a5d661aSToomas Soome 		u_int32_t encap_len;
122*4a5d661aSToomas Soome 		/* encapsulated data here */
123*4a5d661aSToomas Soome 		n_long  capsule[64];
124*4a5d661aSToomas Soome 	} *repl;
125*4a5d661aSToomas Soome 	struct {
126*4a5d661aSToomas Soome 		n_long	h[RPC_HEADER_WORDS];
127*4a5d661aSToomas Soome 		struct args d;
128*4a5d661aSToomas Soome 	} sdata;
129*4a5d661aSToomas Soome 	struct {
130*4a5d661aSToomas Soome 		n_long	h[RPC_HEADER_WORDS];
131*4a5d661aSToomas Soome 		struct repl d;
132*4a5d661aSToomas Soome 	} rdata;
133*4a5d661aSToomas Soome 	char *send_tail, *recv_head;
134*4a5d661aSToomas Soome 	struct iodesc *d;
135*4a5d661aSToomas Soome 	int len, x;
136*4a5d661aSToomas Soome 
137*4a5d661aSToomas Soome 	RPC_PRINTF(("bp_whoami: myip=%s\n", inet_ntoa(myip)));
138*4a5d661aSToomas Soome 
139*4a5d661aSToomas Soome 	if (!(d = socktodesc(sockfd))) {
140*4a5d661aSToomas Soome 		RPC_PRINTF(("bp_whoami: bad socket. %d\n", sockfd));
141*4a5d661aSToomas Soome 		return (-1);
142*4a5d661aSToomas Soome 	}
143*4a5d661aSToomas Soome 	args = &sdata.d;
144*4a5d661aSToomas Soome 	repl = &rdata.d;
145*4a5d661aSToomas Soome 
146*4a5d661aSToomas Soome 	/*
147*4a5d661aSToomas Soome 	 * Build request args for PMAPPROC_CALLIT.
148*4a5d661aSToomas Soome 	 */
149*4a5d661aSToomas Soome 	args->prog = htonl(BOOTPARAM_PROG);
150*4a5d661aSToomas Soome 	args->vers = htonl(BOOTPARAM_VERS);
151*4a5d661aSToomas Soome 	args->proc = htonl(BOOTPARAM_WHOAMI);
152*4a5d661aSToomas Soome 	args->arglen = htonl(sizeof(struct xdr_inaddr));
153*4a5d661aSToomas Soome 	send_tail = (char*) &args->xina;
154*4a5d661aSToomas Soome 
155*4a5d661aSToomas Soome 	/*
156*4a5d661aSToomas Soome 	 * append encapsulated data (client IP address)
157*4a5d661aSToomas Soome 	 */
158*4a5d661aSToomas Soome 	if (xdr_inaddr_encode(&send_tail, myip))
159*4a5d661aSToomas Soome 		return (-1);
160*4a5d661aSToomas Soome 
161*4a5d661aSToomas Soome 	/* RPC: portmap/callit */
162*4a5d661aSToomas Soome 	d->myport = htons(--rpc_port);
163*4a5d661aSToomas Soome 	d->destip.s_addr = INADDR_BROADCAST;	/* XXX: subnet bcast? */
164*4a5d661aSToomas Soome 	/* rpc_call will set d->destport */
165*4a5d661aSToomas Soome 
166*4a5d661aSToomas Soome 	len = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT,
167*4a5d661aSToomas Soome 				  args, send_tail - (char*)args,
168*4a5d661aSToomas Soome 				  repl, sizeof(*repl));
169*4a5d661aSToomas Soome 	if (len < 8) {
170*4a5d661aSToomas Soome 		printf("bootparamd: 'whoami' call failed\n");
171*4a5d661aSToomas Soome 		return (-1);
172*4a5d661aSToomas Soome 	}
173*4a5d661aSToomas Soome 
174*4a5d661aSToomas Soome 	/* Save bootparam server address (from IP header). */
175*4a5d661aSToomas Soome 	rpc_fromaddr(repl, &bp_server_addr, &bp_server_port);
176*4a5d661aSToomas Soome 
177*4a5d661aSToomas Soome 	/*
178*4a5d661aSToomas Soome 	 * Note that bp_server_port is now 111 due to the
179*4a5d661aSToomas Soome 	 * indirect call (using PMAPPROC_CALLIT), so get the
180*4a5d661aSToomas Soome 	 * actual port number from the reply data.
181*4a5d661aSToomas Soome 	 */
182*4a5d661aSToomas Soome 	bp_server_port = repl->port;
183*4a5d661aSToomas Soome 
184*4a5d661aSToomas Soome 	RPC_PRINTF(("bp_whoami: server at %s:%d\n",
185*4a5d661aSToomas Soome 	    inet_ntoa(bp_server_addr), ntohs(bp_server_port)));
186*4a5d661aSToomas Soome 
187*4a5d661aSToomas Soome 	/* We have just done a portmap call, so cache the portnum. */
188*4a5d661aSToomas Soome 	rpc_pmap_putcache(bp_server_addr,
189*4a5d661aSToomas Soome 			  BOOTPARAM_PROG,
190*4a5d661aSToomas Soome 			  BOOTPARAM_VERS,
191*4a5d661aSToomas Soome 			  (int)ntohs(bp_server_port));
192*4a5d661aSToomas Soome 
193*4a5d661aSToomas Soome 	/*
194*4a5d661aSToomas Soome 	 * Parse the encapsulated results from bootparam/whoami
195*4a5d661aSToomas Soome 	 */
196*4a5d661aSToomas Soome 	x = ntohl(repl->encap_len);
197*4a5d661aSToomas Soome 	if (len < x) {
198*4a5d661aSToomas Soome 		printf("bp_whoami: short reply, %d < %d\n", len, x);
199*4a5d661aSToomas Soome 		return (-1);
200*4a5d661aSToomas Soome 	}
201*4a5d661aSToomas Soome 	recv_head = (char*) repl->capsule;
202*4a5d661aSToomas Soome 
203*4a5d661aSToomas Soome 	/* client name */
204*4a5d661aSToomas Soome 	hostnamelen = MAXHOSTNAMELEN-1;
205*4a5d661aSToomas Soome 	if (xdr_string_decode(&recv_head, hostname, &hostnamelen)) {
206*4a5d661aSToomas Soome 		RPC_PRINTF(("bp_whoami: bad hostname\n"));
207*4a5d661aSToomas Soome 		return (-1);
208*4a5d661aSToomas Soome 	}
209*4a5d661aSToomas Soome 
210*4a5d661aSToomas Soome 	/* domain name */
211*4a5d661aSToomas Soome 	domainnamelen = MAXHOSTNAMELEN-1;
212*4a5d661aSToomas Soome 	if (xdr_string_decode(&recv_head, domainname, &domainnamelen)) {
213*4a5d661aSToomas Soome 		RPC_PRINTF(("bp_whoami: bad domainname\n"));
214*4a5d661aSToomas Soome 		return (-1);
215*4a5d661aSToomas Soome 	}
216*4a5d661aSToomas Soome 
217*4a5d661aSToomas Soome 	/* gateway address */
218*4a5d661aSToomas Soome 	if (xdr_inaddr_decode(&recv_head, &gateip)) {
219*4a5d661aSToomas Soome 		RPC_PRINTF(("bp_whoami: bad gateway\n"));
220*4a5d661aSToomas Soome 		return (-1);
221*4a5d661aSToomas Soome 	}
222*4a5d661aSToomas Soome 
223*4a5d661aSToomas Soome 	/* success */
224*4a5d661aSToomas Soome 	return(0);
225*4a5d661aSToomas Soome }
226*4a5d661aSToomas Soome 
227*4a5d661aSToomas Soome 
228*4a5d661aSToomas Soome /*
229*4a5d661aSToomas Soome  * RPC: bootparam/getfile
230*4a5d661aSToomas Soome  * Given client name and file "key", get:
231*4a5d661aSToomas Soome  *	server name
232*4a5d661aSToomas Soome  *	server IP address
233*4a5d661aSToomas Soome  *	server pathname
234*4a5d661aSToomas Soome  */
235*4a5d661aSToomas Soome int
236*4a5d661aSToomas Soome bp_getfile(sockfd, key, serv_addr, pathname)
237*4a5d661aSToomas Soome 	int sockfd;
238*4a5d661aSToomas Soome 	char *key;
239*4a5d661aSToomas Soome 	char *pathname;
240*4a5d661aSToomas Soome 	struct in_addr *serv_addr;
241*4a5d661aSToomas Soome {
242*4a5d661aSToomas Soome 	struct {
243*4a5d661aSToomas Soome 		n_long	h[RPC_HEADER_WORDS];
244*4a5d661aSToomas Soome 		n_long  d[64];
245*4a5d661aSToomas Soome 	} sdata;
246*4a5d661aSToomas Soome 	struct {
247*4a5d661aSToomas Soome 		n_long	h[RPC_HEADER_WORDS];
248*4a5d661aSToomas Soome 		n_long  d[128];
249*4a5d661aSToomas Soome 	} rdata;
250*4a5d661aSToomas Soome 	char serv_name[FNAME_SIZE];
251*4a5d661aSToomas Soome 	char *send_tail, *recv_head;
252*4a5d661aSToomas Soome 	/* misc... */
253*4a5d661aSToomas Soome 	struct iodesc *d;
254*4a5d661aSToomas Soome 	int sn_len, path_len, rlen;
255*4a5d661aSToomas Soome 
256*4a5d661aSToomas Soome 	if (!(d = socktodesc(sockfd))) {
257*4a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad socket. %d\n", sockfd));
258*4a5d661aSToomas Soome 		return (-1);
259*4a5d661aSToomas Soome 	}
260*4a5d661aSToomas Soome 
261*4a5d661aSToomas Soome 	send_tail = (char*) sdata.d;
262*4a5d661aSToomas Soome 	recv_head = (char*) rdata.d;
263*4a5d661aSToomas Soome 
264*4a5d661aSToomas Soome 	/*
265*4a5d661aSToomas Soome 	 * Build request message.
266*4a5d661aSToomas Soome 	 */
267*4a5d661aSToomas Soome 
268*4a5d661aSToomas Soome 	/* client name (hostname) */
269*4a5d661aSToomas Soome 	if (xdr_string_encode(&send_tail, hostname, hostnamelen)) {
270*4a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad client\n"));
271*4a5d661aSToomas Soome 		return (-1);
272*4a5d661aSToomas Soome 	}
273*4a5d661aSToomas Soome 
274*4a5d661aSToomas Soome 	/* key name (root or swap) */
275*4a5d661aSToomas Soome 	if (xdr_string_encode(&send_tail, key, strlen(key))) {
276*4a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad key\n"));
277*4a5d661aSToomas Soome 		return (-1);
278*4a5d661aSToomas Soome 	}
279*4a5d661aSToomas Soome 
280*4a5d661aSToomas Soome 	/* RPC: bootparam/getfile */
281*4a5d661aSToomas Soome 	d->myport = htons(--rpc_port);
282*4a5d661aSToomas Soome 	d->destip   = bp_server_addr;
283*4a5d661aSToomas Soome 	/* rpc_call will set d->destport */
284*4a5d661aSToomas Soome 
285*4a5d661aSToomas Soome 	rlen = rpc_call(d,
286*4a5d661aSToomas Soome 		BOOTPARAM_PROG, BOOTPARAM_VERS, BOOTPARAM_GETFILE,
287*4a5d661aSToomas Soome 		sdata.d, send_tail - (char*)sdata.d,
288*4a5d661aSToomas Soome 		rdata.d, sizeof(rdata.d));
289*4a5d661aSToomas Soome 	if (rlen < 4) {
290*4a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: short reply\n"));
291*4a5d661aSToomas Soome 		errno = EBADRPC;
292*4a5d661aSToomas Soome 		return (-1);
293*4a5d661aSToomas Soome 	}
294*4a5d661aSToomas Soome 	recv_head = (char*) rdata.d;
295*4a5d661aSToomas Soome 
296*4a5d661aSToomas Soome 	/*
297*4a5d661aSToomas Soome 	 * Parse result message.
298*4a5d661aSToomas Soome 	 */
299*4a5d661aSToomas Soome 
300*4a5d661aSToomas Soome 	/* server name */
301*4a5d661aSToomas Soome 	sn_len = FNAME_SIZE-1;
302*4a5d661aSToomas Soome 	if (xdr_string_decode(&recv_head, serv_name, &sn_len)) {
303*4a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad server name\n"));
304*4a5d661aSToomas Soome 		return (-1);
305*4a5d661aSToomas Soome 	}
306*4a5d661aSToomas Soome 
307*4a5d661aSToomas Soome 	/* server IP address (mountd/NFS) */
308*4a5d661aSToomas Soome 	if (xdr_inaddr_decode(&recv_head, serv_addr)) {
309*4a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad server addr\n"));
310*4a5d661aSToomas Soome 		return (-1);
311*4a5d661aSToomas Soome 	}
312*4a5d661aSToomas Soome 
313*4a5d661aSToomas Soome 	/* server pathname */
314*4a5d661aSToomas Soome 	path_len = MAXPATHLEN-1;
315*4a5d661aSToomas Soome 	if (xdr_string_decode(&recv_head, pathname, &path_len)) {
316*4a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad server path\n"));
317*4a5d661aSToomas Soome 		return (-1);
318*4a5d661aSToomas Soome 	}
319*4a5d661aSToomas Soome 
320*4a5d661aSToomas Soome 	/* success */
321*4a5d661aSToomas Soome 	return(0);
322*4a5d661aSToomas Soome }
323*4a5d661aSToomas Soome 
324*4a5d661aSToomas Soome 
325*4a5d661aSToomas Soome /*
326*4a5d661aSToomas Soome  * eXternal Data Representation routines.
327*4a5d661aSToomas Soome  * (but with non-standard args...)
328*4a5d661aSToomas Soome  */
329*4a5d661aSToomas Soome 
330*4a5d661aSToomas Soome 
331*4a5d661aSToomas Soome int
332*4a5d661aSToomas Soome xdr_string_encode(pkt, str, len)
333*4a5d661aSToomas Soome 	char **pkt;
334*4a5d661aSToomas Soome 	char *str;
335*4a5d661aSToomas Soome 	int len;
336*4a5d661aSToomas Soome {
337*4a5d661aSToomas Soome 	u_int32_t *lenp;
338*4a5d661aSToomas Soome 	char *datap;
339*4a5d661aSToomas Soome 	int padlen = (len + 3) & ~3;	/* padded length */
340*4a5d661aSToomas Soome 
341*4a5d661aSToomas Soome 	/* The data will be int aligned. */
342*4a5d661aSToomas Soome 	lenp = (u_int32_t*) *pkt;
343*4a5d661aSToomas Soome 	*pkt += sizeof(*lenp);
344*4a5d661aSToomas Soome 	*lenp = htonl(len);
345*4a5d661aSToomas Soome 
346*4a5d661aSToomas Soome 	datap = *pkt;
347*4a5d661aSToomas Soome 	*pkt += padlen;
348*4a5d661aSToomas Soome 	bcopy(str, datap, len);
349*4a5d661aSToomas Soome 
350*4a5d661aSToomas Soome 	return (0);
351*4a5d661aSToomas Soome }
352*4a5d661aSToomas Soome 
353*4a5d661aSToomas Soome int
354*4a5d661aSToomas Soome xdr_string_decode(pkt, str, len_p)
355*4a5d661aSToomas Soome 	char **pkt;
356*4a5d661aSToomas Soome 	char *str;
357*4a5d661aSToomas Soome 	int *len_p;		/* bufsize - 1 */
358*4a5d661aSToomas Soome {
359*4a5d661aSToomas Soome 	u_int32_t *lenp;
360*4a5d661aSToomas Soome 	char *datap;
361*4a5d661aSToomas Soome 	int slen;	/* string length */
362*4a5d661aSToomas Soome 	int plen;	/* padded length */
363*4a5d661aSToomas Soome 
364*4a5d661aSToomas Soome 	/* The data will be int aligned. */
365*4a5d661aSToomas Soome 	lenp = (u_int32_t*) *pkt;
366*4a5d661aSToomas Soome 	*pkt += sizeof(*lenp);
367*4a5d661aSToomas Soome 	slen = ntohl(*lenp);
368*4a5d661aSToomas Soome 	plen = (slen + 3) & ~3;
369*4a5d661aSToomas Soome 
370*4a5d661aSToomas Soome 	if (slen > *len_p)
371*4a5d661aSToomas Soome 		slen = *len_p;
372*4a5d661aSToomas Soome 	datap = *pkt;
373*4a5d661aSToomas Soome 	*pkt += plen;
374*4a5d661aSToomas Soome 	bcopy(datap, str, slen);
375*4a5d661aSToomas Soome 
376*4a5d661aSToomas Soome 	str[slen] = '\0';
377*4a5d661aSToomas Soome 	*len_p = slen;
378*4a5d661aSToomas Soome 
379*4a5d661aSToomas Soome 	return (0);
380*4a5d661aSToomas Soome }
381*4a5d661aSToomas Soome 
382*4a5d661aSToomas Soome 
383*4a5d661aSToomas Soome int
384*4a5d661aSToomas Soome xdr_inaddr_encode(pkt, ia)
385*4a5d661aSToomas Soome 	char **pkt;
386*4a5d661aSToomas Soome 	struct in_addr ia;		/* network order */
387*4a5d661aSToomas Soome {
388*4a5d661aSToomas Soome 	struct xdr_inaddr *xi;
389*4a5d661aSToomas Soome 	u_char *cp;
390*4a5d661aSToomas Soome 	int32_t *ip;
391*4a5d661aSToomas Soome 	union {
392*4a5d661aSToomas Soome 		n_long l;	/* network order */
393*4a5d661aSToomas Soome 		u_char c[4];
394*4a5d661aSToomas Soome 	} uia;
395*4a5d661aSToomas Soome 
396*4a5d661aSToomas Soome 	/* The data will be int aligned. */
397*4a5d661aSToomas Soome 	xi = (struct xdr_inaddr *) *pkt;
398*4a5d661aSToomas Soome 	*pkt += sizeof(*xi);
399*4a5d661aSToomas Soome 	xi->atype = htonl(1);
400*4a5d661aSToomas Soome 	uia.l = ia.s_addr;
401*4a5d661aSToomas Soome 	cp = uia.c;
402*4a5d661aSToomas Soome 	ip = xi->addr;
403*4a5d661aSToomas Soome 	/*
404*4a5d661aSToomas Soome 	 * Note: the htonl() calls below DO NOT
405*4a5d661aSToomas Soome 	 * imply that uia.l is in host order.
406*4a5d661aSToomas Soome 	 * In fact this needs it in net order.
407*4a5d661aSToomas Soome 	 */
408*4a5d661aSToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
409*4a5d661aSToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
410*4a5d661aSToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
411*4a5d661aSToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
412*4a5d661aSToomas Soome 
413*4a5d661aSToomas Soome 	return (0);
414*4a5d661aSToomas Soome }
415*4a5d661aSToomas Soome 
416*4a5d661aSToomas Soome int
417*4a5d661aSToomas Soome xdr_inaddr_decode(pkt, ia)
418*4a5d661aSToomas Soome 	char **pkt;
419*4a5d661aSToomas Soome 	struct in_addr *ia;		/* network order */
420*4a5d661aSToomas Soome {
421*4a5d661aSToomas Soome 	struct xdr_inaddr *xi;
422*4a5d661aSToomas Soome 	u_char *cp;
423*4a5d661aSToomas Soome 	int32_t *ip;
424*4a5d661aSToomas Soome 	union {
425*4a5d661aSToomas Soome 		n_long l;	/* network order */
426*4a5d661aSToomas Soome 		u_char c[4];
427*4a5d661aSToomas Soome 	} uia;
428*4a5d661aSToomas Soome 
429*4a5d661aSToomas Soome 	/* The data will be int aligned. */
430*4a5d661aSToomas Soome 	xi = (struct xdr_inaddr *) *pkt;
431*4a5d661aSToomas Soome 	*pkt += sizeof(*xi);
432*4a5d661aSToomas Soome 	if (xi->atype != htonl(1)) {
433*4a5d661aSToomas Soome 		RPC_PRINTF(("xdr_inaddr_decode: bad addrtype=%d\n",
434*4a5d661aSToomas Soome 		    ntohl(xi->atype)));
435*4a5d661aSToomas Soome 		return(-1);
436*4a5d661aSToomas Soome 	}
437*4a5d661aSToomas Soome 
438*4a5d661aSToomas Soome 	cp = uia.c;
439*4a5d661aSToomas Soome 	ip = xi->addr;
440*4a5d661aSToomas Soome 	/*
441*4a5d661aSToomas Soome 	 * Note: the ntohl() calls below DO NOT
442*4a5d661aSToomas Soome 	 * imply that uia.l is in host order.
443*4a5d661aSToomas Soome 	 * In fact this needs it in net order.
444*4a5d661aSToomas Soome 	 */
445*4a5d661aSToomas Soome 	*cp++ = ntohl(*ip++);
446*4a5d661aSToomas Soome 	*cp++ = ntohl(*ip++);
447*4a5d661aSToomas Soome 	*cp++ = ntohl(*ip++);
448*4a5d661aSToomas Soome 	*cp++ = ntohl(*ip++);
449*4a5d661aSToomas Soome 	ia->s_addr = uia.l;
450*4a5d661aSToomas Soome 
451*4a5d661aSToomas Soome 	return (0);
452*4a5d661aSToomas Soome }
453