yauuid/
node.rs

1//! NodeID represent a MAC address.
2
3use std::convert::From;
4use std::fs;
5use std::path::Path;
6use std::fmt;
7use std::str::from_utf8_unchecked;
8
9#[path = "util.rs"]
10mod util;
11use util::xtob;
12
13#[path = "macros.rs"]
14#[macro_use]
15mod macros;
16
17/// An IEEE 802 MAC address
18#[derive(Debug, Clone, Copy)]
19pub struct Node([u8; 6]);
20
21impl From<[u8; 6]> for Node {
22    fn from(xs: [u8; 6]) -> Self {
23        Node(xs)
24    }
25}
26
27impl Node {
28    /// Creates a node with specified interface name
29    #[cfg(target_os = "linux")]
30    pub fn new(interface: &str) -> Self {
31        let dir = "/sys/class/net";
32        let mut node: [u8; 6] = Default::default();
33
34        // aa:bb:cc:dd:ee:ff
35        let content = fs::read_to_string(Path::new(dir).join(interface).join("address"))
36            .unwrap_or("00:00:00:00:00:00".to_owned());
37
38        let bs = content.as_bytes();
39        for (idx, &x) in [0, 3, 6, 9, 12, 15].iter().enumerate() {
40            node[idx] = xtob(bs[x], bs[x + 1]).unwrap_or_default();
41        }
42
43        Node(node)
44    }
45
46    pub fn id(self) -> [u8; 6] {
47        self.0
48    }
49}
50
51impl fmt::Display for Node {
52    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
53        let xs = self.0;
54
55        let mut bs: [u8; 17] = [b':'; 17];
56        bytes_format!(bs, xs, 0, 0, 1,
57                                 3, 4,
58                                 6, 7,
59                                 9, 10,
60                                 12, 13,
61                                 15, 16);
62
63        unsafe {
64            f.write_str(from_utf8_unchecked(&bs))
65        }
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    #[cfg(target_os = "linux")]
75    fn test_lo_nodeid() {
76        assert_eq!(Node::new("lo").id(), [0; 6]);
77    }
78
79    #[test]
80    #[cfg(target_os = "linux")]
81    fn test_to_string() {
82        let node = Node::new("lo");
83
84        assert_eq!(node.to_string(), "00:00:00:00:00:00");
85    }
86}