17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate /*
237c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate * This file contains routines responsible for getting the system's
297c478bd9Sstevel@tonic-gate * name and boot params. Most of it comes from the SVR4 diskless boot
307c478bd9Sstevel@tonic-gate * code (dlboot_inet), modified to work in a non socket environment.
317c478bd9Sstevel@tonic-gate */
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate #include <sys/types.h>
347c478bd9Sstevel@tonic-gate #include <rpc/types.h>
357c478bd9Sstevel@tonic-gate #include <sys/errno.h>
367c478bd9Sstevel@tonic-gate #include <rpc/auth.h>
377c478bd9Sstevel@tonic-gate #include <rpc/xdr.h>
387c478bd9Sstevel@tonic-gate #include <rpc/rpc_msg.h>
397c478bd9Sstevel@tonic-gate #include <sys/t_lock.h>
407c478bd9Sstevel@tonic-gate #include "clnt.h"
417c478bd9Sstevel@tonic-gate #include <rpc/rpc.h>
427c478bd9Sstevel@tonic-gate #include <sys/utsname.h>
437c478bd9Sstevel@tonic-gate #include <netinet/in.h>
447c478bd9Sstevel@tonic-gate #include <sys/socket.h>
457c478bd9Sstevel@tonic-gate #include <net/if.h>
467c478bd9Sstevel@tonic-gate #include <netinet/if_ether.h>
477c478bd9Sstevel@tonic-gate #include <netinet/in.h>
487c478bd9Sstevel@tonic-gate #include <sys/promif.h>
497c478bd9Sstevel@tonic-gate #include <rpcsvc/bootparam.h>
507c478bd9Sstevel@tonic-gate #include "pmap.h"
517c478bd9Sstevel@tonic-gate #include "brpc.h"
527c478bd9Sstevel@tonic-gate #include "socket_inet.h"
537c478bd9Sstevel@tonic-gate #include "ipv4.h"
547c478bd9Sstevel@tonic-gate #include <sys/salib.h>
557c478bd9Sstevel@tonic-gate #include <sys/bootdebug.h>
567c478bd9Sstevel@tonic-gate
577c478bd9Sstevel@tonic-gate extern int errno;
587c478bd9Sstevel@tonic-gate static struct bp_whoami_res bp;
597c478bd9Sstevel@tonic-gate static char bp_hostname[SYS_NMLN+1];
607c478bd9Sstevel@tonic-gate static char bp_domainname[SYS_NMLN+1];
617c478bd9Sstevel@tonic-gate static struct in_addr responder; /* network order */
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate static const char *noserver =
647c478bd9Sstevel@tonic-gate "No bootparam (%s) server responding; still trying...\n";
657c478bd9Sstevel@tonic-gate
667c478bd9Sstevel@tonic-gate #define GETFILE_BTIMEO 1
677c478bd9Sstevel@tonic-gate #define GETFILE_BRETRIES 2
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate #define dprintf if (boothowto & RB_DEBUG) printf
707c478bd9Sstevel@tonic-gate
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate * Returns TRUE if it has set the global structure 'bp' to our boot
737c478bd9Sstevel@tonic-gate * parameters, FALSE if some failure occurred.
747c478bd9Sstevel@tonic-gate */
757c478bd9Sstevel@tonic-gate bool_t
whoami(void)767c478bd9Sstevel@tonic-gate whoami(void)
777c478bd9Sstevel@tonic-gate {
787c478bd9Sstevel@tonic-gate struct bp_whoami_arg arg;
797c478bd9Sstevel@tonic-gate struct sockaddr_in to, from;
807c478bd9Sstevel@tonic-gate struct in_addr ipaddr;
817c478bd9Sstevel@tonic-gate enum clnt_stat stat;
827c478bd9Sstevel@tonic-gate bool_t retval = TRUE;
837c478bd9Sstevel@tonic-gate int rexmit; /* retransmission interval */
847c478bd9Sstevel@tonic-gate int resp_wait; /* secs to wait for resp */
857c478bd9Sstevel@tonic-gate int namelen;
867c478bd9Sstevel@tonic-gate int printed_waiting_msg;
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate /*
897c478bd9Sstevel@tonic-gate * Set our destination IP address to the limited broadcast address
907c478bd9Sstevel@tonic-gate * (INADDR_BROADCAST).
917c478bd9Sstevel@tonic-gate */
927c478bd9Sstevel@tonic-gate to.sin_family = AF_INET;
937c478bd9Sstevel@tonic-gate to.sin_addr.s_addr = htonl(INADDR_BROADCAST);
947c478bd9Sstevel@tonic-gate to.sin_port = htons(0);
957c478bd9Sstevel@tonic-gate
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate * Set up the arguments expected by bootparamd.
987c478bd9Sstevel@tonic-gate */
997c478bd9Sstevel@tonic-gate arg.client_address.address_type = IP_ADDR_TYPE;
1007c478bd9Sstevel@tonic-gate ipv4_getipaddr(&ipaddr);
1017c478bd9Sstevel@tonic-gate ipaddr.s_addr = htonl(ipaddr.s_addr);
1027c478bd9Sstevel@tonic-gate bcopy((caddr_t)&ipaddr,
1037c478bd9Sstevel@tonic-gate (caddr_t)&arg.client_address.bp_address_u.ip_addr,
1047c478bd9Sstevel@tonic-gate sizeof (ipaddr));
1057c478bd9Sstevel@tonic-gate
1067c478bd9Sstevel@tonic-gate /*
1077c478bd9Sstevel@tonic-gate * Retransmit/wait for up to resp_wait secs.
1087c478bd9Sstevel@tonic-gate */
1097c478bd9Sstevel@tonic-gate rexmit = 0; /* start at default retransmission interval. */
1107c478bd9Sstevel@tonic-gate resp_wait = 16;
1117c478bd9Sstevel@tonic-gate
1127c478bd9Sstevel@tonic-gate bp.client_name = &bp_hostname[0];
1137c478bd9Sstevel@tonic-gate bp.domain_name = &bp_domainname[0];
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate /*
1167c478bd9Sstevel@tonic-gate * Do a broadcast call to find a bootparam daemon that
1177c478bd9Sstevel@tonic-gate * will tell us our hostname, domainname and any
1187c478bd9Sstevel@tonic-gate * router that we have to use to talk to our NFS server.
1197c478bd9Sstevel@tonic-gate */
1207c478bd9Sstevel@tonic-gate printed_waiting_msg = 0;
1217c478bd9Sstevel@tonic-gate do {
1227c478bd9Sstevel@tonic-gate /*
1237c478bd9Sstevel@tonic-gate * First try the SunOS portmapper and if no reply is
1247c478bd9Sstevel@tonic-gate * received will then try the SVR4 rpcbind.
1257c478bd9Sstevel@tonic-gate * Either way, `bootpaddr' will be set to the
1267c478bd9Sstevel@tonic-gate * correct address for the bootparamd that responds.
1277c478bd9Sstevel@tonic-gate */
1287c478bd9Sstevel@tonic-gate stat = bpmap_rmtcall((rpcprog_t)BOOTPARAMPROG,
1297c478bd9Sstevel@tonic-gate (rpcvers_t)BOOTPARAMVERS, (rpcproc_t)BOOTPARAMPROC_WHOAMI,
1307c478bd9Sstevel@tonic-gate xdr_bp_whoami_arg, (caddr_t)&arg,
1317c478bd9Sstevel@tonic-gate xdr_bp_whoami_res, (caddr_t)&bp, rexmit, resp_wait,
1327c478bd9Sstevel@tonic-gate &to, &from, AUTH_NONE);
1337c478bd9Sstevel@tonic-gate if (stat == RPC_TIMEDOUT && !printed_waiting_msg) {
1347c478bd9Sstevel@tonic-gate dprintf(noserver, "whoami");
1357c478bd9Sstevel@tonic-gate printed_waiting_msg = 1;
1367c478bd9Sstevel@tonic-gate }
1377c478bd9Sstevel@tonic-gate /*
1387c478bd9Sstevel@tonic-gate * Retransmission interval for second and subsequent tries.
1397c478bd9Sstevel@tonic-gate * We expect first bpmap_rmtcall to retransmit and backoff to
1407c478bd9Sstevel@tonic-gate * at least this value.
1417c478bd9Sstevel@tonic-gate */
1427c478bd9Sstevel@tonic-gate rexmit = resp_wait;
1437c478bd9Sstevel@tonic-gate resp_wait = 0; /* go to default wait now. */
1447c478bd9Sstevel@tonic-gate } while (stat == RPC_TIMEDOUT);
1457c478bd9Sstevel@tonic-gate
1467c478bd9Sstevel@tonic-gate if (stat != RPC_SUCCESS) {
1477c478bd9Sstevel@tonic-gate dprintf("whoami RPC call failed with rpc status: %d\n", stat);
1487c478bd9Sstevel@tonic-gate retval = FALSE;
1497c478bd9Sstevel@tonic-gate goto done;
1507c478bd9Sstevel@tonic-gate } else {
1517c478bd9Sstevel@tonic-gate if (printed_waiting_msg && (boothowto & RB_VERBOSE))
1527c478bd9Sstevel@tonic-gate printf("Bootparam response received\n");
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate /* Cache responder... We'll send our getfile here... */
1557c478bd9Sstevel@tonic-gate responder.s_addr = from.sin_addr.s_addr;
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate namelen = strlen(bp.client_name);
1597c478bd9Sstevel@tonic-gate if (namelen > SYS_NMLN) {
1607c478bd9Sstevel@tonic-gate dprintf("whoami: hostname too long");
1617c478bd9Sstevel@tonic-gate retval = FALSE;
1627c478bd9Sstevel@tonic-gate goto done;
1637c478bd9Sstevel@tonic-gate }
1647c478bd9Sstevel@tonic-gate if (namelen > 0) {
1657c478bd9Sstevel@tonic-gate if (boothowto & RB_VERBOSE)
1667c478bd9Sstevel@tonic-gate printf("hostname: %s\n", bp.client_name);
167*b531f6d1SToomas Soome (void) sethostname(bp.client_name, namelen);
1687c478bd9Sstevel@tonic-gate } else {
1697c478bd9Sstevel@tonic-gate dprintf("whoami: no host name\n");
1707c478bd9Sstevel@tonic-gate retval = FALSE;
1717c478bd9Sstevel@tonic-gate goto done;
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate
1747c478bd9Sstevel@tonic-gate namelen = strlen(bp.domain_name);
1757c478bd9Sstevel@tonic-gate if (namelen > SYS_NMLN) {
1767c478bd9Sstevel@tonic-gate dprintf("whoami: domainname too long");
1777c478bd9Sstevel@tonic-gate retval = FALSE;
1787c478bd9Sstevel@tonic-gate goto done;
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate if (namelen > 0)
1817c478bd9Sstevel@tonic-gate if (boothowto & RB_VERBOSE)
1827c478bd9Sstevel@tonic-gate printf("domainname: %s\n", bp.domain_name);
1837c478bd9Sstevel@tonic-gate else
1847c478bd9Sstevel@tonic-gate dprintf("whoami: no domain name\n");
1857c478bd9Sstevel@tonic-gate
1867c478bd9Sstevel@tonic-gate if (bp.router_address.address_type == IP_ADDR_TYPE) {
1877c478bd9Sstevel@tonic-gate bcopy((caddr_t)&bp.router_address.bp_address_u.ip_addr,
1887c478bd9Sstevel@tonic-gate (caddr_t)&ipaddr, sizeof (ipaddr));
1897c478bd9Sstevel@tonic-gate if (ntohl(ipaddr.s_addr) != INADDR_ANY) {
1907c478bd9Sstevel@tonic-gate dprintf("whoami: Router ip is: %s\n",
1917c478bd9Sstevel@tonic-gate inet_ntoa(ipaddr));
1927c478bd9Sstevel@tonic-gate /* ipv4_route expects IP addresses in network order */
1937c478bd9Sstevel@tonic-gate (void) ipv4_route(IPV4_ADD_ROUTE, RT_DEFAULT, NULL,
1947c478bd9Sstevel@tonic-gate &ipaddr);
1957c478bd9Sstevel@tonic-gate }
1967c478bd9Sstevel@tonic-gate } else
1977c478bd9Sstevel@tonic-gate dprintf("whoami: unknown gateway addr family %d\n",
1987c478bd9Sstevel@tonic-gate bp.router_address.address_type);
1997c478bd9Sstevel@tonic-gate done:
2007c478bd9Sstevel@tonic-gate return (retval);
2017c478bd9Sstevel@tonic-gate }
2027c478bd9Sstevel@tonic-gate
2037c478bd9Sstevel@tonic-gate /*
2047c478bd9Sstevel@tonic-gate * Returns:
2057c478bd9Sstevel@tonic-gate * 1) The ascii form of our root servers name in `server_name'.
2067c478bd9Sstevel@tonic-gate * 2) Pathname of our root on the server in `server_path'.
2077c478bd9Sstevel@tonic-gate *
2087c478bd9Sstevel@tonic-gate * NOTE: it's ok for getfile() to do dynamic allocation - it's only
2097c478bd9Sstevel@tonic-gate * used locally, then freed. If the server address returned from the
2107c478bd9Sstevel@tonic-gate * getfile call is different from our current destination address,
2117c478bd9Sstevel@tonic-gate * reset destination IP address to the new value.
2127c478bd9Sstevel@tonic-gate */
2137c478bd9Sstevel@tonic-gate bool_t
getfile(char * fileid,char * server_name,struct in_addr * server_ip,char * server_path)2147c478bd9Sstevel@tonic-gate getfile(char *fileid, char *server_name, struct in_addr *server_ip,
2157c478bd9Sstevel@tonic-gate char *server_path)
2167c478bd9Sstevel@tonic-gate {
2177c478bd9Sstevel@tonic-gate struct bp_getfile_arg arg;
2187c478bd9Sstevel@tonic-gate struct bp_getfile_res res;
2197c478bd9Sstevel@tonic-gate enum clnt_stat stat;
2207c478bd9Sstevel@tonic-gate struct sockaddr_in to, from;
2217c478bd9Sstevel@tonic-gate int rexmit;
2227c478bd9Sstevel@tonic-gate int wait;
2237c478bd9Sstevel@tonic-gate uint_t max_retries = 0xFFFFFFFF;
2247c478bd9Sstevel@tonic-gate int def_rexmit = 0;
2257c478bd9Sstevel@tonic-gate int def_wait = 32;
2267c478bd9Sstevel@tonic-gate int printed_waiting_msg;
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate /*
2297c478bd9Sstevel@tonic-gate * For non-root requests, set a smaller timeout
2307c478bd9Sstevel@tonic-gate */
2317c478bd9Sstevel@tonic-gate if (strcmp(fileid, "root") != 0) {
2327c478bd9Sstevel@tonic-gate /*
2337c478bd9Sstevel@tonic-gate * Only send one request per call
2347c478bd9Sstevel@tonic-gate */
2357c478bd9Sstevel@tonic-gate def_wait = GETFILE_BTIMEO;
2367c478bd9Sstevel@tonic-gate def_rexmit = GETFILE_BTIMEO;
2377c478bd9Sstevel@tonic-gate max_retries = GETFILE_BRETRIES;
2387c478bd9Sstevel@tonic-gate }
2397c478bd9Sstevel@tonic-gate
2407c478bd9Sstevel@tonic-gate arg.client_name = bp.client_name;
2417c478bd9Sstevel@tonic-gate arg.file_id = fileid;
2427c478bd9Sstevel@tonic-gate
2437c478bd9Sstevel@tonic-gate res.server_name = (bp_machine_name_t)bkmem_zalloc(SYS_NMLN + 1);
2447c478bd9Sstevel@tonic-gate res.server_path = (bp_path_t)bkmem_zalloc(SYS_NMLN + 1);
2457c478bd9Sstevel@tonic-gate
2467c478bd9Sstevel@tonic-gate if (res.server_name == NULL || res.server_path == NULL) {
2477c478bd9Sstevel@tonic-gate dprintf("getfile: rpc_call failed: No memory\n");
2487c478bd9Sstevel@tonic-gate errno = ENOMEM;
2497c478bd9Sstevel@tonic-gate if (res.server_name != NULL)
2507c478bd9Sstevel@tonic-gate bkmem_free(res.server_name, SYS_NMLN + 1);
2517c478bd9Sstevel@tonic-gate if (res.server_path != NULL)
2527c478bd9Sstevel@tonic-gate bkmem_free(res.server_path, SYS_NMLN + 1);
2537c478bd9Sstevel@tonic-gate return (FALSE);
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate
2567c478bd9Sstevel@tonic-gate to.sin_family = AF_INET;
2577c478bd9Sstevel@tonic-gate to.sin_addr.s_addr = responder.s_addr;
2587c478bd9Sstevel@tonic-gate to.sin_port = htons(0);
2597c478bd9Sstevel@tonic-gate
2607c478bd9Sstevel@tonic-gate /*
2617c478bd9Sstevel@tonic-gate * Our addressing information was filled in by the call to
2627c478bd9Sstevel@tonic-gate * whoami(), so now send an rpc message to the
2637c478bd9Sstevel@tonic-gate * bootparam daemon requesting our server information.
2647c478bd9Sstevel@tonic-gate *
2657c478bd9Sstevel@tonic-gate * Wait only 32 secs for rpc_call to succeed.
2667c478bd9Sstevel@tonic-gate */
2677c478bd9Sstevel@tonic-gate rexmit = def_rexmit;
2687c478bd9Sstevel@tonic-gate wait = def_wait;
2697c478bd9Sstevel@tonic-gate
2707c478bd9Sstevel@tonic-gate stat = brpc_call((rpcprog_t)BOOTPARAMPROG, (rpcvers_t)BOOTPARAMVERS,
2717c478bd9Sstevel@tonic-gate (rpcproc_t)BOOTPARAMPROC_GETFILE, xdr_bp_getfile_arg, (caddr_t)&arg,
2727c478bd9Sstevel@tonic-gate xdr_bp_getfile_res, (caddr_t)&res, rexmit, wait,
2737c478bd9Sstevel@tonic-gate &to, &from, AUTH_NONE);
2747c478bd9Sstevel@tonic-gate
2757c478bd9Sstevel@tonic-gate if (stat == RPC_TIMEDOUT) {
2767c478bd9Sstevel@tonic-gate /*
2777c478bd9Sstevel@tonic-gate * The server that answered the whoami doesn't
2787c478bd9Sstevel@tonic-gate * answer our getfile. Broadcast the call to all. Keep
2797c478bd9Sstevel@tonic-gate * trying forever. Set up for limited broadcast.
2807c478bd9Sstevel@tonic-gate */
2817c478bd9Sstevel@tonic-gate to.sin_addr.s_addr = htonl(INADDR_BROADCAST);
2827c478bd9Sstevel@tonic-gate to.sin_port = htons(0);
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate rexmit = def_rexmit; /* use default rexmit interval */
2857c478bd9Sstevel@tonic-gate wait = def_wait;
2867c478bd9Sstevel@tonic-gate printed_waiting_msg = 0;
2877c478bd9Sstevel@tonic-gate do {
2887c478bd9Sstevel@tonic-gate /*
2897c478bd9Sstevel@tonic-gate * Limit the number of retries
2907c478bd9Sstevel@tonic-gate */
2917c478bd9Sstevel@tonic-gate if (max_retries-- == 0)
2927c478bd9Sstevel@tonic-gate break;
2937c478bd9Sstevel@tonic-gate
2947c478bd9Sstevel@tonic-gate stat = bpmap_rmtcall((rpcprog_t)BOOTPARAMPROG,
2957c478bd9Sstevel@tonic-gate (rpcvers_t)BOOTPARAMVERS,
2967c478bd9Sstevel@tonic-gate (rpcproc_t)BOOTPARAMPROC_GETFILE,
2977c478bd9Sstevel@tonic-gate xdr_bp_getfile_arg, (caddr_t)&arg,
2987c478bd9Sstevel@tonic-gate xdr_bp_getfile_res, (caddr_t)&res, rexmit,
2997c478bd9Sstevel@tonic-gate wait, &to, &from, AUTH_NONE);
3007c478bd9Sstevel@tonic-gate
3017c478bd9Sstevel@tonic-gate if (stat == RPC_SUCCESS) {
3027c478bd9Sstevel@tonic-gate /*
3037c478bd9Sstevel@tonic-gate * set our destination addresses to
3047c478bd9Sstevel@tonic-gate * those of the server that responded.
3057c478bd9Sstevel@tonic-gate * It's probably our server, and we
3067c478bd9Sstevel@tonic-gate * can thus save arping for no reason later.
3077c478bd9Sstevel@tonic-gate */
3087c478bd9Sstevel@tonic-gate responder.s_addr = from.sin_addr.s_addr;
3097c478bd9Sstevel@tonic-gate if (printed_waiting_msg &&
3107c478bd9Sstevel@tonic-gate (boothowto & RB_VERBOSE)) {
3117c478bd9Sstevel@tonic-gate printf(
3127c478bd9Sstevel@tonic-gate "Bootparam response received.\n");
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate break;
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate if (stat == RPC_TIMEDOUT && !printed_waiting_msg) {
3177c478bd9Sstevel@tonic-gate dprintf(noserver, "getfile");
3187c478bd9Sstevel@tonic-gate printed_waiting_msg = 1;
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate /*
3217c478bd9Sstevel@tonic-gate * Retransmission interval for second and
3227c478bd9Sstevel@tonic-gate * subsequent tries. We expect first bpmap_rmtcall
3237c478bd9Sstevel@tonic-gate * to retransmit and backoff to at least this
3247c478bd9Sstevel@tonic-gate * value.
3257c478bd9Sstevel@tonic-gate */
3267c478bd9Sstevel@tonic-gate rexmit = wait;
3277c478bd9Sstevel@tonic-gate wait = def_wait;
3287c478bd9Sstevel@tonic-gate } while (stat == RPC_TIMEDOUT);
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate
3317c478bd9Sstevel@tonic-gate if (stat == RPC_SUCCESS) {
3327c478bd9Sstevel@tonic-gate /* got the goods */
3337c478bd9Sstevel@tonic-gate bcopy(res.server_name, server_name, strlen(res.server_name));
3347c478bd9Sstevel@tonic-gate bcopy(res.server_path, server_path, strlen(res.server_path));
3357c478bd9Sstevel@tonic-gate switch (res.server_address.address_type) {
3367c478bd9Sstevel@tonic-gate case IP_ADDR_TYPE:
3377c478bd9Sstevel@tonic-gate /*
3387c478bd9Sstevel@tonic-gate * server_address is where we will get our root
3397c478bd9Sstevel@tonic-gate * from. Replace destination entries in address if
3407c478bd9Sstevel@tonic-gate * necessary.
3417c478bd9Sstevel@tonic-gate */
3427c478bd9Sstevel@tonic-gate bcopy((caddr_t)&res.server_address.bp_address_u.ip_addr,
3437c478bd9Sstevel@tonic-gate (caddr_t)server_ip, sizeof (struct in_addr));
3447c478bd9Sstevel@tonic-gate break;
3457c478bd9Sstevel@tonic-gate default:
3467c478bd9Sstevel@tonic-gate dprintf("getfile: unknown address type %d\n",
3477c478bd9Sstevel@tonic-gate res.server_address.address_type);
3487c478bd9Sstevel@tonic-gate server_ip->s_addr = htonl(INADDR_ANY);
3497c478bd9Sstevel@tonic-gate bkmem_free(res.server_name, SYS_NMLN + 1);
3507c478bd9Sstevel@tonic-gate bkmem_free(res.server_path, SYS_NMLN + 1);
3517c478bd9Sstevel@tonic-gate return (FALSE);
3527c478bd9Sstevel@tonic-gate }
3537c478bd9Sstevel@tonic-gate } else {
3547c478bd9Sstevel@tonic-gate dprintf("getfile: rpc_call failed.\n");
3557c478bd9Sstevel@tonic-gate bkmem_free(res.server_name, SYS_NMLN + 1);
3567c478bd9Sstevel@tonic-gate bkmem_free(res.server_path, SYS_NMLN + 1);
3577c478bd9Sstevel@tonic-gate return (FALSE);
3587c478bd9Sstevel@tonic-gate }
3597c478bd9Sstevel@tonic-gate
3607c478bd9Sstevel@tonic-gate bkmem_free(res.server_name, SYS_NMLN + 1);
3617c478bd9Sstevel@tonic-gate bkmem_free(res.server_path, SYS_NMLN + 1);
3627c478bd9Sstevel@tonic-gate
3637c478bd9Sstevel@tonic-gate return (TRUE);
3647c478bd9Sstevel@tonic-gate }
365