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