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