xref: /illumos-gate/usr/src/boot/libsa/bootparam.c (revision 22028508)
1199767f8SToomas Soome /*	$NetBSD: bootparam.c,v 1.11 1997/06/26 19:11:32 drochner Exp $	*/
2199767f8SToomas Soome 
3199767f8SToomas Soome /*
4199767f8SToomas Soome  * Copyright (c) 1995 Gordon W. Ross
5199767f8SToomas Soome  * All rights reserved.
6199767f8SToomas Soome  *
7199767f8SToomas Soome  * Redistribution and use in source and binary forms, with or without
8199767f8SToomas Soome  * modification, are permitted provided that the following conditions
9199767f8SToomas Soome  * are met:
10199767f8SToomas Soome  * 1. Redistributions of source code must retain the above copyright
11199767f8SToomas Soome  *    notice, this list of conditions and the following disclaimer.
12199767f8SToomas Soome  * 2. Redistributions in binary form must reproduce the above copyright
13199767f8SToomas Soome  *    notice, this list of conditions and the following disclaimer in the
14199767f8SToomas Soome  *    documentation and/or other materials provided with the distribution.
15199767f8SToomas Soome  * 3. The name of the author may not be used to endorse or promote products
16199767f8SToomas Soome  *    derived from this software without specific prior written permission.
17199767f8SToomas Soome  * 4. All advertising materials mentioning features or use of this software
18199767f8SToomas Soome  *    must display the following acknowledgement:
19199767f8SToomas Soome  *      This product includes software developed by Gordon W. Ross
20199767f8SToomas Soome  *
21199767f8SToomas Soome  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22199767f8SToomas Soome  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23199767f8SToomas Soome  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24199767f8SToomas Soome  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25199767f8SToomas Soome  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26199767f8SToomas Soome  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27199767f8SToomas Soome  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28199767f8SToomas Soome  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29199767f8SToomas Soome  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30199767f8SToomas Soome  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31199767f8SToomas Soome  */
32199767f8SToomas Soome 
33199767f8SToomas Soome #include <sys/cdefs.h>
34199767f8SToomas Soome 
35199767f8SToomas Soome /*
36199767f8SToomas Soome  * RPC/bootparams
37199767f8SToomas Soome  */
38199767f8SToomas Soome 
39199767f8SToomas Soome #include <sys/param.h>
40199767f8SToomas Soome #include <sys/socket.h>
41199767f8SToomas Soome 
42199767f8SToomas Soome #include <net/if.h>
43199767f8SToomas Soome 
44199767f8SToomas Soome #include <netinet/in.h>
45199767f8SToomas Soome #include <netinet/in_systm.h>
46199767f8SToomas Soome 
47199767f8SToomas Soome #include <string.h>
48199767f8SToomas Soome 
49199767f8SToomas Soome #include "rpcv2.h"
50199767f8SToomas Soome 
51199767f8SToomas Soome #include "stand.h"
52199767f8SToomas Soome #include "net.h"
53199767f8SToomas Soome #include "netif.h"
54199767f8SToomas Soome #include "rpc.h"
55199767f8SToomas Soome #include "bootparam.h"
56199767f8SToomas Soome 
57199767f8SToomas Soome #ifdef DEBUG_RPC
58199767f8SToomas Soome #define RPC_PRINTF(a)	printf a
59199767f8SToomas Soome #else
60199767f8SToomas Soome #define RPC_PRINTF(a)
61199767f8SToomas Soome #endif
62199767f8SToomas Soome 
63199767f8SToomas Soome struct in_addr	bp_server_addr;	/* net order */
64199767f8SToomas Soome n_short		bp_server_port;	/* net order */
65199767f8SToomas Soome 
66199767f8SToomas Soome /*
67199767f8SToomas Soome  * RPC definitions for bootparamd
68199767f8SToomas Soome  */
69199767f8SToomas Soome #define	BOOTPARAM_PROG		100026
70199767f8SToomas Soome #define	BOOTPARAM_VERS		1
71199767f8SToomas Soome #define BOOTPARAM_WHOAMI	1
72199767f8SToomas Soome #define BOOTPARAM_GETFILE	2
73199767f8SToomas Soome 
74199767f8SToomas Soome /*
75199767f8SToomas Soome  * Inet address in RPC messages
76199767f8SToomas Soome  * (Note, really four ints, NOT chars.  Blech.)
77199767f8SToomas Soome  */
78199767f8SToomas Soome struct xdr_inaddr {
79199767f8SToomas Soome 	u_int32_t  atype;
80199767f8SToomas Soome 	int32_t	addr[4];
81199767f8SToomas Soome };
82199767f8SToomas Soome 
83199767f8SToomas Soome int xdr_inaddr_encode(char **p, struct in_addr ia);
84199767f8SToomas Soome int xdr_inaddr_decode(char **p, struct in_addr *ia);
85199767f8SToomas Soome 
86199767f8SToomas Soome int xdr_string_encode(char **p, char *str, int len);
87199767f8SToomas Soome int xdr_string_decode(char **p, char *str, int *len_p);
88199767f8SToomas Soome 
89199767f8SToomas Soome 
90199767f8SToomas Soome /*
91199767f8SToomas Soome  * RPC: bootparam/whoami
92199767f8SToomas Soome  * Given client IP address, get:
93199767f8SToomas Soome  *	client name	(hostname)
94199767f8SToomas Soome  *	domain name (domainname)
95199767f8SToomas Soome  *	gateway address
96199767f8SToomas Soome  *
97199767f8SToomas Soome  * The hostname and domainname are set here for convenience.
98199767f8SToomas Soome  *
99199767f8SToomas Soome  * Note - bpsin is initialized to the broadcast address,
100199767f8SToomas Soome  * and will be replaced with the bootparam server address
101199767f8SToomas Soome  * after this call is complete.  Have to use PMAP_PROC_CALL
102199767f8SToomas Soome  * to make sure we get responses only from a servers that
103199767f8SToomas Soome  * know about us (don't want to broadcast a getport call).
104199767f8SToomas Soome  */
105199767f8SToomas Soome int
bp_whoami(int sockfd)106859472daSToomas Soome bp_whoami(int sockfd)
107199767f8SToomas Soome {
108199767f8SToomas Soome 	/* RPC structures for PMAPPROC_CALLIT */
109199767f8SToomas Soome 	struct args {
110199767f8SToomas Soome 		u_int32_t prog;
111199767f8SToomas Soome 		u_int32_t vers;
112199767f8SToomas Soome 		u_int32_t proc;
113199767f8SToomas Soome 		u_int32_t arglen;
114199767f8SToomas Soome 		struct xdr_inaddr xina;
115199767f8SToomas Soome 	} *args;
116199767f8SToomas Soome 	struct repl {
117199767f8SToomas Soome 		u_int16_t _pad;
118199767f8SToomas Soome 		u_int16_t port;
119199767f8SToomas Soome 		u_int32_t encap_len;
120199767f8SToomas Soome 		/* encapsulated data here */
121199767f8SToomas Soome 		n_long  capsule[64];
122199767f8SToomas Soome 	} *repl;
123199767f8SToomas Soome 	struct {
124199767f8SToomas Soome 		n_long	h[RPC_HEADER_WORDS];
125199767f8SToomas Soome 		struct args d;
126199767f8SToomas Soome 	} sdata;
127199767f8SToomas Soome 	char *send_tail, *recv_head;
128199767f8SToomas Soome 	struct iodesc *d;
129859472daSToomas Soome 	void *pkt;
130859472daSToomas Soome 	int len, x, rc;
131199767f8SToomas Soome 
132199767f8SToomas Soome 	RPC_PRINTF(("bp_whoami: myip=%s\n", inet_ntoa(myip)));
133199767f8SToomas Soome 
134859472daSToomas Soome 	rc = -1;
135199767f8SToomas Soome 	if (!(d = socktodesc(sockfd))) {
136199767f8SToomas Soome 		RPC_PRINTF(("bp_whoami: bad socket. %d\n", sockfd));
137859472daSToomas Soome 		return (rc);
138199767f8SToomas Soome 	}
139199767f8SToomas Soome 	args = &sdata.d;
140199767f8SToomas Soome 
141199767f8SToomas Soome 	/*
142199767f8SToomas Soome 	 * Build request args for PMAPPROC_CALLIT.
143199767f8SToomas Soome 	 */
144199767f8SToomas Soome 	args->prog = htonl(BOOTPARAM_PROG);
145199767f8SToomas Soome 	args->vers = htonl(BOOTPARAM_VERS);
146199767f8SToomas Soome 	args->proc = htonl(BOOTPARAM_WHOAMI);
147199767f8SToomas Soome 	args->arglen = htonl(sizeof(struct xdr_inaddr));
148199767f8SToomas Soome 	send_tail = (char*) &args->xina;
149199767f8SToomas Soome 
150199767f8SToomas Soome 	/*
151199767f8SToomas Soome 	 * append encapsulated data (client IP address)
152199767f8SToomas Soome 	 */
153199767f8SToomas Soome 	if (xdr_inaddr_encode(&send_tail, myip))
154859472daSToomas Soome 		return (rc);
155199767f8SToomas Soome 
156199767f8SToomas Soome 	/* RPC: portmap/callit */
157199767f8SToomas Soome 	d->myport = htons(--rpc_port);
158199767f8SToomas Soome 	d->destip.s_addr = INADDR_BROADCAST;	/* XXX: subnet bcast? */
159199767f8SToomas Soome 	/* rpc_call will set d->destport */
160199767f8SToomas Soome 
161859472daSToomas Soome 	pkt = NULL;
162199767f8SToomas Soome 	len = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT,
163859472daSToomas Soome 	    args, send_tail - (char*)args, (void **)&repl, &pkt);
164199767f8SToomas Soome 	if (len < 8) {
165199767f8SToomas Soome 		printf("bootparamd: 'whoami' call failed\n");
166859472daSToomas Soome 		goto done;
167199767f8SToomas Soome 	}
168199767f8SToomas Soome 
169199767f8SToomas Soome 	/* Save bootparam server address (from IP header). */
170199767f8SToomas Soome 	rpc_fromaddr(repl, &bp_server_addr, &bp_server_port);
171199767f8SToomas Soome 
172199767f8SToomas Soome 	/*
173199767f8SToomas Soome 	 * Note that bp_server_port is now 111 due to the
174199767f8SToomas Soome 	 * indirect call (using PMAPPROC_CALLIT), so get the
175199767f8SToomas Soome 	 * actual port number from the reply data.
176199767f8SToomas Soome 	 */
177199767f8SToomas Soome 	bp_server_port = repl->port;
178199767f8SToomas Soome 
179199767f8SToomas Soome 	RPC_PRINTF(("bp_whoami: server at %s:%d\n",
180199767f8SToomas Soome 	    inet_ntoa(bp_server_addr), ntohs(bp_server_port)));
181199767f8SToomas Soome 
182199767f8SToomas Soome 	/* We have just done a portmap call, so cache the portnum. */
183199767f8SToomas Soome 	rpc_pmap_putcache(bp_server_addr,
184199767f8SToomas Soome 			  BOOTPARAM_PROG,
185199767f8SToomas Soome 			  BOOTPARAM_VERS,
186199767f8SToomas Soome 			  (int)ntohs(bp_server_port));
187199767f8SToomas Soome 
188199767f8SToomas Soome 	/*
189199767f8SToomas Soome 	 * Parse the encapsulated results from bootparam/whoami
190199767f8SToomas Soome 	 */
191199767f8SToomas Soome 	x = ntohl(repl->encap_len);
192199767f8SToomas Soome 	if (len < x) {
193199767f8SToomas Soome 		printf("bp_whoami: short reply, %d < %d\n", len, x);
194859472daSToomas Soome 		goto done;
195199767f8SToomas Soome 	}
196199767f8SToomas Soome 	recv_head = (char*) repl->capsule;
197199767f8SToomas Soome 
198199767f8SToomas Soome 	/* client name */
199199767f8SToomas Soome 	hostnamelen = MAXHOSTNAMELEN-1;
200199767f8SToomas Soome 	if (xdr_string_decode(&recv_head, hostname, &hostnamelen)) {
201199767f8SToomas Soome 		RPC_PRINTF(("bp_whoami: bad hostname\n"));
202859472daSToomas Soome 		goto done;
203199767f8SToomas Soome 	}
204199767f8SToomas Soome 
205199767f8SToomas Soome 	/* domain name */
206199767f8SToomas Soome 	domainnamelen = MAXHOSTNAMELEN-1;
207199767f8SToomas Soome 	if (xdr_string_decode(&recv_head, domainname, &domainnamelen)) {
208199767f8SToomas Soome 		RPC_PRINTF(("bp_whoami: bad domainname\n"));
209859472daSToomas Soome 		goto done;
210199767f8SToomas Soome 	}
211199767f8SToomas Soome 
212199767f8SToomas Soome 	/* gateway address */
213199767f8SToomas Soome 	if (xdr_inaddr_decode(&recv_head, &gateip)) {
214199767f8SToomas Soome 		RPC_PRINTF(("bp_whoami: bad gateway\n"));
215859472daSToomas Soome 		goto done;
216199767f8SToomas Soome 	}
217199767f8SToomas Soome 
218199767f8SToomas Soome 	/* success */
219859472daSToomas Soome 	rc = 0;
220859472daSToomas Soome done:
221859472daSToomas Soome 	free(pkt);
222859472daSToomas Soome 	return(rc);
223199767f8SToomas Soome }
224199767f8SToomas Soome 
225199767f8SToomas Soome 
226199767f8SToomas Soome /*
227199767f8SToomas Soome  * RPC: bootparam/getfile
228199767f8SToomas Soome  * Given client name and file "key", get:
229199767f8SToomas Soome  *	server name
230199767f8SToomas Soome  *	server IP address
231199767f8SToomas Soome  *	server pathname
232199767f8SToomas Soome  */
233199767f8SToomas Soome int
bp_getfile(int sockfd,char * key,struct in_addr * serv_addr,char * pathname)234859472daSToomas Soome bp_getfile(int sockfd, char *key, struct in_addr *serv_addr, char *pathname)
235199767f8SToomas Soome {
236199767f8SToomas Soome 	struct {
237199767f8SToomas Soome 		n_long	h[RPC_HEADER_WORDS];
238199767f8SToomas Soome 		n_long  d[64];
239199767f8SToomas Soome 	} sdata;
240859472daSToomas Soome 	void *pkt;
241199767f8SToomas Soome 	char serv_name[FNAME_SIZE];
242859472daSToomas Soome 	char *rdata, *send_tail;
243199767f8SToomas Soome 	/* misc... */
244199767f8SToomas Soome 	struct iodesc *d;
245859472daSToomas Soome 	int rc = -1, sn_len, path_len, rlen;
246199767f8SToomas Soome 
247199767f8SToomas Soome 	if (!(d = socktodesc(sockfd))) {
248199767f8SToomas Soome 		RPC_PRINTF(("bp_getfile: bad socket. %d\n", sockfd));
249199767f8SToomas Soome 		return (-1);
250199767f8SToomas Soome 	}
251199767f8SToomas Soome 
252199767f8SToomas Soome 	send_tail = (char*) sdata.d;
253199767f8SToomas Soome 
254199767f8SToomas Soome 	/*
255199767f8SToomas Soome 	 * Build request message.
256199767f8SToomas Soome 	 */
257199767f8SToomas Soome 
258199767f8SToomas Soome 	/* client name (hostname) */
259199767f8SToomas Soome 	if (xdr_string_encode(&send_tail, hostname, hostnamelen)) {
260199767f8SToomas Soome 		RPC_PRINTF(("bp_getfile: bad client\n"));
261199767f8SToomas Soome 		return (-1);
262199767f8SToomas Soome 	}
263199767f8SToomas Soome 
264199767f8SToomas Soome 	/* key name (root or swap) */
265199767f8SToomas Soome 	if (xdr_string_encode(&send_tail, key, strlen(key))) {
266199767f8SToomas Soome 		RPC_PRINTF(("bp_getfile: bad key\n"));
267199767f8SToomas Soome 		return (-1);
268199767f8SToomas Soome 	}
269199767f8SToomas Soome 
270199767f8SToomas Soome 	/* RPC: bootparam/getfile */
271199767f8SToomas Soome 	d->myport = htons(--rpc_port);
272199767f8SToomas Soome 	d->destip   = bp_server_addr;
273199767f8SToomas Soome 	/* rpc_call will set d->destport */
274859472daSToomas Soome 	pkt = NULL;
275199767f8SToomas Soome 	rlen = rpc_call(d,
276199767f8SToomas Soome 		BOOTPARAM_PROG, BOOTPARAM_VERS, BOOTPARAM_GETFILE,
277199767f8SToomas Soome 		sdata.d, send_tail - (char*)sdata.d,
278859472daSToomas Soome 		(void **)&rdata, &pkt);
279199767f8SToomas Soome 	if (rlen < 4) {
280199767f8SToomas Soome 		RPC_PRINTF(("bp_getfile: short reply\n"));
281199767f8SToomas Soome 		errno = EBADRPC;
282859472daSToomas Soome 		goto done;
283199767f8SToomas Soome 	}
284199767f8SToomas Soome 
285199767f8SToomas Soome 	/*
286199767f8SToomas Soome 	 * Parse result message.
287199767f8SToomas Soome 	 */
288199767f8SToomas Soome 
289199767f8SToomas Soome 	/* server name */
290199767f8SToomas Soome 	sn_len = FNAME_SIZE-1;
291859472daSToomas Soome 	if (xdr_string_decode(&rdata, serv_name, &sn_len)) {
292199767f8SToomas Soome 		RPC_PRINTF(("bp_getfile: bad server name\n"));
293859472daSToomas Soome 		goto done;
294199767f8SToomas Soome 	}
295199767f8SToomas Soome 
296199767f8SToomas Soome 	/* server IP address (mountd/NFS) */
297859472daSToomas Soome 	if (xdr_inaddr_decode(&rdata, serv_addr)) {
298199767f8SToomas Soome 		RPC_PRINTF(("bp_getfile: bad server addr\n"));
299859472daSToomas Soome 		goto done;
300199767f8SToomas Soome 	}
301199767f8SToomas Soome 
302199767f8SToomas Soome 	/* server pathname */
303199767f8SToomas Soome 	path_len = MAXPATHLEN-1;
304859472daSToomas Soome 	if (xdr_string_decode(&rdata, pathname, &path_len)) {
305199767f8SToomas Soome 		RPC_PRINTF(("bp_getfile: bad server path\n"));
306859472daSToomas Soome 		goto done;
307199767f8SToomas Soome 	}
308199767f8SToomas Soome 
309199767f8SToomas Soome 	/* success */
310859472daSToomas Soome 	rc = 0;
311859472daSToomas Soome done:
312859472daSToomas Soome 	free(pkt);
313859472daSToomas Soome 	return(rc);
314199767f8SToomas Soome }
315199767f8SToomas Soome 
316199767f8SToomas Soome 
317199767f8SToomas Soome /*
318199767f8SToomas Soome  * eXternal Data Representation routines.
319199767f8SToomas Soome  * (but with non-standard args...)
320199767f8SToomas Soome  */
321199767f8SToomas Soome 
322199767f8SToomas Soome 
323199767f8SToomas Soome int
xdr_string_encode(char ** pkt,char * str,int len)324859472daSToomas Soome xdr_string_encode(char **pkt, char *str, int len)
325199767f8SToomas Soome {
326859472daSToomas Soome 	uint32_t *lenp;
327199767f8SToomas Soome 	char *datap;
328199767f8SToomas Soome 	int padlen = (len + 3) & ~3;	/* padded length */
329199767f8SToomas Soome 
330199767f8SToomas Soome 	/* The data will be int aligned. */
331859472daSToomas Soome 	lenp = (uint32_t *) *pkt;
332199767f8SToomas Soome 	*pkt += sizeof(*lenp);
333199767f8SToomas Soome 	*lenp = htonl(len);
334199767f8SToomas Soome 
335199767f8SToomas Soome 	datap = *pkt;
336199767f8SToomas Soome 	*pkt += padlen;
337199767f8SToomas Soome 	bcopy(str, datap, len);
338199767f8SToomas Soome 
339199767f8SToomas Soome 	return (0);
340199767f8SToomas Soome }
341199767f8SToomas Soome 
342199767f8SToomas Soome int
xdr_string_decode(char ** pkt,char * str,int * len_p)343859472daSToomas Soome xdr_string_decode(char **pkt, char *str, int *len_p)
344199767f8SToomas Soome {
345859472daSToomas Soome 	uint32_t *lenp;
346199767f8SToomas Soome 	char *datap;
347199767f8SToomas Soome 	int slen;	/* string length */
348199767f8SToomas Soome 	int plen;	/* padded length */
349199767f8SToomas Soome 
350199767f8SToomas Soome 	/* The data will be int aligned. */
351859472daSToomas Soome 	lenp = (uint32_t *) *pkt;
352199767f8SToomas Soome 	*pkt += sizeof(*lenp);
353199767f8SToomas Soome 	slen = ntohl(*lenp);
354199767f8SToomas Soome 	plen = (slen + 3) & ~3;
355199767f8SToomas Soome 
356199767f8SToomas Soome 	if (slen > *len_p)
357199767f8SToomas Soome 		slen = *len_p;
358199767f8SToomas Soome 	datap = *pkt;
359199767f8SToomas Soome 	*pkt += plen;
360199767f8SToomas Soome 	bcopy(datap, str, slen);
361199767f8SToomas Soome 
362199767f8SToomas Soome 	str[slen] = '\0';
363199767f8SToomas Soome 	*len_p = slen;
364199767f8SToomas Soome 
365199767f8SToomas Soome 	return (0);
366199767f8SToomas Soome }
367199767f8SToomas Soome 
368199767f8SToomas Soome 
369199767f8SToomas Soome int
xdr_inaddr_encode(char ** pkt,struct in_addr ia)370859472daSToomas Soome xdr_inaddr_encode(char **pkt, struct in_addr ia)
371199767f8SToomas Soome {
372199767f8SToomas Soome 	struct xdr_inaddr *xi;
373199767f8SToomas Soome 	u_char *cp;
374199767f8SToomas Soome 	int32_t *ip;
375199767f8SToomas Soome 	union {
376199767f8SToomas Soome 		n_long l;	/* network order */
377199767f8SToomas Soome 		u_char c[4];
378199767f8SToomas Soome 	} uia;
379199767f8SToomas Soome 
380199767f8SToomas Soome 	/* The data will be int aligned. */
381199767f8SToomas Soome 	xi = (struct xdr_inaddr *) *pkt;
382199767f8SToomas Soome 	*pkt += sizeof(*xi);
383199767f8SToomas Soome 	xi->atype = htonl(1);
384199767f8SToomas Soome 	uia.l = ia.s_addr;
385199767f8SToomas Soome 	cp = uia.c;
386199767f8SToomas Soome 	ip = xi->addr;
387199767f8SToomas Soome 	/*
388199767f8SToomas Soome 	 * Note: the htonl() calls below DO NOT
389199767f8SToomas Soome 	 * imply that uia.l is in host order.
390199767f8SToomas Soome 	 * In fact this needs it in net order.
391199767f8SToomas Soome 	 */
392199767f8SToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
393199767f8SToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
394199767f8SToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
395199767f8SToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
396199767f8SToomas Soome 
397199767f8SToomas Soome 	return (0);
398199767f8SToomas Soome }
399199767f8SToomas Soome 
400199767f8SToomas Soome int
xdr_inaddr_decode(char ** pkt,struct in_addr * ia)401859472daSToomas Soome xdr_inaddr_decode(char **pkt, struct in_addr *ia)
402199767f8SToomas Soome {
403199767f8SToomas Soome 	struct xdr_inaddr *xi;
404199767f8SToomas Soome 	u_char *cp;
405199767f8SToomas Soome 	int32_t *ip;
406199767f8SToomas Soome 	union {
407199767f8SToomas Soome 		n_long l;	/* network order */
408199767f8SToomas Soome 		u_char c[4];
409199767f8SToomas Soome 	} uia;
410199767f8SToomas Soome 
411199767f8SToomas Soome 	/* The data will be int aligned. */
412199767f8SToomas Soome 	xi = (struct xdr_inaddr *) *pkt;
413199767f8SToomas Soome 	*pkt += sizeof(*xi);
414199767f8SToomas Soome 	if (xi->atype != htonl(1)) {
415199767f8SToomas Soome 		RPC_PRINTF(("xdr_inaddr_decode: bad addrtype=%d\n",
416199767f8SToomas Soome 		    ntohl(xi->atype)));
417199767f8SToomas Soome 		return(-1);
418199767f8SToomas Soome 	}
419199767f8SToomas Soome 
420199767f8SToomas Soome 	cp = uia.c;
421199767f8SToomas Soome 	ip = xi->addr;
422199767f8SToomas Soome 	/*
423199767f8SToomas Soome 	 * Note: the ntohl() calls below DO NOT
424199767f8SToomas Soome 	 * imply that uia.l is in host order.
425199767f8SToomas Soome 	 * In fact this needs it in net order.
426199767f8SToomas Soome 	 */
427199767f8SToomas Soome 	*cp++ = ntohl(*ip++);
428199767f8SToomas Soome 	*cp++ = ntohl(*ip++);
429199767f8SToomas Soome 	*cp++ = ntohl(*ip++);
430199767f8SToomas Soome 	*cp++ = ntohl(*ip++);
431199767f8SToomas Soome 	ia->s_addr = uia.l;
432199767f8SToomas Soome 
433199767f8SToomas Soome 	return (0);
434199767f8SToomas Soome }
435