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