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