github.com/system-transparency/u-root@v6.0.1-0.20190919065413-ed07a650de4c+incompatible/cmds/exp/dmidecode/dmidecode.go (about)

     1  // Copyright 2016-2019 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"fmt"
     9  	"io"
    10  	"os"
    11  	"strconv"
    12  	"strings"
    13  
    14  	flag "github.com/spf13/pflag"
    15  
    16  	"github.com/u-root/u-root/pkg/smbios"
    17  )
    18  
    19  var (
    20  	flagFromDump = flag.String("from-dump", "", `Read the DMI data from a binary file previously generated using --dump-bin.`)
    21  	flagType     = flag.StringSliceP("type", "t", nil, `Only  display  the  entries of type TYPE. TYPE can be either a DMI type number, or a comma-separated list of type numbers, or a keyword from the following list: bios, system, baseboard, chassis, processor, memory, cache, connector, slot. If this option is used more than once, the set of displayed entries will be the union of all the given types. If TYPE is not provided or not valid, a list of all valid keywords is printed and dmidecode exits with an error.`)
    22  	// NB: When adding flags, update resetFlags in dmidecode_test.
    23  )
    24  
    25  var (
    26  	typeGroups = map[string][]uint8{
    27  		"bios":      {0, 13},
    28  		"system":    {1, 12, 15, 23, 32},
    29  		"baseboard": {2, 10, 41},
    30  		"chassis":   {3},
    31  		"processor": {4},
    32  		"memory":    {5, 6, 16, 17},
    33  		"cache":     {7},
    34  		"connector": {8},
    35  		"slot":      {9},
    36  	}
    37  )
    38  
    39  type dmiDecodeError struct {
    40  	error
    41  	code int
    42  }
    43  
    44  // parseTypeFilter parses the --type argument(s) and returns a set of types taht should be included.
    45  func parseTypeFilter(typeStrings []string) (map[smbios.TableType]bool, error) {
    46  	types := map[smbios.TableType]bool{}
    47  	for _, ts := range typeStrings {
    48  		if tg, ok := typeGroups[strings.ToLower(ts)]; ok {
    49  			for _, t := range tg {
    50  				types[smbios.TableType(t)] = true
    51  			}
    52  		} else {
    53  			u, err := strconv.ParseUint(ts, 0, 8)
    54  			if err != nil {
    55  				return nil, fmt.Errorf("Invalid type: %s", ts)
    56  			}
    57  			types[smbios.TableType(uint8(u))] = true
    58  		}
    59  	}
    60  	return types, nil
    61  }
    62  
    63  func dmiDecode(textOut io.Writer) *dmiDecodeError {
    64  	typeFilter, err := parseTypeFilter(*flagType)
    65  	if err != nil {
    66  		return &dmiDecodeError{code: 2, error: fmt.Errorf("invalid --type: %s", err)}
    67  	}
    68  	entry, data, err := getData(*flagFromDump, "/sys/firmware/dmi/tables")
    69  	if err != nil {
    70  		return &dmiDecodeError{code: 1, error: fmt.Errorf("error parsing loading data: %s", err)}
    71  	}
    72  	si, err := smbios.ParseInfo(entry, data)
    73  	if err != nil {
    74  		return &dmiDecodeError{code: 1, error: fmt.Errorf("error parsing data: %s", err)}
    75  	}
    76  	for _, t := range si.Tables {
    77  		if len(typeFilter) != 0 && !typeFilter[t.Type] {
    78  			continue
    79  		}
    80  		pt, err := smbios.ParseTypedTable(t)
    81  		if err != nil {
    82  			if err != smbios.ErrUnsupportedTableType {
    83  				fmt.Fprintf(os.Stderr, "%s\n", err)
    84  			}
    85  			// Print as raw table
    86  			pt = t
    87  		}
    88  		fmt.Fprintf(textOut, "%s\n\n", pt)
    89  	}
    90  	return nil
    91  }
    92  
    93  func main() {
    94  	flag.Parse()
    95  	err := dmiDecode(os.Stdout)
    96  	if err != nil {
    97  		fmt.Fprintf(os.Stderr, "%s\n", err)
    98  		os.Exit(err.code)
    99  	}
   100  }