1use std::path::Path;
2
3use serde::Serialize;
4
5use crate::{error::CollectResult, utils};
6
7enum KernelRandomInfo {
8 EntropyAvaliable,
9 PoolSize,
10 URandomMinReseedSeconds,
11 WriteWakeupThreshold,
12 ReadWakeupThreshold,
13 Unknown,
14}
15
16impl KernelRandomInfo {
17 fn from(name: &str) -> KernelRandomInfo {
18 match name {
19 "entropy_avail" => KernelRandomInfo::EntropyAvaliable,
20 "poolsize" => KernelRandomInfo::PoolSize,
21 "urandom_min_reseed_secs" => KernelRandomInfo::URandomMinReseedSeconds,
22 "write_wakeup_threshold" => KernelRandomInfo::WriteWakeupThreshold,
23 "read_wakeup_threshold" => KernelRandomInfo::ReadWakeupThreshold,
24 _ => KernelRandomInfo::Unknown,
25 }
26 }
27}
28
29#[derive(Debug, Serialize, Clone, Default)]
31pub struct KernelRandom {
32 pub entropy_available: Option<u64>,
33 pub pool_size: Option<u64>,
34 pub urandom_min_reseed_secs: Option<u64>,
35 pub write_wakeup_threshold: Option<u64>,
36 pub read_wakeup_threshold: Option<u64>,
37}
38
39impl KernelRandom {
40 fn new() -> Self {
41 Default::default()
42 }
43}
44
45pub fn collect() -> CollectResult<KernelRandom> {
58 let krandom_dir = Path::new("/proc/sys/kernel/random");
59 collect_from(krandom_dir)
60}
61
62fn collect_from(base_path: &Path) -> CollectResult<KernelRandom> {
63 let mut krandom = KernelRandom::new();
64
65 for item in utils::list_dir_content(base_path, "", "random") {
66 match KernelRandomInfo::from(&item) {
67 KernelRandomInfo::EntropyAvaliable => {
68 krandom.entropy_available = utils::collect_info_u64(&item, base_path)?
69 }
70 KernelRandomInfo::PoolSize => {
71 krandom.pool_size = utils::collect_info_u64(&item, base_path)?
72 }
73 KernelRandomInfo::URandomMinReseedSeconds => {
74 krandom.urandom_min_reseed_secs = utils::collect_info_u64(&item, base_path)?
75 }
76 KernelRandomInfo::WriteWakeupThreshold => {
77 krandom.write_wakeup_threshold = utils::collect_info_u64(&item, base_path)?
78 }
79 KernelRandomInfo::ReadWakeupThreshold => {
80 krandom.read_wakeup_threshold = utils::collect_info_u64(&item, base_path)?
81 }
82 KernelRandomInfo::Unknown => {}
83 }
84 }
85
86 Ok(krandom)
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn kernel_random_gen() {
95 let krandom_dir = Path::new("test_data/fixtures/proc/sys/kernel/random");
96 let krandom =
97 collect_from(krandom_dir).expect("collecting random number generator information");
98
99 assert_eq!(krandom.entropy_available.unwrap(), 3943);
100 assert_eq!(krandom.pool_size.unwrap(), 4096);
101 assert_eq!(krandom.urandom_min_reseed_secs.unwrap(), 60);
102 assert_eq!(krandom.write_wakeup_threshold.unwrap(), 3072);
103 assert!(krandom.read_wakeup_threshold.is_none());
104 }
105}