1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate /* 30*7c478bd9Sstevel@tonic-gate * This file contains routines responsible for getting the system's 31*7c478bd9Sstevel@tonic-gate * name and boot params. Most of it comes from the SVR4 diskless boot 32*7c478bd9Sstevel@tonic-gate * code (dlboot_inet), modified to work in a non socket environment. 33*7c478bd9Sstevel@tonic-gate */ 34*7c478bd9Sstevel@tonic-gate 35*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 36*7c478bd9Sstevel@tonic-gate #include <rpc/types.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/errno.h> 38*7c478bd9Sstevel@tonic-gate #include <rpc/auth.h> 39*7c478bd9Sstevel@tonic-gate #include <rpc/xdr.h> 40*7c478bd9Sstevel@tonic-gate #include <rpc/rpc_msg.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/t_lock.h> 42*7c478bd9Sstevel@tonic-gate #include "clnt.h" 43*7c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 44*7c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 45*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 46*7c478bd9Sstevel@tonic-gate #include <sys/socket.h> 47*7c478bd9Sstevel@tonic-gate #include <net/if.h> 48*7c478bd9Sstevel@tonic-gate #include <netinet/if_ether.h> 49*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 50*7c478bd9Sstevel@tonic-gate #include <sys/promif.h> 51*7c478bd9Sstevel@tonic-gate #include <rpcsvc/bootparam.h> 52*7c478bd9Sstevel@tonic-gate #include "pmap.h" 53*7c478bd9Sstevel@tonic-gate #include "brpc.h" 54*7c478bd9Sstevel@tonic-gate #include "socket_inet.h" 55*7c478bd9Sstevel@tonic-gate #include "ipv4.h" 56*7c478bd9Sstevel@tonic-gate #include <sys/salib.h> 57*7c478bd9Sstevel@tonic-gate #include <sys/bootdebug.h> 58*7c478bd9Sstevel@tonic-gate 59*7c478bd9Sstevel@tonic-gate extern int errno; 60*7c478bd9Sstevel@tonic-gate static struct bp_whoami_res bp; 61*7c478bd9Sstevel@tonic-gate static char bp_hostname[SYS_NMLN+1]; 62*7c478bd9Sstevel@tonic-gate static char bp_domainname[SYS_NMLN+1]; 63*7c478bd9Sstevel@tonic-gate static struct in_addr responder; /* network order */ 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate static const char *noserver = 66*7c478bd9Sstevel@tonic-gate "No bootparam (%s) server responding; still trying...\n"; 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate #define GETFILE_BTIMEO 1 69*7c478bd9Sstevel@tonic-gate #define GETFILE_BRETRIES 2 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate #define dprintf if (boothowto & RB_DEBUG) printf 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate /* 74*7c478bd9Sstevel@tonic-gate * Returns TRUE if it has set the global structure 'bp' to our boot 75*7c478bd9Sstevel@tonic-gate * parameters, FALSE if some failure occurred. 76*7c478bd9Sstevel@tonic-gate */ 77*7c478bd9Sstevel@tonic-gate bool_t 78*7c478bd9Sstevel@tonic-gate whoami(void) 79*7c478bd9Sstevel@tonic-gate { 80*7c478bd9Sstevel@tonic-gate struct bp_whoami_arg arg; 81*7c478bd9Sstevel@tonic-gate struct sockaddr_in to, from; 82*7c478bd9Sstevel@tonic-gate struct in_addr ipaddr; 83*7c478bd9Sstevel@tonic-gate enum clnt_stat stat; 84*7c478bd9Sstevel@tonic-gate bool_t retval = TRUE; 85*7c478bd9Sstevel@tonic-gate int rexmit; /* retransmission interval */ 86*7c478bd9Sstevel@tonic-gate int resp_wait; /* secs to wait for resp */ 87*7c478bd9Sstevel@tonic-gate int namelen; 88*7c478bd9Sstevel@tonic-gate int printed_waiting_msg; 89*7c478bd9Sstevel@tonic-gate 90*7c478bd9Sstevel@tonic-gate /* 91*7c478bd9Sstevel@tonic-gate * Set our destination IP address to the limited broadcast address 92*7c478bd9Sstevel@tonic-gate * (INADDR_BROADCAST). 93*7c478bd9Sstevel@tonic-gate */ 94*7c478bd9Sstevel@tonic-gate to.sin_family = AF_INET; 95*7c478bd9Sstevel@tonic-gate to.sin_addr.s_addr = htonl(INADDR_BROADCAST); 96*7c478bd9Sstevel@tonic-gate to.sin_port = htons(0); 97*7c478bd9Sstevel@tonic-gate 98*7c478bd9Sstevel@tonic-gate /* 99*7c478bd9Sstevel@tonic-gate * Set up the arguments expected by bootparamd. 100*7c478bd9Sstevel@tonic-gate */ 101*7c478bd9Sstevel@tonic-gate arg.client_address.address_type = IP_ADDR_TYPE; 102*7c478bd9Sstevel@tonic-gate ipv4_getipaddr(&ipaddr); 103*7c478bd9Sstevel@tonic-gate ipaddr.s_addr = htonl(ipaddr.s_addr); 104*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&ipaddr, 105*7c478bd9Sstevel@tonic-gate (caddr_t)&arg.client_address.bp_address_u.ip_addr, 106*7c478bd9Sstevel@tonic-gate sizeof (ipaddr)); 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate /* 109*7c478bd9Sstevel@tonic-gate * Retransmit/wait for up to resp_wait secs. 110*7c478bd9Sstevel@tonic-gate */ 111*7c478bd9Sstevel@tonic-gate rexmit = 0; /* start at default retransmission interval. */ 112*7c478bd9Sstevel@tonic-gate resp_wait = 16; 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate bp.client_name = &bp_hostname[0]; 115*7c478bd9Sstevel@tonic-gate bp.domain_name = &bp_domainname[0]; 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate /* 118*7c478bd9Sstevel@tonic-gate * Do a broadcast call to find a bootparam daemon that 119*7c478bd9Sstevel@tonic-gate * will tell us our hostname, domainname and any 120*7c478bd9Sstevel@tonic-gate * router that we have to use to talk to our NFS server. 121*7c478bd9Sstevel@tonic-gate */ 122*7c478bd9Sstevel@tonic-gate printed_waiting_msg = 0; 123*7c478bd9Sstevel@tonic-gate do { 124*7c478bd9Sstevel@tonic-gate /* 125*7c478bd9Sstevel@tonic-gate * First try the SunOS portmapper and if no reply is 126*7c478bd9Sstevel@tonic-gate * received will then try the SVR4 rpcbind. 127*7c478bd9Sstevel@tonic-gate * Either way, `bootpaddr' will be set to the 128*7c478bd9Sstevel@tonic-gate * correct address for the bootparamd that responds. 129*7c478bd9Sstevel@tonic-gate */ 130*7c478bd9Sstevel@tonic-gate stat = bpmap_rmtcall((rpcprog_t)BOOTPARAMPROG, 131*7c478bd9Sstevel@tonic-gate (rpcvers_t)BOOTPARAMVERS, (rpcproc_t)BOOTPARAMPROC_WHOAMI, 132*7c478bd9Sstevel@tonic-gate xdr_bp_whoami_arg, (caddr_t)&arg, 133*7c478bd9Sstevel@tonic-gate xdr_bp_whoami_res, (caddr_t)&bp, rexmit, resp_wait, 134*7c478bd9Sstevel@tonic-gate &to, &from, AUTH_NONE); 135*7c478bd9Sstevel@tonic-gate if (stat == RPC_TIMEDOUT && !printed_waiting_msg) { 136*7c478bd9Sstevel@tonic-gate dprintf(noserver, "whoami"); 137*7c478bd9Sstevel@tonic-gate printed_waiting_msg = 1; 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate /* 140*7c478bd9Sstevel@tonic-gate * Retransmission interval for second and subsequent tries. 141*7c478bd9Sstevel@tonic-gate * We expect first bpmap_rmtcall to retransmit and backoff to 142*7c478bd9Sstevel@tonic-gate * at least this value. 143*7c478bd9Sstevel@tonic-gate */ 144*7c478bd9Sstevel@tonic-gate rexmit = resp_wait; 145*7c478bd9Sstevel@tonic-gate resp_wait = 0; /* go to default wait now. */ 146*7c478bd9Sstevel@tonic-gate } while (stat == RPC_TIMEDOUT); 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate if (stat != RPC_SUCCESS) { 149*7c478bd9Sstevel@tonic-gate dprintf("whoami RPC call failed with rpc status: %d\n", stat); 150*7c478bd9Sstevel@tonic-gate retval = FALSE; 151*7c478bd9Sstevel@tonic-gate goto done; 152*7c478bd9Sstevel@tonic-gate } else { 153*7c478bd9Sstevel@tonic-gate if (printed_waiting_msg && (boothowto & RB_VERBOSE)) 154*7c478bd9Sstevel@tonic-gate printf("Bootparam response received\n"); 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate /* Cache responder... We'll send our getfile here... */ 157*7c478bd9Sstevel@tonic-gate responder.s_addr = from.sin_addr.s_addr; 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate namelen = strlen(bp.client_name); 161*7c478bd9Sstevel@tonic-gate if (namelen > SYS_NMLN) { 162*7c478bd9Sstevel@tonic-gate dprintf("whoami: hostname too long"); 163*7c478bd9Sstevel@tonic-gate retval = FALSE; 164*7c478bd9Sstevel@tonic-gate goto done; 165*7c478bd9Sstevel@tonic-gate } 166*7c478bd9Sstevel@tonic-gate if (namelen > 0) { 167*7c478bd9Sstevel@tonic-gate if (boothowto & RB_VERBOSE) 168*7c478bd9Sstevel@tonic-gate printf("hostname: %s\n", bp.client_name); 169*7c478bd9Sstevel@tonic-gate sethostname(bp.client_name, namelen); 170*7c478bd9Sstevel@tonic-gate } else { 171*7c478bd9Sstevel@tonic-gate dprintf("whoami: no host name\n"); 172*7c478bd9Sstevel@tonic-gate retval = FALSE; 173*7c478bd9Sstevel@tonic-gate goto done; 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate namelen = strlen(bp.domain_name); 177*7c478bd9Sstevel@tonic-gate if (namelen > SYS_NMLN) { 178*7c478bd9Sstevel@tonic-gate dprintf("whoami: domainname too long"); 179*7c478bd9Sstevel@tonic-gate retval = FALSE; 180*7c478bd9Sstevel@tonic-gate goto done; 181*7c478bd9Sstevel@tonic-gate } 182*7c478bd9Sstevel@tonic-gate if (namelen > 0) 183*7c478bd9Sstevel@tonic-gate if (boothowto & RB_VERBOSE) 184*7c478bd9Sstevel@tonic-gate printf("domainname: %s\n", bp.domain_name); 185*7c478bd9Sstevel@tonic-gate else 186*7c478bd9Sstevel@tonic-gate dprintf("whoami: no domain name\n"); 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate if (bp.router_address.address_type == IP_ADDR_TYPE) { 189*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&bp.router_address.bp_address_u.ip_addr, 190*7c478bd9Sstevel@tonic-gate (caddr_t)&ipaddr, sizeof (ipaddr)); 191*7c478bd9Sstevel@tonic-gate if (ntohl(ipaddr.s_addr) != INADDR_ANY) { 192*7c478bd9Sstevel@tonic-gate dprintf("whoami: Router ip is: %s\n", 193*7c478bd9Sstevel@tonic-gate inet_ntoa(ipaddr)); 194*7c478bd9Sstevel@tonic-gate /* ipv4_route expects IP addresses in network order */ 195*7c478bd9Sstevel@tonic-gate (void) ipv4_route(IPV4_ADD_ROUTE, RT_DEFAULT, NULL, 196*7c478bd9Sstevel@tonic-gate &ipaddr); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate } else 199*7c478bd9Sstevel@tonic-gate dprintf("whoami: unknown gateway addr family %d\n", 200*7c478bd9Sstevel@tonic-gate bp.router_address.address_type); 201*7c478bd9Sstevel@tonic-gate done: 202*7c478bd9Sstevel@tonic-gate return (retval); 203*7c478bd9Sstevel@tonic-gate } 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate /* 206*7c478bd9Sstevel@tonic-gate * Returns: 207*7c478bd9Sstevel@tonic-gate * 1) The ascii form of our root servers name in `server_name'. 208*7c478bd9Sstevel@tonic-gate * 2) Pathname of our root on the server in `server_path'. 209*7c478bd9Sstevel@tonic-gate * 210*7c478bd9Sstevel@tonic-gate * NOTE: it's ok for getfile() to do dynamic allocation - it's only 211*7c478bd9Sstevel@tonic-gate * used locally, then freed. If the server address returned from the 212*7c478bd9Sstevel@tonic-gate * getfile call is different from our current destination address, 213*7c478bd9Sstevel@tonic-gate * reset destination IP address to the new value. 214*7c478bd9Sstevel@tonic-gate */ 215*7c478bd9Sstevel@tonic-gate bool_t 216*7c478bd9Sstevel@tonic-gate getfile(char *fileid, char *server_name, struct in_addr *server_ip, 217*7c478bd9Sstevel@tonic-gate char *server_path) 218*7c478bd9Sstevel@tonic-gate { 219*7c478bd9Sstevel@tonic-gate struct bp_getfile_arg arg; 220*7c478bd9Sstevel@tonic-gate struct bp_getfile_res res; 221*7c478bd9Sstevel@tonic-gate enum clnt_stat stat; 222*7c478bd9Sstevel@tonic-gate struct sockaddr_in to, from; 223*7c478bd9Sstevel@tonic-gate int rexmit; 224*7c478bd9Sstevel@tonic-gate int wait; 225*7c478bd9Sstevel@tonic-gate uint_t max_retries = 0xFFFFFFFF; 226*7c478bd9Sstevel@tonic-gate int def_rexmit = 0; 227*7c478bd9Sstevel@tonic-gate int def_wait = 32; 228*7c478bd9Sstevel@tonic-gate int printed_waiting_msg; 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate /* 231*7c478bd9Sstevel@tonic-gate * For non-root requests, set a smaller timeout 232*7c478bd9Sstevel@tonic-gate */ 233*7c478bd9Sstevel@tonic-gate if (strcmp(fileid, "root") != 0) { 234*7c478bd9Sstevel@tonic-gate /* 235*7c478bd9Sstevel@tonic-gate * Only send one request per call 236*7c478bd9Sstevel@tonic-gate */ 237*7c478bd9Sstevel@tonic-gate def_wait = GETFILE_BTIMEO; 238*7c478bd9Sstevel@tonic-gate def_rexmit = GETFILE_BTIMEO; 239*7c478bd9Sstevel@tonic-gate max_retries = GETFILE_BRETRIES; 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate 242*7c478bd9Sstevel@tonic-gate arg.client_name = bp.client_name; 243*7c478bd9Sstevel@tonic-gate arg.file_id = fileid; 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate res.server_name = (bp_machine_name_t)bkmem_zalloc(SYS_NMLN + 1); 246*7c478bd9Sstevel@tonic-gate res.server_path = (bp_path_t)bkmem_zalloc(SYS_NMLN + 1); 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate if (res.server_name == NULL || res.server_path == NULL) { 249*7c478bd9Sstevel@tonic-gate dprintf("getfile: rpc_call failed: No memory\n"); 250*7c478bd9Sstevel@tonic-gate errno = ENOMEM; 251*7c478bd9Sstevel@tonic-gate if (res.server_name != NULL) 252*7c478bd9Sstevel@tonic-gate bkmem_free(res.server_name, SYS_NMLN + 1); 253*7c478bd9Sstevel@tonic-gate if (res.server_path != NULL) 254*7c478bd9Sstevel@tonic-gate bkmem_free(res.server_path, SYS_NMLN + 1); 255*7c478bd9Sstevel@tonic-gate return (FALSE); 256*7c478bd9Sstevel@tonic-gate } 257*7c478bd9Sstevel@tonic-gate 258*7c478bd9Sstevel@tonic-gate to.sin_family = AF_INET; 259*7c478bd9Sstevel@tonic-gate to.sin_addr.s_addr = responder.s_addr; 260*7c478bd9Sstevel@tonic-gate to.sin_port = htons(0); 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate /* 263*7c478bd9Sstevel@tonic-gate * Our addressing information was filled in by the call to 264*7c478bd9Sstevel@tonic-gate * whoami(), so now send an rpc message to the 265*7c478bd9Sstevel@tonic-gate * bootparam daemon requesting our server information. 266*7c478bd9Sstevel@tonic-gate * 267*7c478bd9Sstevel@tonic-gate * Wait only 32 secs for rpc_call to succeed. 268*7c478bd9Sstevel@tonic-gate */ 269*7c478bd9Sstevel@tonic-gate rexmit = def_rexmit; 270*7c478bd9Sstevel@tonic-gate wait = def_wait; 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate stat = brpc_call((rpcprog_t)BOOTPARAMPROG, (rpcvers_t)BOOTPARAMVERS, 273*7c478bd9Sstevel@tonic-gate (rpcproc_t)BOOTPARAMPROC_GETFILE, xdr_bp_getfile_arg, (caddr_t)&arg, 274*7c478bd9Sstevel@tonic-gate xdr_bp_getfile_res, (caddr_t)&res, rexmit, wait, 275*7c478bd9Sstevel@tonic-gate &to, &from, AUTH_NONE); 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate if (stat == RPC_TIMEDOUT) { 278*7c478bd9Sstevel@tonic-gate /* 279*7c478bd9Sstevel@tonic-gate * The server that answered the whoami doesn't 280*7c478bd9Sstevel@tonic-gate * answer our getfile. Broadcast the call to all. Keep 281*7c478bd9Sstevel@tonic-gate * trying forever. Set up for limited broadcast. 282*7c478bd9Sstevel@tonic-gate */ 283*7c478bd9Sstevel@tonic-gate to.sin_addr.s_addr = htonl(INADDR_BROADCAST); 284*7c478bd9Sstevel@tonic-gate to.sin_port = htons(0); 285*7c478bd9Sstevel@tonic-gate 286*7c478bd9Sstevel@tonic-gate rexmit = def_rexmit; /* use default rexmit interval */ 287*7c478bd9Sstevel@tonic-gate wait = def_wait; 288*7c478bd9Sstevel@tonic-gate printed_waiting_msg = 0; 289*7c478bd9Sstevel@tonic-gate do { 290*7c478bd9Sstevel@tonic-gate /* 291*7c478bd9Sstevel@tonic-gate * Limit the number of retries 292*7c478bd9Sstevel@tonic-gate */ 293*7c478bd9Sstevel@tonic-gate if (max_retries-- == 0) 294*7c478bd9Sstevel@tonic-gate break; 295*7c478bd9Sstevel@tonic-gate 296*7c478bd9Sstevel@tonic-gate stat = bpmap_rmtcall((rpcprog_t)BOOTPARAMPROG, 297*7c478bd9Sstevel@tonic-gate (rpcvers_t)BOOTPARAMVERS, 298*7c478bd9Sstevel@tonic-gate (rpcproc_t)BOOTPARAMPROC_GETFILE, 299*7c478bd9Sstevel@tonic-gate xdr_bp_getfile_arg, (caddr_t)&arg, 300*7c478bd9Sstevel@tonic-gate xdr_bp_getfile_res, (caddr_t)&res, rexmit, 301*7c478bd9Sstevel@tonic-gate wait, &to, &from, AUTH_NONE); 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate if (stat == RPC_SUCCESS) { 304*7c478bd9Sstevel@tonic-gate /* 305*7c478bd9Sstevel@tonic-gate * set our destination addresses to 306*7c478bd9Sstevel@tonic-gate * those of the server that responded. 307*7c478bd9Sstevel@tonic-gate * It's probably our server, and we 308*7c478bd9Sstevel@tonic-gate * can thus save arping for no reason later. 309*7c478bd9Sstevel@tonic-gate */ 310*7c478bd9Sstevel@tonic-gate responder.s_addr = from.sin_addr.s_addr; 311*7c478bd9Sstevel@tonic-gate if (printed_waiting_msg && 312*7c478bd9Sstevel@tonic-gate (boothowto & RB_VERBOSE)) { 313*7c478bd9Sstevel@tonic-gate printf( 314*7c478bd9Sstevel@tonic-gate "Bootparam response received.\n"); 315*7c478bd9Sstevel@tonic-gate } 316*7c478bd9Sstevel@tonic-gate break; 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate if (stat == RPC_TIMEDOUT && !printed_waiting_msg) { 319*7c478bd9Sstevel@tonic-gate dprintf(noserver, "getfile"); 320*7c478bd9Sstevel@tonic-gate printed_waiting_msg = 1; 321*7c478bd9Sstevel@tonic-gate } 322*7c478bd9Sstevel@tonic-gate /* 323*7c478bd9Sstevel@tonic-gate * Retransmission interval for second and 324*7c478bd9Sstevel@tonic-gate * subsequent tries. We expect first bpmap_rmtcall 325*7c478bd9Sstevel@tonic-gate * to retransmit and backoff to at least this 326*7c478bd9Sstevel@tonic-gate * value. 327*7c478bd9Sstevel@tonic-gate */ 328*7c478bd9Sstevel@tonic-gate rexmit = wait; 329*7c478bd9Sstevel@tonic-gate wait = def_wait; 330*7c478bd9Sstevel@tonic-gate } while (stat == RPC_TIMEDOUT); 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate 333*7c478bd9Sstevel@tonic-gate if (stat == RPC_SUCCESS) { 334*7c478bd9Sstevel@tonic-gate /* got the goods */ 335*7c478bd9Sstevel@tonic-gate bcopy(res.server_name, server_name, strlen(res.server_name)); 336*7c478bd9Sstevel@tonic-gate bcopy(res.server_path, server_path, strlen(res.server_path)); 337*7c478bd9Sstevel@tonic-gate switch (res.server_address.address_type) { 338*7c478bd9Sstevel@tonic-gate case IP_ADDR_TYPE: 339*7c478bd9Sstevel@tonic-gate /* 340*7c478bd9Sstevel@tonic-gate * server_address is where we will get our root 341*7c478bd9Sstevel@tonic-gate * from. Replace destination entries in address if 342*7c478bd9Sstevel@tonic-gate * necessary. 343*7c478bd9Sstevel@tonic-gate */ 344*7c478bd9Sstevel@tonic-gate bcopy((caddr_t)&res.server_address.bp_address_u.ip_addr, 345*7c478bd9Sstevel@tonic-gate (caddr_t)server_ip, sizeof (struct in_addr)); 346*7c478bd9Sstevel@tonic-gate break; 347*7c478bd9Sstevel@tonic-gate default: 348*7c478bd9Sstevel@tonic-gate dprintf("getfile: unknown address type %d\n", 349*7c478bd9Sstevel@tonic-gate res.server_address.address_type); 350*7c478bd9Sstevel@tonic-gate server_ip->s_addr = htonl(INADDR_ANY); 351*7c478bd9Sstevel@tonic-gate bkmem_free(res.server_name, SYS_NMLN + 1); 352*7c478bd9Sstevel@tonic-gate bkmem_free(res.server_path, SYS_NMLN + 1); 353*7c478bd9Sstevel@tonic-gate return (FALSE); 354*7c478bd9Sstevel@tonic-gate } 355*7c478bd9Sstevel@tonic-gate } else { 356*7c478bd9Sstevel@tonic-gate dprintf("getfile: rpc_call failed.\n"); 357*7c478bd9Sstevel@tonic-gate bkmem_free(res.server_name, SYS_NMLN + 1); 358*7c478bd9Sstevel@tonic-gate bkmem_free(res.server_path, SYS_NMLN + 1); 359*7c478bd9Sstevel@tonic-gate return (FALSE); 360*7c478bd9Sstevel@tonic-gate } 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate bkmem_free(res.server_name, SYS_NMLN + 1); 363*7c478bd9Sstevel@tonic-gate bkmem_free(res.server_path, SYS_NMLN + 1); 364*7c478bd9Sstevel@tonic-gate 365*7c478bd9Sstevel@tonic-gate return (TRUE); 366*7c478bd9Sstevel@tonic-gate } 367