2019-12-10 11:07:05 +00:00
#!/bin/bash
### NOTE: This file will be moved into the PACCOR project, in the "scripts" directory.
### It's here for review, until I get permissions to the PACCOR project
### User customizable values
APP_HOME = "`dirname " $0 "`"
COMPONENTS_URI = "" # Specify the optional components URI field
COMPONENTS_URI_LOCAL_COPY_FOR_HASH = "" # If empty, the optional hashAlgorithm and hashValue fields will not be included for the URI
PROPERTIES_URI = "" # Specify the optional properties URI field
PROPERTIES_URI_LOCAL_COPY_FOR_HASH = "" # If empty, the optional hashAlgorithm and hashValue fields will not be included for the URI
ENTERPRISE_NUMBERS_FILE = " $APP_HOME " "/enterprise-numbers"
PEN_ROOT = "1.3.6.1.4.1." # OID root for the private enterprise numbers
SMBIOS_SCRIPT = " $APP_HOME " "/smbios.sh"
HW_SCRIPT = " $APP_HOME " "/hw.sh" # For components not covered by SMBIOS
2020-02-25 14:51:45 +00:00
NVME_SCRIPT = " $APP_HOME " "/nvme.sh" # For nvme components, until lshw supports them
2019-12-10 11:07:05 +00:00
### SMBIOS Type Constants
source $SMBIOS_SCRIPT
SMBIOS_TYPE_PLATFORM = "1"
SMBIOS_TYPE_CHASSIS = "3"
SMBIOS_TYPE_BIOS = "0"
SMBIOS_TYPE_BASEBOARD = "2"
SMBIOS_TYPE_CPU = "4"
SMBIOS_TYPE_RAM = "17"
### hw
source $HW_SCRIPT
2020-02-25 14:51:45 +00:00
source $NVME_SCRIPT
2019-12-10 11:07:05 +00:00
### ComponentClass values
COMPCLASS_REGISTRY_TCG = "2.23.133.18.3.1" # switch off values within SMBIOS to reveal accurate component classes
COMPCLASS_BASEBOARD = "00030003" # these values are meant to be an example. check the component class registry.
COMPCLASS_BIOS = "00130003"
COMPCLASS_UEFI = "00130002"
COMPCLASS_CHASSIS = "00020001" # TODO: chassis type is included in SMBIOS
COMPCLASS_CPU = "00010002"
COMPCLASS_HDD = "00070002"
COMPCLASS_NIC = "00090002"
COMPCLASS_RAM = "00060001" # TODO: memory type is included in SMBIOS
COMPCLASS_GFX = "00050002"
### JSON Structure Keywords
JSON_COMPONENTS = "COMPONENTS"
JSON_COMPONENTSURI = "COMPONENTSURI"
JSON_PROPERTIES = "PROPERTIES"
JSON_PROPERTIESURI = "PROPERTIESURI"
JSON_PLATFORM = "PLATFORM"
#### JSON Component Keywords
JSON_COMPONENTCLASS = "COMPONENTCLASS"
JSON_COMPONENTCLASSREGISTRY = "COMPONENTCLASSREGISTRY"
JSON_COMPONENTCLASSVALUE = "COMPONENTCLASSVALUE"
JSON_MANUFACTURER = "MANUFACTURER"
JSON_MODEL = "MODEL"
JSON_SERIAL = "SERIAL"
JSON_REVISION = "REVISION"
JSON_MANUFACTURERID = "MANUFACTURERID"
JSON_FIELDREPLACEABLE = "FIELDREPLACEABLE"
JSON_ADDRESSES = "ADDRESSES"
JSON_ETHERNETMAC = "ETHERNETMAC"
JSON_WLANMAC = "WLANMAC"
JSON_BLUETOOTHMAC = "BLUETOOTHMAC"
JSON_COMPONENTPLATFORMCERT = "PLATFORMCERT"
JSON_ATTRIBUTECERTIDENTIFIER = "ATTRIBUTECERTIDENTIFIER"
JSON_GENERICCERTIDENTIFIER = "GENERICCERTIDENTIFIER"
JSON_ISSUER = "ISSUER"
JSON_COMPONENTPLATFORMCERTURI = "PLATFORMCERTURI"
JSON_STATUS = "STATUS"
#### JSON Platform Keywords (Subject Alternative Name)
JSON_PLATFORMMODEL = "PLATFORMMODEL"
JSON_PLATFORMMANUFACTURERSTR = "PLATFORMMANUFACTURERSTR"
JSON_PLATFORMVERSION = "PLATFORMVERSION"
JSON_PLATFORMSERIAL = "PLATFORMSERIAL"
JSON_PLATFORMMANUFACTURERID = "PLATFORMMANUFACTURERID"
#### JSON Platform URI Keywords
JSON_URI = "UNIFORMRESOURCEIDENTIFIER"
JSON_HASHALG = "HASHALGORITHM"
JSON_HASHVALUE = "HASHVALUE"
#### JSON Properties Keywords
JSON_NAME = "NAME"
JSON_VALUE = "VALUE"
NOT_SPECIFIED = "Not Specified"
CHASSIS_SERIAL_NUMBER = "111111"
BASEBOARD_SERIAL_NUMBER = "222222"
BIOS_SERIAL_NUMBER = "333333"
PARSE_CPU_DATA_SERIAL_NUMBER = "111222"
PARSE_RAM_DATA_SERIAL_NUMBER = "222333"
PARSE_NIC_DATA_SERIAL_NUMBER = "333444"
PARSE_HDD_DATA_SERIAL_NUMBER = "444555"
PARSE_GFX_DATA_SERIAL_NUMBER = "555666"
### JSON Structure Format
JSON_INTERMEDIATE_FILE_OBJECT = ' {
%s
} '
JSON_PLATFORM_TEMPLATE = '
\" '"$JSON_PLATFORM"' \" : {
%s
} '
JSON_PROPERTIESURI_TEMPLATE = '
\" '"$JSON_PROPERTIESURI"' \" : {
%s
} '
JSON_COMPONENTSURI_TEMPLATE = '
\" '"$JSON_COMPONENTSURI"' \" : {
%s
} '
JSON_PROPERTY_ARRAY_TEMPLATE = '
\" '"$JSON_PROPERTIES"' \" : [ %s
] '
JSON_COMPONENT_ARRAY_TEMPLATE = '
\" '"$JSON_COMPONENTS"' \" : [ %s
] '
JSON_COMPONENT_TEMPLATE = '
{
%s
} '
JSON_PROPERTY_TEMPLATE = '
{
\" '"$JSON_NAME"' \" : \" %s\" ,
\" '"$JSON_VALUE"' \" : \" %s\"
}
'
JSON_ADDRESSES_TEMPLATE = ' \"' " $JSON_ADDRESSES " '\": [%s]'
JSON_ETHERNETMAC_TEMPLATE = ' {
\" '"$JSON_ETHERNETMAC"' \" : \" %s\" } '
JSON_WLANMAC_TEMPLATE = ' {
\" '"$JSON_WLANMAC"' \" : \" %s\" } '
JSON_BLUETOOTHMAC_TEMPLATE = ' {
\" '"$JSON_BLUETOOTHMAC"' \" : \" %s\" } '
JSON_COMPONENTCLASS_TEMPLATE = ' \"' " $JSON_COMPONENTCLASS " ' \" : {
\" '"$JSON_COMPONENTCLASSREGISTRY"' \" : \" %s\" ,
\" '"$JSON_COMPONENTCLASSVALUE"' \" : \" %s\"
} '
JSON_ATTRIBUTECERTIDENTIFIER_TEMPLATE = ' \"' " $JSON_ATTRIBUTECERTIDENTIFIER " ' \" : {
\" '"$JSON_HASHALG"' \" : \" %s\" ,
\" '"$JSON_HASHVALUE"' \" : \" %s\"
} ,'
JSON_GENERICCERTIDENTIFIER_TEMPLATE = ' \"' " $JSON_GENERICCERTIDENTIFIER " ' \" : {
\" '"$JSON_ISSUER"' \" : \" %s\" ,
\" '"$JSON_SERIAL"' \" : \" %s\"
} ,'
JSON_COMPONENTPLATFORMCERT_TEMPLATE = '
\" '"$JSON_COMPONENTPLATFORMCERT"' \" : {
%s
} '
JSON_COMPONENTPLATFORMCERTURI_TEMPLATE = '
\" '"$JSON_COMPONENTPLATFORMCERTURI"' \" : {
%s
} '
JSON_STATUS_TEMPLATE = '
\" '"$JSON_STATUS"' \" : {
} '
### JSON Constructor Aides
jsonComponentClass ( ) {
printf " $JSON_COMPONENTCLASS_TEMPLATE " " ${ 1 } " " ${ 2 } "
}
jsonManufacturer ( ) {
manufacturer = $( printf '\"' " $JSON_MANUFACTURER " '\": \"%s\"' " ${ 1 } " )
#tmpManufacturerId=$(queryForPen "${1}")
#if [ -n "$tmpManufacturerId" ] && [ "$tmpManufacturerId" != "$PEN_ROOT" ]; then
# tmpManufacturerId=$(jsonManufacturerId "$tmpManufacturerId")
# manufacturer="$manufacturer"",""$tmpManufacturerId"
#fi
printf " $manufacturer "
}
jsonModel ( ) {
printf '\"' " $JSON_MODEL " '\": \"%s\"' " ${ 1 } "
}
jsonSerial ( ) {
printf '\"' " $JSON_SERIAL " '\": \"%s\"' " ${ 1 } "
}
jsonRevision ( ) {
printf '\"' " $JSON_REVISION " '\": \"%s\"' " ${ 1 } "
}
jsonManufacturerId ( ) {
printf '\"' " $JSON_MANUFACTURERID " '\": \"%s\"' " ${ 1 } "
}
jsonFieldReplaceable ( ) {
printf '\"' " $JSON_FIELDREPLACEABLE " '\": \"%s\"' " ${ 1 } "
}
jsonEthernetMac ( ) {
printf " $JSON_ETHERNETMAC_TEMPLATE " " ${ 1 } "
}
jsonWlanMac ( ) {
printf " $JSON_WLANMAC_TEMPLATE " " ${ 1 } "
}
jsonBluetoothMac ( ) {
printf " $JSON_BLUETOOTHMAC_TEMPLATE " " ${ 1 } "
}
jsonPlatformModel ( ) {
printf '\"' " $JSON_PLATFORMMODEL " '\": \"%s\"' " ${ 1 } "
}
jsonPlatformManufacturerStr ( ) {
manufacturer = $( printf '\"' " $JSON_PLATFORMMANUFACTURERSTR " '\": \"%s\"' " ${ 1 } " )
#tmpManufacturerId=$(queryForPen "${1}")
#if [ -n "$tmpManufacturerId" ] && [ "$tmpManufacturerId" != "$PEN_ROOT" ]; then
# tmpManufacturerId=$(jsonPlatformManufacturerId "$tmpManufacturerId")
# manufacturer="$manufacturer"",""$tmpManufacturerId"
#fi
printf " $manufacturer "
}
jsonPlatformVersion ( ) {
printf '\"' " $JSON_PLATFORMVERSION " '\": \"%s\"' " ${ 1 } "
}
jsonPlatformSerial ( ) {
printf '\"' " $JSON_PLATFORMSERIAL " '\": \"%s\"' " ${ 1 } "
}
jsonPlatformManufacturerId ( ) {
printf '\"' " $JSON_PLATFORMMANUFACTURERID " '\": \"%s\"' " ${ 1 } "
}
queryForPen ( ) {
pen = $( grep -B 1 "^[ \t]*" " ${ 1 } " " $" " $ENTERPRISE_NUMBERS_FILE " | sed -n '1p' | tr -d [ :space:] )
printf "%s%s" " $PEN_ROOT " " $pen "
}
jsonProperty ( ) {
if [ -n " ${ 1 } " ] && [ -n " ${ 2 } " ] ; then
if [ -n " ${ 3 } " ] ; then
printf " $JSON_PROPERTY_TEMPLATE " " ${ 1 } " " ${ 2 } " " ${ 3 } "
else
printf " $JSON_PROPERTY_TEMPLATE " " ${ 1 } " " ${ 2 } "
fi
fi
}
jsonUri ( ) {
printf '\"' " $JSON_URI " '\": \"%s\"' " ${ 1 } "
}
jsonHashAlg ( ) {
printf '\"' " $JSON_HASHALG " '\": \"%s\"' " ${ 1 } "
}
jsonHashValue ( ) {
printf '\"' " $JSON_HASHVALUE " '\": \"%s\"' " ${ 1 } "
}
toCSV ( ) {
old = " $IFS "
IFS = ','
value = " $* "
value = $( printf " $value " | tr -s , | sed -e '1s/^[,]*//' | sed -e '$s/[,]*$//' )
printf " $value "
}
jsonAddress ( ) {
printf " $JSON_ADDRESSES_TEMPLATE " " $( toCSV " $@ " ) "
}
jsonComponent ( ) {
printf " $JSON_COMPONENT_TEMPLATE " " $( toCSV " $@ " ) "
}
jsonComponentArray ( ) {
printf " $JSON_COMPONENT_ARRAY_TEMPLATE " " $( toCSV " $@ " ) "
}
jsonPropertyArray ( ) {
if [ " $# " -ne 0 ] ; then
printf " $JSON_PROPERTY_ARRAY_TEMPLATE " " $( toCSV " $@ " ) "
fi
}
jsonPlatformObject ( ) {
printf " $JSON_PLATFORM_TEMPLATE " " $( toCSV " $@ " ) "
}
jsonComponentsUri ( ) {
if [ -n " $COMPONENTS_URI " ] ; then
componentsUri = $( jsonUri " $COMPONENTS_URI " )
componentsUriDetails = ""
if [ -n " $PROPERTIES_URI_LOCAL_COPY_FOR_HASH " ] ; then
hashAlg = "2.16.840.1.101.3.4.2.1" # SHA256, see https://tools.ietf.org/html/rfc5754 for other common hash algorithm IDs
hashValue = $( sha256sum " $COMPONENTS_URI_LOCAL_COPY_FOR_HASH " | sed -r 's/^([0-9a-f]+).*/\1/' | tr -d [ :space:] | xxd -r -p | base64 -w 0)
hashAlgStr = $( jsonHashAlg " $hashAlg " )
hashValueStr = $( jsonHashValue " $hashValue " )
propertiesUriDetails = " $hashAlgStr " "," " $hashValueStr "
fi
printf " $JSON_COMPONENTSURI_TEMPLATE " " $( toCSV " $componentsUri " " $componentsUriDetails " ) "
fi
}
jsonPropertiesUri ( ) {
if [ -n " $PROPERTIES_URI " ] ; then
propertiesUri = $( jsonUri " $PROPERTIES_URI " )
propertiesUriDetails = ""
if [ -n " $PROPERTIES_URI_LOCAL_COPY_FOR_HASH " ] ; then
hashAlg = "2.16.840.1.101.3.4.2.1" # SHA256, see https://tools.ietf.org/html/rfc5754 for other common hash algorithm IDs
hashValue = $( sha256sum " $PROPERTIES_URI_LOCAL_COPY_FOR_HASH " | sed -r 's/^([0-9a-f]+).*/\1/' | tr -d [ :space:] | xxd -r -p | base64 -w 0)
hashAlgStr = $( jsonHashAlg " $hashAlg " )
hashValueStr = $( jsonHashValue " $hashValue " )
propertiesUriDetails = " $hashAlgStr " "," " $hashValueStr "
fi | sed 's/^[ \t]*//;s/[ \t]*$//'
printf " $JSON_PROPERTIESURI_TEMPLATE " " $( toCSV " $propertiesUri " " $propertiesUriDetails " ) "
fi
}
jsonIntermediateFile ( ) {
printf " $JSON_INTERMEDIATE_FILE_OBJECT " " $( toCSV " $@ " ) "
}
standardizeMACAddr ( ) {
mac = $( printf " ${ 1 } " | tr -d "[[:space:]]:-" | awk '{ print toupper($0) }' )
printf " $mac "
}
## Some of the commands below require root.
if [ " $EUID " -ne 0 ]
then echo "Please run as root"
exit
fi
### Gather platform details for the subject alternative name
dmidecodeParseTypeAssumeOneHandle " $SMBIOS_TYPE_PLATFORM "
platformManufacturer = $( dmidecodeGetString $( dmidecodeGetByte "0x4" ) )
platformModel = $( dmidecodeGetString $( dmidecodeGetByte "0x5" ) )
platformVersion = $( dmidecodeGetString $( dmidecodeGetByte "0x6" ) )
platformSerial = $( dmidecodeGetString $( dmidecodeGetByte "0x7" ) )
if [ [ -z " ${ platformManufacturer // } " ] ] ; then
platformManufacturer = " $NOT_SPECIFIED "
fi
platformManufacturer = $( echo " $platformManufacturer " | sed 's/^[ \t]*//;s/[ \t]*$//' )
platformManufacturer = $( jsonPlatformManufacturerStr " $platformManufacturer " )
if [ [ -z " ${ platformModel // } " ] ] ; then
platformModel = " $NOT_SPECIFIED "
fi
platformModel = $( echo " $platformModel " | sed 's/^[ \t]*//;s/[ \t]*$//' )
platformModel = $( jsonPlatformModel " $platformModel " )
if [ [ -z " ${ platformVersion // } " ] ] ; then
platformVersion = " $NOT_SPECIFIED "
fi
platformVersion = $( echo " $platformVersion " | sed 's/^[ \t]*//;s/[ \t]*$//' )
platformVersion = $( jsonPlatformVersion " $platformVersion " )
if ! [ [ -z " ${ platformSerial // } " ] ] ; then
platformSerial = $( echo " $platformSerial " | sed 's/^[ \t]*//;s/[ \t]*$//' )
platformSerial = $( jsonPlatformSerial " $platformSerial " )
fi
platform = $( jsonPlatformObject " $platformManufacturer " " $platformModel " " $platformVersion " " $platformSerial " )
### Gather component details
dmidecodeParseTypeAssumeOneHandle " $SMBIOS_TYPE_CHASSIS "
chassisClass = $( jsonComponentClass " $COMPCLASS_REGISTRY_TCG " " $COMPCLASS_CHASSIS " )
chassisManufacturer = $( dmidecodeGetString $( dmidecodeGetByte "0x4" ) )
chassisModel = $( dmidecodeGetByte "0x5" )
chassisModel = $( printf "%d" "0x" " $chassisModel " ) # Convert to decimal
chassisSerial = $( dmidecodeGetString $( dmidecodeGetByte "0x7" ) )
chassisRevision = $( dmidecodeGetString $( dmidecodeGetByte "0x6" ) )
if [ [ -z " ${ chassisManufacturer // } " ] ] ; then
chassisManufacturer = " $NOT_SPECIFIED "
fi
chassisManufacturer = $( echo " $chassisManufacturer " | sed 's/^[ \t]*//;s/[ \t]*$//' )
chassisManufacturer = $( jsonManufacturer " $chassisManufacturer " )
if [ [ -z " ${ chassisModel // } " ] ] ; then
chassisModel = " $NOT_SPECIFIED "
fi
chassisModel = $( echo " $chassisModel " | sed 's/^[ \t]*//;s/[ \t]*$//' )
chassisModel = $( jsonModel " $chassisModel " )
chassisOptional = ""
if ! [ [ -z " ${ chassisSerial // } " ] ] ; then
chassisSerial = $( echo " $chassisSerial " | sed 's/^[ \t]*//;s/[ \t]*$//' )
chassisSerial = $( jsonSerial " $chassisSerial " )
chassisOptional = " $chassisOptional " "," " $chassisSerial "
fi
if ! [ [ -z " ${ chassisRevision // } " ] ] ; then
chassisRevision = $( echo " $chassisRevision " | sed 's/^[ \t]*//;s/[ \t]*$//' )
chassisRevision = $( jsonRevision " $chassisRevision " )
chassisOptional = " $chassisOptional " "," " $chassisRevision "
fi
chassisOptional = $( printf " $chassisOptional " | cut -c2-)
# Use default SN#
if [ [ -z " ${ chassisOptional // } " ] ] ; then
chassisSerial = $( jsonSerial " $CHASSIS_SERIAL_NUMBER " )
chassisOptional = " $chassisOptional " "," " $chassisSerial "
fi
componentChassis = $( jsonComponent " $chassisClass " " $chassisManufacturer " " $chassisModel " " $chassisOptional " )
### Gather baseboard details
dmidecodeParseTypeAssumeOneHandle " $SMBIOS_TYPE_BASEBOARD "
baseboardClass = $( jsonComponentClass " $COMPCLASS_REGISTRY_TCG " " $COMPCLASS_BASEBOARD " )
baseboardManufacturer = $( dmidecodeGetString $( dmidecodeGetByte "0x4" ) )
baseboardModel = $( dmidecodeGetString $( dmidecodeGetByte "0x5" ) )
baseboardSerial = $( dmidecodeGetString $( dmidecodeGetByte "0x7" ) )
baseboardRevision = $( dmidecodeGetString $( dmidecodeGetByte "0x6" ) )
baseboardFeatureFlags = $( dmidecodeGetByte "0x9" )
baseboardFeatureFlags = $( printf "%d" "0x" " $baseboardFeatureFlags " ) # Convert to decimal
baseboardReplaceableIndicator = "28"
baseboardFieldReplaceableAnswer = "false"
if ( ( ( baseboardFeatureFlags& baseboardReplaceableIndicator) != 0) ) ; then
baseboardFieldReplaceableAnswer = "true"
fi
baseboardFieldReplaceable = $( jsonFieldReplaceable " $baseboardFieldReplaceableAnswer " )
if [ [ -z " ${ baseboardManufacturer // } " ] ] ; then
baseboardManufacturer = " $NOT_SPECIFIED "
fi
baseboardManufacturer = $( echo " $baseboardManufacturer " | sed 's/^[ \t]*//;s/[ \t]*$//' )
baseboardManufacturer = $( jsonManufacturer " $baseboardManufacturer " )
if [ [ -z " ${ baseboardModel // } " ] ] ; then
baseboardModel = " $NOT_SPECIFIED "
fi
baseboardModel = $( echo " $baseboardModel " | sed 's/^[ \t]*//;s/[ \t]*$//' )
baseboardModel = $( jsonModel " $baseboardModel " )
baseboardOptional = ""
if ! [ [ -z " ${ baseboardSerial // } " ] ] ; then
baseboardSerial = $( echo " $baseboardSerial " | sed 's/^[ \t]*//;s/[ \t]*$//' )
baseboardSerial = $( jsonSerial " $baseboardSerial " )
baseboardOptional = " $baseboardOptional " "," " $baseboardSerial "
fi
if ! [ [ -z " ${ baseboardRevision // } " ] ] ; then
baseboardRevision = $( echo " $baseboardRevision " | sed 's/^[ \t]*//;s/[ \t]*$//' )
baseboardRevision = $( jsonRevision " $baseboardRevision " )
baseboardOptional = " $baseboardOptional " "," " $baseboardRevision "
fi
baseboardOptional = $( printf " $baseboardOptional " | cut -c2-)
# Use default SN#
if [ [ -z " ${ baseboardOptional // } " ] ] ; then
baseboardSerial = $( jsonSerial " $BASEBOARD_SERIAL_NUMBER " )
baseboardOptional = " $baseboardOptional " "," " $baseboardSerial "
fi
componentBaseboard = $( jsonComponent " $baseboardClass " " $baseboardManufacturer " " $baseboardModel " " $baseboardFieldReplaceable " " $baseboardOptional " )
### Gather BIOS details
dmidecodeParseTypeAssumeOneHandle " $SMBIOS_TYPE_BIOS "
biosClass = $( jsonComponentClass " $COMPCLASS_REGISTRY_TCG " " $COMPCLASS_BIOS " )
biosManufacturer = $( dmidecodeGetString $( dmidecodeGetByte "0x4" ) )
biosModel = ""
biosSerial = ""
biosRevision = $( dmidecodeGetString $( dmidecodeGetByte "0x5" ) )
if [ [ -z " ${ biosManufacturer // } " ] ] ; then
biosManufacturer = " $NOT_SPECIFIED "
fi
biosManufacturer = $( echo " $biosManufacturer " | sed 's/^[ \t]*//;s/[ \t]*$//' )
biosManufacturer = $( jsonManufacturer " $biosManufacturer " )
if [ [ -z " ${ biosModel // } " ] ] ; then
biosModel = " $NOT_SPECIFIED "
fi
biosModel = $( echo " $biosModel " | sed 's/^[ \t]*//;s/[ \t]*$//' )
biosModel = $( jsonModel " $biosModel " )
biosOptional = ""
if ! [ [ -z " ${ biosSerial // } " ] ] ; then
biosSerial = $( echo " $biosSerial " | sed 's/^[ \t]*//;s/[ \t]*$//' )
biosSerial = $( jsonSerial " $biosSerial " )
biosOptional = " $biosOptional " "," " $biosSerial "
fi
if ! [ [ -z " ${ biosRevision // } " ] ] ; then
biosRevision = $( echo " $biosRevision " | sed 's/^[ \t]*//;s/[ \t]*$//' )
biosRevision = $( jsonRevision " $biosRevision " )
biosOptional = " $biosOptional " "," " $biosRevision "
fi
biosOptional = $( printf " $biosOptional " | cut -c2-)
# Use default SN#
if [ [ -z " ${ biosOptional // } " ] ] ; then
biosSerial = $( jsonSerial " $BIOS_SERIAL_NUMBER " )
biosOptional = " $biosOptional " "," " $biosSerial "
fi
componentBios = $( jsonComponent " $biosClass " " $biosManufacturer " " $biosModel " " $biosOptional " )
parseCpuData ( ) {
dmidecodeHandles " $SMBIOS_TYPE_CPU "
notReplaceableIndicator = "6"
tmpData = ""
numHandles = $( dmidecodeNumHandles)
class = $( jsonComponentClass " $COMPCLASS_REGISTRY_TCG " " $COMPCLASS_CPU " )
for ( ( i = 0 ; i < numHandles ; i++ ) ) ; do
dmidecodeParseHandle " ${ tableHandles [ $i ] } "
manufacturer = $( dmidecodeGetString $( dmidecodeGetByte "0x7" ) )
model = $( dmidecodeGetByte "0x6" )
model = $( printf "%d" "0x" " $model " ) # Convert to decimal
serial = $( dmidecodeGetString $( dmidecodeGetByte "0x20" ) )
revision = $( dmidecodeGetString $( dmidecodeGetByte "0x10" ) )
processorUpgrade = $( dmidecodeGetByte "0x19" )
processorUpgrade = $( printf "%d" "0x" " $processorUpgrade " ) # Convert to decimal
if [ [ -z " ${ manufacturer // } " ] ] ; then
manufacturer = " $NOT_SPECIFIED "
fi
manufacturer = $( echo " $manufacturer " | sed 's/^[ \t]*//;s/[ \t]*$//' )
manufacturer = $( jsonManufacturer " $manufacturer " )
if [ [ -z " ${ model // } " ] ] ; then
model = " $NOT_SPECIFIED "
fi
model = $( echo " $model " | sed 's/^[ \t]*//;s/[ \t]*$//' )
model = $( jsonModel " $model " )
optional = ""
if ! [ [ -z " ${ serial // } " ] ] ; then
serial = $( echo " $serial " | sed 's/^[ \t]*//;s/[ \t]*$//' )
serial = $( jsonSerial " $serial " )
optional = " $optional " "," " $serial "
fi
if ! [ [ -z " ${ revision // } " ] ] ; then
revision = $( echo " $revision " | sed 's/^[ \t]*//;s/[ \t]*$//' )
revision = $( jsonRevision " $revision " )
optional = " $optional " "," " $revision "
fi
optional = $( printf " $optional " | cut -c2-)
# Use default SN#
if [ [ -z " ${ optional // } " ] ] ; then
serial = $( jsonSerial " $PARSE_CPU_DATA_SERIAL_NUMBER " )
optional = " $optional " "," " $serial "
PARSE_CPU_DATA_SERIAL_NUMBER = $(( PARSE_CPU_DATA_SERIAL_NUMBER + 1 ))
fi
replaceable = "true"
if [ $processorUpgrade -eq $notReplaceableIndicator ] ; then
replaceable = "false"
fi
replaceable = $( jsonFieldReplaceable " $replaceable " )
newCpuData = $( jsonComponent " $class " " $manufacturer " " $model " " $replaceable " " $optional " )
tmpData = " $tmpData " "," " $newCpuData "
done
# remove leading comma
tmpData = $( printf " $tmpData " | cut -c2-)
printf " $tmpData "
}
parseRamData ( ) {
dmidecodeHandles " $SMBIOS_TYPE_RAM "
replaceable = $( jsonFieldReplaceable "true" )
tmpData = ""
numHandles = $( dmidecodeNumHandles)
class = $( jsonComponentClass " $COMPCLASS_REGISTRY_TCG " " $COMPCLASS_RAM " )
for ( ( i = 0 ; i < numHandles ; i++ ) ) ; do
dmidecodeParseHandle " ${ tableHandles [ $i ] } "
manufacturer = $( dmidecodeGetString $( dmidecodeGetByte "0x17" ) )
model = $( dmidecodeGetString $( dmidecodeGetByte "0x1A" ) )
serial = $( dmidecodeGetString $( dmidecodeGetByte "0x18" ) )
revision = $( dmidecodeGetString $( dmidecodeGetByte "0x19" ) )
if ( [ [ -z " ${ manufacturer // } " ] ] && [ [ -z " ${ model // } " ] ] && [ [ -z " ${ serial // } " ] ] && [ [ -z " ${ revision // } " ] ] ) ; then
continue
fi
if [ [ -z " ${ manufacturer // } " ] ] ; then
manufacturer = " $NOT_SPECIFIED "
fi
manufacturer = $( echo " $manufacturer " | sed 's/^[ \t]*//;s/[ \t]*$//' )
manufacturer = $( jsonManufacturer " $manufacturer " )
if [ [ -z " ${ model // } " ] ] ; then
model = " $NOT_SPECIFIED "
fi
model = $( echo " $model " | sed 's/^[ \t]*//;s/[ \t]*$//' )
model = $( jsonModel " $model " )
optional = ""
if ! [ [ -z " ${ serial // } " ] ] ; then
serial = $( echo " $serial " | sed 's/^[ \t]*//;s/[ \t]*$//' )
serial = $( jsonSerial " $serial " )
optional = " $optional " "," " $serial "
fi
if ! [ [ -z " ${ revision // } " ] ] ; then
revision = $( echo " $revision " | sed 's/^[ \t]*//;s/[ \t]*$//' )
revision = $( jsonRevision " $revision " )
optional = " $optional " "," " $revision "
fi
optional = $( printf " $optional " | cut -c2-)
# Use default SN#
if [ [ -z " ${ optional // } " ] ] ; then
serial = $( jsonSerial " $PARSE_RAM_DATA_SERIAL_NUMBER " )
optional = " $optional " "," " $serial "
PARSE_RAM_DATA_SERIAL_NUMBER = $(( PARSE_RAM_DATA_SERIAL_NUMBER + 1 ))
fi
newRamData = $( jsonComponent " $class " " $manufacturer " " $model " " $replaceable " " $optional " )
tmpData = " $tmpData " "," " $newRamData "
done
# remove leading comma
tmpData = $( printf " $tmpData " | cut -c2-)
printf " $tmpData "
}
# Write script to parse multiple responses
# Network:
# lshw description: type of address.
# : Ethernet interface, Wireless interface, Bluetooth wireless interface
# vendor: manufacturer
# product: model
# serial: address & serial number
# version: revision
#
# Example:
# ADDRESS1=$(jsonEthernetMac "AB:CD:EE:EE:DE:34")
# ADDR_LIST=$(jsonAddress "$ADDRESS1" "$ADDRESS2")
parseNicData ( ) {
lshwNetwork
replaceable = $( jsonFieldReplaceable "true" )
tmpData = ""
numHandles = $( lshwNumBusItems)
class = $( jsonComponentClass " $COMPCLASS_REGISTRY_TCG " " $COMPCLASS_NIC " )
for ( ( i = 0 ; i < numHandles ; i++ ) ) ; do
manufacturer = $( lshwGetVendorIDFromBusItem " $i " )
2020-02-20 11:29:48 +00:00
model = $( lshwGetProductIDFromBusItem " $i " )
serialConstant = $( lshwGetLogicalNameFromBusItem " $i " )
serialConstant = $( ethtoolPermAddr " $serialConstant " )
2019-12-10 11:07:05 +00:00
serialConstant = $( standardizeMACAddr " ${ serialConstant } " )
serial = ""
2020-02-20 11:29:48 +00:00
revision = $( lshwGetVersionFromBusItem " $i " )
2019-12-10 11:07:05 +00:00
if [ [ -z " ${ manufacturer // } " ] ] && [ [ -z " ${ model // } " ] ] && ( ! [ [ -z " ${ serialConstant // } " ] ] || ! [ [ -z " ${ revision // } " ] ] ) ; then
manufacturer = $( lshwGetVendorNameFromBusItem " $i " )
model = $( lshwGetProductNameFromBusItem " $i " )
fi
if [ [ -z " ${ manufacturer // } " ] ] ; then
manufacturer = " $NOT_SPECIFIED "
fi
manufacturer = $( echo " $manufacturer " | sed 's/^[ \t]*//;s/[ \t]*$//' )
manufacturer = $( jsonManufacturer " $manufacturer " )
if [ [ -z " ${ model // } " ] ] ; then
model = " $NOT_SPECIFIED "
fi
model = $( echo " $model " | sed 's/^[ \t]*//;s/[ \t]*$//' )
model = $( jsonModel " $model " )
optional = ""
if ! [ [ -z " ${ serialConstant // } " ] ] ; then
serial = $( echo " $serialConstant " | sed 's/^[ \t]*//;s/[ \t]*$//' )
serial = $( jsonSerial " $serialConstant " )
optional = " $optional " "," " $serial "
fi
if ! [ [ -z " ${ revision // } " ] ] ; then
revision = $( echo " $revision " | sed 's/^[ \t]*//;s/[ \t]*$//' | awk '{ print toupper($0) }' )
revision = $( jsonRevision " $revision " )
optional = " $optional " "," " $revision "
fi
bluetoothCap = $( lshwBusItemBluetoothCap " $i " )
ethernetCap = $( lshwBusItemEthernetCap " $i " )
wirelessCap = $( lshwBusItemWirelessCap " $i " )
if ( [ -n " $bluetoothCap " ] || [ -n " $ethernetCap " ] || [ -n " $wirelessCap " ] ) && ! [ [ -z " ${ serialConstant // } " ] ] ; then
thisAddress =
if [ -n " $wirelessCap " ] ; then
thisAddress = $( jsonWlanMac " $serialConstant " )
elif [ -n " $bluetoothCap " ] ; then
thisAddress = $( jsonBluetoothMac " $serialConstant " )
elif [ -n " $ethernetCap " ] ; then
thisAddress = $( jsonEthernetMac " $serialConstant " )
fi
if [ -n " $thisAddress " ] ; then
thisAddress = $( jsonAddress " $thisAddress " )
optional = " $optional " "," " $thisAddress "
fi
fi
optional = $( printf " $optional " | cut -c2-)
# Use default SN#
if [ [ -z " ${ optional // } " ] ] ; then
serial = $( jsonSerial " $PARSE_NIC_DATA_SERIAL_NUMBER " )
optional = " $optional " "," " $serial "
PARSE_NIC_DATA_SERIAL_NUMBER = $(( PARSE_NIC_DATA_SERIAL_NUMBER + 1 ))
fi
newNicData = $( jsonComponent " $class " " $manufacturer " " $model " " $replaceable " " $optional " )
tmpData = " $tmpData " "," " $newNicData "
done
# remove leading comma
tmpData = $( printf " $tmpData " | cut -c2-)
printf " $tmpData "
}
parseHddData ( ) {
lshwDisk
replaceable = $( jsonFieldReplaceable "true" )
tmpData = ""
numHandles = $( lshwNumBusItems)
class = $( jsonComponentClass " $COMPCLASS_REGISTRY_TCG " " $COMPCLASS_HDD " )
for ( ( i = 0 ; i < numHandles ; i++ ) ) ; do
manufacturer = $( lshwGetVendorIDFromBusItem " $i " )
2020-02-20 11:29:48 +00:00
model = $( lshwGetProductIDFromBusItem " $i " )
serial = $( lshwGetSerialFromBusItem " $i " )
revision = $( lshwGetVersionFromBusItem " $i " )
2019-12-10 11:07:05 +00:00
if [ [ -z " ${ manufacturer // } " ] ] && [ [ -z " ${ model // } " ] ] && ( ! [ [ -z " ${ serial // } " ] ] || ! [ [ -z " ${ revision // } " ] ] ) ; then
model = $( lshwGetProductNameFromBusItem " $i " )
manufacturer = ""
revision = "" # Seeing inconsistent behavior cross-OS for this case, will return
fi
if [ [ -z " ${ manufacturer // } " ] ] ; then
manufacturer = " $NOT_SPECIFIED "
fi
manufacturer = $( echo " $manufacturer " | sed 's/^[ \t]*//;s/[ \t]*$//' )
manufacturer = $( jsonManufacturer " $manufacturer " )
if [ [ -z " ${ model // } " ] ] ; then
model = " $NOT_SPECIFIED "
fi
model = $( echo " $model " | sed 's/^[ \t]*//;s/[ \t]*$//' )
model = $( jsonModel " $model " )
optional = ""
if ! [ [ -z " ${ serial // } " ] ] ; then
serial = $( echo " $serial " | sed 's/^[ \t]*//;s/[ \t]*$//' )
serial = $( jsonSerial " $serial " )
optional = " $optional " "," " $serial "
fi
if ! [ [ -z " ${ revision // } " ] ] ; then
revision = $( echo " $revision " | sed 's/^[ \t]*//;s/[ \t]*$//' | awk '{ print toupper($0) }' )
revision = $( jsonRevision " $revision " )
optional = " $optional " "," " $revision "
fi
optional = $( printf " $optional " | cut -c2-)
# Use default SN#
if [ [ -z " ${ optional // } " ] ] ; then
serial = $( jsonSerial "PARSE_HDD_DATA_SERIAL_NUMBER" )
optional = " $optional " "," " $serial "
PARSE_HDD_DATA_SERIAL_NUMBER = $(( PARSE_HDD_DATA_SERIAL_NUMBER + 1 ))
fi
newHddData = $( jsonComponent " $class " " $manufacturer " " $model " " $replaceable " " $optional " )
tmpData = " $tmpData " "," " $newHddData "
done
# remove leading comma
tmpData = $( printf " $tmpData " | cut -c2-)
printf " $tmpData "
}
2020-02-25 14:51:45 +00:00
parseNvmeData ( ) {
nvmeParse
replaceable = $( jsonFieldReplaceable "true" )
tmpData = ""
numHandles = $( nvmeNumDevices)
class = $( jsonComponentClass " $COMPCLASS_REGISTRY_TCG " " $COMPCLASS_HDD " )
for ( ( i = 0 ; i < numHandles ; i++ ) ) ; do
manufacturer = "" # Making this appear as it does on windows, lshw doesn't see nvme drives and nvme-cli doesn't return a manufacturer field
model = $( nvmeGetModelNumberForDevice " $i " )
serial = $( nvmeGetNguidForDevice " $i " )
2020-02-25 15:30:37 +00:00
if [ [ $serial = ~ ^[ 0] +$ ] ] ; then
serial = $( nvmeGetEuiForDevice " $i " )
fi
2020-02-25 14:51:45 +00:00
revision = "" # empty for a similar reason to the manufacturer field
if [ [ -z " ${ manufacturer // } " ] ] ; then
manufacturer = " $NOT_SPECIFIED "
fi
manufacturer = $( echo " $manufacturer " | sed 's/^[ \t]*//;s/[ \t]*$//' )
manufacturer = $( jsonManufacturer " $manufacturer " )
if [ [ -z " ${ model // } " ] ] ; then
model = " $NOT_SPECIFIED "
fi
model = $( echo " ${ model : 0 : 16 } " | sed 's/^[ \t]*//;s/[ \t]*$//' ) # limited to 16 characters for compatibility to windows, then trimmed
model = $( jsonModel " $model " )
optional = ""
if ! [ [ -z " ${ serial // } " ] ] ; then
serial = $( echo " ${ serial ^^ } " | sed 's/^[ \t]*//;s/[ \t]*$//' | sed 's/.\{4\}/&_/g' | sed 's/_$/\./' )
serial = $( jsonSerial " $serial " )
optional = " $optional " "," " $serial "
fi
optional = $( printf " $optional " | cut -c2-)
newHddData = $( jsonComponent " $class " " $manufacturer " " $model " " $replaceable " " $optional " )
tmpData = " $tmpData " "," " $newHddData "
done
# remove leading comma
tmpData = $( printf " $tmpData " | cut -c2-)
printf " $tmpData "
}
2019-12-10 11:07:05 +00:00
parseGfxData ( ) {
lshwDisplay
replaceable = $( jsonFieldReplaceable "true" )
tmpData = ""
numHandles = $( lshwNumBusItems)
class = $( jsonComponentClass " $COMPCLASS_REGISTRY_TCG " " $COMPCLASS_GFX " )
for ( ( i = 0 ; i < numHandles ; i++ ) ) ; do
manufacturer = $( lshwGetVendorIDFromBusItem " $i " )
model = $( lshwGetProductIDFromBusItem " $i " )
serial = $( lshwGetSerialFromBusItem " $i " )
revision = $( lshwGetVersionFromBusItem " $i " )
if [ [ -z " ${ manufacturer // } " ] ] && [ [ -z " ${ model // } " ] ] && ( ! [ [ -z " ${ serial // } " ] ] || ! [ [ -z " ${ revision // } " ] ] ) ; then
manufacturer = $( lshwGetVendorNameFromBusItem " $i " )
2020-02-20 11:29:48 +00:00
model = $( lshwGetProductNameFromBusItem " $i " )
2019-12-10 11:07:05 +00:00
fi
if [ [ -z " ${ manufacturer // } " ] ] ; then
manufacturer = " $NOT_SPECIFIED "
fi
manufacturer = $( echo " $manufacturer " | sed 's/^[ \t]*//;s/[ \t]*$//' )
manufacturer = $( jsonManufacturer " $manufacturer " )
if [ [ -z " ${ model // } " ] ] ; then
model = " $NOT_SPECIFIED "
fi
model = $( echo " $model " | sed 's/^[ \t]*//;s/[ \t]*$//' )
model = $( jsonModel " $model " )
optional = ""
if ! [ [ -z " ${ serial // } " ] ] ; then
serial = $( echo " $serial " | sed 's/^[ \t]*//;s/[ \t]*$//' )
serial = $( jsonSerial " $serial " )
optional = " $optional " "," " $serial "
fi
if ! [ [ -z " ${ revision // } " ] ] ; then
revision = $( echo " $revision " | sed 's/^[ \t]*//;s/[ \t]*$//' | awk '{ print toupper($0) }' )
revision = $( jsonRevision " $revision " )
optional = " $optional " "," " $revision "
fi
optional = $( printf " $optional " | cut -c2-)
# Use default SN#
if [ [ -z " ${ optional // } " ] ] ; then
serial = $( jsonSerial "PARSE_GFX_DATA_SERIAL_NUMBER" )
optional = " $optional " "," " $serial "
PARSE_GFX_DATA_SERIAL_NUMBER = $(( PARSE_GFX_DATA_SERIAL_NUMBER + 1 ))
fi
newGfxData = $( jsonComponent " $class " " $manufacturer " " $model " " $replaceable " " $optional " )
tmpData = " $tmpData " "," " $newGfxData "
done
# remove leading comma
tmpData = $( printf " $tmpData " | cut -c2-)
printf " $tmpData "
}
### Gather property details
property1 = $( jsonProperty "uname -r" " $( uname -r) " ) ## Example1
property2 = $( jsonProperty "OS Release" " $( grep 'PRETTY_NAME=' /etc/os-release | sed 's/[^=]*=//' | sed -e 's/^[[:space:]\"]*//' | sed -e 's/[[:space:]\"]*$//' ) " ) ## Example2
### Collate the component details
componentsCPU = $( parseCpuData)
componentsRAM = $( parseRamData)
componentsNIC = $( parseNicData)
componentsHDD = $( parseHddData)
componentsGFX = $( parseGfxData)
2020-02-25 14:51:45 +00:00
componentArray = $( jsonComponentArray " $componentChassis " " $componentBaseboard " " $componentBios " " $componentsCPU " " $componentsRAM " " $componentsNIC " " $componentsHDD " " $componentsNVMe " " $componentsGFX " )
2019-12-10 11:07:05 +00:00
### Collate the property details
propertyArray = $( jsonPropertyArray " $property1 " " $property2 " )
### Construct the final JSON object
FINAL_JSON_OBJECT = $( jsonIntermediateFile " $platform " " $componentArray " " $propertyArray " )
### Collate the URI details, if parameters above are blank, the fields will be excluded from the final JSON structure
if [ -n " $COMPONENTS_URI " ] ; then
componentsUri = $( jsonComponentsUri)
FINAL_JSON_OBJECT = " $FINAL_JSON_OBJECT " "," " $componentsUri "
fi
if [ -n " $PROPERTIES_URI " ] ; then
propertiesUri = $( jsonPropertiesUri)
FINAL_JSON_OBJECT = " $FINAL_JSON_OBJECT " "," " $propertiesUri "
fi
printf " $FINAL_JSON_OBJECT " "\n\n"