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