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 2002-2003 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 #include <sys/types.h> 30*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 31*7c478bd9Sstevel@tonic-gate #include <dhcp_impl.h> 32*7c478bd9Sstevel@tonic-gate #include <sys/time.h> 33*7c478bd9Sstevel@tonic-gate #include <sys/nvpair.h> 34*7c478bd9Sstevel@tonic-gate #include <netinet/inetutil.h> 35*7c478bd9Sstevel@tonic-gate #include <netinet/in.h> 36*7c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 37*7c478bd9Sstevel@tonic-gate #include <strings.h> 38*7c478bd9Sstevel@tonic-gate #include <net/if.h> 39*7c478bd9Sstevel@tonic-gate #if defined(_BOOT) 40*7c478bd9Sstevel@tonic-gate #include <sys/salib.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/bootcmn.h> 42*7c478bd9Sstevel@tonic-gate #include <ipv4.h> 43*7c478bd9Sstevel@tonic-gate #include <dhcpv4.h> 44*7c478bd9Sstevel@tonic-gate #endif /* defined(_BOOT) */ 45*7c478bd9Sstevel@tonic-gate #include <bootinfo.h> 46*7c478bd9Sstevel@tonic-gate #include <bootinfo_aux.h> 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate /* 49*7c478bd9Sstevel@tonic-gate * Declarations and definitions describing parameters which may be known by 50*7c478bd9Sstevel@tonic-gate * a bootconf name, a property of /chosen, a DHCP option or a 'bootmisc' name. 51*7c478bd9Sstevel@tonic-gate */ 52*7c478bd9Sstevel@tonic-gate typedef struct { 53*7c478bd9Sstevel@tonic-gate const char *opt_name; /* DHCP option name */ 54*7c478bd9Sstevel@tonic-gate dsym_cdtype_t opt_type; /* DHCP option type (dhcp_symbol.h) */ 55*7c478bd9Sstevel@tonic-gate uchar_t opt_cat; /* DHCP option category */ 56*7c478bd9Sstevel@tonic-gate uint16_t opt_code; /* DHCP option code */ 57*7c478bd9Sstevel@tonic-gate uint16_t opt_size; /* DHCP option size (FIELDs only) */ 58*7c478bd9Sstevel@tonic-gate } bi_dhcpopt_t; 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate /* 61*7c478bd9Sstevel@tonic-gate * Possible values for the 'bi_flags' field below. 62*7c478bd9Sstevel@tonic-gate */ 63*7c478bd9Sstevel@tonic-gate #define BI_F_BYTES 0x01 /* chosen value is bytes, not string */ 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate typedef struct { 66*7c478bd9Sstevel@tonic-gate const char *bi_name; /* parameter name */ 67*7c478bd9Sstevel@tonic-gate int bi_repository; /* entry's repository(s) */ 68*7c478bd9Sstevel@tonic-gate int bi_flags; /* BI_F_BYTES or zero */ 69*7c478bd9Sstevel@tonic-gate bi_dhcpopt_t *bi_dhcp; /* &dhcpopt struct */ 70*7c478bd9Sstevel@tonic-gate } bi_param_t; 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate /* 73*7c478bd9Sstevel@tonic-gate * DHCP options which have bootinfo equivalents, and the information 74*7c478bd9Sstevel@tonic-gate * necessary to retrieve their values via dhcp_getinfo(). The 'type' 75*7c478bd9Sstevel@tonic-gate * is necessary so that all values may be converted to ascii strings. 76*7c478bd9Sstevel@tonic-gate */ 77*7c478bd9Sstevel@tonic-gate static bi_dhcpopt_t Yiaddr = { 78*7c478bd9Sstevel@tonic-gate "Yiaddr", DSYM_IP, DSYM_FIELD, 16, 4 79*7c478bd9Sstevel@tonic-gate }; 80*7c478bd9Sstevel@tonic-gate static bi_dhcpopt_t Subnet = { 81*7c478bd9Sstevel@tonic-gate "Subnet", DSYM_IP, DSYM_STANDARD, 1, 0 82*7c478bd9Sstevel@tonic-gate }; 83*7c478bd9Sstevel@tonic-gate static bi_dhcpopt_t Router = { 84*7c478bd9Sstevel@tonic-gate "Router", DSYM_IP, DSYM_STANDARD, 3, 0 85*7c478bd9Sstevel@tonic-gate }; 86*7c478bd9Sstevel@tonic-gate static bi_dhcpopt_t Hostname = { 87*7c478bd9Sstevel@tonic-gate "Hostname", DSYM_ASCII, DSYM_STANDARD, 12, 0 88*7c478bd9Sstevel@tonic-gate }; 89*7c478bd9Sstevel@tonic-gate static bi_dhcpopt_t ClientID = { 90*7c478bd9Sstevel@tonic-gate "ClientID", DSYM_OCTET, DSYM_STANDARD, 61, 0 91*7c478bd9Sstevel@tonic-gate }; 92*7c478bd9Sstevel@tonic-gate static bi_dhcpopt_t SHTTPproxy = { 93*7c478bd9Sstevel@tonic-gate "SHTTPproxy", DSYM_ASCII, DSYM_VENDOR, 17, 0 94*7c478bd9Sstevel@tonic-gate }; 95*7c478bd9Sstevel@tonic-gate #if defined(_BOOT) 96*7c478bd9Sstevel@tonic-gate static bi_dhcpopt_t BootFile = { 97*7c478bd9Sstevel@tonic-gate "BootFile", DSYM_ASCII, DSYM_FIELD, 108, 128 98*7c478bd9Sstevel@tonic-gate }; 99*7c478bd9Sstevel@tonic-gate static bi_dhcpopt_t SbootURI = { 100*7c478bd9Sstevel@tonic-gate "SbootURI", DSYM_ASCII, DSYM_VENDOR, 16, 0 101*7c478bd9Sstevel@tonic-gate }; 102*7c478bd9Sstevel@tonic-gate #else 103*7c478bd9Sstevel@tonic-gate static bi_dhcpopt_t SsysidCF = { 104*7c478bd9Sstevel@tonic-gate "SsysidCF", DSYM_ASCII, DSYM_VENDOR, 13, 0 105*7c478bd9Sstevel@tonic-gate }; 106*7c478bd9Sstevel@tonic-gate static bi_dhcpopt_t SjumpsCF = { 107*7c478bd9Sstevel@tonic-gate "SjumpsCF", DSYM_ASCII, DSYM_VENDOR, 14, 0 108*7c478bd9Sstevel@tonic-gate }; 109*7c478bd9Sstevel@tonic-gate #endif /* defined(_BOOT) */ 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate /* 112*7c478bd9Sstevel@tonic-gate * bootinfo's main data structure. 113*7c478bd9Sstevel@tonic-gate */ 114*7c478bd9Sstevel@tonic-gate static bi_param_t bi_params[] = { 115*7c478bd9Sstevel@tonic-gate /* 116*7c478bd9Sstevel@tonic-gate * Parameters from /chosen or DHCP: 117*7c478bd9Sstevel@tonic-gate */ 118*7c478bd9Sstevel@tonic-gate { BI_HOST_IP, BI_R_CHOSEN|BI_R_DHCPOPT, 119*7c478bd9Sstevel@tonic-gate 0, &Yiaddr }, 120*7c478bd9Sstevel@tonic-gate { BI_SUBNET_MASK, BI_R_CHOSEN|BI_R_DHCPOPT, 121*7c478bd9Sstevel@tonic-gate 0, &Subnet }, 122*7c478bd9Sstevel@tonic-gate { BI_ROUTER_IP, BI_R_CHOSEN|BI_R_DHCPOPT, 123*7c478bd9Sstevel@tonic-gate 0, &Router }, 124*7c478bd9Sstevel@tonic-gate { BI_HOSTNAME, BI_R_CHOSEN|BI_R_DHCPOPT, 125*7c478bd9Sstevel@tonic-gate 0, &Hostname }, 126*7c478bd9Sstevel@tonic-gate { BI_CLIENT_ID, BI_R_CHOSEN|BI_R_DHCPOPT, 127*7c478bd9Sstevel@tonic-gate BI_F_BYTES, &ClientID }, 128*7c478bd9Sstevel@tonic-gate { BI_HTTP_PROXY, BI_R_CHOSEN|BI_R_DHCPOPT, 129*7c478bd9Sstevel@tonic-gate 0, &SHTTPproxy }, 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate #if defined(_BOOT) 132*7c478bd9Sstevel@tonic-gate /* 133*7c478bd9Sstevel@tonic-gate * Parameters from /chosen or DHCP: 134*7c478bd9Sstevel@tonic-gate */ 135*7c478bd9Sstevel@tonic-gate { BI_NETWORK_BOOT_FILE, BI_R_CHOSEN|BI_R_DHCPOPT, 136*7c478bd9Sstevel@tonic-gate 0, &SbootURI }, 137*7c478bd9Sstevel@tonic-gate 138*7c478bd9Sstevel@tonic-gate /* 139*7c478bd9Sstevel@tonic-gate * Parameters from DHCP only: 140*7c478bd9Sstevel@tonic-gate */ 141*7c478bd9Sstevel@tonic-gate { BI_BOOTFILE, BI_R_DHCPOPT, 142*7c478bd9Sstevel@tonic-gate 0, &BootFile }, 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate /* 145*7c478bd9Sstevel@tonic-gate * Parameters from /chosen only: 146*7c478bd9Sstevel@tonic-gate */ 147*7c478bd9Sstevel@tonic-gate { BI_BOOTP_RESPONSE, BI_R_CHOSEN, 148*7c478bd9Sstevel@tonic-gate BI_F_BYTES, NULL }, 149*7c478bd9Sstevel@tonic-gate { BI_NET_CONFIG_STRATEGY, BI_R_CHOSEN, 150*7c478bd9Sstevel@tonic-gate 0, NULL }, 151*7c478bd9Sstevel@tonic-gate 152*7c478bd9Sstevel@tonic-gate /* 153*7c478bd9Sstevel@tonic-gate * Parameters from 'bootmisc' only: 154*7c478bd9Sstevel@tonic-gate */ 155*7c478bd9Sstevel@tonic-gate { BI_BOOTSERVER, BI_R_BOOTMISC, 156*7c478bd9Sstevel@tonic-gate 0, NULL }, 157*7c478bd9Sstevel@tonic-gate { BI_AES_KEY, BI_R_BOOTMISC, 158*7c478bd9Sstevel@tonic-gate BI_F_BYTES, NULL }, 159*7c478bd9Sstevel@tonic-gate { BI_3DES_KEY, BI_R_BOOTMISC, 160*7c478bd9Sstevel@tonic-gate BI_F_BYTES, NULL }, 161*7c478bd9Sstevel@tonic-gate { BI_SHA1_KEY, BI_R_BOOTMISC, 162*7c478bd9Sstevel@tonic-gate BI_F_BYTES, NULL }, 163*7c478bd9Sstevel@tonic-gate #else 164*7c478bd9Sstevel@tonic-gate /* 165*7c478bd9Sstevel@tonic-gate * Parameters from DHCP only: 166*7c478bd9Sstevel@tonic-gate */ 167*7c478bd9Sstevel@tonic-gate { BI_SYSIDCFG, BI_R_DHCPOPT, 168*7c478bd9Sstevel@tonic-gate 0, &SsysidCF }, 169*7c478bd9Sstevel@tonic-gate { BI_JUMPSCFG, BI_R_DHCPOPT, 170*7c478bd9Sstevel@tonic-gate 0, &SjumpsCF }, 171*7c478bd9Sstevel@tonic-gate 172*7c478bd9Sstevel@tonic-gate /* 173*7c478bd9Sstevel@tonic-gate * Parameters from /chosen or 'bootmisc': 174*7c478bd9Sstevel@tonic-gate */ 175*7c478bd9Sstevel@tonic-gate { BI_NET_CONFIG_STRATEGY, BI_R_CHOSEN|BI_R_BOOTMISC, 176*7c478bd9Sstevel@tonic-gate 0, NULL }, 177*7c478bd9Sstevel@tonic-gate 178*7c478bd9Sstevel@tonic-gate /* 179*7c478bd9Sstevel@tonic-gate * Parameters from 'bootmisc' only: 180*7c478bd9Sstevel@tonic-gate */ 181*7c478bd9Sstevel@tonic-gate { BI_ROOTFS_TYPE, BI_R_BOOTMISC, 182*7c478bd9Sstevel@tonic-gate 0, NULL }, 183*7c478bd9Sstevel@tonic-gate { BI_INTERFACE_NAME, BI_R_BOOTMISC, 184*7c478bd9Sstevel@tonic-gate 0, NULL }, 185*7c478bd9Sstevel@tonic-gate #endif /* defined(_BOOT) */ 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate NULL 188*7c478bd9Sstevel@tonic-gate }; 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate /* 191*7c478bd9Sstevel@tonic-gate * Bootmisc data is handled internally as a nvpair list. 192*7c478bd9Sstevel@tonic-gate */ 193*7c478bd9Sstevel@tonic-gate static nvlist_t *bi_nvl = NULL; 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate /* 197*7c478bd9Sstevel@tonic-gate * Scan our parameter table to see whether 'name' matches any entry. 198*7c478bd9Sstevel@tonic-gate */ 199*7c478bd9Sstevel@tonic-gate static bi_param_t * 200*7c478bd9Sstevel@tonic-gate bi_find_param(const char *name) 201*7c478bd9Sstevel@tonic-gate { 202*7c478bd9Sstevel@tonic-gate bi_param_t *bip; 203*7c478bd9Sstevel@tonic-gate 204*7c478bd9Sstevel@tonic-gate for (bip = bi_params; bip->bi_name != NULL; bip++) { 205*7c478bd9Sstevel@tonic-gate if (strcmp(name, bip->bi_name) == 0 || 206*7c478bd9Sstevel@tonic-gate ((bip->bi_repository & BI_R_DHCPOPT) && 207*7c478bd9Sstevel@tonic-gate strcmp(name, bip->bi_dhcp->opt_name) == 0)) { 208*7c478bd9Sstevel@tonic-gate return (bip); 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate return (NULL); 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate /* 215*7c478bd9Sstevel@tonic-gate * Functions for retrieving /chosen, DHCP and bootmisc data. 216*7c478bd9Sstevel@tonic-gate */ 217*7c478bd9Sstevel@tonic-gate static int 218*7c478bd9Sstevel@tonic-gate bi_getval_chosen(bi_param_t *bip, void *valbuf, size_t *vallenp) 219*7c478bd9Sstevel@tonic-gate { 220*7c478bd9Sstevel@tonic-gate size_t buflen = *vallenp; 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate if (!bi_get_chosen_prop(bip->bi_name, valbuf, vallenp)) { 223*7c478bd9Sstevel@tonic-gate return (BI_E_NOVAL); 224*7c478bd9Sstevel@tonic-gate } else if (*vallenp > buflen) { 225*7c478bd9Sstevel@tonic-gate return (BI_E_BUF2SMALL); 226*7c478bd9Sstevel@tonic-gate } 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate return (BI_E_SUCCESS); 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate static int 232*7c478bd9Sstevel@tonic-gate bi_getval_dhcpopt(bi_param_t *bip, void *valbuf, size_t *vallenp) 233*7c478bd9Sstevel@tonic-gate { 234*7c478bd9Sstevel@tonic-gate void *val; 235*7c478bd9Sstevel@tonic-gate size_t len, buflen = *vallenp; 236*7c478bd9Sstevel@tonic-gate struct in_addr ipaddr; 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate if (bip->bi_dhcp->opt_type == DSYM_IP) { 239*7c478bd9Sstevel@tonic-gate val = &ipaddr; 240*7c478bd9Sstevel@tonic-gate len = sizeof (ipaddr); 241*7c478bd9Sstevel@tonic-gate } else { 242*7c478bd9Sstevel@tonic-gate val = valbuf; 243*7c478bd9Sstevel@tonic-gate len = *vallenp; 244*7c478bd9Sstevel@tonic-gate } 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate if (!bi_get_dhcp_info(bip->bi_dhcp->opt_cat, bip->bi_dhcp->opt_code, 247*7c478bd9Sstevel@tonic-gate bip->bi_dhcp->opt_size, val, &len)) { 248*7c478bd9Sstevel@tonic-gate return (BI_E_NOVAL); 249*7c478bd9Sstevel@tonic-gate } 250*7c478bd9Sstevel@tonic-gate 251*7c478bd9Sstevel@tonic-gate switch (bip->bi_dhcp->opt_type) { 252*7c478bd9Sstevel@tonic-gate case DSYM_IP: 253*7c478bd9Sstevel@tonic-gate if (buflen < INET_ADDRSTRLEN + 1) { 254*7c478bd9Sstevel@tonic-gate *vallenp = len; 255*7c478bd9Sstevel@tonic-gate return (BI_E_BUF2SMALL); 256*7c478bd9Sstevel@tonic-gate } 257*7c478bd9Sstevel@tonic-gate len = strlen(strcpy(valbuf, inet_ntoa(ipaddr))) + 1; 258*7c478bd9Sstevel@tonic-gate break; 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate case DSYM_ASCII: 261*7c478bd9Sstevel@tonic-gate if (len >= buflen) 262*7c478bd9Sstevel@tonic-gate return (BI_E_BUF2SMALL); 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate ((uchar_t *)valbuf)[len++] = '\0'; 265*7c478bd9Sstevel@tonic-gate break; 266*7c478bd9Sstevel@tonic-gate } 267*7c478bd9Sstevel@tonic-gate *vallenp = len; 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate return (BI_E_SUCCESS); 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate static int 273*7c478bd9Sstevel@tonic-gate bi_getval_bootmisc(bi_param_t *bip, void *valbuf, size_t *vallenp) 274*7c478bd9Sstevel@tonic-gate { 275*7c478bd9Sstevel@tonic-gate uchar_t *val; 276*7c478bd9Sstevel@tonic-gate uint_t len; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate if (nvlist_lookup_byte_array(bi_nvl, (char *)bip->bi_name, 279*7c478bd9Sstevel@tonic-gate &val, &len) != 0) { 280*7c478bd9Sstevel@tonic-gate return (BI_E_NOVAL); 281*7c478bd9Sstevel@tonic-gate } else if (*vallenp < len) { 282*7c478bd9Sstevel@tonic-gate *vallenp = len; 283*7c478bd9Sstevel@tonic-gate return (BI_E_BUF2SMALL); 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate *vallenp = len; 286*7c478bd9Sstevel@tonic-gate (void) memcpy(valbuf, val, *vallenp); 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate return (BI_E_SUCCESS); 289*7c478bd9Sstevel@tonic-gate } 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate /* 292*7c478bd9Sstevel@tonic-gate * This is also called from the userland bootinfo_aux.c to initialize 293*7c478bd9Sstevel@tonic-gate * its bootmisc data. 294*7c478bd9Sstevel@tonic-gate */ 295*7c478bd9Sstevel@tonic-gate boolean_t 296*7c478bd9Sstevel@tonic-gate bi_put_bootmisc(const char *name, const void *valbuf, size_t vallen) 297*7c478bd9Sstevel@tonic-gate { 298*7c478bd9Sstevel@tonic-gate return (nvlist_add_byte_array(bi_nvl, (char *)name, 299*7c478bd9Sstevel@tonic-gate (uchar_t *)valbuf, (uint_t)vallen) == 0); 300*7c478bd9Sstevel@tonic-gate } 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate #if defined(_BOOT) 303*7c478bd9Sstevel@tonic-gate /* 304*7c478bd9Sstevel@tonic-gate * Functions for storing /chosen and bootmisc data. 305*7c478bd9Sstevel@tonic-gate */ 306*7c478bd9Sstevel@tonic-gate static int 307*7c478bd9Sstevel@tonic-gate bi_putval_chosen(bi_param_t *bip, const void *valbuf, size_t vallen) 308*7c478bd9Sstevel@tonic-gate { 309*7c478bd9Sstevel@tonic-gate return (bi_put_chosen_prop(bip->bi_name, valbuf, vallen, 310*7c478bd9Sstevel@tonic-gate (bip->bi_flags & BI_F_BYTES)) ? BI_E_SUCCESS : BI_E_ERROR); 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate 313*7c478bd9Sstevel@tonic-gate static int 314*7c478bd9Sstevel@tonic-gate bi_putval_bootmisc(bi_param_t *bip, const void *valbuf, size_t vallen) 315*7c478bd9Sstevel@tonic-gate { 316*7c478bd9Sstevel@tonic-gate return (bi_put_bootmisc(bip->bi_name, valbuf, vallen) 317*7c478bd9Sstevel@tonic-gate ? BI_E_SUCCESS : BI_E_ERROR); 318*7c478bd9Sstevel@tonic-gate } 319*7c478bd9Sstevel@tonic-gate #endif /* defined(_BOOT) */ 320*7c478bd9Sstevel@tonic-gate 321*7c478bd9Sstevel@tonic-gate 322*7c478bd9Sstevel@tonic-gate /* 323*7c478bd9Sstevel@tonic-gate * Deallocate resources, etc. after accessing bootinfo. 324*7c478bd9Sstevel@tonic-gate */ 325*7c478bd9Sstevel@tonic-gate void 326*7c478bd9Sstevel@tonic-gate bootinfo_end(void) 327*7c478bd9Sstevel@tonic-gate { 328*7c478bd9Sstevel@tonic-gate if (bi_nvl != NULL) { 329*7c478bd9Sstevel@tonic-gate nvlist_free(bi_nvl); 330*7c478bd9Sstevel@tonic-gate bi_nvl = NULL; 331*7c478bd9Sstevel@tonic-gate bi_end_bootinfo(); 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate } 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate /* 336*7c478bd9Sstevel@tonic-gate * Perform bootinfo initialization. 337*7c478bd9Sstevel@tonic-gate */ 338*7c478bd9Sstevel@tonic-gate boolean_t 339*7c478bd9Sstevel@tonic-gate bootinfo_init(void) 340*7c478bd9Sstevel@tonic-gate { 341*7c478bd9Sstevel@tonic-gate if (bi_nvl == NULL && 342*7c478bd9Sstevel@tonic-gate nvlist_alloc(&bi_nvl, NV_UNIQUE_NAME, 0) == 0) { 343*7c478bd9Sstevel@tonic-gate if (!bi_init_bootinfo()) { 344*7c478bd9Sstevel@tonic-gate nvlist_free(bi_nvl); 345*7c478bd9Sstevel@tonic-gate bi_nvl = NULL; 346*7c478bd9Sstevel@tonic-gate } 347*7c478bd9Sstevel@tonic-gate } 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate return (bi_nvl != NULL); 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate /* 353*7c478bd9Sstevel@tonic-gate * bootinfo_get(const char *name, void *valbuf, size_t *vallenp, 354*7c478bd9Sstevel@tonic-gate * int *repository); 355*7c478bd9Sstevel@tonic-gate * 356*7c478bd9Sstevel@tonic-gate * Obtain a value for a named boot parameter from one of a number of possible 357*7c478bd9Sstevel@tonic-gate * repositories: 358*7c478bd9Sstevel@tonic-gate * 359*7c478bd9Sstevel@tonic-gate * - stored properties under /chosen in the device tree; 360*7c478bd9Sstevel@tonic-gate * - returned DHCP data; 361*7c478bd9Sstevel@tonic-gate * - miscellaneous boot information, determined from the standalone or 362*7c478bd9Sstevel@tonic-gate * the kernel (depending on whether we're in the standalone or userland). 363*7c478bd9Sstevel@tonic-gate * 364*7c478bd9Sstevel@tonic-gate * These repositories are interrogated in the order listed above; the first 365*7c478bd9Sstevel@tonic-gate * one to match is value returned. 366*7c478bd9Sstevel@tonic-gate * 367*7c478bd9Sstevel@tonic-gate * Returns: 368*7c478bd9Sstevel@tonic-gate * 0 => successful, value copied to valbuf, length assigned to *vallen. 369*7c478bd9Sstevel@tonic-gate * >0 => error (BI_E_* codes defined in bootinfo.h) 370*7c478bd9Sstevel@tonic-gate */ 371*7c478bd9Sstevel@tonic-gate bi_errcode_t 372*7c478bd9Sstevel@tonic-gate bootinfo_get(const char *name, void *valbufp, size_t *vallenp, 373*7c478bd9Sstevel@tonic-gate int *repositoryp) 374*7c478bd9Sstevel@tonic-gate { 375*7c478bd9Sstevel@tonic-gate bi_param_t *bip; 376*7c478bd9Sstevel@tonic-gate int repositories; 377*7c478bd9Sstevel@tonic-gate int err; 378*7c478bd9Sstevel@tonic-gate size_t zerolen = 0; 379*7c478bd9Sstevel@tonic-gate 380*7c478bd9Sstevel@tonic-gate /* 381*7c478bd9Sstevel@tonic-gate * Check whether we were successfully initialized. 382*7c478bd9Sstevel@tonic-gate */ 383*7c478bd9Sstevel@tonic-gate if (bi_nvl == NULL) { 384*7c478bd9Sstevel@tonic-gate return (BI_E_ERROR); 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate /* 388*7c478bd9Sstevel@tonic-gate * Determine which repositories might be accessed; a NULL pointer 389*7c478bd9Sstevel@tonic-gate * means to (possibly) access them all. 390*7c478bd9Sstevel@tonic-gate */ 391*7c478bd9Sstevel@tonic-gate if (repositoryp != NULL) { 392*7c478bd9Sstevel@tonic-gate repositories = *repositoryp; 393*7c478bd9Sstevel@tonic-gate *repositoryp = 0; 394*7c478bd9Sstevel@tonic-gate } else { 395*7c478bd9Sstevel@tonic-gate repositories = BI_R_ALL; 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate 398*7c478bd9Sstevel@tonic-gate /* 399*7c478bd9Sstevel@tonic-gate * Check that we know about this name in one or more of the 400*7c478bd9Sstevel@tonic-gate * requested repositories. 401*7c478bd9Sstevel@tonic-gate */ 402*7c478bd9Sstevel@tonic-gate if ((bip = bi_find_param(name)) == NULL) { 403*7c478bd9Sstevel@tonic-gate return (BI_E_ILLNAME); 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate repositories &= bip->bi_repository; 406*7c478bd9Sstevel@tonic-gate if (repositories == 0) { 407*7c478bd9Sstevel@tonic-gate return (BI_E_ILLNAME); 408*7c478bd9Sstevel@tonic-gate } 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate /* 411*7c478bd9Sstevel@tonic-gate * The caller may simply be enquiring whether a value is present: 412*7c478bd9Sstevel@tonic-gate * 413*7c478bd9Sstevel@tonic-gate * bootinfo_get(name, NULL, NULL, repository) == BI_E_BUF2SMALL 414*7c478bd9Sstevel@tonic-gate * 415*7c478bd9Sstevel@tonic-gate * indicates that there is a value, but doesn't fetch it. 416*7c478bd9Sstevel@tonic-gate */ 417*7c478bd9Sstevel@tonic-gate if (vallenp == NULL) { 418*7c478bd9Sstevel@tonic-gate vallenp = &zerolen; 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate 421*7c478bd9Sstevel@tonic-gate /* 422*7c478bd9Sstevel@tonic-gate * To retrieve a value, try the various repositories in order. 423*7c478bd9Sstevel@tonic-gate */ 424*7c478bd9Sstevel@tonic-gate if ((repositories & BI_R_CHOSEN) != 0 && 425*7c478bd9Sstevel@tonic-gate (err = bi_getval_chosen(bip, valbufp, vallenp)) != BI_E_NOVAL) { 426*7c478bd9Sstevel@tonic-gate if (repositoryp != NULL) { 427*7c478bd9Sstevel@tonic-gate *repositoryp = BI_R_CHOSEN; 428*7c478bd9Sstevel@tonic-gate } 429*7c478bd9Sstevel@tonic-gate return (err); 430*7c478bd9Sstevel@tonic-gate } 431*7c478bd9Sstevel@tonic-gate if ((repositories & BI_R_DHCPOPT) != 0 && 432*7c478bd9Sstevel@tonic-gate (err = bi_getval_dhcpopt(bip, valbufp, vallenp)) != BI_E_NOVAL) { 433*7c478bd9Sstevel@tonic-gate if (repositoryp != NULL) { 434*7c478bd9Sstevel@tonic-gate *repositoryp = BI_R_DHCPOPT; 435*7c478bd9Sstevel@tonic-gate } 436*7c478bd9Sstevel@tonic-gate return (err); 437*7c478bd9Sstevel@tonic-gate } 438*7c478bd9Sstevel@tonic-gate if ((repositories & BI_R_BOOTMISC) != 0 && 439*7c478bd9Sstevel@tonic-gate (err = bi_getval_bootmisc(bip, valbufp, vallenp)) != BI_E_NOVAL) { 440*7c478bd9Sstevel@tonic-gate if (repositoryp != NULL) { 441*7c478bd9Sstevel@tonic-gate *repositoryp = BI_R_BOOTMISC; 442*7c478bd9Sstevel@tonic-gate } 443*7c478bd9Sstevel@tonic-gate return (err); 444*7c478bd9Sstevel@tonic-gate } 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate /* 447*7c478bd9Sstevel@tonic-gate * No-one has a value for 'name'. 448*7c478bd9Sstevel@tonic-gate */ 449*7c478bd9Sstevel@tonic-gate return (BI_E_NOVAL); 450*7c478bd9Sstevel@tonic-gate } 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate #if defined(_BOOT) 453*7c478bd9Sstevel@tonic-gate /* 454*7c478bd9Sstevel@tonic-gate * bootinfo_put(const char *name, char *valbuf, int vallen, 455*7c478bd9Sstevel@tonic-gate * int repository); 456*7c478bd9Sstevel@tonic-gate * 457*7c478bd9Sstevel@tonic-gate * Create/update a value in the bootinfo repository (standalone only). 458*7c478bd9Sstevel@tonic-gate * 459*7c478bd9Sstevel@tonic-gate * Returns: 460*7c478bd9Sstevel@tonic-gate * 0 => successful, valbuf[0..vallen-1] bytes stored in repository 461*7c478bd9Sstevel@tonic-gate * >0 => error (BI_E_* codes defined in bootinfo.h) 462*7c478bd9Sstevel@tonic-gate */ 463*7c478bd9Sstevel@tonic-gate int 464*7c478bd9Sstevel@tonic-gate bootinfo_put(const char *name, const void *valbuf, size_t vallen, 465*7c478bd9Sstevel@tonic-gate int repository) 466*7c478bd9Sstevel@tonic-gate { 467*7c478bd9Sstevel@tonic-gate bi_param_t *bip; 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate /* 470*7c478bd9Sstevel@tonic-gate * Check whether we were successfully initialized. 471*7c478bd9Sstevel@tonic-gate */ 472*7c478bd9Sstevel@tonic-gate if (bi_nvl == NULL) { 473*7c478bd9Sstevel@tonic-gate return (BI_E_ERROR); 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate /* 477*7c478bd9Sstevel@tonic-gate * Determine which repositories might be accessed; a zero value 478*7c478bd9Sstevel@tonic-gate * means to (possibly) access them all. 479*7c478bd9Sstevel@tonic-gate */ 480*7c478bd9Sstevel@tonic-gate if (repository == 0) { 481*7c478bd9Sstevel@tonic-gate repository = BI_R_ALL; 482*7c478bd9Sstevel@tonic-gate } 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate /* 485*7c478bd9Sstevel@tonic-gate * Check that we know about this name in the specified repository, 486*7c478bd9Sstevel@tonic-gate * and that it may be written (note that DHCP options cannot be 487*7c478bd9Sstevel@tonic-gate * written). 488*7c478bd9Sstevel@tonic-gate */ 489*7c478bd9Sstevel@tonic-gate if ((bip = bi_find_param(name)) == NULL || 490*7c478bd9Sstevel@tonic-gate (repository & bip->bi_repository) == 0) { 491*7c478bd9Sstevel@tonic-gate return (BI_E_ILLNAME); 492*7c478bd9Sstevel@tonic-gate } 493*7c478bd9Sstevel@tonic-gate if ((repository & bip->bi_repository) == BI_R_DHCPOPT) { 494*7c478bd9Sstevel@tonic-gate return (BI_E_RDONLY); 495*7c478bd9Sstevel@tonic-gate } 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate /* 498*7c478bd9Sstevel@tonic-gate * To put the value, try the various repositories in order. 499*7c478bd9Sstevel@tonic-gate */ 500*7c478bd9Sstevel@tonic-gate if ((bip->bi_repository & BI_R_CHOSEN) != 0) { 501*7c478bd9Sstevel@tonic-gate return (bi_putval_chosen(bip, valbuf, vallen)); 502*7c478bd9Sstevel@tonic-gate } 503*7c478bd9Sstevel@tonic-gate if ((bip->bi_repository & BI_R_BOOTMISC) != 0) { 504*7c478bd9Sstevel@tonic-gate return (bi_putval_bootmisc(bip, valbuf, vallen)); 505*7c478bd9Sstevel@tonic-gate } 506*7c478bd9Sstevel@tonic-gate 507*7c478bd9Sstevel@tonic-gate return (BI_E_ERROR); 508*7c478bd9Sstevel@tonic-gate } 509*7c478bd9Sstevel@tonic-gate #endif /* defined(_BOOT) */ 510