84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * CDDL HEADER START
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * The contents of this file are subject to the terms of the
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier * Common Development and Distribution License (the "License").
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier * You may not use this file except in compliance with the License.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * See the License for the specific language governing permissions
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * and limitations under the License.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * When distributing Covered Code, include this CDDL HEADER in each
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * If applicable, add the following below this CDDL HEADER, with the
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * fields enclosed by brackets "[]" replaced with your own identifying
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * information: Portions Copyright [yyyy] [name of copyright owner]
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * CDDL HEADER END
4e901881a1e657e1cbf12d7ef9b476ec373e7939Dale Ghent * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved.
6734c4b0468cc77a7871a5dd5c23a5562557d64cRobert Mustacchi * Copyright 2015 Joyent, Inc.
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * Use is subject to license terms.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwsstatic const uint_t _smb_hashlen = 64; /* hash length (must be Pof2) */
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwsstatic const char _smb_emptystr[] = ""; /* empty string to return */
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * Strip out identification information for you privacy weenies. This is quite
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * simple using our smbios_info_common() abstraction: we just locate any serial
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * numbers and asset tags for each record, and then zero out those strings.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * Then we must handle two special cases: SMB_TYPE_SYSTEM holds a 16-byte UUID
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * and SMB_TYPE_BATTERY stores a Smart Battery Data Spec 16-bit serial number.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * We use a literal '0' rather than '\0' for zeroing strings because \0\0 in
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * the SMBIOS string table has a special meaning (denotes end-of-record).
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwsstatic void
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws hp->smbh_len >= offsetof(smb_battery_t, smbbat_sdate)) {
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (smbios_info_common(shp, hp->smbh_hdl, &info) != SMB_ERR) {
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwssmbios_bufopen(const smbios_entry_t *ep, const void *buf, size_t len,
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws const uchar_t *p, *q, *s;
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (ep == NULL || buf == NULL || len == 0 || (flags & ~SMB_O_MASK))
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (strncmp(ep->smbe_eanchor, SMB_ENTRY_EANCHOR, SMB_ENTRY_EANCHORLEN))
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (strncmp(ep->smbe_ianchor, SMB_ENTRY_IANCHOR, SMB_ENTRY_IANCHORLEN))
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws smb_dprintf(shp, "opening SMBIOS version %u.%u bcdrev 0x%x\n",
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws ep->smbe_stlen < sizeof (smb_header_t) || len < ep->smbe_stlen)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws for (p = (uchar_t *)ep->smbe_ianchor; p < q + sizeof (*ep); p++)
e4586ebf2f01666696316c178da243993b1a0c04mws * Copy the entry point into our handle. The underlying entry point
e4586ebf2f01666696316c178da243993b1a0c04mws * may be larger than our structure definition, so reset smbe_elen
e4586ebf2f01666696316c178da243993b1a0c04mws * to our internal size and recompute good checksums for our copy.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws shp->sh_structs = smb_alloc(sizeof (smb_struct_t) * ep->smbe_stnum);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws shp->sh_hash = smb_zalloc(sizeof (smb_struct_t *) * shp->sh_hashlen);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws shp->sh_smbvers = SMB_MAJMIN(ep->smbe_major, ep->smbe_minor);
516627f338a630bcf9806a91aa873bbbae9a2facJonathan Matthew if ((const uchar_t *)hp + sizeof (smb_header_t) > q) {
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws smb_dprintf(shp, "struct [%u] type %u len %u hdl %u at %p\n",
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws i, hp->smbh_type, hp->smbh_len, hp->smbh_hdl, (void *)hp);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws break; /* ignore any entries beyond end-of-table */
516627f338a630bcf9806a91aa873bbbae9a2facJonathan Matthew if ((const uchar_t *)hp + hp->smbh_len > q - 2) {
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (*p++ == '\0')
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws n++; /* count strings until \0\0 delimiter */
516627f338a630bcf9806a91aa873bbbae9a2facJonathan Matthew if (p > q - 2) {
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (p > s)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws n++; /* add one for final string in string table */
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws if (*p == '\0') {
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws s = p + 1;
516627f338a630bcf9806a91aa873bbbae9a2facJonathan Matthew /* error out if we couldn't find any complete entries in the table */
516627f338a630bcf9806a91aa873bbbae9a2facJonathan Matthew if ((shp->sh_flags & SMB_FL_TRUNC) && i == 0)
516627f338a630bcf9806a91aa873bbbae9a2facJonathan Matthew return (smb_open_error(shp, errp, ESMB_CORRUPT));
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws sizeof (uint16_t) * shp->sh_structs[i].smbst_strtablen);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws smb_free(shp->sh_structs, sizeof (smb_struct_t) * ep->smbe_stnum);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws smb_free(shp->sh_hash, sizeof (smb_struct_t *) * shp->sh_hashlen);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * Recompute the values of the entry point checksums based upon the content
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * of the specified SMBIOS entry point. We don't need 'shp' but require it
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws * anyway in case future versioning requires variations in the algorithm.
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws/*ARGSUSED*/
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws for (p = (uchar_t *)ep->smbe_ianchor; p < q + sizeof (*ep); p++)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwsconst void *
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws sp->smbstr_size = (size_t)(stp->smbst_end - (uchar_t *)hdr);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwssmbios_lookup_id(smbios_hdl_t *shp, id_t id, smbios_struct_t *sp)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return (0);
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothiersmbios_lookup_type(smbios_hdl_t *shp, uint_t type, smbios_struct_t *sp)
074bb90d80fdbeb2d04a8450a55ecbc96de28785Tom Pothier const smb_struct_t *stp = smb_lookup_type(shp, type);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwssmbios_iter(smbios_hdl_t *shp, smbios_struct_f *func, void *data)
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws const smb_struct_t *stp = shp->sh_hash[id & (shp->sh_hashlen - 1)];
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws switch (id) {
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mwsconst char *
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return ((char *)stp->smbst_str + stp->smbst_strtab[i - 1]);
84ab085a13f931bc78e7415e7ce921dbaa14fcb3mws return (SMB_MAJOR(shp->sh_smbvers) > SMB_MAJOR(version) || (
516627f338a630bcf9806a91aa873bbbae9a2facJonathan Matthew return ((shp->sh_flags & SMB_FL_TRUNC) != 0);