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 }