File: README.md

package info (click to toggle)
rust-smbios-lib 0.9.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,148 kB
  • sloc: makefile: 4
file content (156 lines) | stat: -rw-r--r-- 6,001 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# smbios-lib
An SMBIOS Library created in Rust that reads and parses raw BIOS data

[![crates.io](https://img.shields.io/crates/v/smbios-lib.svg)](https://crates.io/crates/smbios-lib)
[![smbioslib_ci](https://github.com/jrgerber/smbios-lib/actions/workflows/smbios_ci.yml/badge.svg)](https://github.com/jrgerber/smbios-lib/actions/workflows/smbios_ci.yml)
![LOC](https://tokei.rs/b1/github/jrgerber/smbios-lib?category=code)

## Table of contents
* [General info](#general-info)
* [Dependencies](#dependencies)
* [Security](#security)
* [Examples](#examples)

## General info
This project reads raw [SMBIOS](https://en.wikipedia.org/wiki/BIOS) data from either a device or file and provides the data as an API.

For an example project using this library take a look at [dmidecode-rs](https://github.com/jrgerber/dmidecode-rs).

### Supports
* [DMTF System Management BIOS (SMBIOS) Reference
Specification 3.7.0](https://www.dmtf.org/sites/default/files/standards/documents/DSP0134_3.7.0.pdf)
* Linux
* MacOS
* Windows family

> SMBIOS 3.7.0 contains 49 defined structure types, all of which are covered by this library (types 0-46, 126, and 127).  Support via extensibility exists for types 128-255 (reserved for OEMs).  Extensibility also applies in the case when this library has not been updated for the latest specification version or a pre-released specification and a new type is introduced.

### Project Status
In early development.

The current development stage is to finalize the API design.
	
## Dependencies
* Windows
    * libc = "^0.2"
* MacOS
    * libc = "^0.2"
    * mach2 = "^0.4.1"
    * core-foundation = "~0.9"
    * core-foundation-sys = "~0.8"
    * io-kit-sys = "^0.4.0"
	
## Security
This library design follows a strict security mantra: *"Never trust the input"*.

SMBIOS has been around for decades and has undergone many versions and revisions.  Many OEM vendors have interpreted and implemented the specifications over the years. Known cases of incorrect firmware implementations exist.  This presents a veritable labrynth of logic for both the known and the unknown. Rather than creating such a complex state machine, we take advantage of Rust's [Option<>](https://doc.rust-lang.org/std/option/) trait and assert that the act of retrieval for any and all information may fail.  The burden of proof thus shifts from the library to the library consumer who is required to implement the failing condition arm.

## Examples
### Retrieve a Field of a Single Instance Structure
Some structures are required and are a single instance. (e.g. [SMBiosSystemInformation](src/structs/types/system_information.rs))

```rust
#[test]
/// Retrieves the System UUID from a device.
/// UUID is found in the System Information (type 1) structure
fn retrieve_system_uuid() {
    match table_load_from_device() {
        Ok(data) => match data.find_map(|sys_info: SMBiosSystemInformation| sys_info.uuid()) {
            Some(uuid) => println!("System Information UUID == {:?}", uuid),
            None => println!("No System Information (Type 1) structure found with a UUID field"),
        },
        Err(err) => println!("failure: {:?}", err),
    }
}
```

Output:
```
running 1 test
System Information UUID == Uuid(4ee6523f-d56a-f3ea-8e2a-891cf96286ea)
test retrieve_system_uuid ... ok
```

### Retrieve All Instances of a Structure - collect()
Some structures are allowed to have more than one instance. (e.g. [SMBiosMemoryDevice](src/structs/types/memory_device.rs))

```rust
#[test]
/// Prints information for all memory devices within a device.
fn print_all_memory_devices() {
    match table_load_from_device() {
        Ok(data) => {
            for memory_device in data.collect::<SMBiosMemoryDevice>() {
                println!("{:#?}", memory_device);
            }
        }
        Err(err) => println!("failure: {:?}", err),
    }
}
```

Output:
```
running 1 test
smbioslib::structs::types::memory_device::SMBiosMemoryDevice {
    header: smbioslib::core::header::Header {
        struct_type: 17,
        length: 40,
        handle: smbioslib::structs::structure::Handle {
            handle: 8,
        },
    },
    physical_memory_array_handle: Some(
        smbioslib::structs::structure::Handle {
            handle: 1,
        },
    ),
[...elided...]
```

### Retrieve a Structure Given a Handle - find_by_handle()
Some structures point to other structures via handles. (e.g. [SMBiosMemoryDevice](src/structs/types/memory_device.rs) points to [SMBiosPhysicalMemoryArray](src/structs/types/physical_memory_array.rs))

```rust
/// Finds an associated struct by handle
#[test]
fn struct_struct_association() {
    match table_load_from_device() {
        Ok(data) => match data.first::<SMBiosMemoryDevice>() {
            Some(first_memory_device) => {
                let handle = first_memory_device.physical_memory_array_handle().unwrap();
                match data.find_by_handle(&handle) {
                    Some(undefined_struct) => {
                        let physical_memory_array = undefined_struct.defined_struct();
                        println!("{:#?}", physical_memory_array)
                    }
                    None => println!("No Physical Memory Array (Type 16) structure found"),
                }
            }
            None => println!("No Memory Device (Type 17) structure found"),
        },
        Err(err) => println!("failure: {:?}", err),
    }
}
```

Output:
```
running 1 test
PhysicalMemoryArray(
    smbioslib::structs::types::physical_memory_array::SMBiosPhysicalMemoryArray {
        header: smbioslib::core::header::Header {
            struct_type: 16,
            length: 23,
            handle: smbioslib::structs::structure::Handle {
                handle: 1,
            },
        },
        location: Some(
            smbioslib::structs::types::physical_memory_array::MemoryArrayLocationData {
                raw: 3,
                value: SystemBoardOrMotherboard,
            },
        ),
[...elided...]
```