xref: /titanic_52/usr/src/boot/lib/libstand/bootparam.c (revision 7b2a1233f92b2b3cb858f2fdb69378a9ab0a42f1)
14a5d661aSToomas Soome /*	$NetBSD: bootparam.c,v 1.11 1997/06/26 19:11:32 drochner Exp $	*/
24a5d661aSToomas Soome 
34a5d661aSToomas Soome /*
44a5d661aSToomas Soome  * Copyright (c) 1995 Gordon W. Ross
54a5d661aSToomas Soome  * All rights reserved.
64a5d661aSToomas Soome  *
74a5d661aSToomas Soome  * Redistribution and use in source and binary forms, with or without
84a5d661aSToomas Soome  * modification, are permitted provided that the following conditions
94a5d661aSToomas Soome  * are met:
104a5d661aSToomas Soome  * 1. Redistributions of source code must retain the above copyright
114a5d661aSToomas Soome  *    notice, this list of conditions and the following disclaimer.
124a5d661aSToomas Soome  * 2. Redistributions in binary form must reproduce the above copyright
134a5d661aSToomas Soome  *    notice, this list of conditions and the following disclaimer in the
144a5d661aSToomas Soome  *    documentation and/or other materials provided with the distribution.
154a5d661aSToomas Soome  * 3. The name of the author may not be used to endorse or promote products
164a5d661aSToomas Soome  *    derived from this software without specific prior written permission.
174a5d661aSToomas Soome  * 4. All advertising materials mentioning features or use of this software
184a5d661aSToomas Soome  *    must display the following acknowledgement:
194a5d661aSToomas Soome  *      This product includes software developed by Gordon W. Ross
204a5d661aSToomas Soome  *
214a5d661aSToomas Soome  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
224a5d661aSToomas Soome  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
234a5d661aSToomas Soome  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
244a5d661aSToomas Soome  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
254a5d661aSToomas Soome  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
264a5d661aSToomas Soome  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
274a5d661aSToomas Soome  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
284a5d661aSToomas Soome  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
294a5d661aSToomas Soome  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
304a5d661aSToomas Soome  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
314a5d661aSToomas Soome  */
324a5d661aSToomas Soome 
334a5d661aSToomas Soome #include <sys/cdefs.h>
344a5d661aSToomas Soome 
354a5d661aSToomas Soome /*
364a5d661aSToomas Soome  * RPC/bootparams
374a5d661aSToomas Soome  */
384a5d661aSToomas Soome 
394a5d661aSToomas Soome #include <sys/param.h>
404a5d661aSToomas Soome #include <sys/socket.h>
414a5d661aSToomas Soome 
424a5d661aSToomas Soome #include <net/if.h>
434a5d661aSToomas Soome 
444a5d661aSToomas Soome #include <netinet/in.h>
454a5d661aSToomas Soome #include <netinet/in_systm.h>
464a5d661aSToomas Soome 
474a5d661aSToomas Soome #include <string.h>
484a5d661aSToomas Soome 
494a5d661aSToomas Soome #include "rpcv2.h"
504a5d661aSToomas Soome 
514a5d661aSToomas Soome #include "stand.h"
524a5d661aSToomas Soome #include "net.h"
534a5d661aSToomas Soome #include "netif.h"
544a5d661aSToomas Soome #include "rpc.h"
554a5d661aSToomas Soome #include "bootparam.h"
564a5d661aSToomas Soome 
574a5d661aSToomas Soome #ifdef DEBUG_RPC
584a5d661aSToomas Soome #define RPC_PRINTF(a)	printf a
594a5d661aSToomas Soome #else
604a5d661aSToomas Soome #define RPC_PRINTF(a)
614a5d661aSToomas Soome #endif
624a5d661aSToomas Soome 
634a5d661aSToomas Soome struct in_addr	bp_server_addr;	/* net order */
644a5d661aSToomas Soome n_short		bp_server_port;	/* net order */
654a5d661aSToomas Soome 
664a5d661aSToomas Soome /*
674a5d661aSToomas Soome  * RPC definitions for bootparamd
684a5d661aSToomas Soome  */
694a5d661aSToomas Soome #define	BOOTPARAM_PROG		100026
704a5d661aSToomas Soome #define	BOOTPARAM_VERS		1
714a5d661aSToomas Soome #define BOOTPARAM_WHOAMI	1
724a5d661aSToomas Soome #define BOOTPARAM_GETFILE	2
734a5d661aSToomas Soome 
744a5d661aSToomas Soome /*
754a5d661aSToomas Soome  * Inet address in RPC messages
764a5d661aSToomas Soome  * (Note, really four ints, NOT chars.  Blech.)
774a5d661aSToomas Soome  */
784a5d661aSToomas Soome struct xdr_inaddr {
794a5d661aSToomas Soome 	u_int32_t  atype;
804a5d661aSToomas Soome 	int32_t	addr[4];
814a5d661aSToomas Soome };
824a5d661aSToomas Soome 
834a5d661aSToomas Soome int xdr_inaddr_encode(char **p, struct in_addr ia);
844a5d661aSToomas Soome int xdr_inaddr_decode(char **p, struct in_addr *ia);
854a5d661aSToomas Soome 
864a5d661aSToomas Soome int xdr_string_encode(char **p, char *str, int len);
874a5d661aSToomas Soome int xdr_string_decode(char **p, char *str, int *len_p);
884a5d661aSToomas Soome 
894a5d661aSToomas Soome 
904a5d661aSToomas Soome /*
914a5d661aSToomas Soome  * RPC: bootparam/whoami
924a5d661aSToomas Soome  * Given client IP address, get:
934a5d661aSToomas Soome  *	client name	(hostname)
944a5d661aSToomas Soome  *	domain name (domainname)
954a5d661aSToomas Soome  *	gateway address
964a5d661aSToomas Soome  *
974a5d661aSToomas Soome  * The hostname and domainname are set here for convenience.
984a5d661aSToomas Soome  *
994a5d661aSToomas Soome  * Note - bpsin is initialized to the broadcast address,
1004a5d661aSToomas Soome  * and will be replaced with the bootparam server address
1014a5d661aSToomas Soome  * after this call is complete.  Have to use PMAP_PROC_CALL
1024a5d661aSToomas Soome  * to make sure we get responses only from a servers that
1034a5d661aSToomas Soome  * know about us (don't want to broadcast a getport call).
1044a5d661aSToomas Soome  */
1054a5d661aSToomas Soome int
106*7b2a1233SToomas Soome bp_whoami(int sockfd)
1074a5d661aSToomas Soome {
1084a5d661aSToomas Soome 	/* RPC structures for PMAPPROC_CALLIT */
1094a5d661aSToomas Soome 	struct args {
1104a5d661aSToomas Soome 		u_int32_t prog;
1114a5d661aSToomas Soome 		u_int32_t vers;
1124a5d661aSToomas Soome 		u_int32_t proc;
1134a5d661aSToomas Soome 		u_int32_t arglen;
1144a5d661aSToomas Soome 		struct xdr_inaddr xina;
1154a5d661aSToomas Soome 	} *args;
1164a5d661aSToomas Soome 	struct repl {
1174a5d661aSToomas Soome 		u_int16_t _pad;
1184a5d661aSToomas Soome 		u_int16_t port;
1194a5d661aSToomas Soome 		u_int32_t encap_len;
1204a5d661aSToomas Soome 		/* encapsulated data here */
1214a5d661aSToomas Soome 		n_long  capsule[64];
1224a5d661aSToomas Soome 	} *repl;
1234a5d661aSToomas Soome 	struct {
1244a5d661aSToomas Soome 		n_long	h[RPC_HEADER_WORDS];
1254a5d661aSToomas Soome 		struct args d;
1264a5d661aSToomas Soome 	} sdata;
1274a5d661aSToomas Soome 	char *send_tail, *recv_head;
1284a5d661aSToomas Soome 	struct iodesc *d;
129*7b2a1233SToomas Soome 	void *pkt;
130*7b2a1233SToomas Soome 	int len, x, rc;
1314a5d661aSToomas Soome 
1324a5d661aSToomas Soome 	RPC_PRINTF(("bp_whoami: myip=%s\n", inet_ntoa(myip)));
1334a5d661aSToomas Soome 
134*7b2a1233SToomas Soome 	rc = -1;
1354a5d661aSToomas Soome 	if (!(d = socktodesc(sockfd))) {
1364a5d661aSToomas Soome 		RPC_PRINTF(("bp_whoami: bad socket. %d\n", sockfd));
137*7b2a1233SToomas Soome 		return (rc);
1384a5d661aSToomas Soome 	}
1394a5d661aSToomas Soome 	args = &sdata.d;
1404a5d661aSToomas Soome 
1414a5d661aSToomas Soome 	/*
1424a5d661aSToomas Soome 	 * Build request args for PMAPPROC_CALLIT.
1434a5d661aSToomas Soome 	 */
1444a5d661aSToomas Soome 	args->prog = htonl(BOOTPARAM_PROG);
1454a5d661aSToomas Soome 	args->vers = htonl(BOOTPARAM_VERS);
1464a5d661aSToomas Soome 	args->proc = htonl(BOOTPARAM_WHOAMI);
1474a5d661aSToomas Soome 	args->arglen = htonl(sizeof(struct xdr_inaddr));
1484a5d661aSToomas Soome 	send_tail = (char*) &args->xina;
1494a5d661aSToomas Soome 
1504a5d661aSToomas Soome 	/*
1514a5d661aSToomas Soome 	 * append encapsulated data (client IP address)
1524a5d661aSToomas Soome 	 */
1534a5d661aSToomas Soome 	if (xdr_inaddr_encode(&send_tail, myip))
154*7b2a1233SToomas Soome 		return (rc);
1554a5d661aSToomas Soome 
1564a5d661aSToomas Soome 	/* RPC: portmap/callit */
1574a5d661aSToomas Soome 	d->myport = htons(--rpc_port);
1584a5d661aSToomas Soome 	d->destip.s_addr = INADDR_BROADCAST;	/* XXX: subnet bcast? */
1594a5d661aSToomas Soome 	/* rpc_call will set d->destport */
1604a5d661aSToomas Soome 
161*7b2a1233SToomas Soome 	pkt = NULL;
1624a5d661aSToomas Soome 	len = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT,
163*7b2a1233SToomas Soome 	    args, send_tail - (char*)args, (void **)&repl, &pkt);
1644a5d661aSToomas Soome 	if (len < 8) {
1654a5d661aSToomas Soome 		printf("bootparamd: 'whoami' call failed\n");
166*7b2a1233SToomas Soome 		goto done;
1674a5d661aSToomas Soome 	}
1684a5d661aSToomas Soome 
1694a5d661aSToomas Soome 	/* Save bootparam server address (from IP header). */
1704a5d661aSToomas Soome 	rpc_fromaddr(repl, &bp_server_addr, &bp_server_port);
1714a5d661aSToomas Soome 
1724a5d661aSToomas Soome 	/*
1734a5d661aSToomas Soome 	 * Note that bp_server_port is now 111 due to the
1744a5d661aSToomas Soome 	 * indirect call (using PMAPPROC_CALLIT), so get the
1754a5d661aSToomas Soome 	 * actual port number from the reply data.
1764a5d661aSToomas Soome 	 */
1774a5d661aSToomas Soome 	bp_server_port = repl->port;
1784a5d661aSToomas Soome 
1794a5d661aSToomas Soome 	RPC_PRINTF(("bp_whoami: server at %s:%d\n",
1804a5d661aSToomas Soome 	    inet_ntoa(bp_server_addr), ntohs(bp_server_port)));
1814a5d661aSToomas Soome 
1824a5d661aSToomas Soome 	/* We have just done a portmap call, so cache the portnum. */
1834a5d661aSToomas Soome 	rpc_pmap_putcache(bp_server_addr,
1844a5d661aSToomas Soome 			  BOOTPARAM_PROG,
1854a5d661aSToomas Soome 			  BOOTPARAM_VERS,
1864a5d661aSToomas Soome 			  (int)ntohs(bp_server_port));
1874a5d661aSToomas Soome 
1884a5d661aSToomas Soome 	/*
1894a5d661aSToomas Soome 	 * Parse the encapsulated results from bootparam/whoami
1904a5d661aSToomas Soome 	 */
1914a5d661aSToomas Soome 	x = ntohl(repl->encap_len);
1924a5d661aSToomas Soome 	if (len < x) {
1934a5d661aSToomas Soome 		printf("bp_whoami: short reply, %d < %d\n", len, x);
194*7b2a1233SToomas Soome 		goto done;
1954a5d661aSToomas Soome 	}
1964a5d661aSToomas Soome 	recv_head = (char*) repl->capsule;
1974a5d661aSToomas Soome 
1984a5d661aSToomas Soome 	/* client name */
1994a5d661aSToomas Soome 	hostnamelen = MAXHOSTNAMELEN-1;
2004a5d661aSToomas Soome 	if (xdr_string_decode(&recv_head, hostname, &hostnamelen)) {
2014a5d661aSToomas Soome 		RPC_PRINTF(("bp_whoami: bad hostname\n"));
202*7b2a1233SToomas Soome 		goto done;
2034a5d661aSToomas Soome 	}
2044a5d661aSToomas Soome 
2054a5d661aSToomas Soome 	/* domain name */
2064a5d661aSToomas Soome 	domainnamelen = MAXHOSTNAMELEN-1;
2074a5d661aSToomas Soome 	if (xdr_string_decode(&recv_head, domainname, &domainnamelen)) {
2084a5d661aSToomas Soome 		RPC_PRINTF(("bp_whoami: bad domainname\n"));
209*7b2a1233SToomas Soome 		goto done;
2104a5d661aSToomas Soome 	}
2114a5d661aSToomas Soome 
2124a5d661aSToomas Soome 	/* gateway address */
2134a5d661aSToomas Soome 	if (xdr_inaddr_decode(&recv_head, &gateip)) {
2144a5d661aSToomas Soome 		RPC_PRINTF(("bp_whoami: bad gateway\n"));
215*7b2a1233SToomas Soome 		goto done;
2164a5d661aSToomas Soome 	}
2174a5d661aSToomas Soome 
2184a5d661aSToomas Soome 	/* success */
219*7b2a1233SToomas Soome 	rc = 0;
220*7b2a1233SToomas Soome done:
221*7b2a1233SToomas Soome 	free(pkt);
222*7b2a1233SToomas Soome 	return(rc);
2234a5d661aSToomas Soome }
2244a5d661aSToomas Soome 
2254a5d661aSToomas Soome 
2264a5d661aSToomas Soome /*
2274a5d661aSToomas Soome  * RPC: bootparam/getfile
2284a5d661aSToomas Soome  * Given client name and file "key", get:
2294a5d661aSToomas Soome  *	server name
2304a5d661aSToomas Soome  *	server IP address
2314a5d661aSToomas Soome  *	server pathname
2324a5d661aSToomas Soome  */
2334a5d661aSToomas Soome int
234*7b2a1233SToomas Soome bp_getfile(int sockfd, char *key, struct in_addr *serv_addr, char *pathname)
2354a5d661aSToomas Soome {
2364a5d661aSToomas Soome 	struct {
2374a5d661aSToomas Soome 		n_long	h[RPC_HEADER_WORDS];
2384a5d661aSToomas Soome 		n_long  d[64];
2394a5d661aSToomas Soome 	} sdata;
240*7b2a1233SToomas Soome 	void *pkt;
2414a5d661aSToomas Soome 	char serv_name[FNAME_SIZE];
242*7b2a1233SToomas Soome 	char *rdata, *send_tail;
2434a5d661aSToomas Soome 	/* misc... */
2444a5d661aSToomas Soome 	struct iodesc *d;
245*7b2a1233SToomas Soome 	int rc = -1, sn_len, path_len, rlen;
2464a5d661aSToomas Soome 
2474a5d661aSToomas Soome 	if (!(d = socktodesc(sockfd))) {
2484a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad socket. %d\n", sockfd));
2494a5d661aSToomas Soome 		return (-1);
2504a5d661aSToomas Soome 	}
2514a5d661aSToomas Soome 
2524a5d661aSToomas Soome 	send_tail = (char*) sdata.d;
2534a5d661aSToomas Soome 
2544a5d661aSToomas Soome 	/*
2554a5d661aSToomas Soome 	 * Build request message.
2564a5d661aSToomas Soome 	 */
2574a5d661aSToomas Soome 
2584a5d661aSToomas Soome 	/* client name (hostname) */
2594a5d661aSToomas Soome 	if (xdr_string_encode(&send_tail, hostname, hostnamelen)) {
2604a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad client\n"));
2614a5d661aSToomas Soome 		return (-1);
2624a5d661aSToomas Soome 	}
2634a5d661aSToomas Soome 
2644a5d661aSToomas Soome 	/* key name (root or swap) */
2654a5d661aSToomas Soome 	if (xdr_string_encode(&send_tail, key, strlen(key))) {
2664a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad key\n"));
2674a5d661aSToomas Soome 		return (-1);
2684a5d661aSToomas Soome 	}
2694a5d661aSToomas Soome 
2704a5d661aSToomas Soome 	/* RPC: bootparam/getfile */
2714a5d661aSToomas Soome 	d->myport = htons(--rpc_port);
2724a5d661aSToomas Soome 	d->destip   = bp_server_addr;
2734a5d661aSToomas Soome 	/* rpc_call will set d->destport */
274*7b2a1233SToomas Soome 	pkt = NULL;
2754a5d661aSToomas Soome 	rlen = rpc_call(d,
2764a5d661aSToomas Soome 		BOOTPARAM_PROG, BOOTPARAM_VERS, BOOTPARAM_GETFILE,
2774a5d661aSToomas Soome 		sdata.d, send_tail - (char*)sdata.d,
278*7b2a1233SToomas Soome 		(void **)&rdata, &pkt);
2794a5d661aSToomas Soome 	if (rlen < 4) {
2804a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: short reply\n"));
2814a5d661aSToomas Soome 		errno = EBADRPC;
282*7b2a1233SToomas Soome 		goto done;
2834a5d661aSToomas Soome 	}
2844a5d661aSToomas Soome 
2854a5d661aSToomas Soome 	/*
2864a5d661aSToomas Soome 	 * Parse result message.
2874a5d661aSToomas Soome 	 */
2884a5d661aSToomas Soome 
2894a5d661aSToomas Soome 	/* server name */
2904a5d661aSToomas Soome 	sn_len = FNAME_SIZE-1;
291*7b2a1233SToomas Soome 	if (xdr_string_decode(&rdata, serv_name, &sn_len)) {
2924a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad server name\n"));
293*7b2a1233SToomas Soome 		goto done;
2944a5d661aSToomas Soome 	}
2954a5d661aSToomas Soome 
2964a5d661aSToomas Soome 	/* server IP address (mountd/NFS) */
297*7b2a1233SToomas Soome 	if (xdr_inaddr_decode(&rdata, serv_addr)) {
2984a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad server addr\n"));
299*7b2a1233SToomas Soome 		goto done;
3004a5d661aSToomas Soome 	}
3014a5d661aSToomas Soome 
3024a5d661aSToomas Soome 	/* server pathname */
3034a5d661aSToomas Soome 	path_len = MAXPATHLEN-1;
304*7b2a1233SToomas Soome 	if (xdr_string_decode(&rdata, pathname, &path_len)) {
3054a5d661aSToomas Soome 		RPC_PRINTF(("bp_getfile: bad server path\n"));
306*7b2a1233SToomas Soome 		goto done;
3074a5d661aSToomas Soome 	}
3084a5d661aSToomas Soome 
3094a5d661aSToomas Soome 	/* success */
310*7b2a1233SToomas Soome 	rc = 0;
311*7b2a1233SToomas Soome done:
312*7b2a1233SToomas Soome 	free(pkt);
313*7b2a1233SToomas Soome 	return(rc);
3144a5d661aSToomas Soome }
3154a5d661aSToomas Soome 
3164a5d661aSToomas Soome 
3174a5d661aSToomas Soome /*
3184a5d661aSToomas Soome  * eXternal Data Representation routines.
3194a5d661aSToomas Soome  * (but with non-standard args...)
3204a5d661aSToomas Soome  */
3214a5d661aSToomas Soome 
3224a5d661aSToomas Soome 
3234a5d661aSToomas Soome int
324*7b2a1233SToomas Soome xdr_string_encode(char **pkt, char *str, int len)
3254a5d661aSToomas Soome {
326*7b2a1233SToomas Soome 	uint32_t *lenp;
3274a5d661aSToomas Soome 	char *datap;
3284a5d661aSToomas Soome 	int padlen = (len + 3) & ~3;	/* padded length */
3294a5d661aSToomas Soome 
3304a5d661aSToomas Soome 	/* The data will be int aligned. */
331*7b2a1233SToomas Soome 	lenp = (uint32_t *) *pkt;
3324a5d661aSToomas Soome 	*pkt += sizeof(*lenp);
3334a5d661aSToomas Soome 	*lenp = htonl(len);
3344a5d661aSToomas Soome 
3354a5d661aSToomas Soome 	datap = *pkt;
3364a5d661aSToomas Soome 	*pkt += padlen;
3374a5d661aSToomas Soome 	bcopy(str, datap, len);
3384a5d661aSToomas Soome 
3394a5d661aSToomas Soome 	return (0);
3404a5d661aSToomas Soome }
3414a5d661aSToomas Soome 
3424a5d661aSToomas Soome int
343*7b2a1233SToomas Soome xdr_string_decode(char **pkt, char *str, int *len_p)
3444a5d661aSToomas Soome {
345*7b2a1233SToomas Soome 	uint32_t *lenp;
3464a5d661aSToomas Soome 	char *datap;
3474a5d661aSToomas Soome 	int slen;	/* string length */
3484a5d661aSToomas Soome 	int plen;	/* padded length */
3494a5d661aSToomas Soome 
3504a5d661aSToomas Soome 	/* The data will be int aligned. */
351*7b2a1233SToomas Soome 	lenp = (uint32_t *) *pkt;
3524a5d661aSToomas Soome 	*pkt += sizeof(*lenp);
3534a5d661aSToomas Soome 	slen = ntohl(*lenp);
3544a5d661aSToomas Soome 	plen = (slen + 3) & ~3;
3554a5d661aSToomas Soome 
3564a5d661aSToomas Soome 	if (slen > *len_p)
3574a5d661aSToomas Soome 		slen = *len_p;
3584a5d661aSToomas Soome 	datap = *pkt;
3594a5d661aSToomas Soome 	*pkt += plen;
3604a5d661aSToomas Soome 	bcopy(datap, str, slen);
3614a5d661aSToomas Soome 
3624a5d661aSToomas Soome 	str[slen] = '\0';
3634a5d661aSToomas Soome 	*len_p = slen;
3644a5d661aSToomas Soome 
3654a5d661aSToomas Soome 	return (0);
3664a5d661aSToomas Soome }
3674a5d661aSToomas Soome 
3684a5d661aSToomas Soome 
3694a5d661aSToomas Soome int
370*7b2a1233SToomas Soome xdr_inaddr_encode(char **pkt, struct in_addr ia)
3714a5d661aSToomas Soome {
3724a5d661aSToomas Soome 	struct xdr_inaddr *xi;
3734a5d661aSToomas Soome 	u_char *cp;
3744a5d661aSToomas Soome 	int32_t *ip;
3754a5d661aSToomas Soome 	union {
3764a5d661aSToomas Soome 		n_long l;	/* network order */
3774a5d661aSToomas Soome 		u_char c[4];
3784a5d661aSToomas Soome 	} uia;
3794a5d661aSToomas Soome 
3804a5d661aSToomas Soome 	/* The data will be int aligned. */
3814a5d661aSToomas Soome 	xi = (struct xdr_inaddr *) *pkt;
3824a5d661aSToomas Soome 	*pkt += sizeof(*xi);
3834a5d661aSToomas Soome 	xi->atype = htonl(1);
3844a5d661aSToomas Soome 	uia.l = ia.s_addr;
3854a5d661aSToomas Soome 	cp = uia.c;
3864a5d661aSToomas Soome 	ip = xi->addr;
3874a5d661aSToomas Soome 	/*
3884a5d661aSToomas Soome 	 * Note: the htonl() calls below DO NOT
3894a5d661aSToomas Soome 	 * imply that uia.l is in host order.
3904a5d661aSToomas Soome 	 * In fact this needs it in net order.
3914a5d661aSToomas Soome 	 */
3924a5d661aSToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
3934a5d661aSToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
3944a5d661aSToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
3954a5d661aSToomas Soome 	*ip++ = htonl((unsigned int)*cp++);
3964a5d661aSToomas Soome 
3974a5d661aSToomas Soome 	return (0);
3984a5d661aSToomas Soome }
3994a5d661aSToomas Soome 
4004a5d661aSToomas Soome int
401*7b2a1233SToomas Soome xdr_inaddr_decode(char **pkt, struct in_addr *ia)
4024a5d661aSToomas Soome {
4034a5d661aSToomas Soome 	struct xdr_inaddr *xi;
4044a5d661aSToomas Soome 	u_char *cp;
4054a5d661aSToomas Soome 	int32_t *ip;
4064a5d661aSToomas Soome 	union {
4074a5d661aSToomas Soome 		n_long l;	/* network order */
4084a5d661aSToomas Soome 		u_char c[4];
4094a5d661aSToomas Soome 	} uia;
4104a5d661aSToomas Soome 
4114a5d661aSToomas Soome 	/* The data will be int aligned. */
4124a5d661aSToomas Soome 	xi = (struct xdr_inaddr *) *pkt;
4134a5d661aSToomas Soome 	*pkt += sizeof(*xi);
4144a5d661aSToomas Soome 	if (xi->atype != htonl(1)) {
4154a5d661aSToomas Soome 		RPC_PRINTF(("xdr_inaddr_decode: bad addrtype=%d\n",
4164a5d661aSToomas Soome 		    ntohl(xi->atype)));
4174a5d661aSToomas Soome 		return(-1);
4184a5d661aSToomas Soome 	}
4194a5d661aSToomas Soome 
4204a5d661aSToomas Soome 	cp = uia.c;
4214a5d661aSToomas Soome 	ip = xi->addr;
4224a5d661aSToomas Soome 	/*
4234a5d661aSToomas Soome 	 * Note: the ntohl() calls below DO NOT
4244a5d661aSToomas Soome 	 * imply that uia.l is in host order.
4254a5d661aSToomas Soome 	 * In fact this needs it in net order.
4264a5d661aSToomas Soome 	 */
4274a5d661aSToomas Soome 	*cp++ = ntohl(*ip++);
4284a5d661aSToomas Soome 	*cp++ = ntohl(*ip++);
4294a5d661aSToomas Soome 	*cp++ = ntohl(*ip++);
4304a5d661aSToomas Soome 	*cp++ = ntohl(*ip++);
4314a5d661aSToomas Soome 	ia->s_addr = uia.l;
4324a5d661aSToomas Soome 
4334a5d661aSToomas Soome 	return (0);
4344a5d661aSToomas Soome }
435