1use local_ip_address::list_afinet_netifas;
2use std::fmt::Write;
3use std::fs::File;
4use std::io::BufReader;
5use std::io::Read;
6
7const HOSTIDFILE: &str = "/etc/hostid";
8const HOSTSFILE: &str = "/etc/hosts";
9
10#[inline]
11pub fn gethostid() -> String {
21 let fd = File::open(HOSTIDFILE);
22
23 if let Ok(f) = fd {
24 let mut reader = BufReader::new(f);
25
26 let mut buf: [u8; 4] = [0; 4];
27 reader.read_exact(&mut buf[..]).unwrap();
28 buf.reverse();
29
30 let mut s = String::new();
31 for byte in buf.bytes() {
32 write!(&mut s, "{:x}", byte.unwrap()).expect("Unable to write as hex");
33 }
34
35 s
36 }
37 else {
39 let hostname = gethostname().trim().to_string();
40 let fd = File::open(HOSTSFILE);
42
43 let mut ip: Option<String> = None;
44 if let Ok(f) = fd {
45 let mut reader = BufReader::new(f);
46 let mut buf = String::new();
47 reader.read_to_string(&mut buf).unwrap();
48
49 for spl in buf.split('\n') {
50 if spl.contains(&hostname) {
51 ip = Some(spl.split('\t').collect::<Vec<_>>()[0].to_string());
52 }
53 }
54 }
55
56 let ip = match ip {
58 Some(i) => i,
59 None => {
60 let network_interfaces = list_afinet_netifas().unwrap();
61 let (_, i) = local_ip_address::find_ifa(network_interfaces, "lo").unwrap();
62 i.to_string()
63 }
64 };
65
66 let mut u_vec = Vec::with_capacity(4);
68 for c in ip.split('.') {
69 u_vec.push(c.parse().unwrap())
70 }
71 u_vec.reverse();
72
73 let to_shift = u32::from_le_bytes(u_vec.try_into().unwrap());
74 let shifted = to_shift << 16 | to_shift >> 16;
75
76 let mut s = String::with_capacity(4);
77 for byte in shifted.to_le_bytes() {
78 write!(&mut s, "{:02x}", byte).expect("Unable to write as hex");
79 }
80
81 s
82 }
83}
84
85const ETC_HOSTNAME: &str = "/etc/hostname";
86const PROC_HOSTNAME: &str = "/proc/sys/kernel/hostname";
87
88fn gethostname() -> String {
92 if let Ok(f) = File::open(ETC_HOSTNAME) {
93 _get_host_name(f)
94 } else if let Ok(f) = File::open(PROC_HOSTNAME) {
95 _get_host_name(f)
96 } else {
97 panic!("Host does not have hostname");
98 }
99}
100
101#[inline]
102fn _get_host_name(f: File) -> String {
103 let mut reader = BufReader::new(f);
104 let mut buf = String::new();
105 reader.read_to_string(&mut buf).unwrap();
106
107 buf
108}